mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2025-03-12 22:01:31 +00:00
Increase performance on drawing/stitching geometry by reducing blockmap operations
This commit is contained in:
parent
444aa706fb
commit
6d97c9d830
2 changed files with 51 additions and 86 deletions
|
@ -967,11 +967,6 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
List<Vertex> nonmergeverts = new List<Vertex>(General.Map.Map.Vertices);
|
||||
MapSet map = General.Map.Map;
|
||||
|
||||
//mxd. Let's use a blockmap...
|
||||
RectangleF area = MapSet.CreateArea(oldlines);
|
||||
BlockMap<BlockEntry> oldlinesmap = new BlockMap<BlockEntry>(area);
|
||||
oldlinesmap.AddLinedefsSet(oldlines);
|
||||
|
||||
General.Map.Map.ClearAllMarks(false);
|
||||
|
||||
// Any points to do?
|
||||
|
@ -1116,7 +1111,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
foreach(Linedef ld in newlines)
|
||||
{
|
||||
Vector2D ldcp = ld.GetCenterPoint();
|
||||
Linedef nld = MapSet.NearestLinedef(oldlinesmap, ldcp); //mxd. Lines collection -> Blockmap
|
||||
Linedef nld = MapSet.NearestLinedef(oldlines, ldcp); //mxd. Lines collection -> Blockmap
|
||||
if(nld != null)
|
||||
{
|
||||
float ldside = nld.SideOfLine(ldcp);
|
||||
|
@ -1153,7 +1148,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
List<LinedefSide> endpoints = new List<LinedefSide>();
|
||||
|
||||
// Find out where the start will stitch and create test points
|
||||
Linedef l1 = MapSet.NearestLinedefRange(oldlinesmap, firstline.Start.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap
|
||||
Linedef l1 = MapSet.NearestLinedefRange(oldlines, firstline.Start.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap
|
||||
Vertex vv1 = null;
|
||||
if(l1 != null)
|
||||
{
|
||||
|
@ -1178,7 +1173,7 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
}
|
||||
|
||||
// Find out where the end will stitch and create test points
|
||||
Linedef l2 = MapSet.NearestLinedefRange(oldlinesmap, lastline.End.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap
|
||||
Linedef l2 = MapSet.NearestLinedefRange(oldlines, lastline.End.Position, MapSet.STITCH_DISTANCE); //mxd. Lines collection -> Blockmap
|
||||
Vertex vv2 = null;
|
||||
if(l2 != null)
|
||||
{
|
||||
|
|
|
@ -2079,18 +2079,18 @@ namespace CodeImp.DoomBuilder.Map
|
|||
// Find vertices
|
||||
HashSet<Vertex> movingverts = new HashSet<Vertex>(General.Map.Map.GetMarkedVertices(true));
|
||||
HashSet<Vertex> fixedverts = new HashSet<Vertex>(General.Map.Map.GetMarkedVertices(false));
|
||||
|
||||
|
||||
// Find lines that moved during the drag
|
||||
HashSet<Linedef> movinglines = new HashSet<Linedef>(LinedefsFromMarkedVertices(false, true, true));
|
||||
|
||||
// Find all non-moving lines
|
||||
HashSet<Linedef> fixedlines = new HashSet<Linedef>(LinedefsFromMarkedVertices(true, false, false));
|
||||
|
||||
|
||||
// Determine area in which we are editing
|
||||
RectangleF editarea = CreateArea(movinglines);
|
||||
editarea = IncreaseArea(editarea, movingverts);
|
||||
editarea.Inflate(1.0f, 1.0f);
|
||||
|
||||
|
||||
// Join nearby vertices
|
||||
BeginAddRemove();
|
||||
JoinVertices(fixedverts, movingverts, true, STITCH_DISTANCE);
|
||||
|
@ -2100,23 +2100,24 @@ namespace CodeImp.DoomBuilder.Map
|
|||
Update(true, false);
|
||||
|
||||
BeginAddRemove();
|
||||
|
||||
|
||||
// Split moving lines with unselected vertices
|
||||
ICollection<Vertex> nearbyfixedverts = FilterByArea(fixedverts, ref editarea);
|
||||
if(!SplitLinesByVertices(movinglines, nearbyfixedverts, STITCH_DISTANCE, movinglines, mergemode))
|
||||
return false;
|
||||
|
||||
// Split non-moving lines with selected vertices
|
||||
fixedlines = new HashSet<Linedef>(fixedlines.Where(fixedline => !fixedline.IsDisposed));
|
||||
// Split non-moving lines with selected vertices
|
||||
fixedlines = FilterByArea(fixedlines, ref editarea);
|
||||
fixedlines = new HashSet<Linedef>(fixedlines.Where(fixedline => !fixedline.IsDisposed));
|
||||
if(!SplitLinesByVertices(fixedlines, movingverts, STITCH_DISTANCE, movinglines, mergemode))
|
||||
return false;
|
||||
|
||||
//mxd. Split moving lines with fixed lines
|
||||
if(!SplitLinesByLines(fixedlines, movinglines, mergemode)) return false;
|
||||
|
||||
|
||||
// Remove looped linedefs
|
||||
RemoveLoopedLinedefs(movinglines);
|
||||
|
||||
|
||||
// Join overlapping lines
|
||||
if(!JoinOverlappingLines(movinglines)) return false;
|
||||
|
||||
|
@ -2186,7 +2187,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
{
|
||||
FlipBackwardLinedefs(changedlines);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2792,87 +2793,55 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
do
|
||||
{
|
||||
//mxd. Create blockmap
|
||||
ICollection<Vertex> biggerset, smallerset;
|
||||
bool keepsmaller;
|
||||
if(set1.Count > set2.Count)
|
||||
{
|
||||
biggerset = set1;
|
||||
smallerset = set2;
|
||||
keepsmaller = !keepsecond;
|
||||
}
|
||||
else
|
||||
{
|
||||
biggerset = set2;
|
||||
smallerset = set1;
|
||||
keepsmaller = keepsecond;
|
||||
}
|
||||
|
||||
RectangleF area = CreateArea(biggerset);
|
||||
BlockMap<BlockEntry> blockmap = new BlockMap<BlockEntry>(area);
|
||||
blockmap.AddVerticesSet(biggerset);
|
||||
|
||||
// No joins yet
|
||||
joined = false;
|
||||
|
||||
// Go for all vertices in the smaller set
|
||||
foreach(Vertex v1 in smallerset)
|
||||
// Go for all vertices in the first set
|
||||
foreach (Vertex v1 in set1)
|
||||
{
|
||||
HashSet<BlockEntry> blocks = new HashSet<BlockEntry>
|
||||
// Go for all vertices in the second set
|
||||
foreach (Vertex v2 in set2)
|
||||
{
|
||||
blockmap.GetBlockAt(v1.Position),
|
||||
blockmap.GetBlockAt(new Vector2D(v1.Position.x + joindist, v1.Position.y + joindist)),
|
||||
blockmap.GetBlockAt(new Vector2D(v1.Position.x + joindist, v1.Position.y - joindist)),
|
||||
blockmap.GetBlockAt(new Vector2D(v1.Position.x - joindist, v1.Position.y + joindist)),
|
||||
blockmap.GetBlockAt(new Vector2D(v1.Position.x - joindist, v1.Position.y - joindist))
|
||||
};
|
||||
|
||||
foreach(BlockEntry be in blocks)
|
||||
{
|
||||
if(be == null) continue;
|
||||
foreach(Vertex v2 in be.Vertices)
|
||||
// Check if vertices are close enough
|
||||
if (v1.DistanceToSq(v2.Position) <= joindist2)
|
||||
{
|
||||
// Check if vertices are close enough
|
||||
if(v1.DistanceToSq(v2.Position) <= joindist2)
|
||||
// Check if not the same vertex
|
||||
if (v1 != v2)
|
||||
{
|
||||
// Check if not the same vertex
|
||||
if(v1 != v2)
|
||||
// Move the second vertex to match the first
|
||||
v2.Move(v1.Position);
|
||||
|
||||
// Check which one to keep
|
||||
if (keepsecond)
|
||||
{
|
||||
// Move the second vertex to match the first
|
||||
v2.Move(v1.Position);
|
||||
|
||||
// Check which one to keep
|
||||
if(keepsmaller)
|
||||
{
|
||||
// Join the first into the second
|
||||
// Second is kept, first is removed
|
||||
v1.Join(v2);
|
||||
biggerset.Remove(v1);
|
||||
smallerset.Remove(v1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Join the second into the first
|
||||
// First is kept, second is removed
|
||||
v2.Join(v1);
|
||||
biggerset.Remove(v2);
|
||||
smallerset.Remove(v2);
|
||||
}
|
||||
|
||||
// Count the join
|
||||
joinsdone++;
|
||||
joined = true;
|
||||
break;
|
||||
// Join the first into the second
|
||||
// Second is kept, first is removed
|
||||
v1.Join(v2);
|
||||
set1.Remove(v1);
|
||||
set2.Remove(v1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Join the second into the first
|
||||
// First is kept, second is removed
|
||||
v2.Join(v1);
|
||||
set1.Remove(v2);
|
||||
set2.Remove(v2);
|
||||
}
|
||||
|
||||
// Count the join
|
||||
joinsdone++;
|
||||
joined = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Will have to restart when joined
|
||||
if(joined) break;
|
||||
if (joined) break;
|
||||
}
|
||||
}
|
||||
while(joined);
|
||||
while (joined);
|
||||
|
||||
// Return result
|
||||
return joinsdone;
|
||||
|
@ -2959,6 +2928,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
//mxd. Create blockmap
|
||||
RectangleF area = CreateArea(lines);
|
||||
IncreaseArea(area, verts);
|
||||
General.WriteLogLine("Area = " + area.Width + ", " + area.Height);
|
||||
BlockMap<BlockEntry> blockmap = new BlockMap<BlockEntry>(area);
|
||||
blockmap.AddVerticesSet(verts);
|
||||
blockmap.AddLinedefsSet(lines);
|
||||
|
@ -3079,10 +3049,10 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
}
|
||||
|
||||
// [ZZ] note: disposing a vertex means also disposing all attached linedefs!
|
||||
// we need to iterate through our lines collection and make sure no disposed linedefs exist there.
|
||||
// also, just in case, do it for vertices as well, because vertices can be chain-disposed.
|
||||
foreach (Linedef line in lines.Where(line => line.IsDisposed).ToList())
|
||||
// [ZZ] note: disposing a vertex means also disposing all attached linedefs!
|
||||
// we need to iterate through our lines collection and make sure no disposed linedefs exist there.
|
||||
// also, just in case, do it for vertices as well, because vertices can be chain-disposed.
|
||||
foreach (Linedef line in lines.Where(line => line.IsDisposed).ToList())
|
||||
while (lines.Remove(line));
|
||||
foreach (Vertex vert in verts.Where(vert => vert.IsDisposed).ToList())
|
||||
while (verts.Remove(vert));
|
||||
|
|
Loading…
Reference in a new issue