refactor(render): remove the production portal frame carrier

This commit is contained in:
Erik 2026-08-31 05:34:46 +02:00
parent 69e69408e8
commit cb22691beb
10 changed files with 128 additions and 443 deletions

View file

@ -23,6 +23,48 @@ public class ClipFrameAssemblerTests
return view;
}
[Fact]
public void BeginWalkFrame_OutdoorRoot_SeedsOneFullScreenDefaultView()
{
using ClipFrame frame = ClipFrame.NoClip();
ClipFrameAssembly assembly = ClipFrameAssembler.BeginWalkFrame(
frame,
outdoorRoot: true);
ClipViewSlice slice = Assert.Single(assembly.OutsideViewSlices);
Assert.Equal(0, slice.Slot);
Assert.Empty(slice.Planes);
Assert.Equal(new Vector4(-1f, -1f, 1f, 1f), slice.NdcAabb);
Assert.True(assembly.OutdoorVisible);
Assert.True(assembly.HasOutsideView);
Assert.Equal(TerrainClipMode.Scissor, assembly.TerrainMode);
Assert.Equal(1, frame.SlotCount);
}
[Fact]
public void BeginWalkFrame_InteriorRoot_ResetsReusedOutdoorAssemblyToEmpty()
{
using ClipFrame frame = ClipFrame.NoClip();
ClipFrameAssembly reuse = ClipFrameAssembler.BeginWalkFrame(
frame,
outdoorRoot: true);
ClipFrameAssembly assembly = ClipFrameAssembler.BeginWalkFrame(
frame,
outdoorRoot: false,
reuse);
Assert.Same(reuse, assembly);
Assert.Empty(assembly.OutsideViewSlices);
Assert.False(assembly.OutdoorVisible);
Assert.False(assembly.HasOutsideView);
Assert.Equal(TerrainClipMode.Skip, assembly.TerrainMode);
Assert.Equal(Vector4.Zero, assembly.OutsideViewNdcAabb);
Assert.Equal(0, assembly.ScissorFallbacks);
Assert.Equal(1, frame.SlotCount);
}
[Fact]
public void TwoVisibleCells_PlusOutsideView_ProducesCorrectSlotMapAndCounts()
{
@ -128,39 +170,6 @@ public class ClipFrameAssemblerTests
Assert.Equal(TerrainClipMode.Planes, asm.TerrainMode);
}
[Fact]
public void AppendLookInFrames_PacksEveryNestedCellViewWithoutReplacingMainRoutes()
{
const uint mainCell = 0xA9B40100;
const uint lookInCell = 0xA9B40106;
var main = new PortalVisibilityFrame();
main.CellViews[mainCell] = ViewOf(Square(0f, 0f, 0.8f));
main.OrderedVisibleCells.Add(mainCell);
main.OutsideView.Add(Square(0f, 0f, 0.7f));
var nested = new PortalVisibilityFrame();
nested.CellViews[lookInCell] = ViewOf(
Square(-0.35f, 0f, 0.15f),
Square(0.35f, 0f, 0.15f));
nested.OrderedVisibleCells.Add(lookInCell);
using ClipFrame frame = ClipFrame.NoClip();
ClipFrameAssembly assembly = ClipFrameAssembler.Assemble(frame, main);
int mainSlot = assembly.CellIdToSlot[mainCell];
int slotsBeforeLookIn = frame.SlotCount;
ClipFrameAssembler.AppendLookInFrames(frame, [nested], assembly);
var key = new LookInClipCell(0, lookInCell);
ClipViewSlice[] slices = assembly.LookInCellToViewSlices[key];
Assert.Equal(2, slices.Length);
Assert.All(slices, slice => Assert.True(slice.Slot >= slotsBeforeLookIn));
Assert.NotEqual(slices[0].Slot, slices[1].Slot);
Assert.Equal(slices[0].Slot, assembly.LookInCellToSlot[key]);
Assert.Equal(mainSlot, assembly.CellIdToSlot[mainCell]);
Assert.DoesNotContain(lookInCell, assembly.CellIdToSlot.Keys);
}
[Fact]
public void Assemble_OutsideViewWithExitPortal_HasOutsideViewTrue_AabbMatchesBounds()
{

View file

@ -1,226 +0,0 @@
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;
/// <summary>
/// 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.
/// </summary>
[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<LoadedCell> Cells(
Dictionary<uint, LoadedCell> cells,
uint firstLow,
uint lastLow)
{
var result = new List<LoadedCell>();
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<LandBlockInfo>(dats.Get<LandBlockInfo>(Landblock | 0xfffeu));
Dictionary<uint, LoadedCell> cells =
Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, Landblock);
LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out LoadedCell? cell) ? cell : null;
IReadOnlyList<LoadedCell> building3 = Cells(cells, 0x0103u, 0x0105u);
IReadOnlyList<LoadedCell> 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<uint, LoadedCell> 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<LoadedCell> opposite,
Func<uint, LoadedCell?> 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<uint, LoadedCell> 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);
}
}

View file

@ -228,18 +228,12 @@ public sealed class WorldRenderDiagnosticsTests
skyDrawn: false,
depthClear: false,
outdoorSceneryDrawn: false,
outdoorPortalDrawn: false,
outdoorRootObjectCount: 0,
liveDynamicDrawnCount: 0,
sceneParticles: "none",
portalFrame: null,
visibleCells: null,
clipAssembly: null,
drawableCells: null,
partition: null,
exteriorPortalFrame: null,
exteriorClipAssembly: null,
exteriorDrawableCells: null,
exteriorPartition: null,
cameraPosition: Vector3.Zero,
playerPosition: Vector3.Zero);
}

View file

@ -739,24 +739,16 @@ public sealed class WorldSceneRendererTests
// Distinct flood-only vs in-view sets: 0x01010003 is a look-in
// cell that is drawn but never part of the main flood.
_interiorResult = new RetailPViewFrameResult().Reset(
new PortalVisibilityFrame(),
new ClipFrameAssembly(),
ClipFrameAssembler.BeginWalkFrame(
ClipFrame.NoClip(), outdoorRoot: false),
[0x01010001u],
[0x01010001u, 0x01010003u],
default,
default,
diagnosticPartition: null);
var outdoorPortalFrame = new PortalVisibilityFrame();
outdoorPortalFrame.OutsideView.Add(new ViewPolygon(
[
new Vector2(-1f, -1f),
new Vector2(1f, -1f),
new Vector2(1f, 1f),
new Vector2(-1f, 1f),
]));
_outdoorResult = new RetailPViewFrameResult().Reset(
outdoorPortalFrame,
ClipFrameAssembler.Assemble(ClipFrame.NoClip(), outdoorPortalFrame),
ClipFrameAssembler.BeginWalkFrame(
ClipFrame.NoClip(), outdoorRoot: true),
[],
[],
default,
@ -886,7 +878,8 @@ public sealed class WorldSceneRendererTests
public CameraCellResolution CameraCellResolution => CameraCellResolution.None;
public void EmitPViewInput(
PortalVisibilityFrame portalFrame,
IReadOnlySet<uint> visibleCells,
int outsideViewCount,
Matrix4x4 viewProjection,
LoadedCell clipRoot,
Vector3 cameraPosition,