@ work on (G)ZDoom Editing plugin

This commit is contained in:
codeimp 2010-09-03 15:12:07 +00:00
parent 6e26ced98e
commit 5317ef1dc9
5 changed files with 194 additions and 56 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -419,7 +419,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
{
// Make fresh sector data when it doesn't exist yet
if(!sectordata.ContainsKey(s))
sectordata[s] = new SectorData(s);
sectordata[s] = new SectorData(this, s);
return sectordata[s];
}

View file

@ -45,7 +45,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
#region ================== Variables
protected BaseVisualMode mode;
protected SectorData data;
protected VisualFloor floor;
protected VisualCeiling ceiling;
protected Dictionary<Sidedef, VisualSidedefParts> sides;
@ -56,7 +57,8 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
#endregion
#region ================== Properties
public SectorData Data { get { return data; } }
public VisualFloor Floor { get { return floor; } }
public VisualCeiling Ceiling { get { return ceiling; } }
public bool Changed { get { return changed; } set { changed |= value; } }
@ -140,16 +142,20 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
// Forget old geometry
base.ClearGeometry();
// Get sector data
data = mode.GetSectorData(this.Sector);
if(!data.Built) data.BuildLevels();
// 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);

View file

@ -16,91 +16,194 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
internal class SectorData
{
#region ================== Variables
// Sector for which this data is
private Sector sector;
// Levels have been built?
private bool built;
// First level is the sector's absolute ceiling
// Last level is the sector's absolute floor
// This is to prevent recursion when sectors need each other to build
private bool isbuilding;
// Levels sorted by height
private List<SectorLevel> levels;
// Original floor and ceiling levels
private SectorLevel floor;
private SectorLevel ceiling;
// Linedefs and Things of interest when building the levels
// See RebuildSectorData() in BaseVisualMode.cs for the logic which selects interesting elements
private List<Linedef> linedefs;
private List<Thing> things;
#endregion
#region ================== Properties
public Sector Sector { get { return sector; } }
public bool Built { get { return built; } }
public List<SectorLevel> Levels { get { return levels; } }
public SectorLevel Floor { get { return floor; } }
public SectorLevel Ceiling { get { return ceiling; } }
#endregion
#region ================== Constructor / Destructor
// Constructor
public SectorData(Sector s)
public SectorData(BaseVisualMode mode, Sector s)
{
int color = -1, flight = s.Brightness, clight = s.Brightness;
bool fabs = true, cabs = true;
// Initialize
this.sector = s;
this.built = false;
this.levels = new List<SectorLevel>(2);
this.linedefs = new List<Linedef>(1);
this.things = new List<Thing>(1);
}
#endregion
#region ================== Public Methods
// This adds a linedef that of interest to this sector, because it modifies the sector
public void AddLinedef(Linedef l) { linedefs.Add(l); }
// This adds a thing that of interest to this sector, because it modifies the sector
public void AddThing(Thing t) { things.Add(t); }
// This creates the levels with the things and linedefs of interest
public void BuildLevels(BaseVisualMode mode)
{
int color = -1, light = sector.Brightness;
bool absolute = true;
// Create floor
SectorLevel fl = new SectorLevel();
fl.type = SectorLevelType.Floor;
fl.plane = new Plane(new Vector3D(0, 0, 1), sector.FloorHeight);
fl.color = -1;
levels.Add(fl);
// Create floor and ceiling planes
floor = new SectorLevel(s, SectorLevelType.Floor);
ceiling = new SectorLevel(s, SectorLevelType.Ceiling);
floor.plane = new Plane(new Vector3D(0, 0, 1), sector.FloorHeight);
ceiling.plane = new Plane(new Vector3D(0, 0, -1), sector.CeilHeight);
// Create ceiling
SectorLevel cl = new SectorLevel();
cl.type = SectorLevelType.Ceiling;
cl.plane = new Plane(new Vector3D(0, 0, -1), sector.CeilHeight);
// Determine colors
try
{
// Fetch ZDoom fields
color = sector.Fields.ContainsKey("lightcolor") ? (int)sector.Fields["lightcolor"].Value : -1;
light = sector.Fields.ContainsKey("lightfloor") ? (int)sector.Fields["lightfloor"].Value : 0;
absolute = sector.Fields.ContainsKey("lightfloorabsolute") ? (bool)sector.Fields["lightfloorabsolute"].Value : false;
flight = sector.Fields.ContainsKey("lightfloor") ? (int)sector.Fields["lightfloor"].Value : 0;
fabs = sector.Fields.ContainsKey("lightfloorabsolute") ? (bool)sector.Fields["lightfloorabsolute"].Value : false;
clight = sector.Fields.ContainsKey("lightceiling") ? (int)sector.Fields["lightceiling"].Value : 0;
cabs = sector.Fields.ContainsKey("lightceilingabsolute") ? (bool)sector.Fields["lightceilingabsolute"].Value : false;
}
catch(Exception) { }
if(!absolute) light = sector.Brightness + light;
PixelColor lightcolor = PixelColor.FromInt(color);
PixelColor brightness = PixelColor.FromInt(mode.CalculateBrightness(light));
PixelColor finalcolor = PixelColor.Modulate(lightcolor, brightness);
cl.color = finalcolor.WithAlpha(255).ToInt();
levels.Add(cl);
if(!fabs) flight = sector.Brightness + flight;
if(!cabs) clight = sector.Brightness + clight;
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(flight));
PixelColor ceilingbrightness = PixelColor.FromInt(mode.CalculateBrightness(clight));
PixelColor floorcolor = PixelColor.Modulate(lightcolor, floorbrightness);
PixelColor ceilingcolor = PixelColor.Modulate(lightcolor, ceilingbrightness);
floor.color = floorcolor.WithAlpha(255).ToInt();
ceiling.color = ceilingcolor.WithAlpha(255).ToInt();
ceiling.brightnessbelow = sector.Brightness;
ceiling.colorbelow = lightcolor;
// Add ceiling and floor
levels.Add(floor);
levels.Add(ceiling);
}
#endregion
#region ================== Public Methods
// This adds a linedef that of interest to this sector, because it modifies the sector
public void AddLinedef(Linedef l) { linedefs.Add(l); }
// This adds a thing that of interest to this sector, because it modifies the sector
public void AddThing(Thing t) { things.Add(t); }
// This creates additional levels from things and linedefs
public void BuildLevels(BaseVisualMode mode)
{
// Begin
if(isbuilding) return;
isbuilding = true;
foreach(Linedef l in linedefs)
{
// Plane Align (see http://zdoom.org/wiki/Plane_Align)
if(l.Action == 181)
{
// Find the vertex furthest from the line
Vertex foundv = null;
float founddist = -1.0f;
foreach(Sidedef sd in sector.Sidedefs)
{
Vertex v = sd.IsFront ? sd.Line.Start : sd.Line.End;
float d = l.DistanceToSq(v.Position, false);
if(d > founddist)
{
foundv = v;
founddist = d;
}
}
// Align floor with back of line
if((l.Args[0] == 1) && (l.Front.Sector == sector) && (l.Back != null))
{
Vector3D v1 = new Vector3D(foundv.Position.x, foundv.Position.y, sector.FloorHeight);
Vector3D v2 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.FloorHeight);
Vector3D v3 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.FloorHeight);
floor.plane = new Plane(v1, v2, v3);
}
// Align floor with front of line
else if((l.Args[0] == 2) && (l.Back.Sector == sector) && (l.Front != null))
{
Vector3D v1 = new Vector3D(foundv.Position.x, foundv.Position.y, sector.FloorHeight);
Vector3D v2 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.FloorHeight);
Vector3D v3 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.FloorHeight);
floor.plane = new Plane(v1, v2, v3);
}
// Align ceiling with back of line
if((l.Args[1] == 1) && (l.Front.Sector == sector) && (l.Back != null))
{
Vector3D v1 = new Vector3D(foundv.Position.x, foundv.Position.y, sector.CeilHeight);
Vector3D v2 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Back.Sector.CeilHeight);
Vector3D v3 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Back.Sector.CeilHeight);
ceiling.plane = new Plane(v1, v2, v3);
}
// Align ceiling with front of line
else if((l.Args[1] == 2) && (l.Back.Sector == sector) && (l.Front != null))
{
Vector3D v1 = new Vector3D(foundv.Position.x, foundv.Position.y, sector.CeilHeight);
Vector3D v2 = new Vector3D(l.Start.Position.x, l.Start.Position.y, l.Front.Sector.CeilHeight);
Vector3D v3 = new Vector3D(l.End.Position.x, l.End.Position.y, l.Front.Sector.CeilHeight);
ceiling.plane = new Plane(v1, v2, v3);
}
}
}
foreach(Thing t in things)
{
// Copy floor slope
if(t.Type == 9510)
{
// Find tagged sector
Sector ts = null;
foreach(Sector s in General.Map.Map.Sectors)
{
if(s.Tag == t.Args[0])
{
ts = s;
break;
}
}
if(ts != null)
{
SectorData tsd = mode.GetSectorData(ts);
if(!tsd.Built) tsd.BuildLevels(mode);
floor.plane = tsd.floor.plane;
}
}
}
// Sort the levels
levels.Sort();
// Done
built = true;
isbuilding = false;
}
#endregion
}
}

View file

@ -6,20 +6,49 @@ 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 struct SectorLevel
internal class SectorLevel : IComparable<SectorLevel>
{
// Center of sector to use for plane comparison
public Vector3D center;
// Type of level
public SectorLevelType type;
// Plane in the sector
public Plane plane;
// Color below the plane (includes brightness)
// Color of the plane (includes brightness)
public int color;
// Color and brightness below the plane
public int brightnessbelow;
public PixelColor colorbelow;
// Constructor
public SectorLevel(Sector s, SectorLevelType type)
{
this.type = type;
this.center = new Vector3D(s.BBox.Left + s.BBox.Width / 2, s.BBox.Top + s.BBox.Height / 2, (s.FloorHeight + s.CeilHeight) / 2);
}
// Comparer
public int CompareTo(SectorLevel other)
{
float delta = this.plane.ClosestOnPlane(center).z - other.plane.ClosestOnPlane(center).z;
if(delta > 0.0f)
return 1;
else if(delta < 0.0f)
return -1;
else
return 0;
}
}
}