mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 22:01:45 +00:00
Added a GZDoom Visual Mode, with floor and ceiling texture transformation and coloring
This commit is contained in:
parent
98582e1394
commit
3bbeb51e77
22 changed files with 4879 additions and 2 deletions
|
@ -40,12 +40,29 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="General\BuilderPlug.cs" />
|
||||
<Compile Include="General\CopyStructures.cs" />
|
||||
<Compile Include="General\UndoGroup.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="VisualModes\BaseVisualGeometrySector.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualGeometrySidedef.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualMode.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualSector.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualThing.cs" />
|
||||
<Compile Include="VisualModes\IVisualEventReceiver.cs" />
|
||||
<Compile Include="VisualModes\NullVisualEventReceiver.cs" />
|
||||
<Compile Include="VisualModes\VisualActionResult.cs" />
|
||||
<Compile Include="VisualModes\VisualCeiling.cs" />
|
||||
<Compile Include="VisualModes\VisualFloor.cs" />
|
||||
<Compile Include="VisualModes\VisualLower.cs" />
|
||||
<Compile Include="VisualModes\VisualMiddleDouble.cs" />
|
||||
<Compile Include="VisualModes\VisualMiddleSingle.cs" />
|
||||
<Compile Include="VisualModes\VisualSidedefParts.cs" />
|
||||
<Compile Include="VisualModes\VisualUpper.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
|
@ -62,6 +79,9 @@
|
|||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\VisualModeZ.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\Actions.cfg" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -50,6 +50,23 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
// Static instance
|
||||
private static BuilderPlug me;
|
||||
|
||||
// Settings
|
||||
private int showvisualthings; // 0 = none, 1 = sprite only, 2 = sprite caged
|
||||
private int changeheightbysidedef; // 0 = nothing, 1 = change ceiling, 2 = change floor
|
||||
private bool visualmodeclearselection;
|
||||
private bool usegravity;
|
||||
private bool usehighlight;
|
||||
|
||||
// Copy/paste
|
||||
private string copiedtexture;
|
||||
private string copiedflat;
|
||||
private Point copiedoffsets;
|
||||
private VertexProperties copiedvertexprops;
|
||||
private SectorProperties copiedsectorprops;
|
||||
private SidedefProperties copiedsidedefprops;
|
||||
private LinedefProperties copiedlinedefprops;
|
||||
private ThingProperties copiedthingprops;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -57,6 +74,23 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
// Static property to access the BuilderPlug
|
||||
public static BuilderPlug Me { get { return me; } }
|
||||
|
||||
// Settings
|
||||
public int ShowVisualThings { get { return showvisualthings; } set { showvisualthings = value; } }
|
||||
public int ChangeHeightBySidedef { get { return changeheightbysidedef; } }
|
||||
public bool VisualModeClearSelection { get { return visualmodeclearselection; } }
|
||||
public bool UseGravity { get { return usegravity; } set { usegravity = value; } }
|
||||
public bool UseHighlight { get { return usehighlight; } set { usehighlight = value; } }
|
||||
|
||||
// Copy/paste
|
||||
public string CopiedTexture { get { return copiedtexture; } set { copiedtexture = value; } }
|
||||
public string CopiedFlat { get { return copiedflat; } set { copiedflat = value; } }
|
||||
public Point CopiedOffsets { get { return copiedoffsets; } set { copiedoffsets = value; } }
|
||||
public VertexProperties CopiedVertexProps { get { return copiedvertexprops; } set { copiedvertexprops = value; } }
|
||||
public SectorProperties CopiedSectorProps { get { return copiedsectorprops; } set { copiedsectorprops = value; } }
|
||||
public SidedefProperties CopiedSidedefProps { get { return copiedsidedefprops; } set { copiedsidedefprops = value; } }
|
||||
public LinedefProperties CopiedLinedefProps { get { return copiedlinedefprops; } set { copiedlinedefprops = value; } }
|
||||
public ThingProperties CopiedThingProps { get { return copiedthingprops; } set { copiedthingprops = value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Initialize / Dispose
|
||||
|
@ -68,6 +102,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
// Keep a static reference
|
||||
me = this;
|
||||
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
// This is called when the plugin is terminated
|
||||
|
@ -78,8 +114,32 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
#endregion
|
||||
|
||||
#region ================== Classic Mode Surfaces
|
||||
#region ================== Methods
|
||||
|
||||
// This loads the plugin settings
|
||||
private void LoadSettings()
|
||||
{
|
||||
changeheightbysidedef = General.Settings.ReadPluginSetting("changeheightbysidedef", 0);
|
||||
visualmodeclearselection = General.Settings.ReadPluginSetting("visualmodeclearselection", false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
// When the Preferences dialog is closed
|
||||
public override void OnClosePreferences(PreferencesController controller)
|
||||
{
|
||||
base.OnClosePreferences(controller);
|
||||
|
||||
// Apply settings that could have been changed
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Classic Mode Surfaces
|
||||
|
||||
// This is called when the vertices are created for the classic mode surfaces
|
||||
public override void OnSectorFloorSurfaceUpdate(Sector s, ref FlatVertex[] vertices)
|
||||
{
|
||||
|
|
226
Source/Plugins/GZDoomEditing/General/CopyStructures.cs
Normal file
226
Source/Plugins/GZDoomEditing/General/CopyStructures.cs
Normal file
|
@ -0,0 +1,226 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.Plugins;
|
||||
using CodeImp.DoomBuilder.Types;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
// Vertex
|
||||
public class VertexProperties
|
||||
{
|
||||
private UniFields fields;
|
||||
|
||||
public VertexProperties(Vertex v)
|
||||
{
|
||||
fields = new UniFields(v.Fields);
|
||||
}
|
||||
|
||||
public void Apply(Vertex v)
|
||||
{
|
||||
v.Fields.BeforeFieldsChange();
|
||||
v.Fields.Clear();
|
||||
foreach(KeyValuePair<string, UniValue> uv in fields)
|
||||
v.Fields.Add(uv.Key, new UniValue(uv.Value));
|
||||
}
|
||||
}
|
||||
|
||||
// Sector
|
||||
public class SectorProperties
|
||||
{
|
||||
private int floorheight;
|
||||
private int ceilheight;
|
||||
private string floortexture;
|
||||
private string ceilingtexture;
|
||||
private int effect;
|
||||
private int brightness;
|
||||
private int tag;
|
||||
private UniFields fields;
|
||||
|
||||
public SectorProperties(Sector s)
|
||||
{
|
||||
floorheight = s.FloorHeight;
|
||||
ceilheight = s.CeilHeight;
|
||||
floortexture = s.FloorTexture;
|
||||
ceilingtexture = s.CeilTexture;
|
||||
brightness = s.Brightness;
|
||||
effect = s.Effect;
|
||||
tag = s.Tag;
|
||||
fields = new UniFields(s.Fields);
|
||||
}
|
||||
|
||||
public void Apply(Sector s)
|
||||
{
|
||||
s.FloorHeight = floorheight;
|
||||
s.CeilHeight = ceilheight;
|
||||
s.SetFloorTexture(floortexture);
|
||||
s.SetCeilTexture(ceilingtexture);
|
||||
s.Brightness = brightness;
|
||||
s.Tag = tag;
|
||||
s.Effect = effect;
|
||||
s.Fields.BeforeFieldsChange();
|
||||
s.Fields.Clear();
|
||||
foreach(KeyValuePair<string, UniValue> v in fields)
|
||||
s.Fields.Add(v.Key, new UniValue(v.Value));
|
||||
}
|
||||
}
|
||||
|
||||
// Sidedef
|
||||
public class SidedefProperties
|
||||
{
|
||||
private string hightexture;
|
||||
private string middletexture;
|
||||
private string lowtexture;
|
||||
private int offsetx;
|
||||
private int offsety;
|
||||
private UniFields fields;
|
||||
|
||||
public SidedefProperties(Sidedef s)
|
||||
{
|
||||
hightexture = s.HighTexture;
|
||||
middletexture = s.MiddleTexture;
|
||||
lowtexture = s.LowTexture;
|
||||
offsetx = s.OffsetX;
|
||||
offsety = s.OffsetY;
|
||||
fields = new UniFields(s.Fields);
|
||||
}
|
||||
|
||||
public void Apply(Sidedef s)
|
||||
{
|
||||
s.SetTextureHigh(hightexture);
|
||||
s.SetTextureMid(middletexture);
|
||||
s.SetTextureLow(lowtexture);
|
||||
s.OffsetX = offsetx;
|
||||
s.OffsetY = offsety;
|
||||
s.Fields.BeforeFieldsChange();
|
||||
s.Fields.Clear();
|
||||
foreach(KeyValuePair<string, UniValue> v in fields)
|
||||
s.Fields.Add(v.Key, new UniValue(v.Value));
|
||||
}
|
||||
}
|
||||
|
||||
// Linedef
|
||||
public class LinedefProperties
|
||||
{
|
||||
private SidedefProperties front;
|
||||
private SidedefProperties back;
|
||||
private Dictionary<string, bool> flags;
|
||||
private int action;
|
||||
private int activate;
|
||||
private int tag;
|
||||
private int[] args;
|
||||
private UniFields fields;
|
||||
|
||||
public LinedefProperties(Linedef l)
|
||||
{
|
||||
if(l.Front != null)
|
||||
front = new SidedefProperties(l.Front);
|
||||
else
|
||||
front = null;
|
||||
|
||||
if(l.Back != null)
|
||||
back = new SidedefProperties(l.Back);
|
||||
else
|
||||
back = null;
|
||||
|
||||
flags = l.GetFlags();
|
||||
action = l.Action;
|
||||
activate = l.Activate;
|
||||
tag = l.Tag;
|
||||
args = (int[])(l.Args.Clone());
|
||||
fields = new UniFields(l.Fields);
|
||||
}
|
||||
|
||||
public void Apply(Linedef l)
|
||||
{
|
||||
if((front != null) && (l.Front != null)) front.Apply(l.Front);
|
||||
if((back != null) && (l.Back != null)) back.Apply(l.Back);
|
||||
l.ClearFlags();
|
||||
foreach(KeyValuePair<string, bool> f in flags)
|
||||
l.SetFlag(f.Key, f.Value);
|
||||
l.Action = action;
|
||||
l.Activate = activate;
|
||||
l.Tag = tag;
|
||||
for(int i = 0; i < l.Args.Length; i++)
|
||||
l.Args[i] = args[i];
|
||||
l.Fields.BeforeFieldsChange();
|
||||
l.Fields.Clear();
|
||||
foreach(KeyValuePair<string, UniValue> v in fields)
|
||||
l.Fields.Add(v.Key, new UniValue(v.Value));
|
||||
}
|
||||
}
|
||||
|
||||
// Thing
|
||||
public class ThingProperties
|
||||
{
|
||||
private int type;
|
||||
private float angle;
|
||||
private Dictionary<string, bool> flags;
|
||||
private int tag;
|
||||
private int action;
|
||||
private int[] args;
|
||||
private UniFields fields;
|
||||
|
||||
public ThingProperties(Thing t)
|
||||
{
|
||||
type = t.Type;
|
||||
angle = t.Angle;
|
||||
flags = t.GetFlags();
|
||||
tag = t.Tag;
|
||||
action = t.Action;
|
||||
args = (int[])(t.Args.Clone());
|
||||
fields = new UniFields(t.Fields);
|
||||
}
|
||||
|
||||
public void Apply(Thing t)
|
||||
{
|
||||
t.Type = type;
|
||||
t.Rotate(angle);
|
||||
t.ClearFlags();
|
||||
foreach(KeyValuePair<string, bool> f in flags)
|
||||
t.SetFlag(f.Key, f.Value);
|
||||
t.Tag = tag;
|
||||
t.Action = action;
|
||||
for(int i = 0; i < t.Args.Length; i++)
|
||||
t.Args[i] = args[i];
|
||||
t.Fields.BeforeFieldsChange();
|
||||
t.Fields.Clear();
|
||||
foreach(KeyValuePair<string, UniValue> v in fields)
|
||||
t.Fields.Add(v.Key, new UniValue(v.Value));
|
||||
}
|
||||
}
|
||||
}
|
42
Source/Plugins/GZDoomEditing/General/UndoGroup.cs
Normal file
42
Source/Plugins/GZDoomEditing/General/UndoGroup.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
public class UndoGroup
|
||||
{
|
||||
public const int None = 0;
|
||||
public const int FloorHeightChange = 1;
|
||||
public const int CeilingHeightChange = 2;
|
||||
public const int SectorBrightnessChange = 3;
|
||||
public const int TextureOffsetChange = 4;
|
||||
public const int SectorHeightChange = 5;
|
||||
}
|
||||
}
|
14
Source/Plugins/GZDoomEditing/Resources/Actions.cfg
Normal file
14
Source/Plugins/GZDoomEditing/Resources/Actions.cfg
Normal file
|
@ -0,0 +1,14 @@
|
|||
/******************************************\
|
||||
Doom Builder Actions Configuration
|
||||
\******************************************/
|
||||
|
||||
gzdoomvisualmode
|
||||
{
|
||||
title = "GZDoom Visual Mode";
|
||||
category = "modes";
|
||||
description = "Switches to the (G)ZDoom visual editing mode.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
}
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal abstract class BaseVisualGeometrySector : VisualGeometry, IVisualEventReceiver
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
protected BaseVisualMode mode;
|
||||
protected long setuponloadedtexture;
|
||||
|
||||
// This is only used to see if this object has already received a change
|
||||
// in a multiselection. The Changed property on the BaseVisualSector is
|
||||
// used to indicate a rebuild is needed.
|
||||
protected bool changed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
new public BaseVisualSector Sector { get { return (BaseVisualSector)base.Sector; } }
|
||||
public bool Changed { get { return changed; } set { changed = value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Destructor
|
||||
|
||||
// Constructor
|
||||
public BaseVisualGeometrySector(BaseVisualMode mode, VisualSector vs) : base(vs)
|
||||
{
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This changes the height
|
||||
protected abstract void ChangeHeight(int amount);
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
// Unused
|
||||
public abstract bool Setup();
|
||||
public virtual void OnSelectBegin(){ }
|
||||
public virtual void OnEditBegin() { }
|
||||
public virtual void OnMouseMove(MouseEventArgs e) { }
|
||||
public virtual void OnChangeTextureOffset(int horizontal, int vertical) { }
|
||||
public virtual void OnTextureAlign(bool alignx, bool aligny) { }
|
||||
public virtual void OnToggleUpperUnpegged() { }
|
||||
public virtual void OnToggleLowerUnpegged() { }
|
||||
public virtual void OnResetTextureOffset() { }
|
||||
public virtual void OnCopyTextureOffsets() { }
|
||||
public virtual void OnPasteTextureOffsets() { }
|
||||
public virtual void OnInsert() { }
|
||||
public virtual void OnDelete() { }
|
||||
protected virtual void SetTexture(string texturename) { }
|
||||
public virtual void ApplyUpperUnpegged(bool set) { }
|
||||
public virtual void ApplyLowerUnpegged(bool set) { }
|
||||
|
||||
// Select or deselect
|
||||
public virtual void OnSelectEnd()
|
||||
{
|
||||
if(this.selected)
|
||||
{
|
||||
this.selected = false;
|
||||
mode.RemoveSelectedObject(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selected = true;
|
||||
mode.AddSelectedObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Processing
|
||||
public virtual void OnProcess(double deltatime)
|
||||
{
|
||||
// If the texture was not loaded, but is loaded now, then re-setup geometry
|
||||
if(setuponloadedtexture != 0)
|
||||
{
|
||||
ImageData t = General.Map.Data.GetFlatImage(setuponloadedtexture);
|
||||
if(t != null)
|
||||
{
|
||||
if(t.IsImageLoaded)
|
||||
{
|
||||
setuponloadedtexture = 0;
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flood-fill textures
|
||||
public virtual void OnTextureFloodfill()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedFlat != null)
|
||||
{
|
||||
string oldtexture = GetTextureName();
|
||||
long oldtexturelong = Lump.MakeLongName(oldtexture);
|
||||
string newtexture = BuilderPlug.Me.CopiedFlat;
|
||||
if(newtexture != oldtexture)
|
||||
{
|
||||
// Get the texture
|
||||
ImageData newtextureimage = General.Map.Data.GetFlatImage(newtexture);
|
||||
if(newtextureimage != null)
|
||||
{
|
||||
bool fillceilings = (this is VisualCeiling);
|
||||
|
||||
if(fillceilings)
|
||||
{
|
||||
mode.CreateUndo("Flood-fill ceilings with " + newtexture);
|
||||
mode.SetActionResult("Flood-filled ceilings with " + newtexture + ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
mode.CreateUndo("Flood-fill floors with " + newtexture);
|
||||
mode.SetActionResult("Flood-filled floors with " + newtexture + ".");
|
||||
}
|
||||
|
||||
mode.Renderer.SetCrosshairBusy(true);
|
||||
General.Interface.RedrawDisplay();
|
||||
|
||||
if(mode.IsSingleSelection)
|
||||
{
|
||||
// Clear all marks, this will align everything it can
|
||||
General.Map.Map.ClearMarkedSectors(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Limit the alignment to selection only
|
||||
General.Map.Map.ClearMarkedSectors(true);
|
||||
List<Sector> sectors = mode.GetSelectedSectors();
|
||||
foreach(Sector s in sectors) s.Marked = false;
|
||||
}
|
||||
|
||||
// Do the fill
|
||||
Tools.FloodfillFlats(this.Sector.Sector, fillceilings, oldtexturelong, newtextureimage, false);
|
||||
|
||||
// Get the changed sectors
|
||||
List<Sector> changes = General.Map.Map.GetMarkedSectors(true);
|
||||
foreach(Sector s in changes)
|
||||
{
|
||||
// Update the visual sector
|
||||
if(mode.VisualSectorExists(s))
|
||||
{
|
||||
BaseVisualSector vs = (mode.GetVisualSector(s) as BaseVisualSector);
|
||||
if(fillceilings)
|
||||
vs.Ceiling.Setup();
|
||||
else
|
||||
vs.Floor.Setup();
|
||||
}
|
||||
}
|
||||
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
mode.Renderer.SetCrosshairBusy(false);
|
||||
mode.ShowTargetInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy properties
|
||||
public virtual void OnCopyProperties()
|
||||
{
|
||||
BuilderPlug.Me.CopiedSectorProps = new SectorProperties(Sector.Sector);
|
||||
mode.SetActionResult("Copied sector properties.");
|
||||
}
|
||||
|
||||
// Paste properties
|
||||
public virtual void OnPasteProperties()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedSectorProps != null)
|
||||
{
|
||||
mode.CreateUndo("Paste sector properties");
|
||||
mode.SetActionResult("Pasted sector properties.");
|
||||
BuilderPlug.Me.CopiedSectorProps.Apply(Sector.Sector);
|
||||
Sector.UpdateSectorGeometry(true);
|
||||
mode.ShowTargetInfo();
|
||||
}
|
||||
}
|
||||
|
||||
// Select texture
|
||||
public virtual void OnSelectTexture()
|
||||
{
|
||||
if(General.Interface.IsActiveWindow)
|
||||
{
|
||||
string oldtexture = GetTextureName();
|
||||
string newtexture = General.Interface.BrowseFlat(General.Interface, oldtexture);
|
||||
if(newtexture != oldtexture)
|
||||
{
|
||||
mode.ApplySelectTexture(newtexture, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Texture
|
||||
public virtual void ApplyTexture(string texture)
|
||||
{
|
||||
mode.CreateUndo("Change flat " + texture);
|
||||
SetTexture(texture);
|
||||
}
|
||||
|
||||
// Copy texture
|
||||
public virtual void OnCopyTexture()
|
||||
{
|
||||
BuilderPlug.Me.CopiedFlat = GetTextureName();
|
||||
if(General.Map.Config.MixTexturesFlats) BuilderPlug.Me.CopiedTexture = GetTextureName();
|
||||
mode.SetActionResult("Copied flat " + GetTextureName() + ".");
|
||||
}
|
||||
|
||||
public virtual void OnPasteTexture() { }
|
||||
|
||||
// Return texture name
|
||||
public virtual string GetTextureName() { return ""; }
|
||||
|
||||
// Edit button released
|
||||
public virtual void OnEditEnd()
|
||||
{
|
||||
if(General.Interface.IsActiveWindow)
|
||||
{
|
||||
List<Sector> sectors = mode.GetSelectedSectors();
|
||||
DialogResult result = General.Interface.ShowEditSectors(sectors);
|
||||
if(result == DialogResult.OK)
|
||||
{
|
||||
// Rebuild sector
|
||||
foreach(Sector s in sectors)
|
||||
{
|
||||
VisualSector vs = mode.GetVisualSector(s);
|
||||
if(vs != null)
|
||||
(vs as BaseVisualSector).UpdateSectorGeometry(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sector height change
|
||||
public virtual void OnChangeTargetHeight(int amount)
|
||||
{
|
||||
changed = true;
|
||||
|
||||
ChangeHeight(amount);
|
||||
|
||||
// Rebuild sector
|
||||
Sector.UpdateSectorGeometry(true);
|
||||
}
|
||||
|
||||
// Sector brightness change
|
||||
public virtual void OnChangeTargetBrightness(bool up)
|
||||
{
|
||||
mode.CreateUndo("Change sector brightness", UndoGroup.SectorBrightnessChange, Sector.Sector.FixedIndex);
|
||||
|
||||
if(up)
|
||||
Sector.Sector.Brightness = General.Map.Config.BrightnessLevels.GetNextHigher(Sector.Sector.Brightness);
|
||||
else
|
||||
Sector.Sector.Brightness = General.Map.Config.BrightnessLevels.GetNextLower(Sector.Sector.Brightness);
|
||||
|
||||
mode.SetActionResult("Changed sector brightness to " + Sector.Sector.Brightness + ".");
|
||||
|
||||
Sector.Sector.UpdateCache();
|
||||
|
||||
// Rebuild sector
|
||||
Sector.UpdateSectorGeometry(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,686 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
using System.Drawing;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal abstract class BaseVisualGeometrySidedef : VisualGeometry, IVisualEventReceiver
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const float DRAG_ANGLE_TOLERANCE = 0.06f;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
protected BaseVisualMode mode;
|
||||
|
||||
protected float top;
|
||||
protected float bottom;
|
||||
protected long setuponloadedtexture;
|
||||
|
||||
// UV dragging
|
||||
private float dragstartanglexy;
|
||||
private float dragstartanglez;
|
||||
private Vector3D dragorigin;
|
||||
private Vector3D deltaxy;
|
||||
private Vector3D deltaz;
|
||||
private int startoffsetx;
|
||||
private int startoffsety;
|
||||
protected bool uvdragging;
|
||||
private int prevoffsetx; // We have to provide delta offsets, but I don't
|
||||
private int prevoffsety; // want to calculate with delta offsets to prevent
|
||||
// inaccuracy in the dragging.
|
||||
// Undo/redo
|
||||
private int undoticket;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public bool IsDraggingUV { get { return uvdragging; } }
|
||||
new public BaseVisualSector Sector { get { return (BaseVisualSector)base.Sector; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Destructor
|
||||
|
||||
// Constructor for sidedefs
|
||||
public BaseVisualGeometrySidedef(BaseVisualMode mode, VisualSector vs, Sidedef sd) : base(vs, sd)
|
||||
{
|
||||
this.mode = mode;
|
||||
this.deltaz = new Vector3D(0.0f, 0.0f, 1.0f);
|
||||
this.deltaxy = (sd.Line.End.Position - sd.Line.Start.Position) * sd.Line.LengthInv;
|
||||
if(!sd.IsFront) this.deltaxy = -this.deltaxy;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This performs a fast test in object picking
|
||||
public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||
{
|
||||
// Check if intersection point is between top and bottom
|
||||
return (pickintersect.z >= bottom) && (pickintersect.z <= top);
|
||||
}
|
||||
|
||||
// This performs an accurate test for object picking
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||
{
|
||||
// The fast reject pass is already as accurate as it gets,
|
||||
// so we just return the intersection distance here
|
||||
u_ray = pickrayu;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
// Unused
|
||||
public virtual void OnEditBegin() { }
|
||||
protected virtual void SetTexture(string texturename) { }
|
||||
public abstract bool Setup();
|
||||
|
||||
// Insert middle texture
|
||||
public virtual void OnInsert()
|
||||
{
|
||||
// No middle texture yet?
|
||||
if(!Sidedef.MiddleRequired() && (string.IsNullOrEmpty(Sidedef.MiddleTexture) || (Sidedef.MiddleTexture[0] == '-')))
|
||||
{
|
||||
// Make it now
|
||||
mode.CreateUndo("Create middle texture");
|
||||
mode.SetActionResult("Created middle texture.");
|
||||
General.Settings.FindDefaultDrawSettings();
|
||||
Sidedef.SetTextureMid(General.Settings.DefaultTexture);
|
||||
|
||||
// Update
|
||||
Sector.Changed = true;
|
||||
|
||||
// Other side as well
|
||||
if(string.IsNullOrEmpty(Sidedef.Other.MiddleTexture) || (Sidedef.Other.MiddleTexture[0] == '-'))
|
||||
{
|
||||
Sidedef.Other.SetTextureMid(General.Settings.DefaultTexture);
|
||||
|
||||
// Update
|
||||
VisualSector othersector = mode.GetVisualSector(Sidedef.Other.Sector);
|
||||
if(othersector is BaseVisualSector) (othersector as BaseVisualSector).Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete texture
|
||||
public virtual void OnDelete()
|
||||
{
|
||||
// Remove texture
|
||||
mode.CreateUndo("Delete texture");
|
||||
mode.SetActionResult("Deleted a texture.");
|
||||
SetTexture("-");
|
||||
|
||||
// Update
|
||||
Sector.Changed = true;
|
||||
}
|
||||
|
||||
// Processing
|
||||
public virtual void OnProcess(double deltatime)
|
||||
{
|
||||
// If the texture was not loaded, but is loaded now, then re-setup geometry
|
||||
if(setuponloadedtexture != 0)
|
||||
{
|
||||
ImageData t = General.Map.Data.GetTextureImage(setuponloadedtexture);
|
||||
if(t != null)
|
||||
{
|
||||
if(t.IsImageLoaded)
|
||||
{
|
||||
setuponloadedtexture = 0;
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change target height
|
||||
public virtual void OnChangeTargetHeight(int amount)
|
||||
{
|
||||
switch(BuilderPlug.Me.ChangeHeightBySidedef)
|
||||
{
|
||||
// Change ceiling
|
||||
case 1:
|
||||
if(!this.Sector.Ceiling.Changed)
|
||||
this.Sector.Ceiling.OnChangeTargetHeight(amount);
|
||||
break;
|
||||
|
||||
// Change floor
|
||||
case 2:
|
||||
if(!this.Sector.Floor.Changed)
|
||||
this.Sector.Floor.OnChangeTargetHeight(amount);
|
||||
break;
|
||||
|
||||
// Change both
|
||||
case 3:
|
||||
if(!this.Sector.Floor.Changed)
|
||||
this.Sector.Floor.OnChangeTargetHeight(amount);
|
||||
if(!this.Sector.Ceiling.Changed)
|
||||
this.Sector.Ceiling.OnChangeTargetHeight(amount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset texture offsets
|
||||
public virtual void OnResetTextureOffset()
|
||||
{
|
||||
mode.CreateUndo("Reset texture offsets");
|
||||
mode.SetActionResult("Texture offsets reset.");
|
||||
|
||||
// Apply offsets
|
||||
Sidedef.OffsetX = 0;
|
||||
Sidedef.OffsetY = 0;
|
||||
|
||||
// Update sidedef geometry
|
||||
VisualSidedefParts parts = Sector.GetSidedefParts(Sidedef);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
|
||||
// Toggle upper-unpegged
|
||||
public virtual void OnToggleUpperUnpegged()
|
||||
{
|
||||
if(this.Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag))
|
||||
{
|
||||
// Remove flag
|
||||
mode.ApplyUpperUnpegged(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add flag
|
||||
mode.ApplyUpperUnpegged(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle lower-unpegged
|
||||
public virtual void OnToggleLowerUnpegged()
|
||||
{
|
||||
if(this.Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
// Remove flag
|
||||
mode.ApplyLowerUnpegged(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add flag
|
||||
mode.ApplyLowerUnpegged(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This sets the Upper Unpegged flag
|
||||
public virtual void ApplyUpperUnpegged(bool set)
|
||||
{
|
||||
if(!set)
|
||||
{
|
||||
// Remove flag
|
||||
mode.CreateUndo("Remove upper-unpegged setting");
|
||||
mode.SetActionResult("Removed upper-unpegged setting.");
|
||||
this.Sidedef.Line.SetFlag(General.Map.Config.UpperUnpeggedFlag, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add flag
|
||||
mode.CreateUndo("Set upper-unpegged setting");
|
||||
mode.SetActionResult("Set upper-unpegged setting.");
|
||||
this.Sidedef.Line.SetFlag(General.Map.Config.UpperUnpeggedFlag, true);
|
||||
}
|
||||
|
||||
// Update sidedef geometry
|
||||
VisualSidedefParts parts = Sector.GetSidedefParts(Sidedef);
|
||||
parts.SetupAllParts();
|
||||
|
||||
// Update other sidedef geometry
|
||||
if(Sidedef.Other != null)
|
||||
{
|
||||
BaseVisualSector othersector = (BaseVisualSector)mode.GetVisualSector(Sidedef.Other.Sector);
|
||||
parts = othersector.GetSidedefParts(Sidedef.Other);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This sets the Lower Unpegged flag
|
||||
public virtual void ApplyLowerUnpegged(bool set)
|
||||
{
|
||||
if(!set)
|
||||
{
|
||||
// Remove flag
|
||||
mode.CreateUndo("Remove lower-unpegged setting");
|
||||
mode.SetActionResult("Removed lower-unpegged setting.");
|
||||
this.Sidedef.Line.SetFlag(General.Map.Config.LowerUnpeggedFlag, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add flag
|
||||
mode.CreateUndo("Set lower-unpegged setting");
|
||||
mode.SetActionResult("Set lower-unpegged setting.");
|
||||
this.Sidedef.Line.SetFlag(General.Map.Config.LowerUnpeggedFlag, true);
|
||||
}
|
||||
|
||||
// Update sidedef geometry
|
||||
VisualSidedefParts parts = Sector.GetSidedefParts(Sidedef);
|
||||
parts.SetupAllParts();
|
||||
|
||||
// Update other sidedef geometry
|
||||
if(Sidedef.Other != null)
|
||||
{
|
||||
BaseVisualSector othersector = (BaseVisualSector)mode.GetVisualSector(Sidedef.Other.Sector);
|
||||
parts = othersector.GetSidedefParts(Sidedef.Other);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Flood-fill textures
|
||||
public virtual void OnTextureFloodfill()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedTexture != null)
|
||||
{
|
||||
string oldtexture = GetTextureName();
|
||||
long oldtexturelong = Lump.MakeLongName(oldtexture);
|
||||
string newtexture = BuilderPlug.Me.CopiedTexture;
|
||||
if(newtexture != oldtexture)
|
||||
{
|
||||
mode.CreateUndo("Flood-fill textures with " + newtexture);
|
||||
mode.SetActionResult("Flood-filled textures with " + newtexture + ".");
|
||||
|
||||
mode.Renderer.SetCrosshairBusy(true);
|
||||
General.Interface.RedrawDisplay();
|
||||
|
||||
// Get the texture
|
||||
ImageData newtextureimage = General.Map.Data.GetTextureImage(newtexture);
|
||||
if(newtextureimage != null)
|
||||
{
|
||||
if(mode.IsSingleSelection)
|
||||
{
|
||||
// Clear all marks, this will align everything it can
|
||||
General.Map.Map.ClearMarkedSidedefs(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Limit the alignment to selection only
|
||||
General.Map.Map.ClearMarkedSidedefs(true);
|
||||
List<Sidedef> sides = mode.GetSelectedSidedefs();
|
||||
foreach(Sidedef sd in sides) sd.Marked = false;
|
||||
}
|
||||
|
||||
// Do the alignment
|
||||
Tools.FloodfillTextures(this.Sidedef, oldtexturelong, newtextureimage, false);
|
||||
|
||||
// Get the changed sidedefs
|
||||
List<Sidedef> changes = General.Map.Map.GetMarkedSidedefs(true);
|
||||
foreach(Sidedef sd in changes)
|
||||
{
|
||||
// Update the parts for this sidedef!
|
||||
if(mode.VisualSectorExists(sd.Sector))
|
||||
{
|
||||
BaseVisualSector vs = (mode.GetVisualSector(sd.Sector) as BaseVisualSector);
|
||||
VisualSidedefParts parts = vs.GetSidedefParts(sd);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
}
|
||||
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
mode.Renderer.SetCrosshairBusy(false);
|
||||
mode.ShowTargetInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-align texture X offsets
|
||||
public virtual void OnTextureAlign(bool alignx, bool aligny)
|
||||
{
|
||||
mode.CreateUndo("Auto-align textures");
|
||||
mode.SetActionResult("Auto-aligned textures.");
|
||||
|
||||
// Make sure the texture is loaded (we need the texture size)
|
||||
if(!base.Texture.IsImageLoaded) base.Texture.LoadImage();
|
||||
|
||||
if(mode.IsSingleSelection)
|
||||
{
|
||||
// Clear all marks, this will align everything it can
|
||||
General.Map.Map.ClearMarkedSidedefs(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Limit the alignment to selection only
|
||||
General.Map.Map.ClearMarkedSidedefs(true);
|
||||
List<Sidedef> sides = mode.GetSelectedSidedefs();
|
||||
foreach(Sidedef sd in sides) sd.Marked = false;
|
||||
}
|
||||
|
||||
// Do the alignment
|
||||
Tools.AutoAlignTextures(this.Sidedef, base.Texture, alignx, aligny, false);
|
||||
|
||||
// Get the changed sidedefs
|
||||
List<Sidedef> changes = General.Map.Map.GetMarkedSidedefs(true);
|
||||
foreach(Sidedef sd in changes)
|
||||
{
|
||||
// Update the parts for this sidedef!
|
||||
if(mode.VisualSectorExists(sd.Sector))
|
||||
{
|
||||
BaseVisualSector vs = (mode.GetVisualSector(sd.Sector) as BaseVisualSector);
|
||||
VisualSidedefParts parts = vs.GetSidedefParts(sd);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Select texture
|
||||
public virtual void OnSelectTexture()
|
||||
{
|
||||
if(General.Interface.IsActiveWindow)
|
||||
{
|
||||
string oldtexture = GetTextureName();
|
||||
string newtexture = General.Interface.BrowseTexture(General.Interface, oldtexture);
|
||||
if(newtexture != oldtexture)
|
||||
{
|
||||
mode.ApplySelectTexture(newtexture, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply Texture
|
||||
public virtual void ApplyTexture(string texture)
|
||||
{
|
||||
mode.CreateUndo("Change texture " + texture);
|
||||
SetTexture(texture);
|
||||
}
|
||||
|
||||
// Paste texture
|
||||
public virtual void OnPasteTexture()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedTexture != null)
|
||||
{
|
||||
mode.CreateUndo("Paste texture " + BuilderPlug.Me.CopiedTexture);
|
||||
mode.SetActionResult("Pasted texture " + BuilderPlug.Me.CopiedTexture + ".");
|
||||
SetTexture(BuilderPlug.Me.CopiedTexture);
|
||||
}
|
||||
}
|
||||
|
||||
// Paste texture offsets
|
||||
public virtual void OnPasteTextureOffsets()
|
||||
{
|
||||
mode.CreateUndo("Paste texture offsets");
|
||||
Sidedef.OffsetX = BuilderPlug.Me.CopiedOffsets.X;
|
||||
Sidedef.OffsetY = BuilderPlug.Me.CopiedOffsets.Y;
|
||||
mode.SetActionResult("Pasted texture offsets " + Sidedef.OffsetX + ", " + Sidedef.OffsetY + ".");
|
||||
|
||||
// Update sidedef geometry
|
||||
VisualSidedefParts parts = Sector.GetSidedefParts(Sidedef);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
|
||||
// Copy texture
|
||||
public virtual void OnCopyTexture()
|
||||
{
|
||||
BuilderPlug.Me.CopiedTexture = GetTextureName();
|
||||
if(General.Map.Config.MixTexturesFlats) BuilderPlug.Me.CopiedFlat = GetTextureName();
|
||||
mode.SetActionResult("Copied texture " + GetTextureName() + ".");
|
||||
}
|
||||
|
||||
// Copy texture offsets
|
||||
public virtual void OnCopyTextureOffsets()
|
||||
{
|
||||
BuilderPlug.Me.CopiedOffsets = new Point(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
mode.SetActionResult("Copied texture offsets " + Sidedef.OffsetX + ", " + Sidedef.OffsetY + ".");
|
||||
}
|
||||
|
||||
// Copy properties
|
||||
public virtual void OnCopyProperties()
|
||||
{
|
||||
BuilderPlug.Me.CopiedSidedefProps = new SidedefProperties(Sidedef);
|
||||
mode.SetActionResult("Copied sidedef properties.");
|
||||
}
|
||||
|
||||
// Paste properties
|
||||
public virtual void OnPasteProperties()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedSidedefProps != null)
|
||||
{
|
||||
mode.CreateUndo("Paste sidedef properties");
|
||||
mode.SetActionResult("Pasted sidedef properties.");
|
||||
BuilderPlug.Me.CopiedSidedefProps.Apply(Sidedef);
|
||||
|
||||
// Update sectors on both sides
|
||||
BaseVisualSector front = (BaseVisualSector)mode.GetVisualSector(Sidedef.Sector);
|
||||
if(front != null) front.Changed = true;
|
||||
if(Sidedef.Other != null)
|
||||
{
|
||||
BaseVisualSector back = (BaseVisualSector)mode.GetVisualSector(Sidedef.Other.Sector);
|
||||
if(back != null) back.Changed = true;
|
||||
}
|
||||
mode.ShowTargetInfo();
|
||||
}
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
public virtual string GetTextureName() { return ""; }
|
||||
|
||||
// Select button pressed
|
||||
public virtual void OnSelectBegin()
|
||||
{
|
||||
mode.LockTarget();
|
||||
dragstartanglexy = General.Map.VisualCamera.AngleXY;
|
||||
dragstartanglez = General.Map.VisualCamera.AngleZ;
|
||||
dragorigin = pickintersect;
|
||||
startoffsetx = Sidedef.OffsetX;
|
||||
startoffsety = Sidedef.OffsetY;
|
||||
prevoffsetx = Sidedef.OffsetX;
|
||||
prevoffsety = Sidedef.OffsetY;
|
||||
}
|
||||
|
||||
// Select button released
|
||||
public virtual void OnSelectEnd()
|
||||
{
|
||||
mode.UnlockTarget();
|
||||
|
||||
// Was dragging?
|
||||
if(uvdragging)
|
||||
{
|
||||
// Dragging stops now
|
||||
uvdragging = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add/remove selection
|
||||
if(this.selected)
|
||||
{
|
||||
this.selected = false;
|
||||
mode.RemoveSelectedObject(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selected = true;
|
||||
mode.AddSelectedObject(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Edit button released
|
||||
public virtual void OnEditEnd()
|
||||
{
|
||||
if(General.Interface.IsActiveWindow)
|
||||
{
|
||||
List<Linedef> linedefs = mode.GetSelectedLinedefs();
|
||||
DialogResult result = General.Interface.ShowEditLinedefs(linedefs);
|
||||
if(result == DialogResult.OK)
|
||||
{
|
||||
foreach(Linedef l in linedefs)
|
||||
{
|
||||
if(l.Front != null)
|
||||
{
|
||||
VisualSector vs = mode.GetVisualSector(l.Front.Sector);
|
||||
if(vs != null)
|
||||
(vs as BaseVisualSector).Changed = true;
|
||||
}
|
||||
|
||||
if(l.Back != null)
|
||||
{
|
||||
VisualSector vs = mode.GetVisualSector(l.Back.Sector);
|
||||
if(vs != null)
|
||||
(vs as BaseVisualSector).Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mouse moves
|
||||
public virtual void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
// Dragging UV?
|
||||
if(uvdragging)
|
||||
{
|
||||
UpdateDragUV();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Select button pressed?
|
||||
if(General.Actions.CheckActionActive(General.ThisAssembly, "visualselect"))
|
||||
{
|
||||
// Check if tolerance is exceeded to start UV dragging
|
||||
float deltaxy = General.Map.VisualCamera.AngleXY - dragstartanglexy;
|
||||
float deltaz = General.Map.VisualCamera.AngleZ - dragstartanglez;
|
||||
if((Math.Abs(deltaxy) + Math.Abs(deltaz)) > DRAG_ANGLE_TOLERANCE)
|
||||
{
|
||||
mode.PreAction(UndoGroup.TextureOffsetChange);
|
||||
mode.CreateUndo("Change texture offsets");
|
||||
|
||||
// Start drag now
|
||||
uvdragging = true;
|
||||
mode.Renderer.ShowSelection = false;
|
||||
mode.Renderer.ShowHighlight = false;
|
||||
UpdateDragUV();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is called to update UV dragging
|
||||
protected virtual void UpdateDragUV()
|
||||
{
|
||||
float u_ray;
|
||||
|
||||
// Calculate intersection position
|
||||
Line2D ray = new Line2D(General.Map.VisualCamera.Position, General.Map.VisualCamera.Target);
|
||||
Sidedef.Line.Line.GetIntersection(ray, out u_ray);
|
||||
Vector3D intersect = General.Map.VisualCamera.Position + (General.Map.VisualCamera.Target - General.Map.VisualCamera.Position) * u_ray;
|
||||
|
||||
// Calculate offsets
|
||||
Vector3D dragdelta = intersect - dragorigin;
|
||||
Vector3D dragdeltaxy = dragdelta * deltaxy;
|
||||
Vector3D dragdeltaz = dragdelta * deltaz;
|
||||
float offsetx = dragdeltaxy.GetLength();
|
||||
float offsety = dragdeltaz.GetLength();
|
||||
if((Math.Sign(dragdeltaxy.x) < 0) || (Math.Sign(dragdeltaxy.y) < 0) || (Math.Sign(dragdeltaxy.z) < 0)) offsetx = -offsetx;
|
||||
if((Math.Sign(dragdeltaz.x) < 0) || (Math.Sign(dragdeltaz.y) < 0) || (Math.Sign(dragdeltaz.z) < 0)) offsety = -offsety;
|
||||
|
||||
// Apply offsets
|
||||
int newoffsetx = startoffsetx - (int)Math.Round(offsetx);
|
||||
int newoffsety = startoffsety + (int)Math.Round(offsety);
|
||||
mode.ApplyTextureOffsetChange(prevoffsetx - newoffsetx, prevoffsety - newoffsety);
|
||||
prevoffsetx = newoffsetx;
|
||||
prevoffsety = newoffsety;
|
||||
|
||||
mode.ShowTargetInfo();
|
||||
}
|
||||
|
||||
// Sector brightness change
|
||||
public virtual void OnChangeTargetBrightness(bool up)
|
||||
{
|
||||
if(!Sector.Changed)
|
||||
{
|
||||
// Change brightness
|
||||
mode.CreateUndo("Change sector brightness", UndoGroup.SectorBrightnessChange, Sector.Sector.FixedIndex);
|
||||
|
||||
if(up)
|
||||
Sector.Sector.Brightness = General.Map.Config.BrightnessLevels.GetNextHigher(Sector.Sector.Brightness);
|
||||
else
|
||||
Sector.Sector.Brightness = General.Map.Config.BrightnessLevels.GetNextLower(Sector.Sector.Brightness);
|
||||
|
||||
mode.SetActionResult("Changed sector brightness to " + Sector.Sector.Brightness + ".");
|
||||
|
||||
Sector.Sector.UpdateCache();
|
||||
|
||||
// Rebuild sector
|
||||
Sector.Changed = true;
|
||||
|
||||
// Go for all things in this sector
|
||||
foreach(Thing t in General.Map.Map.Things)
|
||||
{
|
||||
if(t.Sector == Sector.Sector)
|
||||
{
|
||||
if(mode.VisualThingExists(t))
|
||||
{
|
||||
// Update thing
|
||||
BaseVisualThing vt = (mode.GetVisualThing(t) as BaseVisualThing);
|
||||
vt.Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Texture offset change
|
||||
public virtual void OnChangeTextureOffset(int horizontal, int vertical)
|
||||
{
|
||||
if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
|
||||
undoticket = mode.CreateUndo("Change texture offsets");
|
||||
|
||||
// Apply offsets
|
||||
Sidedef.OffsetX -= horizontal;
|
||||
Sidedef.OffsetY -= vertical;
|
||||
|
||||
mode.SetActionResult("Changed texture offsets to " + Sidedef.OffsetX + ", " + Sidedef.OffsetY + ".");
|
||||
|
||||
// Update sidedef geometry
|
||||
VisualSidedefParts parts = Sector.GetSidedefParts(Sidedef);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
1253
Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs
Normal file
1253
Source/Plugins/GZDoomEditing/VisualModes/BaseVisualMode.cs
Normal file
File diff suppressed because it is too large
Load diff
209
Source/Plugins/GZDoomEditing/VisualModes/BaseVisualSector.cs
Normal file
209
Source/Plugins/GZDoomEditing/VisualModes/BaseVisualSector.cs
Normal file
|
@ -0,0 +1,209 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal class BaseVisualSector : VisualSector
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
protected BaseVisualMode mode;
|
||||
|
||||
protected VisualFloor floor;
|
||||
protected VisualCeiling ceiling;
|
||||
protected Dictionary<Sidedef, VisualSidedefParts> sides;
|
||||
|
||||
// If this is set to true, the sector will be rebuilt after the action is performed.
|
||||
protected bool changed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public VisualFloor Floor { get { return floor; } }
|
||||
public VisualCeiling Ceiling { get { return ceiling; } }
|
||||
public bool Changed { get { return changed; } set { changed |= value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
||||
// Constructor
|
||||
public BaseVisualSector(BaseVisualMode mode, Sector s) : base(s)
|
||||
{
|
||||
this.mode = mode;
|
||||
|
||||
// Initialize
|
||||
Rebuild();
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Disposer
|
||||
public override void Dispose()
|
||||
{
|
||||
// Not already disposed?
|
||||
if(!IsDisposed)
|
||||
{
|
||||
// Clean up
|
||||
sides = null;
|
||||
floor = null;
|
||||
ceiling = null;
|
||||
|
||||
// Dispose base
|
||||
base.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// Thisvirtuals the secotr and neightbours if needed
|
||||
public void UpdateSectorGeometry(bool includeneighbours)
|
||||
{
|
||||
// Rebuild sector
|
||||
this.Changed = true;
|
||||
|
||||
// Go for all things in this sector
|
||||
foreach(Thing t in General.Map.Map.Things)
|
||||
{
|
||||
if(t.Sector == this.Sector)
|
||||
{
|
||||
if(mode.VisualThingExists(t))
|
||||
{
|
||||
// Update thing
|
||||
BaseVisualThing vt = (mode.GetVisualThing(t) as BaseVisualThing);
|
||||
vt.Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(includeneighbours)
|
||||
{
|
||||
// Also rebuild surrounding sectors, because outside sidedefs may need to be adjusted
|
||||
foreach(Sidedef sd in this.Sector.Sidedefs)
|
||||
{
|
||||
if(sd.Other != null)
|
||||
{
|
||||
if(mode.VisualSectorExists(sd.Other.Sector))
|
||||
{
|
||||
BaseVisualSector bvs = (BaseVisualSector)mode.GetVisualSector(sd.Other.Sector);
|
||||
bvs.Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This (re)builds the visual sector, calculating all geometry from scratch
|
||||
public void Rebuild()
|
||||
{
|
||||
// Forget old geometry
|
||||
base.ClearGeometry();
|
||||
|
||||
// Create floor
|
||||
if(floor == null) floor = new VisualFloor(mode, this);
|
||||
floor.Setup();
|
||||
base.AddGeometry(floor);
|
||||
|
||||
// Create ceiling
|
||||
if(ceiling == null) ceiling = new VisualCeiling(mode, this);
|
||||
ceiling.Setup();
|
||||
base.AddGeometry(ceiling);
|
||||
|
||||
// Go for all sidedefs
|
||||
Dictionary<Sidedef, VisualSidedefParts> oldsides = sides ?? new Dictionary<Sidedef, VisualSidedefParts>(1);
|
||||
sides = new Dictionary<Sidedef, VisualSidedefParts>(base.Sector.Sidedefs.Count);
|
||||
foreach(Sidedef sd in base.Sector.Sidedefs)
|
||||
{
|
||||
// VisualSidedef already exists?
|
||||
VisualSidedefParts parts = oldsides.ContainsKey(sd) ? oldsides[sd] : new VisualSidedefParts();
|
||||
|
||||
// Doublesided or singlesided?
|
||||
if(sd.Other != null)
|
||||
{
|
||||
// Create upper part
|
||||
VisualUpper vu = parts.upper ?? new VisualUpper(mode, this, sd);
|
||||
vu.Setup();
|
||||
base.AddGeometry(vu);
|
||||
|
||||
// Create lower part
|
||||
VisualLower vl = parts.lower ?? new VisualLower(mode, this, sd);
|
||||
vl.Setup();
|
||||
base.AddGeometry(vl);
|
||||
|
||||
// Create middle part
|
||||
VisualMiddleDouble vm = parts.middledouble ?? new VisualMiddleDouble(mode, this, sd);
|
||||
vm.Setup();
|
||||
base.AddGeometry(vm);
|
||||
|
||||
// Store
|
||||
sides.Add(sd, new VisualSidedefParts(vu, vl, vm));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create middle part
|
||||
VisualMiddleSingle vm = parts.middlesingle ?? new VisualMiddleSingle(mode, this, sd);
|
||||
vm.Setup();
|
||||
base.AddGeometry(vm);
|
||||
|
||||
// Store
|
||||
sides.Add(sd, new VisualSidedefParts(vm));
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
changed = false;
|
||||
}
|
||||
|
||||
// This returns the visual sidedef parts for a given sidedef
|
||||
public VisualSidedefParts GetSidedefParts(Sidedef sd)
|
||||
{
|
||||
if(sides.ContainsKey(sd))
|
||||
return sides[sd];
|
||||
else
|
||||
return new VisualSidedefParts();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
462
Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs
Normal file
462
Source/Plugins/GZDoomEditing/VisualModes/BaseVisualThing.cs
Normal file
|
@ -0,0 +1,462 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal class BaseVisualThing : VisualThing, IVisualEventReceiver
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
protected BaseVisualMode mode;
|
||||
|
||||
private ThingTypeInfo info;
|
||||
private bool isloaded;
|
||||
private ImageData sprite;
|
||||
private float cageradius2;
|
||||
private Vector2D pos2d;
|
||||
private Vector3D boxp1;
|
||||
private Vector3D boxp2;
|
||||
|
||||
// Undo/redo
|
||||
private int undoticket;
|
||||
|
||||
// If this is set to true, the thing will be rebuilt after the action is performed.
|
||||
protected bool changed;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public bool Changed { get { return changed; } set { changed |= value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public BaseVisualThing(BaseVisualMode mode, Thing t) : base(t)
|
||||
{
|
||||
this.mode = mode;
|
||||
|
||||
Rebuild();
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the thing geometry. Returns false when nothing was created.
|
||||
public virtual bool Setup()
|
||||
{
|
||||
PixelColor sectorcolor = new PixelColor(255, 255, 255, 255);
|
||||
|
||||
// Must have a width and height!
|
||||
if((info.Radius < 0.1f) || (info.Height < 0.1f)) return false;
|
||||
|
||||
// Find the sector in which the thing resides
|
||||
Thing.DetermineSector(mode.BlockMap);
|
||||
|
||||
if(sprite != null)
|
||||
{
|
||||
if(Thing.Sector != null)
|
||||
{
|
||||
// Use sector brightness for color shading
|
||||
byte brightness = (byte)General.Clamp(Thing.Sector.Brightness, 0, 255);
|
||||
sectorcolor = new PixelColor(255, brightness, brightness, brightness);
|
||||
}
|
||||
|
||||
// Check if the texture is loaded
|
||||
sprite.LoadImage();
|
||||
isloaded = sprite.IsImageLoaded;
|
||||
if(isloaded)
|
||||
{
|
||||
float offsetx = 0.0f;
|
||||
float offsety = 0.0f;
|
||||
|
||||
base.Texture = sprite;
|
||||
|
||||
// Determine sprite size and offset
|
||||
float radius = sprite.ScaledWidth * 0.5f;
|
||||
float height = sprite.ScaledHeight;
|
||||
if(sprite is SpriteImage)
|
||||
{
|
||||
offsetx = (sprite as SpriteImage).OffsetX - radius;
|
||||
offsety = (sprite as SpriteImage).OffsetY - height;
|
||||
}
|
||||
|
||||
// Scale by thing type/actor scale
|
||||
// We do this after the offset x/y determination above, because that is entirely in sprite pixels space
|
||||
radius *= info.SpriteScale.Width;
|
||||
height *= info.SpriteScale.Height;
|
||||
offsetx *= info.SpriteScale.Width;
|
||||
offsety *= info.SpriteScale.Height;
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(-radius + offsetx, 0.0f, 0.0f + offsety, sectorcolor.ToInt(), 0.0f, 1.0f);
|
||||
verts[1] = new WorldVertex(-radius + offsetx, 0.0f, height + offsety, sectorcolor.ToInt(), 0.0f, 0.0f);
|
||||
verts[2] = new WorldVertex(+radius + offsetx, 0.0f, height + offsety, sectorcolor.ToInt(), 1.0f, 0.0f);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(+radius + offsetx, 0.0f, 0.0f + offsety, sectorcolor.ToInt(), 1.0f, 1.0f);
|
||||
SetVertices(verts);
|
||||
}
|
||||
else
|
||||
{
|
||||
base.Texture = General.Map.Data.Hourglass3D;
|
||||
|
||||
// Determine sprite size
|
||||
float radius = Math.Min(info.Radius, info.Height / 2f);
|
||||
float height = Math.Min(info.Radius * 2f, info.Height);
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(-radius, 0.0f, 0.0f, sectorcolor.ToInt(), 0.0f, 1.0f);
|
||||
verts[1] = new WorldVertex(-radius, 0.0f, height, sectorcolor.ToInt(), 0.0f, 0.0f);
|
||||
verts[2] = new WorldVertex(+radius, 0.0f, height, sectorcolor.ToInt(), 1.0f, 0.0f);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(+radius, 0.0f, 0.0f, sectorcolor.ToInt(), 1.0f, 1.0f);
|
||||
SetVertices(verts);
|
||||
}
|
||||
}
|
||||
|
||||
// Determine position
|
||||
Vector3D pos = Thing.Position;
|
||||
if(info.AbsoluteZ)
|
||||
{
|
||||
// Absolute Z position
|
||||
pos.z = Thing.Position.z;
|
||||
}
|
||||
else if(info.Hangs)
|
||||
{
|
||||
// Hang from ceiling
|
||||
if(Thing.Sector != null) pos.z = Thing.Sector.CeilHeight - info.Height;
|
||||
if(Thing.Position.z > 0) pos.z -= Thing.Position.z;
|
||||
|
||||
// Check if below floor
|
||||
if((Thing.Sector != null) && (pos.z < Thing.Sector.FloorHeight))
|
||||
{
|
||||
// Put thing on the floor
|
||||
pos.z = Thing.Sector.FloorHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stand on floor
|
||||
if(Thing.Sector != null) pos.z = Thing.Sector.FloorHeight;
|
||||
if(Thing.Position.z > 0) pos.z += Thing.Position.z;
|
||||
|
||||
// Check if above ceiling
|
||||
if((Thing.Sector != null) && ((pos.z + info.Height) > Thing.Sector.CeilHeight))
|
||||
{
|
||||
// Put thing against ceiling
|
||||
pos.z = Thing.Sector.CeilHeight - info.Height;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply settings
|
||||
SetPosition(pos);
|
||||
SetCageSize(info.Radius, info.Height);
|
||||
SetCageColor(Thing.Color);
|
||||
|
||||
// Keep info for object picking
|
||||
cageradius2 = info.Radius * Angle2D.SQRT2;
|
||||
cageradius2 = cageradius2 * cageradius2;
|
||||
pos2d = pos;
|
||||
boxp1 = new Vector3D(pos.x - info.Radius, pos.y - info.Radius, pos.z);
|
||||
boxp2 = new Vector3D(pos.x + info.Radius, pos.y + info.Radius, pos.z + info.Height);
|
||||
|
||||
// Done
|
||||
changed = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Disposing
|
||||
public override void Dispose()
|
||||
{
|
||||
if(!IsDisposed)
|
||||
{
|
||||
if(sprite != null)
|
||||
{
|
||||
sprite.RemoveReference();
|
||||
sprite = null;
|
||||
}
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This forces to rebuild the whole thing
|
||||
public void Rebuild()
|
||||
{
|
||||
// Find thing information
|
||||
info = General.Map.Data.GetThingInfo(Thing.Type);
|
||||
|
||||
// Find sprite texture
|
||||
if(info.Sprite.Length > 0)
|
||||
{
|
||||
sprite = General.Map.Data.GetSpriteImage(info.Sprite);
|
||||
if(sprite != null) sprite.AddReference();
|
||||
}
|
||||
|
||||
// Setup visual thing
|
||||
Setup();
|
||||
}
|
||||
|
||||
// This updates the thing when needed
|
||||
public override void Update()
|
||||
{
|
||||
if(!isloaded)
|
||||
{
|
||||
// Rebuild sprite geometry when sprite is loaded
|
||||
if(sprite.IsImageLoaded)
|
||||
{
|
||||
Setup();
|
||||
}
|
||||
}
|
||||
|
||||
// Let the base update
|
||||
base.Update();
|
||||
}
|
||||
|
||||
// This performs a fast test in object picking
|
||||
public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||
{
|
||||
float distance2 = Line2D.GetDistanceToLineSq(from, to, pos2d, false);
|
||||
return (distance2 <= cageradius2);
|
||||
}
|
||||
|
||||
// This performs an accurate test for object picking
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||
{
|
||||
Vector3D delta = to - from;
|
||||
float tfar = float.MaxValue;
|
||||
float tnear = float.MinValue;
|
||||
|
||||
// Ray-Box intersection code
|
||||
// See http://www.masm32.com/board/index.php?topic=9941.0
|
||||
|
||||
// Check X slab
|
||||
if(delta.x == 0.0f)
|
||||
{
|
||||
if(from.x > boxp2.x || from.x < boxp1.x)
|
||||
{
|
||||
// Ray is parallel to the planes & outside slab
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = 1.0f / delta.x;
|
||||
float t1 = (boxp1.x - from.x) * tmp;
|
||||
float t2 = (boxp2.x - from.x) * tmp;
|
||||
if(t1 > t2) General.Swap(ref t1, ref t2);
|
||||
if(t1 > tnear) tnear = t1;
|
||||
if(t2 < tfar) tfar = t2;
|
||||
if(tnear > tfar || tfar < 0.0f)
|
||||
{
|
||||
// Ray missed box or box is behind ray
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check Y slab
|
||||
if(delta.y == 0.0f)
|
||||
{
|
||||
if(from.y > boxp2.y || from.y < boxp1.y)
|
||||
{
|
||||
// Ray is parallel to the planes & outside slab
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = 1.0f / delta.y;
|
||||
float t1 = (boxp1.y - from.y) * tmp;
|
||||
float t2 = (boxp2.y - from.y) * tmp;
|
||||
if(t1 > t2) General.Swap(ref t1, ref t2);
|
||||
if(t1 > tnear) tnear = t1;
|
||||
if(t2 < tfar) tfar = t2;
|
||||
if(tnear > tfar || tfar < 0.0f)
|
||||
{
|
||||
// Ray missed box or box is behind ray
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check Z slab
|
||||
if(delta.z == 0.0f)
|
||||
{
|
||||
if(from.z > boxp2.z || from.z < boxp1.z)
|
||||
{
|
||||
// Ray is parallel to the planes & outside slab
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float tmp = 1.0f / delta.z;
|
||||
float t1 = (boxp1.z - from.z) * tmp;
|
||||
float t2 = (boxp2.z - from.z) * tmp;
|
||||
if(t1 > t2) General.Swap(ref t1, ref t2);
|
||||
if(t1 > tnear) tnear = t1;
|
||||
if(t2 < tfar) tfar = t2;
|
||||
if(tnear > tfar || tfar < 0.0f)
|
||||
{
|
||||
// Ray missed box or box is behind ray
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set interpolation point
|
||||
u_ray = (tnear > 0.0f) ? tnear : tfar;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
||||
// Unused
|
||||
public virtual void OnSelectBegin() { }
|
||||
public virtual void OnEditBegin() { }
|
||||
public virtual void OnMouseMove(MouseEventArgs e) { }
|
||||
public virtual void OnChangeTargetBrightness(bool up) { }
|
||||
public virtual void OnChangeTextureOffset(int horizontal, int vertical) { }
|
||||
public virtual void OnSelectTexture() { }
|
||||
public virtual void OnCopyTexture() { }
|
||||
public virtual void OnPasteTexture() { }
|
||||
public virtual void OnCopyTextureOffsets() { }
|
||||
public virtual void OnPasteTextureOffsets() { }
|
||||
public virtual void OnTextureAlign(bool alignx, bool aligny) { }
|
||||
public virtual void OnToggleUpperUnpegged() { }
|
||||
public virtual void OnToggleLowerUnpegged() { }
|
||||
public virtual void OnResetTextureOffset() { }
|
||||
public virtual void OnProcess(double deltatime) { }
|
||||
public virtual void OnTextureFloodfill() { }
|
||||
public virtual void OnInsert() { }
|
||||
public virtual void OnDelete() { }
|
||||
public virtual void ApplyTexture(string texture) { }
|
||||
public virtual void ApplyUpperUnpegged(bool set) { }
|
||||
public virtual void ApplyLowerUnpegged(bool set) { }
|
||||
|
||||
// Return texture name
|
||||
public virtual string GetTextureName() { return ""; }
|
||||
|
||||
// Select or deselect
|
||||
public virtual void OnSelectEnd()
|
||||
{
|
||||
if(this.selected)
|
||||
{
|
||||
this.selected = false;
|
||||
mode.RemoveSelectedObject(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selected = true;
|
||||
mode.AddSelectedObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy properties
|
||||
public virtual void OnCopyProperties()
|
||||
{
|
||||
BuilderPlug.Me.CopiedThingProps = new ThingProperties(Thing);
|
||||
mode.SetActionResult("Copied thing properties.");
|
||||
}
|
||||
|
||||
// Paste properties
|
||||
public virtual void OnPasteProperties()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedThingProps != null)
|
||||
{
|
||||
mode.CreateUndo("Paste thing properties");
|
||||
mode.SetActionResult("Pasted thing properties.");
|
||||
BuilderPlug.Me.CopiedThingProps.Apply(Thing);
|
||||
Thing.UpdateConfiguration();
|
||||
this.Rebuild();
|
||||
mode.ShowTargetInfo();
|
||||
}
|
||||
}
|
||||
|
||||
// Edit button released
|
||||
public virtual void OnEditEnd()
|
||||
{
|
||||
if(General.Interface.IsActiveWindow)
|
||||
{
|
||||
List<Thing> things = mode.GetSelectedThings();
|
||||
DialogResult result = General.Interface.ShowEditThings(things);
|
||||
if(result == DialogResult.OK)
|
||||
{
|
||||
foreach(Thing t in things)
|
||||
{
|
||||
VisualThing vt = mode.GetVisualThing(t);
|
||||
if(vt != null)
|
||||
(vt as BaseVisualThing).Changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Raise/lower thing
|
||||
public virtual void OnChangeTargetHeight(int amount)
|
||||
{
|
||||
if(General.Map.FormatInterface.HasThingHeight)
|
||||
{
|
||||
if((General.Map.UndoRedo.NextUndo == null) || (General.Map.UndoRedo.NextUndo.TicketID != undoticket))
|
||||
undoticket = mode.CreateUndo("Change thing height");
|
||||
|
||||
Thing.Move(Thing.Position + new Vector3D(0.0f, 0.0f, (float)amount));
|
||||
|
||||
mode.SetActionResult("Changed thing height to " + Thing.Position.z + ".");
|
||||
|
||||
this.Changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal interface IVisualEventReceiver
|
||||
{
|
||||
// The events that must be handled
|
||||
void OnSelectBegin();
|
||||
void OnSelectEnd();
|
||||
void OnEditBegin();
|
||||
void OnEditEnd();
|
||||
void OnMouseMove(MouseEventArgs e);
|
||||
void OnChangeTargetHeight(int amount);
|
||||
void OnChangeTargetBrightness(bool up);
|
||||
void OnChangeTextureOffset(int horizontal, int vertical);
|
||||
void OnResetTextureOffset();
|
||||
void OnSelectTexture();
|
||||
void OnCopyTexture();
|
||||
void OnPasteTexture();
|
||||
void OnCopyTextureOffsets();
|
||||
void OnPasteTextureOffsets();
|
||||
void OnCopyProperties();
|
||||
void OnPasteProperties();
|
||||
void OnTextureAlign(bool alignx, bool aligny);
|
||||
void OnTextureFloodfill();
|
||||
void OnToggleUpperUnpegged();
|
||||
void OnToggleLowerUnpegged();
|
||||
void OnProcess(double deltatime);
|
||||
void OnInsert();
|
||||
void OnDelete();
|
||||
|
||||
// Assist functions
|
||||
void ApplyTexture(string texture);
|
||||
void ApplyUpperUnpegged(bool set);
|
||||
void ApplyLowerUnpegged(bool set);
|
||||
|
||||
// Other methods
|
||||
string GetTextureName();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
// This doesn't do jack shit.
|
||||
internal class NullVisualEventReceiver : IVisualEventReceiver
|
||||
{
|
||||
public NullVisualEventReceiver()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSelectBegin()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSelectEnd()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnEditBegin()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnEditEnd()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnChangeTargetHeight(int amount)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnChangeTargetBrightness(bool up)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnChangeTextureOffset(int horizontal, int vertical)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnResetTextureOffset()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnSelectTexture()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCopyTexture()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnPasteTexture()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCopyTextureOffsets()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnPasteTextureOffsets()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnCopyProperties()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnPasteProperties()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnTextureAlign(bool alignx, bool aligny)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnTextureFloodfill()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnToggleUpperUnpegged()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnToggleLowerUnpegged()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnProcess(double deltatime)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnInsert()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnDelete()
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyTexture(string texture)
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyUpperUnpegged(bool set)
|
||||
{
|
||||
}
|
||||
|
||||
public void ApplyLowerUnpegged(bool set)
|
||||
{
|
||||
}
|
||||
|
||||
public string GetTextureName()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
public struct VisualActionResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Status description to show after action hasbeen performed. Set to null to show no message.
|
||||
/// </summary>
|
||||
public string displaystatus;
|
||||
}
|
||||
}
|
233
Source/Plugins/GZDoomEditing/VisualModes/VisualCeiling.cs
Normal file
233
Source/Plugins/GZDoomEditing/VisualModes/VisualCeiling.cs
Normal file
|
@ -0,0 +1,233 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal sealed class VisualCeiling : BaseVisualGeometrySector
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public VisualCeiling(BaseVisualMode mode, VisualSector vs) : base(mode, vs)
|
||||
{
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
WorldVertex[] verts;
|
||||
WorldVertex v;
|
||||
Sector s = base.Sector.Sector;
|
||||
float xpan, ypan, xscale, yscale, rotate;
|
||||
int color, light;
|
||||
bool absolute;
|
||||
Vector2D texscale;
|
||||
|
||||
try
|
||||
{
|
||||
// Fetch ZDoom fields
|
||||
xpan = s.Fields.ContainsKey("xpanningceiling") ? (float)s.Fields["xpanningceiling"].Value : 0.0f;
|
||||
ypan = s.Fields.ContainsKey("ypanningceiling") ? (float)s.Fields["ypanningceiling"].Value : 0.0f;
|
||||
xscale = s.Fields.ContainsKey("xscaleceiling") ? (float)s.Fields["xscaleceiling"].Value : 1.0f;
|
||||
yscale = s.Fields.ContainsKey("yscaleceiling") ? (float)s.Fields["yscaleceiling"].Value : 1.0f;
|
||||
rotate = s.Fields.ContainsKey("rotationceiling") ? (float)s.Fields["rotationceiling"].Value : 0.0f;
|
||||
color = s.Fields.ContainsKey("lightcolor") ? (int)s.Fields["lightcolor"].Value : -1;
|
||||
light = s.Fields.ContainsKey("lightceiling") ? (int)s.Fields["lightceiling"].Value : 0;
|
||||
absolute = s.Fields.ContainsKey("lightceilingabsolute") ? (bool)s.Fields["lightceilingabsolute"].Value : false;
|
||||
}
|
||||
catch(Exception) { return false; }
|
||||
|
||||
// Load floor texture
|
||||
base.Texture = General.Map.Data.GetFlatImage(s.LongCeilTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = s.LongCeilTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = s.LongCeilTexture;
|
||||
}
|
||||
|
||||
// Determine texture scale
|
||||
if(base.Texture.IsImageLoaded)
|
||||
texscale = new Vector2D(1.0f / base.Texture.ScaledWidth, 1.0f / base.Texture.ScaledHeight);
|
||||
else
|
||||
texscale = new Vector2D(1.0f / 64.0f, 1.0f / 64.0f);
|
||||
|
||||
// Prepare for math!
|
||||
rotate = Angle2D.DegToRad(rotate);
|
||||
Vector2D scale = new Vector2D(xscale, yscale);
|
||||
Vector2D offset = new Vector2D(xpan, ypan);
|
||||
if(!absolute) light = s.Brightness + light;
|
||||
PixelColor lightcolor = PixelColor.FromInt(color);
|
||||
PixelColor brightness = PixelColor.FromInt(mode.CalculateBrightness(light));
|
||||
PixelColor finalcolor = PixelColor.Modulate(lightcolor, brightness);
|
||||
color = finalcolor.WithAlpha(255).ToInt();
|
||||
|
||||
// Make vertices
|
||||
verts = new WorldVertex[s.Triangles.Vertices.Count];
|
||||
for(int i = 0; i < s.Triangles.Vertices.Count; i++)
|
||||
{
|
||||
// Color shading
|
||||
verts[i].c = color;
|
||||
|
||||
// Vertex coordinates
|
||||
verts[i].x = s.Triangles.Vertices[i].x;
|
||||
verts[i].y = s.Triangles.Vertices[i].y;
|
||||
verts[i].z = (float)s.CeilHeight;
|
||||
|
||||
// Texture coordinates
|
||||
Vector2D pos = s.Triangles.Vertices[i];
|
||||
pos = pos.GetRotated(rotate);
|
||||
pos.y = -pos.y;
|
||||
pos = (pos + offset) * scale * texscale;
|
||||
verts[i].u = pos.x;
|
||||
verts[i].v = pos.y;
|
||||
}
|
||||
|
||||
// The sector triangulation created clockwise triangles that
|
||||
// are right up for the floor. For the ceiling we must flip
|
||||
// the triangles upside down.
|
||||
// Swap some vertices to flip all triangles
|
||||
for(int i = 0; i < verts.Length; i += 3)
|
||||
{
|
||||
// Swap
|
||||
v = verts[i];
|
||||
verts[i] = verts[i + 1];
|
||||
verts[i + 1] = v;
|
||||
}
|
||||
|
||||
// Apply vertices
|
||||
base.SetVertices(verts);
|
||||
return (verts.Length > 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// Paste texture
|
||||
public override void OnPasteTexture()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedFlat != null)
|
||||
{
|
||||
mode.CreateUndo("Paste ceiling " + BuilderPlug.Me.CopiedFlat);
|
||||
mode.SetActionResult("Pasted flat " + BuilderPlug.Me.CopiedFlat + " on ceiling.");
|
||||
SetTexture(BuilderPlug.Me.CopiedFlat);
|
||||
this.Setup();
|
||||
}
|
||||
}
|
||||
|
||||
// This changes the height
|
||||
protected override void ChangeHeight(int amount)
|
||||
{
|
||||
mode.CreateUndo("Change ceiling height", UndoGroup.CeilingHeightChange, this.Sector.Sector.FixedIndex);
|
||||
this.Sector.Sector.CeilHeight += amount;
|
||||
mode.SetActionResult("Changed ceiling height to " + Sector.Sector.CeilHeight + ".");
|
||||
}
|
||||
|
||||
// This performs a fast test in object picking
|
||||
public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||
{
|
||||
float planez = (float)Sector.Sector.CeilHeight;
|
||||
|
||||
// Check if line crosses the z height
|
||||
if((from.z < planez) && (to.z > planez))
|
||||
{
|
||||
// Calculate intersection point using the z height
|
||||
pickrayu = (planez - from.z) / (to.z - from.z);
|
||||
pickintersect = from + (to - from) * pickrayu;
|
||||
|
||||
// Intersection point within bbox?
|
||||
RectangleF bbox = Sector.Sector.BBox;
|
||||
return ((pickintersect.x >= bbox.Left) && (pickintersect.x <= bbox.Right) &&
|
||||
(pickintersect.y >= bbox.Top) && (pickintersect.y <= bbox.Bottom));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not even crossing the z height (or not in the right direction)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This performs an accurate test for object picking
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||
{
|
||||
u_ray = pickrayu;
|
||||
|
||||
// Check on which side of the nearest sidedef we are
|
||||
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
|
||||
float side = sd.Line.SideOfLine(pickintersect);
|
||||
return (((side <= 0.0f) && sd.IsFront) || ((side > 0.0f) && !sd.IsFront));
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
return this.Sector.Sector.CeilTexture;
|
||||
}
|
||||
|
||||
// This changes the texture
|
||||
protected override void SetTexture(string texturename)
|
||||
{
|
||||
this.Sector.Sector.SetCeilTexture(texturename);
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
this.Setup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
220
Source/Plugins/GZDoomEditing/VisualModes/VisualFloor.cs
Normal file
220
Source/Plugins/GZDoomEditing/VisualModes/VisualFloor.cs
Normal file
|
@ -0,0 +1,220 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal sealed class VisualFloor : BaseVisualGeometrySector
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public VisualFloor(BaseVisualMode mode, VisualSector vs) : base(mode, vs)
|
||||
{
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
WorldVertex[] verts;
|
||||
Sector s = base.Sector.Sector;
|
||||
float xpan, ypan, xscale, yscale, rotate;
|
||||
int color, light;
|
||||
bool absolute;
|
||||
Vector2D texscale;
|
||||
|
||||
try
|
||||
{
|
||||
// Fetch ZDoom fields
|
||||
xpan = s.Fields.ContainsKey("xpanningfloor") ? (float)s.Fields["xpanningfloor"].Value : 0.0f;
|
||||
ypan = s.Fields.ContainsKey("ypanningfloor") ? (float)s.Fields["ypanningfloor"].Value : 0.0f;
|
||||
xscale = s.Fields.ContainsKey("xscalefloor") ? (float)s.Fields["xscalefloor"].Value : 1.0f;
|
||||
yscale = s.Fields.ContainsKey("yscalefloor") ? (float)s.Fields["yscalefloor"].Value : 1.0f;
|
||||
rotate = s.Fields.ContainsKey("rotationfloor") ? (float)s.Fields["rotationfloor"].Value : 0.0f;
|
||||
color = s.Fields.ContainsKey("lightcolor") ? (int)s.Fields["lightcolor"].Value : -1;
|
||||
light = s.Fields.ContainsKey("lightfloor") ? (int)s.Fields["lightfloor"].Value : 0;
|
||||
absolute = s.Fields.ContainsKey("lightfloorabsolute") ? (bool)s.Fields["lightfloorabsolute"].Value : false;
|
||||
}
|
||||
catch(Exception) { return false; }
|
||||
|
||||
// Load floor texture
|
||||
base.Texture = General.Map.Data.GetFlatImage(s.LongFloorTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = s.LongFloorTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = s.LongFloorTexture;
|
||||
}
|
||||
|
||||
// Determine texture scale
|
||||
if(base.Texture.IsImageLoaded)
|
||||
texscale = new Vector2D(1.0f / base.Texture.ScaledWidth, 1.0f / base.Texture.ScaledHeight);
|
||||
else
|
||||
texscale = new Vector2D(1.0f / 64.0f, 1.0f / 64.0f);
|
||||
|
||||
// Prepare for math!
|
||||
rotate = Angle2D.DegToRad(rotate);
|
||||
Vector2D scale = new Vector2D(xscale, yscale);
|
||||
Vector2D offset = new Vector2D(xpan, ypan);
|
||||
if(!absolute) light = s.Brightness + light;
|
||||
PixelColor lightcolor = PixelColor.FromInt(color);
|
||||
PixelColor brightness = PixelColor.FromInt(mode.CalculateBrightness(light));
|
||||
PixelColor finalcolor = PixelColor.Modulate(lightcolor, brightness);
|
||||
color = finalcolor.WithAlpha(255).ToInt();
|
||||
|
||||
// Make vertices
|
||||
verts = new WorldVertex[s.Triangles.Vertices.Count];
|
||||
for(int i = 0; i < s.Triangles.Vertices.Count; i++)
|
||||
{
|
||||
// Color shading
|
||||
verts[i].c = color;
|
||||
|
||||
// Vertex coordinates
|
||||
verts[i].x = s.Triangles.Vertices[i].x;
|
||||
verts[i].y = s.Triangles.Vertices[i].y;
|
||||
verts[i].z = (float)s.FloorHeight;
|
||||
|
||||
// Texture coordinates
|
||||
Vector2D pos = s.Triangles.Vertices[i];
|
||||
pos = pos.GetRotated(rotate);
|
||||
pos.y = -pos.y;
|
||||
pos = (pos + offset) * scale * texscale;
|
||||
verts[i].u = pos.x;
|
||||
verts[i].v = pos.y;
|
||||
}
|
||||
|
||||
// Apply vertices
|
||||
base.SetVertices(verts);
|
||||
return (verts.Length > 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// Paste texture
|
||||
public override void OnPasteTexture()
|
||||
{
|
||||
if(BuilderPlug.Me.CopiedFlat != null)
|
||||
{
|
||||
mode.CreateUndo("Paste floor " + BuilderPlug.Me.CopiedFlat);
|
||||
mode.SetActionResult("Pasted flat " + BuilderPlug.Me.CopiedFlat + " on floor.");
|
||||
SetTexture(BuilderPlug.Me.CopiedFlat);
|
||||
this.Setup();
|
||||
}
|
||||
}
|
||||
|
||||
// This changes the height
|
||||
protected override void ChangeHeight(int amount)
|
||||
{
|
||||
mode.CreateUndo("Change floor height", UndoGroup.FloorHeightChange, this.Sector.Sector.FixedIndex);
|
||||
this.Sector.Sector.FloorHeight += amount;
|
||||
mode.SetActionResult("Changed floor height to " + Sector.Sector.FloorHeight + ".");
|
||||
}
|
||||
|
||||
// This performs a fast test in object picking
|
||||
public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||
{
|
||||
float planez = (float)Sector.Sector.FloorHeight;
|
||||
|
||||
// Check if line crosses the z height
|
||||
if((from.z > planez) && (to.z < planez))
|
||||
{
|
||||
// Calculate intersection point using the z height
|
||||
pickrayu = (planez - from.z) / (to.z - from.z);
|
||||
pickintersect = from + (to - from) * pickrayu;
|
||||
|
||||
// Intersection point within bbox?
|
||||
RectangleF bbox = Sector.Sector.BBox;
|
||||
return ((pickintersect.x >= bbox.Left) && (pickintersect.x <= bbox.Right) &&
|
||||
(pickintersect.y >= bbox.Top) && (pickintersect.y <= bbox.Bottom));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not even crossing the z height (or not in the right direction)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This performs an accurate test for object picking
|
||||
public override bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||
{
|
||||
u_ray = pickrayu;
|
||||
|
||||
// Check on which side of the nearest sidedef we are
|
||||
Sidedef sd = MapSet.NearestSidedef(Sector.Sector.Sidedefs, pickintersect);
|
||||
float side = sd.Line.SideOfLine(pickintersect);
|
||||
return (((side <= 0.0f) && sd.IsFront) || ((side > 0.0f) && !sd.IsFront));
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
return this.Sector.Sector.FloorTexture;
|
||||
}
|
||||
|
||||
// This changes the texture
|
||||
protected override void SetTexture(string texturename)
|
||||
{
|
||||
this.Sector.Sector.SetFloorTexture(texturename);
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
this.Setup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
193
Source/Plugins/GZDoomEditing/VisualModes/VisualLower.cs
Normal file
193
Source/Plugins/GZDoomEditing/VisualModes/VisualLower.cs
Normal file
|
@ -0,0 +1,193 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal sealed class VisualLower : BaseVisualGeometrySidedef
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public VisualLower(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
|
||||
{
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
int brightness = mode.CalculateBrightness(Sidedef.Sector.Brightness);
|
||||
|
||||
// Calculate size of this wall part
|
||||
float geotop = (float)Sidedef.Other.Sector.FloorHeight;
|
||||
float geobottom = (float)Sidedef.Sector.FloorHeight;
|
||||
float geoheight = geotop - geobottom;
|
||||
if(geoheight > 0.001f)
|
||||
{
|
||||
Vector2D t1 = new Vector2D();
|
||||
Vector2D t2 = new Vector2D();
|
||||
|
||||
// Texture given?
|
||||
if((Sidedef.LowTexture.Length > 0) && (Sidedef.LowTexture[0] != '-'))
|
||||
{
|
||||
// Load texture
|
||||
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongLowTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = Sidedef.LongLowTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = Sidedef.LongLowTexture;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use missing texture
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = 0;
|
||||
}
|
||||
|
||||
// Get texture scaled size
|
||||
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
|
||||
|
||||
// Determine texture coordinates
|
||||
// See http://doom.wikia.com/wiki/Texture_alignment
|
||||
// We just use pixels for coordinates for now
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
// When lower unpegged is set, the lower texture is bound to the bottom
|
||||
t1.y = (float)Sidedef.Sector.CeilHeight - geotop;
|
||||
}
|
||||
t2.x = t1.x + Sidedef.Line.Length;
|
||||
t2.y = t1.y + geoheight;
|
||||
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
t2 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
t2 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
}
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
t1 /= tsz;
|
||||
t2 /= tsz;
|
||||
|
||||
// Get world coordinates for geometry
|
||||
Vector2D v1, v2;
|
||||
if(Sidedef.IsFront)
|
||||
{
|
||||
v1 = Sidedef.Line.Start.Position;
|
||||
v2 = Sidedef.Line.End.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
v1 = Sidedef.Line.End.Position;
|
||||
v2 = Sidedef.Line.Start.Position;
|
||||
}
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, brightness, t1.x, t2.y);
|
||||
verts[1] = new WorldVertex(v1.x, v1.y, geotop, brightness, t1.x, t1.y);
|
||||
verts[2] = new WorldVertex(v2.x, v2.y, geotop, brightness, t2.x, t1.y);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, brightness, t2.x, t2.y);
|
||||
|
||||
// Keep properties
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
|
||||
// Apply vertices
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No geometry for invisible wall
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
WorldVertex[] verts = new WorldVertex[0];
|
||||
base.SetVertices(verts);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
return this.Sidedef.LowTexture;
|
||||
}
|
||||
|
||||
// This changes the texture
|
||||
protected override void SetTexture(string texturename)
|
||||
{
|
||||
this.Sidedef.SetTextureLow(texturename);
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
this.Setup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
214
Source/Plugins/GZDoomEditing/VisualModes/VisualMiddleDouble.cs
Normal file
214
Source/Plugins/GZDoomEditing/VisualModes/VisualMiddleDouble.cs
Normal file
|
@ -0,0 +1,214 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal sealed class VisualMiddleDouble : BaseVisualGeometrySidedef
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public VisualMiddleDouble(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
|
||||
{
|
||||
// Set render pass
|
||||
this.RenderPass = RenderPass.Mask;
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
WorldVertex[] verts;
|
||||
|
||||
int brightness = mode.CalculateBrightness(Sidedef.Sector.Brightness);
|
||||
|
||||
// Calculate size of this wall part
|
||||
float geotop = (float)Math.Min(Sidedef.Sector.CeilHeight, Sidedef.Other.Sector.CeilHeight);
|
||||
float geobottom = (float)Math.Max(Sidedef.Sector.FloorHeight, Sidedef.Other.Sector.FloorHeight);
|
||||
float geoheight = geotop - geobottom;
|
||||
if(geoheight > 0.001f)
|
||||
{
|
||||
// Texture given?
|
||||
if((Sidedef.MiddleTexture.Length > 0) && (Sidedef.MiddleTexture[0] != '-'))
|
||||
{
|
||||
Vector2D t1 = new Vector2D();
|
||||
Vector2D t2 = new Vector2D();
|
||||
float textop, texbottom;
|
||||
float cliptop = 0.0f;
|
||||
float clipbottom = 0.0f;
|
||||
|
||||
// Load texture
|
||||
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
|
||||
// Get texture scaled size
|
||||
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
|
||||
|
||||
// Because the middle texture on a double sided line does not repeat vertically,
|
||||
// we first determine the visible portion of the texture
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
textop = geobottom + tsz.y;
|
||||
else
|
||||
textop = geotop;
|
||||
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets)
|
||||
{
|
||||
textop += Sidedef.OffsetY * base.Texture.Scale.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
textop += Sidedef.OffsetY;
|
||||
}
|
||||
|
||||
|
||||
// Calculate texture portion bottom
|
||||
texbottom = textop - tsz.y;
|
||||
|
||||
// Clip texture portion by geometry
|
||||
if(geotop < textop) { cliptop = textop - geotop; textop = geotop; }
|
||||
if(geobottom > texbottom) { clipbottom = geobottom - texbottom; texbottom = geobottom; }
|
||||
|
||||
// Check if anything is still visible
|
||||
if((textop - texbottom) > 0.001f)
|
||||
{
|
||||
// Determine texture coordinatess
|
||||
t1.y = cliptop;
|
||||
t2.y = tsz.y - clipbottom;
|
||||
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
t1.x = Sidedef.OffsetX * base.Texture.Scale.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
t1.x = Sidedef.OffsetX;
|
||||
}
|
||||
|
||||
t2.x = t1.x + Sidedef.Line.Length;
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
t1 /= tsz;
|
||||
t2 /= tsz;
|
||||
|
||||
// Get world coordinates for geometry
|
||||
Vector2D v1, v2;
|
||||
if(Sidedef.IsFront)
|
||||
{
|
||||
v1 = Sidedef.Line.Start.Position;
|
||||
v2 = Sidedef.Line.End.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
v1 = Sidedef.Line.End.Position;
|
||||
v2 = Sidedef.Line.Start.Position;
|
||||
}
|
||||
|
||||
// Make vertices
|
||||
verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(v1.x, v1.y, texbottom, brightness, t1.x, t2.y);
|
||||
verts[1] = new WorldVertex(v1.x, v1.y, textop, brightness, t1.x, t1.y);
|
||||
verts[2] = new WorldVertex(v2.x, v2.y, textop, brightness, t2.x, t1.y);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(v2.x, v2.y, texbottom, brightness, t2.x, t2.y);
|
||||
|
||||
// Keep properties
|
||||
base.top = textop;
|
||||
base.bottom = texbottom;
|
||||
|
||||
// Apply vertices
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No geometry for invisible wall
|
||||
base.top = geotop;
|
||||
base.bottom = geotop; // bottom same as top so that it has a height of 0 (otherwise it will still be picked up by object picking)
|
||||
verts = new WorldVertex[0];
|
||||
base.SetVertices(verts);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
return this.Sidedef.MiddleTexture;
|
||||
}
|
||||
|
||||
// This changes the texture
|
||||
protected override void SetTexture(string texturename)
|
||||
{
|
||||
this.Sidedef.SetTextureMid(texturename);
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
this.Setup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
193
Source/Plugins/GZDoomEditing/VisualModes/VisualMiddleSingle.cs
Normal file
193
Source/Plugins/GZDoomEditing/VisualModes/VisualMiddleSingle.cs
Normal file
|
@ -0,0 +1,193 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal sealed class VisualMiddleSingle : BaseVisualGeometrySidedef
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public VisualMiddleSingle(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
|
||||
{
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
int brightness = mode.CalculateBrightness(Sidedef.Sector.Brightness);
|
||||
|
||||
// Calculate size of this wall part
|
||||
float geotop = (float)Sidedef.Sector.CeilHeight;
|
||||
float geobottom = (float)Sidedef.Sector.FloorHeight;
|
||||
float geoheight = geotop - geobottom;
|
||||
if(geoheight > 0.001f)
|
||||
{
|
||||
Vector2D t1 = new Vector2D();
|
||||
Vector2D t2 = new Vector2D();
|
||||
|
||||
// Texture given?
|
||||
if((Sidedef.MiddleTexture.Length > 0) && (Sidedef.MiddleTexture[0] != '-'))
|
||||
{
|
||||
// Load texture
|
||||
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use missing texture
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = 0;
|
||||
}
|
||||
|
||||
// Get texture scaled size
|
||||
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
|
||||
|
||||
// Determine texture coordinates
|
||||
// See http://doom.wikia.com/wiki/Texture_alignment
|
||||
// We just use pixels for coordinates for now
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
// When lower unpegged is set, the middle texture is bound to the bottom
|
||||
t1.y = tsz.y - geoheight;
|
||||
}
|
||||
t2.x = t1.x + Sidedef.Line.Length;
|
||||
t2.y = t1.y + geoheight;
|
||||
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
t2 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
t2 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
}
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
t1 /= tsz;
|
||||
t2 /= tsz;
|
||||
|
||||
// Get world coordinates for geometry
|
||||
Vector2D v1, v2;
|
||||
if(Sidedef.IsFront)
|
||||
{
|
||||
v1 = Sidedef.Line.Start.Position;
|
||||
v2 = Sidedef.Line.End.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
v1 = Sidedef.Line.End.Position;
|
||||
v2 = Sidedef.Line.Start.Position;
|
||||
}
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, brightness, t1.x, t2.y);
|
||||
verts[1] = new WorldVertex(v1.x, v1.y, geotop, brightness, t1.x, t1.y);
|
||||
verts[2] = new WorldVertex(v2.x, v2.y, geotop, brightness, t2.x, t1.y);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, brightness, t2.x, t2.y);
|
||||
|
||||
// Keep properties
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
|
||||
// Apply vertices
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No geometry for invisible wall
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
WorldVertex[] verts = new WorldVertex[0];
|
||||
base.SetVertices(verts);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
return this.Sidedef.MiddleTexture;
|
||||
}
|
||||
|
||||
// This changes the texture
|
||||
protected override void SetTexture(string texturename)
|
||||
{
|
||||
this.Sidedef.SetTextureMid(texturename);
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
this.Setup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using CodeImp.DoomBuilder.Windows;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal struct VisualSidedefParts
|
||||
{
|
||||
// Members
|
||||
public VisualUpper upper;
|
||||
public VisualLower lower;
|
||||
public VisualMiddleDouble middledouble;
|
||||
public VisualMiddleSingle middlesingle;
|
||||
|
||||
// Constructor
|
||||
public VisualSidedefParts(VisualUpper u, VisualLower l, VisualMiddleDouble m)
|
||||
{
|
||||
this.upper = u;
|
||||
this.lower = l;
|
||||
this.middledouble = m;
|
||||
this.middlesingle = null;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
public VisualSidedefParts(VisualMiddleSingle m)
|
||||
{
|
||||
this.upper = null;
|
||||
this.lower = null;
|
||||
this.middledouble = null;
|
||||
this.middlesingle = m;
|
||||
}
|
||||
|
||||
// This calls Setup() on all parts
|
||||
public void SetupAllParts()
|
||||
{
|
||||
if(lower != null) lower.Setup();
|
||||
if(middledouble != null) middledouble.Setup();
|
||||
if(middlesingle != null) middlesingle.Setup();
|
||||
if(upper != null) upper.Setup();
|
||||
}
|
||||
}
|
||||
}
|
194
Source/Plugins/GZDoomEditing/VisualModes/VisualUpper.cs
Normal file
194
Source/Plugins/GZDoomEditing/VisualModes/VisualUpper.cs
Normal file
|
@ -0,0 +1,194 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Drawing;
|
||||
using System.ComponentModel;
|
||||
using CodeImp.DoomBuilder.GZDoomEditing;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using System.Drawing.Imaging;
|
||||
using CodeImp.DoomBuilder.Data;
|
||||
using CodeImp.DoomBuilder.Editing;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
using CodeImp.DoomBuilder.VisualModes;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal sealed class VisualUpper : BaseVisualGeometrySidedef
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public VisualUpper(BaseVisualMode mode, VisualSector vs, Sidedef s) : base(mode, vs, s)
|
||||
{
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
int brightness = mode.CalculateBrightness(Sidedef.Sector.Brightness);
|
||||
|
||||
// Calculate size of this wall part
|
||||
float geotop = (float)Sidedef.Sector.CeilHeight;
|
||||
float geobottom = (float)Sidedef.Other.Sector.CeilHeight;
|
||||
float geoheight = geotop - geobottom;
|
||||
if(geoheight > 0.001f)
|
||||
{
|
||||
Vector2D t1 = new Vector2D();
|
||||
Vector2D t2 = new Vector2D();
|
||||
|
||||
// Texture given?
|
||||
if((Sidedef.HighTexture.Length > 0) && (Sidedef.HighTexture[0] != '-'))
|
||||
{
|
||||
// Load texture
|
||||
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongHighTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = Sidedef.LongHighTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = Sidedef.LongHighTexture;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use missing texture
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = 0;
|
||||
}
|
||||
|
||||
// Get texture scaled size
|
||||
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
|
||||
|
||||
// Determine texture coordinates
|
||||
// See http://doom.wikia.com/wiki/Texture_alignment
|
||||
// We just use pixels for coordinates for now
|
||||
if(!Sidedef.Line.IsFlagSet(General.Map.Config.UpperUnpeggedFlag))
|
||||
{
|
||||
// When upper unpegged is NOT set, the upper texture is bound to the bottom
|
||||
t1.y = tsz.y - geoheight;
|
||||
}
|
||||
t2.x = t1.x + Sidedef.Line.Length;
|
||||
t2.y = t1.y + geoheight;
|
||||
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
t2 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
t2 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
}
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
t1 /= tsz;
|
||||
t2 /= tsz;
|
||||
|
||||
// Get world coordinates for geometry
|
||||
Vector2D v1, v2;
|
||||
if(Sidedef.IsFront)
|
||||
{
|
||||
v1 = Sidedef.Line.Start.Position;
|
||||
v2 = Sidedef.Line.End.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
v1 = Sidedef.Line.End.Position;
|
||||
v2 = Sidedef.Line.Start.Position;
|
||||
}
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, brightness, t1.x, t2.y);
|
||||
verts[1] = new WorldVertex(v1.x, v1.y, geotop, brightness, t1.x, t1.y);
|
||||
verts[2] = new WorldVertex(v2.x, v2.y, geotop, brightness, t2.x, t1.y);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, brightness, t2.x, t2.y);
|
||||
|
||||
// Keep properties
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
|
||||
// Apply vertices
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No geometry for invisible wall
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
WorldVertex[] verts = new WorldVertex[0];
|
||||
base.SetVertices(verts);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
return this.Sidedef.HighTexture;
|
||||
}
|
||||
|
||||
// This changes the texture
|
||||
protected override void SetTexture(string texturename)
|
||||
{
|
||||
this.Sidedef.SetTextureHigh(texturename);
|
||||
General.Map.Data.UpdateUsedTextures();
|
||||
this.Setup();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ maps
|
|||
backoffsety = 0;
|
||||
backscalex = 100;
|
||||
backscaley = 100;
|
||||
gridsize = 32;
|
||||
gridsize = 2;
|
||||
}
|
||||
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue