Code review caught a CRITICAL under-inclusion: ApplyReciprocalClip scanned for the first OtherCellId match, so a cell with two portals to the same neighbour clipped both near-side openings against the FIRST reciprocal polygon — hiding geometry through the second opening (real on Holtburg cellar cells 0x148<->0x149). Plumb the dat's OtherPortalId back-link through CellPortalInfo + BuildLoadedCell and index the reciprocal directly (retail arg2->other_portal_id, 433557). Skip (degrade to over-include) when the index is unresolvable — never clip against a guessed polygon. Adds a disjoint two-back- portal regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
55 lines
1.8 KiB
C#
55 lines
1.8 KiB
C#
// CellVisibilityPortalPolygonsTests.cs — verifies BuildLoadedCell preserves
|
|
// portal polygon vertices in LoadedCell.PortalPolygons.
|
|
//
|
|
// Phase A8 — Indoor-cell visibility culling. Issue #78.
|
|
|
|
using System.Numerics;
|
|
using AcDream.App.Rendering;
|
|
using Xunit;
|
|
|
|
namespace AcDream.App.Tests.Rendering;
|
|
|
|
public class CellVisibilityPortalPolygonsTests
|
|
{
|
|
[Fact]
|
|
public void LoadedCell_DefaultPortalPolygons_IsEmpty()
|
|
{
|
|
var cell = new LoadedCell();
|
|
Assert.NotNull(cell.PortalPolygons);
|
|
Assert.Empty(cell.PortalPolygons);
|
|
}
|
|
|
|
[Fact]
|
|
public void LoadedCell_PortalPolygons_ParallelIndexedToPortals()
|
|
{
|
|
// Hand-construct: two portals, one with a 4-vertex polygon, one with
|
|
// an empty polygon (resolution failure simulated by an empty array).
|
|
// The data-class semantics: PortalPolygons[i] corresponds to
|
|
// Portals[i] and ClipPlanes[i].
|
|
var cell = new LoadedCell
|
|
{
|
|
Portals = new()
|
|
{
|
|
new CellPortalInfo(0xFFFF, 100, 0, 0), // exit portal, has geometry
|
|
new CellPortalInfo(0x0102, 101, 0, 0), // inner portal, no geometry resolved
|
|
},
|
|
ClipPlanes = new() { default, default },
|
|
PortalPolygons = new()
|
|
{
|
|
new[]
|
|
{
|
|
new Vector3(0, 0, 0),
|
|
new Vector3(1, 0, 0),
|
|
new Vector3(1, 1, 0),
|
|
new Vector3(0, 1, 0),
|
|
},
|
|
System.Array.Empty<Vector3>(),
|
|
},
|
|
};
|
|
|
|
Assert.Equal(2, cell.Portals.Count);
|
|
Assert.Equal(2, cell.PortalPolygons.Count);
|
|
Assert.Equal(4, cell.PortalPolygons[0].Length);
|
|
Assert.Empty(cell.PortalPolygons[1]);
|
|
}
|
|
}
|