refactor(render): Phase A8.F — Task 4 review follow-up (honest cap comment, cycle guard test, file fixpoint fast-follow)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-29 12:16:11 +02:00
parent 0ed462cb62
commit 270c21f263
3 changed files with 97 additions and 2 deletions

View file

@ -104,6 +104,23 @@ public class PortalVisibilityBuilderTests
for (int i = 0; i < p.Length; i++) { var a = p[i]; var b = p[(i + 1) % p.Length]; area2 += a.X * b.Y - b.X * a.Y; }
Assert.True(area2 > 0f, "clipped OutsideView region should be CCW after winding normalization");
}
[Fact]
public void Builder_CyclicGraph_TerminatesWithBoundedPolys()
{
// A <-> B cycle; B also has an exit window. Must terminate and not blow up.
var a = Cell(0x0001, new CellPortalInfo(0x0002, 0, 0));
a.PortalPolygons.Add(Quad(0f, 0f, 0.5f, 0.5f, -3f));
var b = Cell(0x0002, new CellPortalInfo(0x0001, 0, 0), new CellPortalInfo(0xFFFF, 1, 0));
b.PortalPolygons.Add(Quad(0f, 0f, 0.5f, 0.5f, -2f)); // back to A
b.PortalPolygons.Add(Quad(0f, 0f, 1.0f, 1.0f, -6f)); // exit window
var all = new Dictionary<uint, LoadedCell> { [0x0001] = a, [0x0002] = b };
var frame = Build(a, all); // must return (no infinite loop)
Assert.False(frame.OutsideView.IsEmpty);
Assert.True(frame.OutsideView.Polygons.Count < 256,
$"OutsideView poly count {frame.OutsideView.Polygons.Count} — termination/dedup regression guard");
}
}
internal static class PortalFrameTestHelper