mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-23 04:12:12 +00:00
@ work on (G)ZDoom Editing plugin
This commit is contained in:
parent
f289920dca
commit
f2e16e0707
14 changed files with 516 additions and 181 deletions
|
@ -55,6 +55,8 @@
|
|||
<Compile Include="VisualModes\BaseVisualThing.cs" />
|
||||
<Compile Include="VisualModes\IVisualEventReceiver.cs" />
|
||||
<Compile Include="VisualModes\NullVisualEventReceiver.cs" />
|
||||
<Compile Include="VisualModes\Sector3DFloor.cs" />
|
||||
<Compile Include="VisualModes\VisualMiddle3D.cs" />
|
||||
<Compile Include="VisualModes\WallPolygon.cs" />
|
||||
<Compile Include="VisualModes\SectorData.cs" />
|
||||
<Compile Include="VisualModes\SectorLevel.cs" />
|
||||
|
|
|
@ -73,7 +73,10 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
// Static property to access the BuilderPlug
|
||||
public static BuilderPlug Me { get { return me; } }
|
||||
|
||||
|
||||
// This is the lowest Doom Builder core revision that is required for this plugin to work
|
||||
public override int MinimumRevision { get { return 1382; } }
|
||||
|
||||
// Settings
|
||||
public int ShowVisualThings { get { return showvisualthings; } set { showvisualthings = value; } }
|
||||
public int ChangeHeightBySidedef { get { return changeheightbysidedef; } }
|
||||
|
|
|
@ -121,9 +121,9 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
polygons.Add(poly);
|
||||
|
||||
// Go for all levels to build geometry
|
||||
for(int i = sd.Levels.Count - 1; i >= 0; i--)
|
||||
for(int i = sd.LightLevels.Count - 1; i >= 0; i--)
|
||||
{
|
||||
SectorLevel l = sd.Levels[i];
|
||||
SectorLevel l = sd.LightLevels[i];
|
||||
if((l != sd.Floor) && (l != sd.Ceiling) && (l.type != SectorLevelType.Floor))
|
||||
{
|
||||
// Go for all polygons
|
||||
|
|
|
@ -542,7 +542,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
// Camera below floor level?
|
||||
Vector3D feetposition = General.Map.VisualCamera.Position - new Vector3D(0, 0, cameraflooroffset - 7.0f);
|
||||
SectorLevel floorlevel = sd.GetFloorBelow(feetposition) ?? sd.Levels[0];
|
||||
SectorLevel floorlevel = sd.GetFloorBelow(feetposition) ?? sd.LightLevels[0];
|
||||
float floorheight = floorlevel.plane.GetZ(General.Map.VisualCamera.Position);
|
||||
if(General.Map.VisualCamera.Position.z < (floorheight + cameraflooroffset + 0.01f))
|
||||
{
|
||||
|
@ -559,7 +559,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
if(gravity.z > 3.0f) gravity.z = 3.0f;
|
||||
|
||||
// Test if we don't go through a floor
|
||||
SectorLevel newfloorlevel = sd.GetFloorBelow(feetposition + gravity) ?? sd.Levels[0];
|
||||
SectorLevel newfloorlevel = sd.GetFloorBelow(feetposition + gravity) ?? sd.LightLevels[0];
|
||||
if(newfloorlevel != floorlevel)
|
||||
{
|
||||
// Stay above floor
|
||||
|
@ -577,7 +577,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
// Camera above ceiling?
|
||||
feetposition = General.Map.VisualCamera.Position - new Vector3D(0, 0, cameraflooroffset - 7.0f);
|
||||
SectorLevel ceillevel = sd.GetCeilingAbove(feetposition) ?? sd.Levels[sd.Levels.Count - 1];
|
||||
SectorLevel ceillevel = sd.GetCeilingAbove(feetposition) ?? sd.LightLevels[sd.LightLevels.Count - 1];
|
||||
float ceilheight = ceillevel.plane.GetZ(General.Map.VisualCamera.Position);
|
||||
if(General.Map.VisualCamera.Position.z > (ceilheight - cameraceilingoffset - 0.01f))
|
||||
{
|
||||
|
|
|
@ -146,27 +146,29 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
data = mode.GetSectorData(this.Sector);
|
||||
if(!data.Built) data.BuildLevels(mode);
|
||||
|
||||
// Create levels
|
||||
foreach(SectorLevel lvl in data.Levels)
|
||||
// Create floor
|
||||
floor = floor ?? new VisualFloor(mode, this, data.Floor);
|
||||
floor.Setup();
|
||||
base.AddGeometry(floor);
|
||||
|
||||
// Create ceiling
|
||||
ceiling = ceiling ?? new VisualCeiling(mode, this, data.Ceiling);
|
||||
ceiling.Setup();
|
||||
base.AddGeometry(ceiling);
|
||||
|
||||
// Create 3D floors
|
||||
foreach(Sector3DFloor ef in data.ExtraFloors)
|
||||
{
|
||||
if(lvl.type == SectorLevelType.Floor)
|
||||
{
|
||||
// Create a floor
|
||||
VisualFloor g = new VisualFloor(mode, this, lvl);
|
||||
g.Setup();
|
||||
base.AddGeometry(g);
|
||||
}
|
||||
else if(lvl.type == SectorLevelType.Ceiling)
|
||||
{
|
||||
// Create a ceiling
|
||||
VisualCeiling g = new VisualCeiling(mode, this, lvl);
|
||||
g.Setup();
|
||||
base.AddGeometry(g);
|
||||
}
|
||||
// Create a floor
|
||||
VisualFloor vf = new VisualFloor(mode, this, ef.floor);
|
||||
vf.Setup();
|
||||
base.AddGeometry(vf);
|
||||
|
||||
// Create a ceiling
|
||||
VisualCeiling vc = new VisualCeiling(mode, this, ef.ceiling);
|
||||
vc.Setup();
|
||||
base.AddGeometry(vc);
|
||||
}
|
||||
|
||||
// NOTE: Because we no longer use the Floor and Ceiling members, these are now null.
|
||||
// They need to be replaced with a different system that works for all levels in the sector.
|
||||
|
||||
// Go for all sidedefs
|
||||
Dictionary<Sidedef, VisualSidedefParts> oldsides = sides ?? new Dictionary<Sidedef, VisualSidedefParts>(1);
|
||||
|
@ -193,9 +195,22 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
VisualMiddleDouble vm = parts.middledouble ?? new VisualMiddleDouble(mode, this, sd);
|
||||
vm.Setup();
|
||||
base.AddGeometry(vm);
|
||||
|
||||
|
||||
// Create 3D wall parts
|
||||
SectorData osd = mode.GetSectorData(sd.Other.Sector);
|
||||
if(!osd.Built) osd.BuildLevels(mode);
|
||||
Dictionary<Sector3DFloor, VisualMiddle3D> oldfloors = parts.middle3d ?? new Dictionary<Sector3DFloor, VisualMiddle3D>(2);
|
||||
Dictionary<Sector3DFloor, VisualMiddle3D> newfloors = new Dictionary<Sector3DFloor, VisualMiddle3D>(2);
|
||||
foreach(Sector3DFloor ef in osd.ExtraFloors)
|
||||
{
|
||||
VisualMiddle3D vm3 = oldfloors.ContainsKey(ef) ? oldfloors[ef] : new VisualMiddle3D(mode, this, sd, ef);
|
||||
vm3.Setup();
|
||||
base.AddGeometry(vm3);
|
||||
newfloors.Add(ef, vm3);
|
||||
}
|
||||
|
||||
// Store
|
||||
sides.Add(sd, new VisualSidedefParts(vu, vl, vm));
|
||||
sides.Add(sd, new VisualSidedefParts(vu, vl, vm, newfloors));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
60
Source/Plugins/GZDoomEditing/VisualModes/Sector3DFloor.cs
Normal file
60
Source/Plugins/GZDoomEditing/VisualModes/Sector3DFloor.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
#region === Copyright (c) 2010 Pascal van der Heiden ===
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal class Sector3DFloor
|
||||
{
|
||||
// Floor and ceiling planes
|
||||
public SectorLevel floor;
|
||||
public SectorLevel ceiling;
|
||||
|
||||
// Linedef that is used to create this 3D floor
|
||||
public Linedef linedef;
|
||||
|
||||
// Constructor
|
||||
public Sector3DFloor(SectorData controlsector, Linedef sourcelinedef)
|
||||
{
|
||||
linedef = sourcelinedef;
|
||||
|
||||
// For non-vavoom types, we must switch the level types
|
||||
if((sourcelinedef.Args[1] & 0x03) != 0)
|
||||
{
|
||||
floor = new SectorLevel(controlsector.Ceiling);
|
||||
ceiling = new SectorLevel(controlsector.Floor);
|
||||
floor.type = SectorLevelType.Floor;
|
||||
floor.plane = floor.plane.GetInverted();
|
||||
ceiling.type = SectorLevelType.Ceiling;
|
||||
ceiling.plane = ceiling.plane.GetInverted();
|
||||
}
|
||||
else
|
||||
{
|
||||
floor = new SectorLevel(controlsector.Floor);
|
||||
ceiling = new SectorLevel(controlsector.Ceiling);
|
||||
}
|
||||
|
||||
// A 3D floor's color is always that of the sector it is placed in
|
||||
floor.color = 0;
|
||||
|
||||
// Do not adjust light? (works only for non-vavoom types)
|
||||
if(((sourcelinedef.Args[2] & 1) != 0) && ((sourcelinedef.Args[1] & 0x03) != 0))
|
||||
{
|
||||
floor.brightnessbelow = -1;
|
||||
floor.colorbelow = PixelColor.FromInt(0);
|
||||
ceiling.color = 0;
|
||||
ceiling.brightnessbelow = -1;
|
||||
ceiling.colorbelow = PixelColor.FromInt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,7 +27,10 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
private bool isbuilding;
|
||||
|
||||
// Levels sorted by height
|
||||
private List<SectorLevel> levels;
|
||||
private List<SectorLevel> lightlevels;
|
||||
|
||||
// 3D floors
|
||||
private List<Sector3DFloor> extrafloors;
|
||||
|
||||
// Original floor and ceiling levels
|
||||
private SectorLevel floor;
|
||||
|
@ -44,7 +47,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
public Sector Sector { get { return sector; } }
|
||||
public bool Built { get { return built; } }
|
||||
public List<SectorLevel> Levels { get { return levels; } }
|
||||
public List<SectorLevel> LightLevels { get { return lightlevels; } }
|
||||
public List<Sector3DFloor> ExtraFloors { get { return extrafloors; } }
|
||||
public SectorLevel Floor { get { return floor; } }
|
||||
public SectorLevel Ceiling { get { return ceiling; } }
|
||||
|
||||
|
@ -61,7 +65,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
// Initialize
|
||||
this.sector = s;
|
||||
this.built = false;
|
||||
this.levels = new List<SectorLevel>(2);
|
||||
this.lightlevels = new List<SectorLevel>(2);
|
||||
this.extrafloors = new List<Sector3DFloor>(1);
|
||||
this.linedefs = new List<Linedef>(1);
|
||||
this.things = new List<Thing>(1);
|
||||
|
||||
|
@ -97,8 +102,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
ceiling.colorbelow = lightcolor.WithAlpha(255);
|
||||
|
||||
// Add ceiling and floor
|
||||
levels.Add(floor);
|
||||
levels.Add(ceiling);
|
||||
lightlevels.Add(floor);
|
||||
lightlevels.Add(ceiling);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -118,7 +123,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
if(isbuilding) return;
|
||||
isbuilding = true;
|
||||
|
||||
levels.Clear();
|
||||
lightlevels.Clear();
|
||||
|
||||
foreach(Linedef l in linedefs)
|
||||
{
|
||||
|
@ -192,32 +197,14 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
{
|
||||
SectorData sd = mode.GetSectorData(l.Front.Sector);
|
||||
if(!sd.Built) sd.BuildLevels(mode);
|
||||
|
||||
SectorLevel f = new SectorLevel(sd.Floor);
|
||||
SectorLevel c = new SectorLevel(sd.Ceiling);
|
||||
|
||||
// For non-vavoom types, we must switch the level types
|
||||
if((l.Args[1] & 0x03) != 0)
|
||||
{
|
||||
f.type = SectorLevelType.Ceiling;
|
||||
c.type = SectorLevelType.Floor;
|
||||
}
|
||||
|
||||
// A 3D floor's color is always that of the sector it is placed in
|
||||
f.color = 0;
|
||||
// Create 3D floor
|
||||
Sector3DFloor ef = new Sector3DFloor(sd, l);
|
||||
extrafloors.Add(ef);
|
||||
|
||||
// Do not adjust light? (works only for non-vavoom types)
|
||||
if(((l.Args[2] & 1) != 0) && ((l.Args[1] & 0x03) != 0))
|
||||
{
|
||||
f.brightnessbelow = -1;
|
||||
f.colorbelow = PixelColor.FromInt(0);
|
||||
c.color = 0;
|
||||
c.brightnessbelow = -1;
|
||||
c.colorbelow = PixelColor.FromInt(0);
|
||||
}
|
||||
|
||||
levels.Add(f);
|
||||
levels.Add(c);
|
||||
// Add levels so that they can participate in lighting
|
||||
lightlevels.Add(ef.floor);
|
||||
lightlevels.Add(ef.ceiling);
|
||||
}
|
||||
}
|
||||
// ========== Transfer Brightness (see http://zdoom.org/wiki/ExtraFloor_LightOnly) =========
|
||||
|
@ -236,7 +223,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
//f.brightnessbelow = 0;
|
||||
//f.colorbelow = PixelColor.FromInt(0);
|
||||
//levels.Add(f);
|
||||
levels.Add(c);
|
||||
lightlevels.Add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,22 +287,22 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
}
|
||||
|
||||
// Sort the levels
|
||||
levels.Sort();
|
||||
lightlevels.Sort();
|
||||
|
||||
// Floor is always first, ceiling always last
|
||||
levels.Add(ceiling);
|
||||
levels.Insert(0, floor);
|
||||
lightlevels.Add(ceiling);
|
||||
lightlevels.Insert(0, floor);
|
||||
|
||||
// Now that we know the levels in this sector (and in the right order) we
|
||||
// can determine the lighting in between and on the levels.
|
||||
// Start from the absolute ceiling and go down to 'cast' the lighting
|
||||
for(int i = levels.Count - 2; i >= 0; i--)
|
||||
for(int i = lightlevels.Count - 2; i >= 0; i--)
|
||||
{
|
||||
SectorLevel l = levels[i];
|
||||
SectorLevel pl = levels[i + 1];
|
||||
SectorLevel l = lightlevels[i];
|
||||
SectorLevel pl = lightlevels[i + 1];
|
||||
|
||||
// Set color when no color is specified, or when a 3D floor is placed above the absolute floor
|
||||
if((l.color == 0) || ((l == floor) && (levels.Count > 2)))
|
||||
if((l.color == 0) || ((l == floor) && (lightlevels.Count > 2)))
|
||||
{
|
||||
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(pl.brightnessbelow));
|
||||
PixelColor floorcolor = PixelColor.Modulate(pl.colorbelow, floorbrightness);
|
||||
|
@ -340,7 +327,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
SectorLevel found = null;
|
||||
float dist = float.MaxValue;
|
||||
|
||||
foreach(SectorLevel l in levels)
|
||||
foreach(SectorLevel l in lightlevels)
|
||||
{
|
||||
float d = l.plane.GetZ(pos) - pos.z;
|
||||
if((d > 0.0f) && (d < dist))
|
||||
|
@ -359,7 +346,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
SectorLevel found = null;
|
||||
float dist = float.MaxValue;
|
||||
|
||||
foreach(SectorLevel l in levels)
|
||||
foreach(SectorLevel l in lightlevels)
|
||||
{
|
||||
if(l.type == SectorLevelType.Ceiling)
|
||||
{
|
||||
|
@ -381,7 +368,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
SectorLevel found = null;
|
||||
float dist = float.MaxValue;
|
||||
|
||||
foreach(SectorLevel l in levels)
|
||||
foreach(SectorLevel l in lightlevels)
|
||||
{
|
||||
float d = pos.z - l.plane.GetZ(pos);
|
||||
if((d > 0.0f) && (d < dist))
|
||||
|
@ -400,7 +387,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
SectorLevel found = null;
|
||||
float dist = float.MaxValue;
|
||||
|
||||
foreach(SectorLevel l in levels)
|
||||
foreach(SectorLevel l in lightlevels)
|
||||
{
|
||||
if(l.type == SectorLevelType.Floor)
|
||||
{
|
||||
|
|
|
@ -127,7 +127,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
tp.trb.y = tp.tlt.y + ((float)Sidedef.Other.Sector.FloorHeight - ((float)Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
if(General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
tp.tlt += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
tp.trb += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
|
@ -179,15 +179,9 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
217
Source/Plugins/GZDoomEditing/VisualModes/VisualMiddle3D.cs
Normal file
217
Source/Plugins/GZDoomEditing/VisualModes/VisualMiddle3D.cs
Normal file
|
@ -0,0 +1,217 @@
|
|||
|
||||
#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 VisualMiddle3D : BaseVisualGeometrySidedef
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
private Sector3DFloor extrafloor;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Setup
|
||||
|
||||
// Constructor
|
||||
public VisualMiddle3D(BaseVisualMode mode, VisualSector vs, Sidedef s, Sector3DFloor extrafloor) : base(mode, vs, s)
|
||||
{
|
||||
this.extrafloor = extrafloor;
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
Vector2D vl, vr;
|
||||
Sidedef sourceside = extrafloor.linedef.Front;
|
||||
|
||||
// Left and right vertices for this sidedef
|
||||
if(Sidedef.IsFront)
|
||||
{
|
||||
vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
|
||||
vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
|
||||
vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
|
||||
}
|
||||
|
||||
// Load sector data
|
||||
SectorData sd = mode.GetSectorData(Sidedef.Sector);
|
||||
|
||||
// Texture given?
|
||||
if((sourceside.MiddleTexture.Length > 0) && (sourceside.MiddleTexture[0] != '-'))
|
||||
{
|
||||
// Load texture
|
||||
base.Texture = General.Map.Data.GetTextureImage(sourceside.LongMiddleTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = sourceside.LongMiddleTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = sourceside.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 plane as they would be in normal circumstances.
|
||||
// We can then use this plane to find any texture coordinate we need.
|
||||
// The logic here is the same as in the original VisualMiddleSingle (except that
|
||||
// the values are stored in a TexturePlane)
|
||||
// NOTE: I use a small bias for the floor height, because if the difference in
|
||||
// height is 0 then the TexturePlane doesn't work!
|
||||
TexturePlane tp = new TexturePlane();
|
||||
float floorbias = (Sidedef.Other.Sector.FloorHeight == Sidedef.Sector.FloorHeight) ? 1.0f : 0.0f;
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
// When lower unpegged is set, the lower texture is bound to the bottom
|
||||
tp.tlt.y = (float)Sidedef.Sector.CeilHeight - (float)sourceside.Sector.FloorHeight;
|
||||
}
|
||||
tp.trb.x = tp.tlt.x + Sidedef.Line.Length;
|
||||
tp.trb.y = tp.tlt.y + ((float)sourceside.Sector.FloorHeight - ((float)Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
// Apply texture offset
|
||||
if(General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
tp.tlt += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
tp.trb += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.tlt += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
tp.trb += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
}
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
tp.vlt = new Vector3D(vl.x, vl.y, (float)sourceside.Sector.FloorHeight);
|
||||
tp.vrb = new Vector3D(vr.x, vr.y, (float)Sidedef.Sector.FloorHeight + floorbias);
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
|
||||
// Get ceiling and floor heights
|
||||
float fl = sd.Floor.plane.GetZ(vl);
|
||||
float fr = sd.Floor.plane.GetZ(vr);
|
||||
float cl = sd.Ceiling.plane.GetZ(vl);
|
||||
float cr = sd.Ceiling.plane.GetZ(vr);
|
||||
|
||||
// Anything to see?
|
||||
if(((cl - fl) > 0.01f) || ((cr - fr) > 0.01f))
|
||||
{
|
||||
// Keep top and bottom planes for intersection testing
|
||||
top = extrafloor.floor.plane;
|
||||
bottom = extrafloor.ceiling.plane;
|
||||
|
||||
// Create initial polygon, which is just a quad between floor and ceiling
|
||||
WallPolygon poly = new WallPolygon();
|
||||
poly.Add(new Vector3D(vl.x, vl.y, fl));
|
||||
poly.Add(new Vector3D(vl.x, vl.y, cl));
|
||||
poly.Add(new Vector3D(vr.x, vr.y, cr));
|
||||
poly.Add(new Vector3D(vr.x, vr.y, fr));
|
||||
|
||||
// Determine initial color
|
||||
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(sd.Ceiling.brightnessbelow));
|
||||
PixelColor wallcolor = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness);
|
||||
poly.color = wallcolor.WithAlpha(255).ToInt();
|
||||
|
||||
// Cut off the part above the 3D floor and below the 3D ceiling
|
||||
CropPoly(ref poly, extrafloor.floor.plane, false);
|
||||
CropPoly(ref poly, extrafloor.ceiling.plane, false);
|
||||
|
||||
// Process the polygon and create vertices
|
||||
List<WorldVertex> verts = CreatePolygonVertices(poly, tp);
|
||||
if(verts.Count > 0)
|
||||
{
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -47,6 +47,10 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
#region ================== Variables
|
||||
|
||||
private bool repeatmidtex;
|
||||
private Plane topclipplane;
|
||||
private Plane bottomclipplane;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -68,25 +72,31 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
WorldVertex[] verts;
|
||||
|
||||
int brightness = mode.CalculateBrightness(Sidedef.Sector.Brightness);
|
||||
Vector2D vl, vr;
|
||||
|
||||
// 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] != '-'))
|
||||
{
|
||||
// Left and right vertices for this sidedef
|
||||
if(Sidedef.IsFront)
|
||||
{
|
||||
vl = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
|
||||
vr = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
vl = new Vector2D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y);
|
||||
vr = new Vector2D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y);
|
||||
}
|
||||
|
||||
// Load sector data
|
||||
SectorData sd = mode.GetSectorData(Sidedef.Sector);
|
||||
SectorData osd = mode.GetSectorData(Sidedef.Other.Sector);
|
||||
if(!osd.Built) osd.BuildLevels(mode);
|
||||
|
||||
// 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)
|
||||
|
@ -99,89 +109,126 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
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
|
||||
}
|
||||
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 plane as they would be in normal circumstances.
|
||||
// We can then use this plane to find any texture coordinate we need.
|
||||
// The logic here is the same as in the original VisualMiddleSingle (except that
|
||||
// the values are stored in a TexturePlane)
|
||||
// NOTE: I use a small bias for the floor height, because if the difference in
|
||||
// height is 0 then the TexturePlane doesn't work!
|
||||
TexturePlane tp = new TexturePlane();
|
||||
float floorbias = (Sidedef.Sector.CeilHeight == Sidedef.Sector.FloorHeight) ? 1.0f : 0.0f;
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
// When lower unpegged is set, the middle texture is bound to the bottom
|
||||
tp.tlt.y = tsz.y - (float)(Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight);
|
||||
}
|
||||
tp.trb.x = tp.tlt.x + Sidedef.Line.Length;
|
||||
tp.trb.y = tp.tlt.y + ((float)Sidedef.Sector.CeilHeight - ((float)Sidedef.Sector.FloorHeight + floorbias));
|
||||
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
tp.tlt += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
tp.trb += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.tlt += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
tp.trb += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
}
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
tp.vlt = new Vector3D(vl.x, vl.y, (float)Sidedef.Sector.CeilHeight);
|
||||
tp.vrb = new Vector3D(vr.x, vr.y, (float)Sidedef.Sector.FloorHeight + floorbias);
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
|
||||
// Keep top and bottom planes for intersection testing
|
||||
top = sd.Ceiling.plane;
|
||||
bottom = sd.Floor.plane;
|
||||
|
||||
// Create initial polygon, which is just a quad between floor and ceiling
|
||||
WallPolygon poly = new WallPolygon();
|
||||
poly.Add(new Vector3D(vl.x, vl.y, sd.Floor.plane.GetZ(vl)));
|
||||
poly.Add(new Vector3D(vl.x, vl.y, sd.Ceiling.plane.GetZ(vl)));
|
||||
poly.Add(new Vector3D(vr.x, vr.y, sd.Ceiling.plane.GetZ(vr)));
|
||||
poly.Add(new Vector3D(vr.x, vr.y, sd.Floor.plane.GetZ(vr)));
|
||||
|
||||
// Determine initial color
|
||||
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(sd.Ceiling.brightnessbelow));
|
||||
PixelColor wallcolor = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness);
|
||||
poly.color = wallcolor.WithAlpha(255).ToInt();
|
||||
|
||||
// Cut off the part below the other floor and above the other ceiling
|
||||
CropPoly(ref poly, osd.Ceiling.plane, true);
|
||||
CropPoly(ref poly, osd.Floor.plane, true);
|
||||
|
||||
// Determine if we should repeat the middle texture
|
||||
repeatmidtex = false;
|
||||
if(Sidedef.Fields.ContainsKey("wrapmidtex"))
|
||||
{
|
||||
if(Sidedef.Fields["wrapmidtex"].Value is bool)
|
||||
repeatmidtex = (bool)Sidedef.Fields["wrapmidtex"].Value;
|
||||
}
|
||||
|
||||
if(!repeatmidtex)
|
||||
{
|
||||
// First determine the visible portion of the texture
|
||||
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 textop, texbottom;
|
||||
|
||||
// Determine top portion height
|
||||
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
|
||||
// Calculate bottom portion height
|
||||
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)
|
||||
// Create crop planes (we also need these for intersection testing)
|
||||
topclipplane = new Plane(new Vector3D(0, 0, -1), textop);
|
||||
bottomclipplane = new Plane(new Vector3D(0, 0, 1), -texbottom);
|
||||
|
||||
// Crop polygon by these heights
|
||||
CropPoly(ref poly, topclipplane, true);
|
||||
CropPoly(ref poly, bottomclipplane, true);
|
||||
}
|
||||
|
||||
if(poly.Count > 2)
|
||||
{
|
||||
// Keep top and bottom planes for intersection testing
|
||||
top = osd.Ceiling.plane;
|
||||
bottom = osd.Floor.plane;
|
||||
|
||||
// Process the polygon and create vertices
|
||||
List<WorldVertex> verts = CreatePolygonVertices(poly, tp);
|
||||
if(verts.Count > 0)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// Apply vertices
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No geometry for invisible wall
|
||||
verts = new WorldVertex[0];
|
||||
base.SetVertices(verts);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -189,6 +236,20 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
|
||||
#region ================== Methods
|
||||
|
||||
// This performs a fast test in object picking
|
||||
public override bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||
{
|
||||
if(!repeatmidtex)
|
||||
{
|
||||
// Whe nthe texture is not repeated, leave when outside crop planes
|
||||
if((pickintersect.z < bottomclipplane.GetZ(pickintersect)) ||
|
||||
(pickintersect.z > topclipplane.GetZ(pickintersect)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.PickFastReject(from, to, dir);
|
||||
}
|
||||
|
||||
// Return texture name
|
||||
public override string GetTextureName()
|
||||
{
|
||||
|
|
|
@ -180,15 +180,9 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -43,16 +43,18 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
public VisualLower lower;
|
||||
public VisualMiddleDouble middledouble;
|
||||
public VisualMiddleSingle middlesingle;
|
||||
|
||||
public Dictionary<Sector3DFloor, VisualMiddle3D> middle3d;
|
||||
|
||||
// Constructor
|
||||
public VisualSidedefParts(VisualUpper u, VisualLower l, VisualMiddleDouble m)
|
||||
public VisualSidedefParts(VisualUpper u, VisualLower l, VisualMiddleDouble m, Dictionary<Sector3DFloor, VisualMiddle3D> e)
|
||||
{
|
||||
this.upper = u;
|
||||
this.lower = l;
|
||||
this.middledouble = m;
|
||||
this.middlesingle = null;
|
||||
this.middle3d = e;
|
||||
}
|
||||
|
||||
|
||||
// Constructor
|
||||
public VisualSidedefParts(VisualMiddleSingle m)
|
||||
{
|
||||
|
@ -60,8 +62,9 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
this.lower = null;
|
||||
this.middledouble = null;
|
||||
this.middlesingle = m;
|
||||
this.middle3d = null;
|
||||
}
|
||||
|
||||
|
||||
// This calls Setup() on all parts
|
||||
public void SetupAllParts()
|
||||
{
|
||||
|
@ -69,6 +72,11 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
if(middledouble != null) middledouble.Setup();
|
||||
if(middlesingle != null) middlesingle.Setup();
|
||||
if(upper != null) upper.Setup();
|
||||
if(middle3d != null)
|
||||
{
|
||||
foreach(VisualMiddle3D m in middle3d.Values)
|
||||
m.Setup();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,15 +179,9 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue