using System;
using DatReaderWriter;
using DatReaderWriter.Options;
using Xunit;
using Xunit.Abstractions;
using DatSetup = DatReaderWriter.DBObjs.Setup;
using DatGfxObj = DatReaderWriter.DBObjs.GfxObj;
namespace AcDream.App.Tests.Rendering;
///
/// #131 diagnostic (throwaway): identify the Holtburg portal among the
/// outside-stage setup ids captured by the [outstage] probe, by dumping each
/// candidate setup's parts + bounds from the dat. The portal's setup is the
/// translucent swirl; lamp posts / creatures / signs identify by part shape.
///
public class Issue131SetupProbeTests
{
private readonly ITestOutputHelper _out;
public Issue131SetupProbeTests(ITestOutputHelper output) => _out = output;
/// #131: from the captured cottage-interior frame (the user's
/// portal-missing viewpoint), does the look-in flood admit the hall's
/// PORCH cell 0xA9B4017A (the portal's owner cell, pinned by the teleport
/// pCell flip)? If not admitted, no pass can draw the swirl regardless of
/// the emitter plumbing.
[Fact]
public void Diagnostic_LookInFlood_AdmitsHallPorchFromCottage()
{
var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; }
using var dats = new DatCollection(datDir, DatAccessType.Read);
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, 0xA9B40000u);
_out.WriteLine(FormattableString.Invariant($"loaded {cells.Count} A9B4 interior cells; hasPorch017A={cells.ContainsKey(0xA9B4017Au)}"));
AcDream.App.Rendering.LoadedCell? Lookup(uint id) => cells.TryGetValue(id, out var c) ? c : null;
// The captured frame: [viewer] root=0xA9B40171 eye=(155.255,14.533,96.074)
// fwd=(0.0702,0.9554,-0.2869) (portal-owner-verdicts.log:135118).
var eye = new System.Numerics.Vector3(155.255f, 14.533f, 96.074f);
var fwd = new System.Numerics.Vector3(0.0702f, 0.9554f, -0.2869f);
var view = System.Numerics.Matrix4x4.CreateLookAt(eye, eye + fwd, System.Numerics.Vector3.UnitZ);
var proj = System.Numerics.Matrix4x4.CreatePerspectiveFieldOfView(1.2f, 1280f / 720f, 1f, 5000f);
var viewProj = view * proj;
var root = cells[0xA9B40171u];
var pv = AcDream.App.Rendering.PortalVisibilityBuilder.Build(
root, eye, Lookup, viewProj,
buildingMembership: null,
drawLiftZ: AcDream.App.Rendering.PortalVisibilityBuilder.ShellDrawLiftZ);
_out.WriteLine(FormattableString.Invariant(
$"main flood={pv.OrderedVisibleCells.Count} outPolys={pv.OutsideView.Polygons.Count}"));
var lookIn = AcDream.App.Rendering.PortalVisibilityBuilder.BuildFromExterior(
cells.Values, eye, Lookup, viewProj,
float.PositiveInfinity, pv.OutsideView.Polygons);
var sb = new System.Text.StringBuilder("look-in admitted:");
foreach (uint id in lookIn.OrderedVisibleCells)
sb.Append(FormattableString.Invariant($" 0x{id & 0xFFFFu:X4}"));
_out.WriteLine(sb.ToString());
_out.WriteLine(FormattableString.Invariant(
$"porch 0x017A admitted: {lookIn.OrderedVisibleCells.Contains(0xA9B4017Au)}"));
}
[Fact]
public void Diagnostic_DumpOutstageCandidateSetups()
{
var datDir = CornerFloodReplayTests.ResolveDatDir();
if (datDir is null) { _out.WriteLine("SKIP: dats unavailable"); return; }
using var dats = new DatCollection(datDir, DatAccessType.Read);
uint[] candidates =
{
0x020010AC, // 0x7A9B4050 PASS r=11.9 — portal candidate A
0x02000B8E, // 0x7A9B403B PASS r=11.6 — portal candidate B
0x020019FF, // many instances (lamp posts?)
0x02000290,
0x02000001, // baseline (human?)
0x02000E08,
};
foreach (uint setupId in candidates)
{
var setup = dats.Get(setupId);
if (setup is null)
{
_out.WriteLine(FormattableString.Invariant($"setup 0x{setupId:X8}: NOT FOUND"));
continue;
}
_out.WriteLine(FormattableString.Invariant(
$"setup 0x{setupId:X8}: parts={setup.Parts.Count}"));
int shown = 0;
foreach (uint partId in setup.Parts)
{
if (shown++ >= 4) { _out.WriteLine(" ..."); break; }
var gfx = dats.Get(partId);
if (gfx is null) { _out.WriteLine(FormattableString.Invariant($" part 0x{partId:X8}: not found")); continue; }
var sb = new System.Text.StringBuilder();
sb.Append(FormattableString.Invariant(
$" part 0x{partId:X8}: polys={gfx.Polygons.Count} verts={gfx.VertexArray.Vertices.Count} surfaces=["));
int sShown = 0;
foreach (uint surfId in gfx.Surfaces)
{
if (sShown++ >= 6) { sb.Append(" ..."); break; }
sb.Append(FormattableString.Invariant($" 0x{surfId:X8}"));
}
sb.Append(" ]");
_out.WriteLine(sb.ToString());
}
}
}
}