test(conformance): skipNoTexture confirmation - ALL Holtburg portal-fill quads are Base1Solid (untextured)
Phase A confirmation fact (DumpPortalFillSurfaceTypes): every portal-fill polygon on the audited building models (hall 0x010014C3, cottages 0x01000827/0x0100082E/0x01000C17) carries an untextured surface (Base1Solid, mostly +Translucent) with Stippling=NoPos and no negative surface. Retail's skipNoTexture rule (D3DPolyRender inner draw 0x0059d4a0, default on @0x00820e30) therefore skips ALL of them on the building/cell pass - door fills, window fills, AND the phantom stair-ramp. Retail never draws any baked fill; visible doors are door ENTITIES. acdream draws the solid batches as colored geometry, which is both the phantom staircase AND why dropping them read as 'doors disappeared'. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e223325410
commit
31ea849277
1 changed files with 50 additions and 0 deletions
|
|
@ -181,6 +181,56 @@ public sealed class Issue113DoorVanishDiagnosticTests
|
|||
return n.LengthSquared() < 1e-10f ? Vector3.Zero : Vector3.Normalize(n);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Phase A confirmation: retail's building/cell mesh pass skips surface
|
||||
/// batches whose CSurface type has neither Base1Image (0x2) nor
|
||||
/// Base1ClipMap (0x4) — the skipNoTexture rule (D3DPolyRender inner draw
|
||||
/// 0x0059d4a0; default skipNoTexture=1). Prediction: the hall's phantom
|
||||
/// stair-ramp portal-fill polys {0,1} reference SOLID (untextured)
|
||||
/// surfaces while cottage door/window fills reference TEXTURED surfaces —
|
||||
/// which is exactly why retail shows doors but not the ramp.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void DumpPortalFillSurfaceTypes()
|
||||
{
|
||||
var datDir = ConformanceDats.ResolveDatDir();
|
||||
if (datDir is null) { _out.WriteLine("dats unavailable — skipped"); return; }
|
||||
using var dats = new DatCollection(datDir, DatAccessType.Read);
|
||||
|
||||
foreach (uint mid in new uint[] { 0x010014C3u, 0x01000827u, 0x0100082Eu, 0x01000C17u })
|
||||
{
|
||||
var gfx = dats.Get<DatReaderWriter.DBObjs.GfxObj>(mid);
|
||||
if (gfx?.DrawingBSP?.Root is null) continue;
|
||||
|
||||
var walked = new HashSet<ushort>();
|
||||
void Walk(DatReaderWriter.Types.DrawingBSPNode? n)
|
||||
{
|
||||
if (n is null) return;
|
||||
if (n.Polygons is not null) foreach (var pid in n.Polygons) walked.Add((ushort)pid);
|
||||
Walk(n.PosNode); Walk(n.NegNode);
|
||||
}
|
||||
Walk(gfx.DrawingBSP.Root);
|
||||
var portalFills = gfx.Polygons.Keys.Where(k => !walked.Contains(k)).OrderBy(k => k).ToList();
|
||||
|
||||
_out.WriteLine($"=== model 0x{mid:X8}: {portalFills.Count} portal-fill polys; Surfaces list has {gfx.Surfaces.Count} entries ===");
|
||||
foreach (var pid in portalFills)
|
||||
{
|
||||
var poly = gfx.Polygons[pid];
|
||||
string Describe(short surfIdx)
|
||||
{
|
||||
if (surfIdx < 0 || surfIdx >= gfx.Surfaces.Count) return $"idx{surfIdx}=OOB";
|
||||
uint sid = gfx.Surfaces[surfIdx];
|
||||
var surf = dats.Get<DatReaderWriter.DBObjs.Surface>(sid);
|
||||
if (surf is null) return $"0x{sid:X8}=MISSING";
|
||||
bool textured = surf.Type.HasFlag(DatReaderWriter.Enums.SurfaceType.Base1Image)
|
||||
|| surf.Type.HasFlag(DatReaderWriter.Enums.SurfaceType.Base1ClipMap);
|
||||
return $"0x{sid:X8} type={surf.Type} -> {(textured ? "TEXTURED (drawn)" : "SOLID (skipNoTexture SKIPS on building/cell pass)")}";
|
||||
}
|
||||
_out.WriteLine($" poly {pid,3}: sides={poly.SidesType} stip={poly.Stippling} pos[{Describe(poly.PosSurface)}] neg[{Describe(poly.NegSurface)}]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Control group: the two #113 models (hall + cottage) whose orphans ARE
|
||||
/// the phantom geometry, for type-model comparison against the door.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue