using System.Collections.Generic; using System.Numerics; using AcDream.App.Rendering; using DatReaderWriter; using DatReaderWriter.DBObjs; using DatReaderWriter.Options; using Xunit; namespace AcDream.App.Tests.Rendering; /// /// Sanctuary cathedral seam captured 2026-08-27. The stationary player is in /// F4180104 while chase-camera zoom crosses the coincident outside portals at /// world Y=48 and the viewer root switches between two separate buildings: /// B3={0103,0104,0105} and B4={0106..0111}. The opposite cathedral half must /// remain available through the interior-root building look-in on both sides. /// [Trait("Lane", "InstalledDat")] public sealed class SanctuaryPortalSeamTests { private const uint Landblock = 0xF4180000u; private const uint Cell0104 = Landblock | 0x0104u; private const uint Cell0106 = Landblock | 0x0106u; private static Matrix4x4 ViewProjection(Vector3 eye) { // Derived from the two exact flap-sweep points. Extending their zoom // ray reaches the stable chase target at the player's head. var target = new Vector3(36.033f, 49.638f, 171.353f); var view = Matrix4x4.CreateLookAt(eye, target, Vector3.UnitZ); var projection = Matrix4x4.CreatePerspectiveFieldOfView( 1.2f, 893f / 522f, 1f, 5000f); return view * projection; } private static IReadOnlyList Cells( Dictionary cells, uint firstLow, uint lastLow) { var result = new List(); for (uint low = firstLow; low <= lastLow; low++) result.Add(cells[Landblock | low]); return result; } [Fact] public void CapturedZoomHandoff_BothRootsBuildTheExactOppositeCathedralSeed() { string? datDir = CornerFloodReplayTests.ResolveDatDir(); if (datDir is null) { Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory; see docs/release-gate.md."); } using var dats = new DatCollection(datDir, DatAccessType.Read); LandBlockInfo info = Assert.IsType(dats.Get(Landblock | 0xfffeu)); Dictionary cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, Landblock); LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out LoadedCell? cell) ? cell : null; IReadOnlyList building3 = Cells(cells, 0x0103u, 0x0105u); IReadOnlyList building4 = Cells(cells, 0x0106u, 0x0111u); Assert.Equal(0x01001FB2u, info.Buildings[3].ModelId); Assert.Equal(0x01001FB3u, info.Buildings[4].ModelId); var captures = new[] { new { Name = "near/root0104", Eye = new Vector3(32.742317f, 48.034306f, 172.447845f), Root = cells[Cell0104], Opposite = building4, ExpectedOppositeCell = Cell0106, ExpectedSeedPortal = 2, OppositeBuildingIndex = 4, }, new { Name = "far/root0106", Eye = new Vector3(32.308865f, 47.823200f, 172.592255f), Root = cells[Cell0106], Opposite = building3, ExpectedOppositeCell = Cell0104, ExpectedSeedPortal = 0, OppositeBuildingIndex = 3, }, }; foreach (var capture in captures) { Matrix4x4 viewProjection = ViewProjection(capture.Eye); PortalVisibilityFrame main = PortalVisibilityBuilder.Build( capture.Root, capture.Eye, Lookup, viewProjection); PortalVisibilityFrame lookIn = PortalVisibilityBuilder.ConstructViewBuilding( capture.Opposite, capture.Eye, Lookup, viewProjection, maxSeedDistance: float.PositiveInfinity, seedRegion: main.OutsideView.Polygons); Assert.Contains(capture.ExpectedOppositeCell, lookIn.OrderedVisibleCells); Assert.True( lookIn.CellViews.TryGetValue(capture.ExpectedOppositeCell, out CellView? view) && view.Polygons.Count > 0, $"{capture.Name} must retain a clipped aperture for the opposite cathedral half"); ExteriorPortalSeed seed = Assert.Single(lookIn.ExteriorSeedPortals); Assert.Equal(capture.ExpectedOppositeCell, seed.CellId); Assert.Equal(capture.ExpectedSeedPortal, seed.PortalIndex); Assert.NotEmpty(seed.View.Polygons); using ClipFrame clipFrame = ClipFrame.NoClip(); ClipFrameAssembly assembly = ClipFrameAssembler.Assemble( clipFrame, main); ClipFrameAssembler.AppendLookInFrames( clipFrame, [lookIn], assembly); ClipViewSlice[] nestedSlices = assembly.LookInCellToViewSlices[ new LookInClipCell(0, capture.ExpectedOppositeCell)]; Assert.Equal(view.Polygons.Count, nestedSlices.Length); Assert.All(nestedSlices, slice => Assert.True(slice.Slot > 0)); Assert.Contains( info.Buildings[capture.OppositeBuildingIndex].Portals, portal => portal.OtherCellId == (capture.ExpectedOppositeCell & 0xffffu) && portal.OtherPortalId == capture.ExpectedSeedPortal); } } [Fact] public void ReportedLateralTransition_BothRootsKeepTheOppositeFacadePortal() { string? datDir = CornerFloodReplayTests.ResolveDatDir(); if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory."); using var dats = new DatCollection(datDir, DatAccessType.Read); Dictionary cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, Landblock); LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out LoadedCell? cell) ? cell : null; static (PortalVisibilityFrame Main, PortalVisibilityFrame LookIn) Build( Vector3 eye, Vector3 target, LoadedCell root, IReadOnlyList opposite, Func lookup) { Matrix4x4 viewProjection = Matrix4x4.CreateLookAt(eye, target, Vector3.UnitZ) * Matrix4x4.CreatePerspectiveFieldOfView(MathF.PI / 3f, 1.6f, 0.1f, 5000f); PortalVisibilityFrame main = PortalVisibilityBuilder.Build( root, eye, lookup, viewProjection); PortalVisibilityFrame lookIn = PortalVisibilityBuilder.ConstructViewBuilding( opposite, eye, lookup, viewProjection, seedRegion: main.OutsideView.Polygons); return (main, lookIn); } (PortalVisibilityFrame Main, PortalVisibilityFrame LookIn) from0106 = Build( new Vector3(31.189594f, 46.280170f, 171.783646f), new Vector3(32.787731f, 46.275948f, 171.354993f), cells[Cell0106], Cells(cells, 0x0103u, 0x0105u), Lookup); (PortalVisibilityFrame Main, PortalVisibilityFrame LookIn) from0104 = Build( new Vector3(31.198704f, 49.733287f, 171.783646f), new Vector3(32.796841f, 49.729065f, 171.354993f), cells[Cell0104], Cells(cells, 0x0106u, 0x0111u), Lookup); Assert.Equal([Cell0106, Landblock | 0x010Fu], from0106.Main.OrderedVisibleCells); Assert.Equal([Cell0104], from0106.LookIn.OrderedVisibleCells); ExteriorPortalSeed seed0104 = Assert.Single(from0106.LookIn.ExteriorSeedPortals); Assert.Equal(Cell0104, seed0104.CellId); Assert.Equal(0, seed0104.PortalIndex); Assert.NotEmpty(seed0104.View.Polygons); Assert.Equal([Cell0104], from0104.Main.OrderedVisibleCells); Assert.Equal([Cell0106, Landblock | 0x010Fu], from0104.LookIn.OrderedVisibleCells); ExteriorPortalSeed seed0106 = Assert.Single(from0104.LookIn.ExteriorSeedPortals); Assert.Equal(Cell0106, seed0106.CellId); Assert.Equal(2, seed0106.PortalIndex); Assert.NotEmpty(seed0106.View.Polygons); } [Fact] public void ReportedExactSteamSeam_Root0104KeepsTheOppositeCathedralPortal() { string? datDir = CornerFloodReplayTests.ResolveDatDir(); if (datDir is null) Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory."); using var dats = new DatCollection(datDir, DatAccessType.Read); Dictionary cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, Landblock); LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out LoadedCell? cell) ? cell : null; // Live ACDREAM_PROBE_CELL capture for the user-reported stationary // frame at player [32.792290, 48.000618, 169.804993]. The chase eye is // only ~4 mm across the coincident 0104/0106 exterior portal plane. var eye = new Vector3(31.189665f, 48.004852f, 171.784988f); var target = new Vector3(32.792290f, 48.000618f, 171.354993f); Matrix4x4 viewProjection = Matrix4x4.CreateLookAt(eye, target, Vector3.UnitZ) * Matrix4x4.CreatePerspectiveFieldOfView(1.2f, 1555f / 1019f, 1f, 5000f); PortalVisibilityFrame main = PortalVisibilityBuilder.Build( cells[Cell0104], eye, Lookup, viewProjection); PortalVisibilityFrame lookIn = PortalVisibilityBuilder.ConstructViewBuilding( Cells(cells, 0x0106u, 0x0111u), eye, Lookup, viewProjection, seedRegion: main.OutsideView.Polygons); Assert.Contains(Cell0106, lookIn.OrderedVisibleCells); ExteriorPortalSeed seed = Assert.Single(lookIn.ExteriorSeedPortals); Assert.Equal(Cell0106, seed.CellId); Assert.Equal(2, seed.PortalIndex); Assert.NotEmpty(seed.View.Polygons); } }