refactor(render): move root-cell dynamics onto walk turns

This commit is contained in:
Erik 2026-08-31 03:44:32 +02:00
parent f9a80fbc44
commit 474b05e7dc
4 changed files with 54 additions and 29 deletions

View file

@ -518,7 +518,7 @@ internal sealed class WalkFrameDriver : IWalkEventSink, IWalkLookInViewSource
private bool _skyDrawnThisFrame;
private WalkDrawStage? _currentDcStage;
private bool _readyToReplay;
private int _lookInRouteIndex;
private int _cellViewRouteIndex;
internal WalkFrameDriver(
WbDrawDispatcher dispatcher,
@ -626,7 +626,7 @@ internal sealed class WalkFrameDriver : IWalkEventSink, IWalkLookInViewSource
VisitedBuildings.Clear();
VisitedLandscapeCellIds.Clear();
InteriorFloodCells.Clear();
_lookInRouteIndex = 0;
_cellViewRouteIndex = 0;
}
/// <summary>Records the final segment mark (plan §FW3.2b-1's "at frame
@ -981,36 +981,35 @@ internal sealed class WalkFrameDriver : IWalkEventSink, IWalkLookInViewSource
_stream, stage, cellId, records.Records, records.TupleLandblockId,
_cameraWorldPosition, _viewProjection);
MarkIfGrown();
// PView::DrawObjCellForDummies draws this cell's live objects at the
// same turn as its statics. Capture the currently installed portal
// views before the walk pops them, then apply retail's per-GfxObj
// drawing-sphere viewcone check in the walk classifier.
int viewRouteIndex = _cellViewRouteIndex++;
CaptureCellViews(cellId);
if (stage == WalkDrawStage.LookInStatic)
{
// Retail draws a look-in cell's complete object list at this
// re-entrant DrawCells turn. The packed dynamic route used to run
// much later at the pre-clear boundary, after nearer building
// shells, which let the cathedral's 0x112 remote player overpaint
// opaque walls. Keep animation/fade in the packed route, but replay
// it here between this cell's content and the building shell.
int routeIndex = _lookInRouteIndex++;
LookInCellTurns.Add(cellId);
LookInCells.Add(cellId);
CaptureLookInViews(cellId);
WalkFrameStaticRecords dynamics = _worldData.GetCellDynamics(cellId);
_populator.PopulateCellDynamics(
_stream,
cellId,
dynamics.Records,
dynamics.TupleLandblockId,
_cameraWorldPosition,
_viewProjection,
this,
routeIndex);
MarkIfGrown();
if (HasAnyOwner(records) || HasAnyOwner(dynamics))
_events.Add(WalkFrameEvent.CellParticles(cellId));
}
WalkFrameStaticRecords dynamics = _worldData.GetCellDynamics(cellId);
_populator.PopulateCellDynamics(
_stream,
cellId,
dynamics.Records,
dynamics.TupleLandblockId,
_cameraWorldPosition,
_viewProjection,
this,
viewRouteIndex);
MarkIfGrown();
if (HasAnyOwner(records) || HasAnyOwner(dynamics))
_events.Add(WalkFrameEvent.CellParticles(cellId));
}
private void CaptureLookInViews(uint cellId)
private void CaptureCellViews(uint cellId)
{
IWalkBuildingFrameContext ctx = RequireOpenFrame();
WalkCell? cell = ctx.GetVisible(cellId);