acdream/tests/AcDream.App.Tests/Rendering/Walk/WalkPortalGateDumpTests.cs
Erik 66f9e0d459 feat(render) Campaign FW1: SIX OF TEN FIXTURES FULLY CONFORMANT
Three final pins complete the still-fixture set: (1) the CELL portal
side decode is the INVERSE of the 0x2 bit (uniform with the building
convention; the doorway-still flood proved it - ov=2 n=3 exact, and
foundry-deep stays green); (2) interior frames key the landscape order
off the OUTSIDE-projected landcell (get_outside_cell_id - derived from
the camera origin); (3) the outdoor pview has draw_landscape=FALSE so
look-in floods discard exit portals - the ov=0 pattern of every traced
look-in. CONFORMANT: foundry-deep (every frame), doorway-still,
street-outdoor, terrace-center, terrace-edge (the #456 acceptance
pose), cathedral-arrival - full frames identical to retail. The moving
four diverge only at punch-edge frames (walkabout F9, foundry-entry
F67) - pose-timing sensitivity parked in the driver Skip note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-30 11:07:29 +02:00

88 lines
4 KiB
C#

using AcDream.App.Tests.Rendering;
using AcDream.App.Rendering.Walk;
using DatReaderWriter;
using DatReaderWriter.Options;
using System.Numerics;
using System.Text;
namespace AcDream.App.Tests.Rendering.Walk;
/// <summary>
/// FW1 look-in gate microscope: for the street fixture pose, dump every
/// gate input for building a9b4001a (retail punches it) vs a9b4001e
/// (retail does not): raw portal flags, the BSP-emitted polygon's plane,
/// the eye's signed distance and side, and the active-view clip count.
/// Writes the dump to the scratch directory; always passes.
/// </summary>
[Trait("Lane", "InstalledDat")]
public sealed class WalkPortalGateDumpTests
{
[Fact]
public void Dump_the_gate_inputs_for_a_punching_and_a_silent_building()
{
string? datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null)
{
Assert.Fail("Lane=InstalledDat requires an installed retail DAT directory.");
}
IReadOnlyList<WalkOracleFrame> frames =
WalkOracleTrace.Load("posed/holtburg-street-outdoor");
WalkOracleFrame frame = frames[1];
Assert.NotNull(frame.Pose);
using var dats = new DatCollection(datDir!, DatAccessType.Read);
WalkLandscapeDatBuilder.BuiltWorld world =
WalkLandscapeDatBuilder.Build(dats, frame.Pose!.CellId, frame.Pose.Origin);
var ctx = new WalkTraceReplayContext(frame.Pose, world.Cells)
{
Buildings = world.Buildings,
};
// Install the outdoor default view as the active clip context.
var defaultView = new WalkPortalView();
WalkCopyView.AppendFullViewportQuad(
defaultView, ctx.Rays, ctx.WorldViewpoint,
ctx.ViewportWidth, ctx.ViewportHeight);
ctx.SetActiveView(defaultView, 0);
var dump = new StringBuilder();
Span<WalkScreenPoint> clipped = stackalloc WalkScreenPoint[64];
dump.AppendLine($"pose cell={frame.Pose.CellId:x8} origin={frame.Pose.Origin}");
foreach (uint id in new[] { 0xA9B4001Au, 0xA9B4001Eu, 0xA9B40022u, 0xA9B40026u })
{
WalkBuilding building = world.Buildings.Keys.Single(b => b.PositionCellId == id);
float dist = ctx.ViewerDistanceTo(building);
Vector3 eyeInBuilding = ctx.ViewpointInBuilding(building);
dump.AppendLine(
$"building {id:x8}: dist={dist:f1} eff={MathF.Max(0f, dist - 100f):f1} "
+ $"eyeLocal={eyeInBuilding} portals={building.Portals.Length}");
WalkBspNode? bsp = building.SelectDrawingBsp(dist);
var refs = new List<WalkPortalRef>();
Collect(bsp, refs);
dump.AppendLine($" level BSP portal refs: {refs.Count}");
foreach (WalkPortalRef portalRef in refs)
{
ref WalkBldPortal bp = ref building.Portals[portalRef.PortalIndex];
float d = Vector3.Dot(portalRef.Polygon.Plane.Normal, eyeInBuilding)
+ portalRef.Polygon.Plane.D;
int side = d > WalkVisibilityMath.Epsilon ? 0
: d < -WalkVisibilityMath.Epsilon ? 1 : 2;
int n = ctx.ClipBuildingPolygon(building, portalRef.Polygon, side, clipped);
dump.AppendLine(
$" ref idx={portalRef.PortalIndex} other={bp.OtherCellId:x8} "
+ $"rawSide={bp.PortalSide} exact={bp.ExactMatch} "
+ $"planeD@eye={d:f2} eyeSide={side} clipN={n} "
+ $"gate(side==rawSide)={(side == bp.PortalSide ? "PASS" : "reject")}");
}
}
string path = Path.Combine(Path.GetTempPath(), "fw1-portal-gate-dump.txt");
File.WriteAllText(path, dump.ToString());
Assert.True(true);
}
private static void Collect(WalkBspNode? node, List<WalkPortalRef> into)
{
if (node is null) return;
if (node.InPortals is not null) into.AddRange(node.InPortals);
Collect(node.PosNode, into);
Collect(node.NegNode, into);
}
}