3D Floor Mode: fixed an issue where new control sectors could not be created if any sector's bounding box completely encompassed the Control Sector Area

This commit is contained in:
biwa 2023-08-14 23:00:42 +02:00
parent 882744593d
commit 7e29ba3099

View file

@ -320,11 +320,12 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
); );
// The way our blockmap is built and queried we will always get exactly one block // The way our blockmap is built and queried we will always get exactly one block
if (blocks[0].Sectors.Count == 0) // Try the next position of the current one is occupied by another sector
{ if (blocks[0].Sectors.Any(s => SectorInNewControlSectorSpace(x, y, s)))
continue;
positions.Add(new Vector2D(x + margin, y - margin)); positions.Add(new Vector2D(x + margin, y - margin));
numsectors--; numsectors--;
}
if (numsectors == 0) if (numsectors == 0)
return positions; return positions;
@ -357,8 +358,10 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
); );
// The way our blockmap is built and queried we will always get exactly one block // The way our blockmap is built and queried we will always get exactly one block
if (blocks[0].Sectors.Count == 0) // Try the next position of the current one is occupied by another sector
{ if (blocks[0].Sectors.Any(s => SectorInNewControlSectorSpace(x, y, s)))
continue;
Point p = new Point(x + margin, y - margin); Point p = new Point(x + margin, y - margin);
dv.Add(SectorVertex(p.X, p.Y)); dv.Add(SectorVertex(p.X, p.Y));
@ -373,11 +376,63 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
return dv; return dv;
} }
} }
}
throw new NoSpaceInCSAException("No space left for control sectors"); throw new NoSpaceInCSAException("No space left for control sectors");
} }
/// <summary>
/// Checks if the given sector and position for the new control sector intersect in any way.
/// </summary>
/// <param name="x">Leftmost X position of the new control sector space</param>
/// <param name="y">Topmost Y position of the new control sector space</param>
/// <param name="sector">The sector to check against</param>
/// <returns>true if there's an intersection, false if there isn't</returns>
private bool SectorInNewControlSectorSpace(int x, int y, Sector sector)
{
RectangleF rect = new RectangleF(x + 1, y - 1, gridsize - 2, gridsize - 2);
HashSet<Vertex> sectorvertices = new HashSet<Vertex>();
// Any of the sector's sidedef's linedef's vertices inside the new control sector's space?
foreach (Sidedef sd in sector.Sidedefs)
{
sectorvertices.Add(sd.Line.Start);
sectorvertices.Add(sd.Line.End);
}
foreach (Vertex v in sectorvertices)
if (rect.Contains((float)v.Position.x, (float)v.Position.y))
return true;
// Any of the new vertex positions in the sector?
Vector2D[] points = new Vector2D[]
{
new Vector2D(x + 1, y - 1),
new Vector2D(x + gridsize - 1, y - 1),
new Vector2D(x + gridsize - 1, y + gridsize + 1),
new Vector2D(x + 1, y + gridsize + 1)
};
foreach (Vector2D v in points)
if (sector.Intersect(v))
return true;
// Any of the new lines and the sector's lines overlapping?
Line2D[] lines = new Line2D[]
{
new Line2D(points[0], points[1]),
new Line2D(points[1], points[2]),
new Line2D(points[2], points[3]),
new Line2D(points[3], points[0])
};
foreach (Sidedef sd in sector.Sidedefs)
foreach (Line2D line in lines)
if (Line2D.GetIntersection(sd.Line.Line, line))
return true;
return false;
}
public bool Inside(float x, float y) public bool Inside(float x, float y)
{ {
return Inside(new Vector2D(x, y)); return Inside(new Vector2D(x, y));