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; /// /// 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. /// [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 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 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(); 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 into) { if (node is null) return; if (node.InPortals is not null) into.AddRange(node.InPortals); Collect(node.PosNode, into); Collect(node.NegNode, into); } }