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

@ -317,14 +317,15 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
List<BlockEntry> blocks = blockmap.GetLineBlocks( List<BlockEntry> blocks = blockmap.GetLineBlocks(
new Vector2D(x + 1, y - 1), new Vector2D(x + 1, y - 1),
new Vector2D(x + gridsize - 1, y - gridsize + 1) new Vector2D(x + gridsize - 1, y - gridsize + 1)
); );
// 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)))
positions.Add(new Vector2D(x + margin, y - margin)); continue;
numsectors--;
} positions.Add(new Vector2D(x + margin, y - margin));
numsectors--;
if (numsectors == 0) if (numsectors == 0)
return positions; return positions;
@ -354,30 +355,84 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode
List<BlockEntry> blocks = blockmap.GetLineBlocks( List<BlockEntry> blocks = blockmap.GetLineBlocks(
new Vector2D(x + 1, y - 1), new Vector2D(x + 1, y - 1),
new Vector2D(x + gridsize - 1, y - gridsize + 1) new Vector2D(x + gridsize - 1, y - gridsize + 1)
); );
// 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)))
Point p = new Point(x + margin, y - margin); continue;
dv.Add(SectorVertex(p.X, p.Y)); Point p = new Point(x + margin, y - margin);
dv.Add(SectorVertex(p.X + BuilderPlug.Me.ControlSectorArea.SectorSize, p.Y));
dv.Add(SectorVertex(p.X + BuilderPlug.Me.ControlSectorArea.SectorSize, p.Y - BuilderPlug.Me.ControlSectorArea.SectorSize)); dv.Add(SectorVertex(p.X, p.Y));
dv.Add(SectorVertex(p.X, p.Y - BuilderPlug.Me.ControlSectorArea.SectorSize)); dv.Add(SectorVertex(p.X + BuilderPlug.Me.ControlSectorArea.SectorSize, p.Y));
dv.Add(SectorVertex(p.X, p.Y)); dv.Add(SectorVertex(p.X + BuilderPlug.Me.ControlSectorArea.SectorSize, p.Y - BuilderPlug.Me.ControlSectorArea.SectorSize));
dv.Add(SectorVertex(p.X, p.Y - BuilderPlug.Me.ControlSectorArea.SectorSize));
numsectors--; dv.Add(SectorVertex(p.X, p.Y));
if (numsectors == 0) numsectors--;
return dv;
} if (numsectors == 0)
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));