fix(rendering): reconcile shadow roots from live runtime
Recover ordinary live roots from LiveEntityRuntime's canonical active spatial workset instead of relying on already-retained derived records. Keep attached children callback-authoritative, cache immutable selection geometry fingerprints, and pin zero-allocation retained update paths with regression tests. Release gate: 3,733 App tests / 3 skips; 8,217 complete-solution tests / 5 skips. Co-Authored-By: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
056bbd4efd
commit
91463db551
7 changed files with 272 additions and 15 deletions
|
|
@ -25,6 +25,7 @@ internal sealed class LiveRenderProjectionJournal : ILiveRenderProjectionSink
|
|||
private readonly LiveEntityRuntime _runtime;
|
||||
private readonly RenderProjectionJournal _journal;
|
||||
private readonly Dictionary<uint, TrackedProjection> _byLocalId = [];
|
||||
private readonly List<LiveEntityRecord> _activeRootScratch = [];
|
||||
private readonly List<TrackedProjection> _activeScratch = [];
|
||||
|
||||
public LiveRenderProjectionJournal(
|
||||
|
|
@ -107,10 +108,34 @@ internal sealed class LiveRenderProjectionJournal : ILiveRenderProjectionSink
|
|||
/// </summary>
|
||||
public void SynchronizeActiveSources()
|
||||
{
|
||||
// The canonical live-runtime workset is the source of truth for world
|
||||
// roots. Walking only this journal's already-tracked values would make
|
||||
// a missed/reordered derived callback permanent and prevent shadow
|
||||
// comparison from converging after a same-location revisit.
|
||||
_runtime.CopySpatialRootObjectRecordsTo(_activeRootScratch);
|
||||
for (int i = 0; i < _activeRootScratch.Count; i++)
|
||||
{
|
||||
LiveEntityRecord record = _activeRootScratch[i];
|
||||
if (!record.ResourcesRegistered
|
||||
|| record.WorldEntity is not { } entity
|
||||
|| !_runtime.IsCurrentSpatialRootObject(record))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Upsert(record, entity, record.IsSpatiallyVisible);
|
||||
}
|
||||
|
||||
// Attached children are not members of the ordinary root workset.
|
||||
// Their exact EntityReady/pose/removal callbacks remain authoritative;
|
||||
// synchronization only refreshes children whose attachment projection
|
||||
// is still retained by this derived scene.
|
||||
_activeScratch.Clear();
|
||||
foreach (TrackedProjection tracked in _byLocalId.Values)
|
||||
{
|
||||
if (tracked.Record.IsSpatiallyProjected)
|
||||
if (tracked.Record.IsSpatiallyProjected
|
||||
&& tracked.Record.ProjectionKind is
|
||||
LiveEntityProjectionKind.Attached)
|
||||
_activeScratch.Add(tracked);
|
||||
}
|
||||
|
||||
|
|
@ -137,6 +162,7 @@ internal sealed class LiveRenderProjectionJournal : ILiveRenderProjectionSink
|
|||
public void ResetTracking()
|
||||
{
|
||||
_byLocalId.Clear();
|
||||
_activeRootScratch.Clear();
|
||||
_activeScratch.Clear();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue