feat(rendering): journal live scene projections

Mirror exact live-root and equipped-child lifetimes behind the non-drawing render-scene boundary. Ready, visibility, final-pose, rebucket, removal, and resource teardown edges retain canonical LiveEntityRuntime identity while active-only synchronization avoids resident-static scans.

Co-authored-by: Erik Nilsson <erikn@users.noreply.github.com>
This commit is contained in:
Erik 2026-07-24 22:05:42 +02:00
parent 5d19c56d15
commit 58e7c2eb99
10 changed files with 949 additions and 148 deletions

View file

@ -43,6 +43,45 @@ internal sealed class RenderProjectionJournal
id,
incarnation));
public void AppendDifference(
in RenderProjectionRecord prior,
in RenderProjectionRecord current)
{
if (prior.Id != current.Id
|| prior.OwnerIncarnation != current.OwnerIncarnation
|| prior.ProjectionClass != current.ProjectionClass)
{
throw new ArgumentException(
"A channel update cannot change projection identity, incarnation, or class.",
nameof(current));
}
if (prior.Transform != current.Transform
|| prior.Bounds != current.Bounds
|| prior.SortKey != current.SortKey
|| prior.Source.TransformFingerprint
!= current.Source.TransformFingerprint)
{
Update(RenderProjectionDeltaKind.UpdateTransform, in current);
}
if (prior.MeshSet != current.MeshSet
|| prior.Material != current.Material
|| prior.DegradeState != current.DegradeState
|| prior.Source.GeometryFingerprint
!= current.Source.GeometryFingerprint
|| prior.Source.AppearanceFingerprint
!= current.Source.AppearanceFingerprint)
{
Update(RenderProjectionDeltaKind.UpdateAppearance, in current);
}
if (prior.Residency != current.Residency)
Update(RenderProjectionDeltaKind.Rebucket, in current);
if (prior.Flags != current.Flags)
Update(RenderProjectionDeltaKind.UpdateFlags, in current);
}
public RenderDeltaApplyResult DrainTo(IRenderScene scene)
{
ArgumentNullException.ThrowIfNull(scene);