diff --git a/src/AcDream.App/Rendering/Wb/ObjectMeshManager.cs b/src/AcDream.App/Rendering/Wb/ObjectMeshManager.cs index f73e9226..7817fa75 100644 --- a/src/AcDream.App/Rendering/Wb/ObjectMeshManager.cs +++ b/src/AcDream.App/Rendering/Wb/ObjectMeshManager.cs @@ -1023,16 +1023,22 @@ namespace AcDream.App.Rendering.Wb { // The Holtburg meeting hall (0x010014C3) keeps its walkable exterior // stair-ramp as dictionary polys {0,1}: in the PhysicsBSP (NPCs walk // it) but absent from every DrawingBSP node — retail shows a plain - // wall; iterating the dictionary drew the "phantom staircase" + // wall; iterating the dictionary draws the "phantom staircase" // (invisible-but-walkable in retail, visible in acdream). The hill - // cottage (0x01000827) carries 8 such orphans. Filter to the BSP- - // referenced set when a drawing BSP exists; models without one draw - // everything (unchanged). - var drawnPolyIds = CollectDrawingBspPolygonIds(gfxObj); - + // cottage (0x01000827) carries 8 such orphans. + // + // ⚠️ FILTER NOT APPLIED (e46d3d9 un-applied same day): naively + // filtering to CollectDrawingBspPolygonIds(gfxObj) made DOORS + // disappear across Holtburg (user gate 2026-06-11) — the naive + // PosNode/NegNode walk evidently misses polys some models reference + // another way (portal-type nodes? leaf indexing? DatReaderWriter + // parse gap?). Diagnose with the histogram fact in + // Issue113PhantomStairsDumpTests on a door GfxObj BEFORE re-landing. + // The full retail draw is BSP-TRAVERSAL ORDER drawing, not a + // dictionary iteration with a filter — see the holistic port handoff + // docs/research/2026-06-11-building-render-holistic-port-handoff.md. foreach (var polyEntry in gfxObj.Polygons) { ct.ThrowIfCancellationRequested(); - if (drawnPolyIds is not null && !drawnPolyIds.Contains(polyEntry.Key)) continue; var poly = polyEntry.Value; if (poly.VertexIds.Count < 3) continue;