Use BSP tree instead of blockmap to find the sector a Thing is in (unless explicitly disabled in Preferences)

This commit is contained in:
MascaraSnake 2016-01-10 17:15:27 +01:00
parent c9037f18f3
commit 4f6f748b31
15 changed files with 1007 additions and 580 deletions

View file

@ -750,6 +750,7 @@ plugins
editnewthing = true;
editnewsector = false;
additiveselect = false;
dontusenodes = false;
stitchrange = 20;
highlightrange = 20;
highlightthingsrange = 10;

View file

@ -187,6 +187,10 @@
<DependentUpon>ThingStatisticsForm.cs</DependentUpon>
</Compile>
<Compile Include="IO\SRB2MapSetIO.cs" />
<Compile Include="Map\BSP.cs" />
<Compile Include="Map\Node.cs" />
<Compile Include="Map\Seg.cs" />
<Compile Include="Map\Subsector.cs" />
<Compile Include="VisualModes\VisualBlockMap.cs" />
<Compile Include="VisualModes\VisualMode.cs" />
<Compile Include="General\Clock.cs" />

View file

@ -46,10 +46,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
public Vector3D Position { get { return position; } }
public bool IsCurved;
public PathNode(Thing t, VisualBlockMap blockmap)
public PathNode(Thing t, VisualBlockMap blockmap, BSP bsp, bool useblockmap)
{
thing = t;
position = new Vector3D(t.Position, (blockmap != null ? t.Position.z + GetCorrectHeight(t, blockmap) : t.Position.z));
position = new Vector3D(t.Position, (blockmap != null ? t.Position.z + GetCorrectHeight(t, blockmap, bsp, useblockmap) : t.Position.z));
nextnodes = new Dictionary<int, PathNode>();
prevnodes = new Dictionary<int, PathNode>();
}
@ -72,13 +72,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
}
}
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things) { return GetThingLinks(things, null); }
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things, VisualBlockMap blockmap)
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things) { return GetThingLinks(things, null, null, false); }
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things, VisualBlockMap blockmap, BSP bsp, bool useblockmap)
{
return GetThingLinks(GetSpecialThings(things, blockmap), blockmap);
return GetThingLinks(GetSpecialThings(things, blockmap, bsp, useblockmap), blockmap, bsp, useblockmap);
}
private static SpecialThings GetSpecialThings(IEnumerable<Thing> things, VisualBlockMap blockmap)
private static SpecialThings GetSpecialThings(IEnumerable<Thing> things, VisualBlockMap blockmap, BSP bsp, bool useblockmap)
{
SpecialThings result = new SpecialThings();
@ -130,7 +130,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
{
case "interpolationpoint":
if(!result.InterpolationPoints.ContainsKey(t.Tag)) result.InterpolationPoints.Add(t.Tag, new List<PathNode>());
result.InterpolationPoints[t.Tag].Add(new PathNode(t, blockmap));
result.InterpolationPoints[t.Tag].Add(new PathNode(t, blockmap, bsp, useblockmap));
break;
case "movingcamera":
@ -154,7 +154,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
return result;
}
private static List<Line3D> GetThingLinks(SpecialThings result, VisualBlockMap blockmap)
private static List<Line3D> GetThingLinks(SpecialThings result, VisualBlockMap blockmap, BSP bsp, bool useblockmap)
{
var lines = new List<Line3D>();
var actormovertargets = new Dictionary<int, List<Thing>>();
@ -180,12 +180,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
if(!result.PatrolPoints.ContainsKey(t.Args[0])) continue;
start = t.Position;
start.z += GetCorrectHeight(t, blockmap);
start.z += GetCorrectHeight(t, blockmap, bsp, useblockmap);
foreach(Thing tt in result.PatrolPoints[t.Args[0]])
{
end = tt.Position;
end.z += GetCorrectHeight(tt, blockmap);
end.z += GetCorrectHeight(tt, blockmap, bsp, useblockmap);
lines.Add(new Line3D(start, end));
}
}
@ -197,12 +197,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
if(!result.PatrolPoints.ContainsKey(t.Args[1])) continue;
start = t.Position;
start.z += GetCorrectHeight(t, blockmap);
start.z += GetCorrectHeight(t, blockmap, bsp, useblockmap);
foreach(Thing tt in result.PatrolPoints[t.Args[1]])
{
end = tt.Position;
end.z += GetCorrectHeight(tt, blockmap);
end.z += GetCorrectHeight(tt, blockmap, bsp, useblockmap);
lines.Add(new Line3D(start, end, General.Colors.Selection));
}
@ -216,7 +216,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
bool interpolatepath = ((t.Args[2] & 1) != 1);
start = t.Position;
start.z += GetCorrectHeight(t, blockmap);
start.z += GetCorrectHeight(t, blockmap, bsp, useblockmap);
foreach(PathNode node in result.InterpolationPoints[targettag])
{
@ -237,7 +237,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
{
bool interpolatepath = ((t.Args[2] & 1) != 1);
start = t.Position;
start.z += GetCorrectHeight(t, blockmap);
start.z += GetCorrectHeight(t, blockmap, bsp, useblockmap);
foreach(PathNode node in result.InterpolationPoints[targettag])
{
@ -250,12 +250,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
if(actormovertargets.ContainsKey(t.Args[3]))
{
start = t.Position;
start.z += GetCorrectHeight(t, blockmap);
start.z += GetCorrectHeight(t, blockmap, bsp, useblockmap);
foreach(Thing tt in actormovertargets[t.Args[3]])
{
end = tt.Position;
end.z += GetCorrectHeight(tt, blockmap);
end.z += GetCorrectHeight(tt, blockmap, bsp, useblockmap);
lines.Add(new Line3D(start, end, General.Colors.Selection));
}
}
@ -270,7 +270,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
bool interpolatepath = (t.Args[2] & 1) != 1;
start = t.Position;
start.z += GetCorrectHeight(t, blockmap);
start.z += GetCorrectHeight(t, blockmap, bsp, useblockmap);
foreach(PathNode node in result.InterpolationPoints[targettag])
{
@ -286,12 +286,12 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
foreach(Thing anchor in group.Value)
{
start = anchor.Position;
start.z += GetCorrectHeight(anchor, blockmap);
start.z += GetCorrectHeight(anchor, blockmap, bsp, useblockmap);
foreach(Thing startspot in result.PolyobjectStartSpots[group.Key])
{
end = startspot.Position;
end.z += GetCorrectHeight(startspot, blockmap);
end.z += GetCorrectHeight(startspot, blockmap, bsp, useblockmap);
lines.Add(new Line3D(start, end, General.Colors.Selection));
}
}
@ -385,11 +385,17 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
}
// Required only when called from VisualMode
private static float GetCorrectHeight(Thing thing, VisualBlockMap blockmap)
private static float GetCorrectHeight(Thing thing, VisualBlockMap blockmap, BSP bsp, bool useblockmap)
{
if(blockmap == null) return 0f;
float height = thing.Height / 2f;
if(thing.Sector == null) thing.DetermineSector(blockmap);
if (thing.Sector == null)
{
if (useblockmap)
thing.DetermineSector(blockmap);
else
thing.DetermineSector(bsp);
}
if(thing.Sector != null) height += thing.Sector.FloorHeight;
return height;
}

298
Source/Core/Map/BSP.cs Normal file
View file

@ -0,0 +1,298 @@
#region ================== Namespaces
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.Map;
#endregion
namespace CodeImp.DoomBuilder.Map
{
public class BSP
{
#region ================== Constants
#endregion
#region ================== Variables
private Seg[] segs;
private Node[] nodes;
private Vector2D[] verts;
private Subsector[] ssectors;
private bool deactivate;
private bool isdisposed;
#endregion
#region ================== Properties
public Seg[] Segs { get { return segs; } }
public Node[] Nodes { get { return nodes; } }
public Vector2D[] Vertices { get { return verts; } }
public Subsector[] Subsectors { get { return ssectors; } }
#endregion
#region ================== Constructor / Destructor
// Constructor
public BSP(bool deactivate)
{
this.deactivate = deactivate;
if (!deactivate)
{
if (General.Map.IsChanged) BuildNodes();
LoadStructures();
}
}
// Disposer
public void Dispose()
{
// Not already disposed?
if (!isdisposed)
{
// Clean up
segs = null;
nodes = null;
verts = null;
ssectors = null;
// Done
isdisposed = true;
}
}
#endregion
#region ================== Methods
public void Update()
{
if (!deactivate && General.Map.IsChanged)
{
BuildNodes();
LoadStructures();
}
}
/// <summary>
/// This (re)builds the nodes for the whole map.
/// </summary>
private void BuildNodes()
{
// There is no API available to do this directly, but we export the map which will
// cause the DB core to build the nodes (with testing parameters)
General.Interface.DisplayStatus(StatusType.Busy, "Building map nodes...");
string tempfile = General.MakeTempFilename(General.Map.TempPath, "wad");
General.Map.IsChanged = true;
General.Map.ExportToFile(tempfile);
File.Delete(tempfile);
}
/// <summary>
/// This loads all nodes structures data from the lumps
/// </summary>
private bool LoadStructures()
{
// Load the nodes structure
MemoryStream nodesstream = General.Map.GetLumpData("NODES");
int numnodes = (int)nodesstream.Length / 28;
//mxd. Boilerplate!
if(numnodes < 1)
{
// Cancel mode
MessageBox.Show("The map has only one subsector. Please add more sectors, then try running this mode again.", "THY NODETH ARETH BROKH!", MessageBoxButtons.OK, MessageBoxIcon.Error);
General.Editing.CancelMode();
return false;
}
BinaryReader nodesreader = new BinaryReader(nodesstream);
nodes = new Node[numnodes];
for(int i = 0; i < nodes.Length; i++)
{
nodes[i].linestart.x = nodesreader.ReadInt16();
nodes[i].linestart.y = nodesreader.ReadInt16();
nodes[i].linedelta.x = nodesreader.ReadInt16();
nodes[i].linedelta.y = nodesreader.ReadInt16();
float top = nodesreader.ReadInt16();
float bot = nodesreader.ReadInt16();
float left = nodesreader.ReadInt16();
float right = nodesreader.ReadInt16();
nodes[i].rightbox = new RectangleF(left, top, (right - left), (bot - top));
top = nodesreader.ReadInt16();
bot = nodesreader.ReadInt16();
left = nodesreader.ReadInt16();
right = nodesreader.ReadInt16();
nodes[i].leftbox = new RectangleF(left, top, (right - left), (bot - top));
int rightindex = nodesreader.ReadInt16();
int leftindex = nodesreader.ReadInt16();
nodes[i].rightchild = rightindex & 0x7FFF;
nodes[i].leftchild = leftindex & 0x7FFF;
nodes[i].rightsubsector = (rightindex & 0x8000) != 0;
nodes[i].leftsubsector = (leftindex & 0x8000) != 0;
}
nodesreader.Close();
nodesstream.Close();
nodesstream.Dispose();
// Add additional properties to nodes
nodes[nodes.Length - 1].parent = -1;
RecursiveSetupNodes(nodes.Length - 1);
// Load the segs structure
MemoryStream segsstream = General.Map.GetLumpData("SEGS");
BinaryReader segsreader = new BinaryReader(segsstream);
int numsegs = (int)segsstream.Length / 12;
//mxd. Boilerplate!
if(numsegs < 1)
{
// Cancel mode
MessageBox.Show("The map has empty SEGS lump. Please rebuild the nodes, then try running this mode again.", "THY SEGS HATH SINNETH!", MessageBoxButtons.OK, MessageBoxIcon.Error);
General.Editing.CancelMode();
return false;
}
segs = new Seg[numsegs];
for(int i = 0; i < segs.Length; i++)
{
segs[i].startvertex = segsreader.ReadInt16();
segs[i].endvertex = segsreader.ReadInt16();
segs[i].angle = Angle2D.DoomToReal(segsreader.ReadInt16());
segs[i].lineindex = segsreader.ReadInt16();
segs[i].leftside = segsreader.ReadInt16() != 0;
segs[i].offset = segsreader.ReadInt16();
}
segsreader.Close();
segsstream.Close();
segsstream.Dispose();
// Load the vertexes structure
MemoryStream vertsstream = General.Map.GetLumpData("VERTEXES");
BinaryReader vertsreader = new BinaryReader(vertsstream);
int numverts = (int)vertsstream.Length / 4;
//mxd. Boilerplate!
if(numverts < 1)
{
// Cancel mode
MessageBox.Show("The map has empty VERTEXES lump. Please rebuild the nodes, then try running this mode again.", "THY VERTEXES ARETH FOUL!", MessageBoxButtons.OK, MessageBoxIcon.Error);
General.Editing.CancelMode();
return false;
}
verts = new Vector2D[numverts];
for(int i = 0; i < verts.Length; i++)
{
verts[i].x = vertsreader.ReadInt16();
verts[i].y = vertsreader.ReadInt16();
}
vertsreader.Close();
vertsstream.Close();
vertsstream.Dispose();
// Load the subsectors structure
MemoryStream ssecstream = General.Map.GetLumpData("SSECTORS");
BinaryReader ssecreader = new BinaryReader(ssecstream);
int numssec = (int)ssecstream.Length / 4;
//mxd. Boilerplate!
if(numssec < 1)
{
// Cancel mode
MessageBox.Show("The map has empty SSECTORS lump. Please rebuild the nodes, then try running this mode again.", "THY SSECTORS ARETH HERETYSH!", MessageBoxButtons.OK, MessageBoxIcon.Error);
General.Editing.CancelMode();
return false;
}
ssectors = new Subsector[numssec];
for(int i = 0; i < ssectors.Length; i++)
{
ssectors[i].numsegs = ssecreader.ReadInt16();
ssectors[i].firstseg = ssecreader.ReadInt16();
}
ssecreader.Close();
ssecstream.Close();
ssecstream.Dispose();
// Link all segs to their subsectors
for(int i = 0; i < ssectors.Length; i++)
{
int lastseg = ssectors[i].firstseg + ssectors[i].numsegs - 1;
for(int sg = ssectors[i].firstseg; sg <= lastseg; sg++)
{
segs[sg].ssector = i;
}
}
return true;
}
/// <summary>
/// This recursively sets up the nodes structure with additional properties
/// </summary>
private void RecursiveSetupNodes(int nodeindex)
{
Node n = nodes[nodeindex];
if(!n.leftsubsector)
{
nodes[n.leftchild].parent = nodeindex;
RecursiveSetupNodes(n.leftchild);
}
if(!n.rightsubsector)
{
nodes[n.rightchild].parent = nodeindex;
RecursiveSetupNodes(n.rightchild);
}
}
private bool PointOnSide(Vector2D p, Node node)
{
if (node.linedelta.x == 0)
return p.x <= node.linestart.x ? node.linedelta.y > 0 : node.linedelta.y < 0;
if (node.linedelta.y == 0)
return p.y <= node.linestart.y ? node.linedelta.x < 0 : node.linedelta.x > 0;
float dx = p.x - node.linestart.x;
float dy = p.y - node.linestart.y;
// Try to quickly decide by looking at sign bits.
if (((node.linedelta.y < 0) ^ (node.linedelta.x < 0) ^ (dx < 0) ^ (dy < 0)))
return (node.linedelta.y < 0) ^ (dx < 0); // (left is negative)
return dy*node.linedelta.x/65536 >= dx*node.linedelta.y/65536;
}
private Subsector PointInSubsector(Vector2D p)
{
int nodenum = nodes.Length - 1;
bool reachedsubsector = false;
while (!reachedsubsector)
{
bool side = !PointOnSide(p, nodes[nodenum]);
reachedsubsector = side ? nodes[nodenum].rightsubsector : nodes[nodenum].leftsubsector;
nodenum = side ? nodes[nodenum].rightchild : nodes[nodenum].leftchild;
}
return ssectors[nodenum];
}
public Sector GetSector(Vector2D p)
{
Subsector ss = PointInSubsector(p);
Seg seg = segs[ss.firstseg];
Linedef line = General.Map.Map.GetLinedefByIndex(seg.lineindex);
Sidedef sidedef = seg.leftside ? line.Back : line.Front;
return sidedef.Sector;
}
#endregion
}
}

22
Source/Core/Map/Node.cs Normal file
View file

@ -0,0 +1,22 @@
#region === Copyright (c) 2010 Pascal van der Heiden ===
using System.Drawing;
using CodeImp.DoomBuilder.Geometry;
#endregion
namespace CodeImp.DoomBuilder.Map
{
public struct Node
{
public Vector2D linestart;
public Vector2D linedelta;
public RectangleF rightbox;
public RectangleF leftbox;
public int rightchild;
public int leftchild;
public bool rightsubsector;
public bool leftsubsector;
public int parent;
}
}

17
Source/Core/Map/Seg.cs Normal file
View file

@ -0,0 +1,17 @@
#region === Copyright (c) 2010 Pascal van der Heiden ===
#endregion
namespace CodeImp.DoomBuilder.Map
{
public struct Seg
{
public int startvertex;
public int endvertex;
public float angle;
public int lineindex;
public bool leftside;
public float offset;
public int ssector;
}
}

View file

@ -0,0 +1,18 @@
#region === Copyright (c) 2010 Pascal van der Heiden ===
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Rendering;
#endregion
namespace CodeImp.DoomBuilder.Map
{
public struct Subsector
{
public int numsegs;
public int firstseg;
public Vector2D[] points;
public FlatVertex[] vertices;
}
}

View file

@ -274,7 +274,7 @@ namespace CodeImp.DoomBuilder.Map
sector = map.GetSectorByCoordinates(pos);
}
// This determines which sector the thing is in and links it
// This determines which sector the thing is in by looking at the blockmap and links it
public void DetermineSector(VisualBlockMap blockmap)
{
// Find nearest sectors using the blockmap
@ -292,8 +292,14 @@ namespace CodeImp.DoomBuilder.Map
}
}
// This translates the flags into UDMF fields
internal void TranslateToUDMF()
// This determines which sector the thing is in by looking at the BSP tree and links it
public void DetermineSector(BSP bsp)
{
sector = bsp.GetSector((Vector2D)pos);
}
// This translates the flags into UDMF fields
internal void TranslateToUDMF()
{
// First make a single integer with all flags
int bits = 0;

View file

@ -104,7 +104,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
private bool editnewthing;
private bool editnewsector;
private bool additiveselect;
private bool autoclearselection;
private bool dontusenodes;
private bool autoclearselection;
private bool visualmodeclearselection;
private string copiedtexture;
private string copiedflat;
@ -155,7 +156,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
public bool EditNewThing { get { return editnewthing; } }
public bool EditNewSector { get { return editnewsector; } }
public bool AdditiveSelect { get { return additiveselect; } }
public bool AutoClearSelection { get { return autoclearselection; } }
public bool DontUseNodes { get { return dontusenodes; } }
public bool AutoClearSelection { get { return autoclearselection; } }
public bool VisualModeClearSelection { get { return visualmodeclearselection; } }
public string CopiedTexture { get { return copiedtexture; } set { copiedtexture = value; } }
public string CopiedFlat { get { return copiedflat; } set { copiedflat = value; } }
@ -280,7 +282,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
editnewthing = General.Settings.ReadPluginSetting("editnewthing", true);
editnewsector = General.Settings.ReadPluginSetting("editnewsector", false);
additiveselect = General.Settings.ReadPluginSetting("additiveselect", false);
autoclearselection = General.Settings.ReadPluginSetting("autoclearselection", false);
dontusenodes = General.Settings.ReadPluginSetting("dontusenodes", false);
autoclearselection = General.Settings.ReadPluginSetting("autoclearselection", false);
visualmodeclearselection = General.Settings.ReadPluginSetting("visualmodeclearselection", false);
stitchrange = General.Settings.ReadPluginSetting("stitchrange", 20);
highlightrange = General.Settings.ReadPluginSetting("highlightrange", 20);

File diff suppressed because it is too large Load diff

View file

@ -46,7 +46,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
editnewthing.Checked = General.Settings.ReadPluginSetting("editnewthing", true);
editnewsector.Checked = General.Settings.ReadPluginSetting("editnewsector", false);
additiveselect.Checked = General.Settings.ReadPluginSetting("additiveselect", false);
stitchrange.Text = General.Settings.ReadPluginSetting("stitchrange", 20).ToString();
dontusenodes.Checked = General.Settings.ReadPluginSetting("dontusenodes", false);
stitchrange.Text = General.Settings.ReadPluginSetting("stitchrange", 20).ToString();
highlightrange.Text = General.Settings.ReadPluginSetting("highlightrange", 20).ToString();
highlightthingsrange.Text = General.Settings.ReadPluginSetting("highlightthingsrange", 10).ToString();
splitlinedefsrange.Text = General.Settings.ReadPluginSetting("splitlinedefsrange", 10).ToString();
@ -75,7 +76,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Settings.WritePluginSetting("editnewthing", editnewthing.Checked);
General.Settings.WritePluginSetting("editnewsector", editnewsector.Checked);
General.Settings.WritePluginSetting("additiveselect", additiveselect.Checked);
General.Settings.WritePluginSetting("stitchrange", stitchrange.GetResult(0));
General.Settings.WritePluginSetting("dontusenodes", dontusenodes.Checked);
General.Settings.WritePluginSetting("stitchrange", stitchrange.GetResult(0));
General.Settings.WritePluginSetting("highlightrange", highlightrange.GetResult(0));
General.Settings.WritePluginSetting("highlightthingsrange", highlightthingsrange.GetResult(0));
General.Settings.WritePluginSetting("splitlinedefsrange", splitlinedefsrange.GetResult(0));

View file

@ -97,8 +97,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
private static bool gzdoomRenderingEffects = true; //mxd
//mxd. Moved here from Tools
private struct SidedefAlignJob
private BSP bsp;
//mxd. Moved here from Tools
private struct SidedefAlignJob
{
public Sidedef sidedef;
@ -166,13 +168,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
public bool IsSingleSelection { get { return singleselection; } }
public bool SelectionChanged { get { return selectionchanged; } set { selectionchanged |= value; } }
public BSP BSP { get { return bsp; } }
#endregion
#region ================== Constructor / Disposer
#endregion
// Constructor
public BaseVisualMode()
#region ================== Constructor / Disposer
// Constructor
public BaseVisualMode()
{
// Initialize
this.gravity = new Vector3D(0.0f, 0.0f, 0.0f);
@ -183,6 +186,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.selectioninfoupdatetimer = new Timer();
selectioninfoupdatetimer.Interval = 100;
selectioninfoupdatetimer.Tick += SelectioninfoupdatetimerOnTick;
bsp = new BSP(BuilderPlug.Me.DontUseNodes);
// We have no destructor
GC.SuppressFinalize(this);
@ -194,10 +199,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Not already disposed?
if(!isdisposed)
{
// Clean up
// Done
base.Dispose();
// Clean up
bsp.Dispose();
bsp = null;
// Done
base.Dispose();
}
}
@ -523,7 +530,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
//mxd. Update event lines (still better than updating them on every frame redraw)
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap, bsp, BuilderPlug.Me.DontUseNodes));
}
//mxd
@ -776,6 +783,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
//mxd
Sector[] sectorsWithEffects = null;
bsp.Update();
if(!gzdoomRenderingEffects)
{
@ -1077,7 +1085,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if (slopevertices.Count >= 3)
{
SectorData sd = GetSectorData(s);
sd.AddEffectSRB2ThingVertexSlope(slopevertices, slopefloor, blockmap);
sd.AddEffectSRB2ThingVertexSlope(slopevertices, slopefloor, blockmap, bsp);
}
}
}
@ -1223,7 +1231,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
RebuildElementData();
//mxd. Update event lines
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap, bsp, BuilderPlug.Me.DontUseNodes));
}
// When returning to another mode
@ -3355,7 +3363,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.ThingsFilter.Update();
// Update event lines
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap, bsp, BuilderPlug.Me.DontUseNodes));
}
//mxd. We'll just use currently selected objects

View file

@ -101,8 +101,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This builds the thing geometry. Returns false when nothing was created.
public bool Setup()
{
// Find the sector in which the thing resides
Thing.DetermineSector(mode.BlockMap);
// Find the sector in which the thing resides
if (BuilderPlug.Me.DontUseNodes)
Thing.DetermineSector(mode.BlockMap);
else
Thing.DetermineSector(mode.BSP);
//mxd. If the thing is inside a sector, apply DECORATE/UDMF alpha/renderstyle overrides
byte alpha = 255;

View file

@ -21,13 +21,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
private bool slopefloor;
private VisualBlockMap blockmap;
private BSP bsp;
// Constructor
public EffectSRB2ThingVertexSlope(SectorData data, List<Thing> sourcethings, bool floor, VisualBlockMap bmap) : base(data)
public EffectSRB2ThingVertexSlope(SectorData data, List<Thing> sourcethings, bool floor, VisualBlockMap bmap, BSP bsptree) : base(data)
{
things = sourcethings;
slopefloor = floor;
blockmap = bmap;
bsp = bsptree;
// New effect added: This sector needs an update!
if(data.Mode.VisualSectorExists(data.Sector))
@ -48,7 +50,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
ThingData td = data.Mode.GetThingData(t);
td.AddUpdateSector(data.Sector, true);
Vector3D position = t.Position;
t.DetermineSector(blockmap);
if (BuilderPlug.Me.DontUseNodes)
t.DetermineSector(blockmap);
else
t.DetermineSector(bsp);
position.z += t.Sector.FloorHeight;
verts[index] = position;
index++;

View file

@ -179,9 +179,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// SRB2-style Thing vertex slope effect
public void AddEffectSRB2ThingVertexSlope(List<Thing> sourcethings, bool slopefloor, VisualBlockMap blockmap)
public void AddEffectSRB2ThingVertexSlope(List<Thing> sourcethings, bool slopefloor, VisualBlockMap blockmap, BSP bsp)
{
EffectSRB2ThingVertexSlope e = new EffectSRB2ThingVertexSlope(this, sourcethings, slopefloor, blockmap);
EffectSRB2ThingVertexSlope e = new EffectSRB2ThingVertexSlope(this, sourcethings, slopefloor, blockmap, bsp);
alleffects.Add(e);
}