diag #181 (refined): 0x0181's region is a zero-area sliver; the amplifier is per-drawn-cell state shifting with the cell list, not light-pool scoping
Diagnostic_FlappingCellViewRegion_SliverOrLarge: at the flap pose the admitted region is one degenerate triangle (ndcArea ~0), and ClipPlaneSet.From handles degenerates correctly (area<1e-7 -> Empty) - the cell's own gated geometry costs ~zero pixels either way. The a7 pseudocode CORRECTION-2 re-read kills the flood-scoped-lights framing (the pool is already resident+player-anchored since d8984e87). Remaining suspects: per-cell light-set SSBO slot assignment (SelectForCell) or the seal/punch assembly keyed to the drawn-cell list. Next instrument: parked ACDREAM_PROBE_SEAMDRAW=1 run, diff the washed cell's [seam-blk] applied-set lines between vis=31 and vis=32 frames. ISSUES #181 + render digest updated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
864e4d9e75
commit
d366f36557
2 changed files with 76 additions and 6 deletions
|
|
@ -55,6 +55,65 @@ public class Issue181VisFlapReplayTests
|
|||
private static string CellSetString(IEnumerable<uint> ids)
|
||||
=> string.Join(" ", ids.Select(id => $"{id & 0xFFFFu:X4}"));
|
||||
|
||||
[Fact]
|
||||
public void Diagnostic_FlappingCellViewRegion_SliverOrLarge()
|
||||
{
|
||||
var datDir = CornerFloodReplayTests.ResolveDatDir();
|
||||
if (datDir is null) { _out.WriteLine("SKIP: no dat dir"); return; }
|
||||
using var dats = new DatCollection(datDir, DatAccessType.Read);
|
||||
var cells = Issue120ReciprocalPingPongTests.LoadAllInteriorCells(dats, FacilityHub);
|
||||
uint flapper = FacilityHub | 0x0181u;
|
||||
|
||||
// The most unstable pose from the perturbation sweep.
|
||||
float yaw = 15f * MathF.PI / 180f, pitch = -20f * MathF.PI / 180f;
|
||||
var gaze = new Vector3(
|
||||
MathF.Cos(pitch) * MathF.Cos(yaw),
|
||||
MathF.Cos(pitch) * MathF.Sin(yaw),
|
||||
MathF.Sin(pitch));
|
||||
|
||||
Func<uint, LoadedCell?> lookup = id => cells.TryGetValue(id, out var c) ? c : null;
|
||||
|
||||
foreach (var (label, eye) in new (string, Vector3)[]
|
||||
{
|
||||
("base ", LiveEye),
|
||||
("+0.5mm x ", LiveEye + new Vector3(0.0005f, 0, 0)),
|
||||
("-0.5mm x ", LiveEye - new Vector3(0.0005f, 0, 0)),
|
||||
("+5mm x ", LiveEye + new Vector3(0.005f, 0, 0)),
|
||||
("-5mm x ", LiveEye - new Vector3(0.005f, 0, 0)),
|
||||
("+2cm z ", LiveEye + new Vector3(0, 0, 0.02f)),
|
||||
("-2cm z ", LiveEye - new Vector3(0, 0, 0.02f)),
|
||||
})
|
||||
{
|
||||
var frame = PortalVisibilityBuilder.Build(
|
||||
cells[LiveRoot], eye, lookup, ViewProjFor(eye, gaze),
|
||||
buildingMembership: null,
|
||||
drawLiftZ: PortalVisibilityBuilder.ShellDrawLiftZ);
|
||||
|
||||
if (!frame.CellViews.TryGetValue(flapper, out var view) || view.IsEmpty)
|
||||
{
|
||||
_out.WriteLine($"{label}: 0181 NOT ADMITTED");
|
||||
continue;
|
||||
}
|
||||
|
||||
// NDC shoelace area of the admitted region (screen is 4.0 NDC-units total).
|
||||
float area = 0f; int polys = 0, verts = 0;
|
||||
foreach (var vp in view.Polygons)
|
||||
{
|
||||
var v = vp.Vertices;
|
||||
polys++; verts += v.Length;
|
||||
float a = 0f;
|
||||
for (int i = 0; i < v.Length; i++)
|
||||
{
|
||||
var p = v[i]; var q = v[(i + 1) % v.Length];
|
||||
a += p.X * q.Y - q.X * p.Y;
|
||||
}
|
||||
area += MathF.Abs(a) * 0.5f;
|
||||
}
|
||||
_out.WriteLine(FormattableString.Invariant(
|
||||
$"{label}: 0181 admitted polys={polys} verts={verts} ndcArea={area:F4} ({area / 4f * 100f:F1}% of screen)"));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Diagnostic_SubMillimeterEyePerturbation_MustNotChangeAdmission()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue