fix(rendering): preserve exact scene traversal order

This commit is contained in:
Erik 2026-07-25 02:03:58 +02:00
parent 06e7754619
commit e0f36caa70
12 changed files with 500 additions and 77 deletions

View file

@ -24,16 +24,20 @@ internal sealed class LiveRenderProjectionJournal : ILiveRenderProjectionSink
private readonly LiveEntityRuntime _runtime;
private readonly RenderProjectionJournal _journal;
private readonly IRenderTraversalOrderSource _traversalOrder;
private readonly Dictionary<uint, TrackedProjection> _byLocalId = [];
private readonly List<LiveEntityRecord> _activeRootScratch = [];
private readonly List<TrackedProjection> _activeScratch = [];
public LiveRenderProjectionJournal(
LiveEntityRuntime runtime,
RenderProjectionJournal journal)
RenderProjectionJournal journal,
IRenderTraversalOrderSource traversalOrder)
{
_runtime = runtime ?? throw new ArgumentNullException(nameof(runtime));
_journal = journal ?? throw new ArgumentNullException(nameof(journal));
_traversalOrder = traversalOrder
?? throw new ArgumentNullException(nameof(traversalOrder));
}
public int ProjectionCount => _byLocalId.Count;
@ -257,7 +261,8 @@ internal sealed class LiveRenderProjectionJournal : ILiveRenderProjectionSink
: fullCellId == 0
? 0
: Canonicalize(fullCellId);
return RenderProjectionRecordFactory.ProjectEntity(
RenderProjectionRecord projected =
RenderProjectionRecordFactory.ProjectEntity(
ProjectionId(entity.Id),
record.ProjectionKind is LiveEntityProjectionKind.Attached
? RenderProjectionClass.EquippedChild
@ -268,6 +273,21 @@ internal sealed class LiveRenderProjectionJournal : ILiveRenderProjectionSink
fullCellId,
entity,
spatiallyVisible);
if (_traversalOrder.TryGetTraversalSortKey(
entity,
out RenderSortKey sortKey))
{
return projected with { SortKey = sortKey };
}
// Spatial withdrawal is not logical destruction. Retain the last
// resident order while the projection is inactive so a portal/rebucket
// edge does not manufacture an unrelated ordering mutation.
return _byLocalId.TryGetValue(
entity.Id,
out TrackedProjection? retained)
? projected with { SortKey = retained.Projection.SortKey }
: projected;
}
private void Remove(TrackedProjection tracked)