fix(render): Phase A8 — LiveDynamic in indoor branch + cull A/B gate

Two changes from visual-gate-#2 evidence.

LiveDynamic fix (real bug closure):
The user reported "can't see char ... door is missing" in visual gate #2.
Doors and the player char are LiveDynamic entities (ServerGuid != 0). The
outdoor branch's Draw(set: All) includes them; the indoor branch's
RenderInsideOutAcdream only renders IndoorPass + OutdoorScenery partitions,
implicitly excluding LiveDynamic. The method's own header comment promised
"LiveDynamic is drawn last in BOTH branches" but no call existed in the
indoor path — a documented behavior with no implementation. Wire the
LiveDynamic Draw after RenderInsideOutAcdream returns with stencil + state
restored to defaults at its cleanup block.

Cull A/B diagnostic (bisect floor-missing root cause):
ACDREAM_A8_DISABLE_CULL=1 forces every cell-mesh batch's effective CullMode
to None. The visual-gate-#2 audit confirmed cell meshes upload correctly
(every cell has multi-batch render data with non-zero indices, no null
data, no zero handles). Every batch uniformly reports CullMode.Landblock
which maps to glCullFace(Back) — identical to WB's mapping. So data is
fine and CullMode lookup is fine; only the BIND-TIME interaction (polygon
winding orientation in our coord system + cull-back) could still hide
specific polys. If floor appears with this gate set, cull/winding is the
remaining bug (need to either invert winding upstream or remap CullMode);
if not, the issue is elsewhere (lighting / depth / alpha) and we look
there. Tight bisect — one launch's evidence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-05-27 20:00:54 +02:00
parent 772d69c7a6
commit b19f3c14a9
2 changed files with 30 additions and 0 deletions

View file

@ -7361,6 +7361,22 @@ public sealed class GameWindow : IDisposable
camBuildings, otherBuildings,
camera, frustum, playerLb, animatedIds,
visibility?.VisibleCellIds);
// Phase A8 fix (2026-05-28 visual-gate-#2 follow-up): LiveDynamic
// entities (player char, NPCs, dropped items, doors) were missing
// inside buildings because RenderInsideOutAcdream only renders the
// IndoorPass + OutdoorScenery partitions; LiveDynamic was implicitly
// excluded. The method's own header comment promised "LiveDynamic
// is drawn last in BOTH branches" but no call existed in the indoor
// path. Wire it here, after RenderInsideOutAcdream returns with
// stencil + state restored to defaults at its cleanup block. Same
// shape as the outdoor branch's Draw(All) for the LiveDynamic
// subset only.
_wbDrawDispatcher!.Draw(camera, _worldState.LandblockEntries, frustum,
neverCullLandblockId: playerLb,
visibleCellIds: visibility?.VisibleCellIds,
animatedEntityIds: animatedIds,
set: AcDream.App.Rendering.Wb.WbDrawDispatcher.EntitySet.LiveDynamic);
}
else
{