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:
Erik 2026-07-24 22:45:14 +02:00
parent 056bbd4efd
commit 91463db551
7 changed files with 272 additions and 15 deletions

View file

@ -211,6 +211,8 @@ internal sealed class CurrentRenderSceneOracle :
new(ReferenceEqualityComparer.Instance);
private readonly List<CurrentRenderSelectionFingerprint>
_selectionParts = [];
private readonly Dictionary<uint, SelectionGeometryCacheEntry>
_selectionGeometryByGfxObj = [];
private ulong _frameSequence;
private int _abortedFrames;
private int _outdoorStaticCount;
@ -637,16 +639,15 @@ internal sealed class CurrentRenderSceneOracle :
}
ArgumentNullException.ThrowIfNull(mesh);
StableRenderHash128 geometry = StableRenderHash128.Create();
geometry.Add(mesh.SphereCenter);
geometry.Add(mesh.SphereRadius);
geometry.Add(mesh.Polygons.Count);
foreach (RetailSelectionPolygon polygon in mesh.Polygons)
if (!_selectionGeometryByGfxObj.TryGetValue(
gfxObjId,
out SelectionGeometryCacheEntry cachedGeometry)
|| !ReferenceEquals(cachedGeometry.Mesh, mesh))
{
geometry.Add(polygon.SingleSided);
geometry.Add(polygon.Vertices.Count);
foreach (Vector3 vertex in polygon.Vertices)
geometry.Add(vertex);
cachedGeometry = new SelectionGeometryCacheEntry(
mesh,
FingerprintSelectionGeometry(mesh));
_selectionGeometryByGfxObj[gfxObjId] = cachedGeometry;
}
var fingerprint = new CurrentRenderSelectionFingerprint(
@ -656,7 +657,7 @@ internal sealed class CurrentRenderSceneOracle :
PartIndex: partIndex,
GfxObjId: gfxObjId,
LocalToWorld: localToWorld,
Geometry: geometry.Finish());
Geometry: cachedGeometry.Fingerprint);
_selectionParts.Add(fingerprint);
_selectionHash.Add(fingerprint.Sequence);
_selectionHash.Add(fingerprint.ServerGuid);
@ -722,8 +723,11 @@ internal sealed class CurrentRenderSceneOracle :
StableRenderHash128 geometry = StableRenderHash128.Create();
geometry.Add(entity.MeshRefs.Count);
foreach (MeshRef mesh in entity.MeshRefs)
for (int meshIndex = 0;
meshIndex < entity.MeshRefs.Count;
meshIndex++)
{
MeshRef mesh = entity.MeshRefs[meshIndex];
geometry.Add(mesh.GfxObjId);
geometry.Add(mesh.PartTransform);
}
@ -734,8 +738,12 @@ internal sealed class CurrentRenderSceneOracle :
appearance.Add(true);
appearance.Add(palette.BasePaletteId);
appearance.Add(palette.SubPalettes.Count);
foreach (PaletteOverride.SubPaletteRange range in palette.SubPalettes)
for (int rangeIndex = 0;
rangeIndex < palette.SubPalettes.Count;
rangeIndex++)
{
PaletteOverride.SubPaletteRange range =
palette.SubPalettes[rangeIndex];
appearance.Add(range.SubPaletteId);
appearance.Add(range.Offset);
appearance.Add(range.Length);
@ -747,8 +755,11 @@ internal sealed class CurrentRenderSceneOracle :
}
appearance.Add(entity.PartOverrides.Count);
foreach (PartOverride part in entity.PartOverrides)
for (int partIndex = 0;
partIndex < entity.PartOverrides.Count;
partIndex++)
{
PartOverride part = entity.PartOverrides[partIndex];
appearance.Add(part.PartIndex);
appearance.Add(part.GfxObjId);
}
@ -784,6 +795,31 @@ internal sealed class CurrentRenderSceneOracle :
Appearance: appearance.Finish());
}
private static RenderSceneHash128 FingerprintSelectionGeometry(
RetailSelectionMesh mesh)
{
StableRenderHash128 geometry = StableRenderHash128.Create();
geometry.Add(mesh.SphereCenter);
geometry.Add(mesh.SphereRadius);
geometry.Add(mesh.Polygons.Count);
for (int polygonIndex = 0;
polygonIndex < mesh.Polygons.Count;
polygonIndex++)
{
RetailSelectionPolygon polygon = mesh.Polygons[polygonIndex];
geometry.Add(polygon.SingleSided);
geometry.Add(polygon.Vertices.Count);
for (int vertexIndex = 0;
vertexIndex < polygon.Vertices.Count;
vertexIndex++)
{
geometry.Add(polygon.Vertices[vertexIndex]);
}
}
return geometry.Finish();
}
private static InteriorEntityPartition.ProjectionClass ProjectionClassOf(
WorldEntity entity) =>
entity.ServerGuid != 0
@ -792,6 +828,10 @@ internal sealed class CurrentRenderSceneOracle :
? InteriorEntityPartition.ProjectionClass.CellStatic
: InteriorEntityPartition.ProjectionClass.OutdoorStatic;
private readonly record struct SelectionGeometryCacheEntry(
RetailSelectionMesh Mesh,
RenderSceneHash128 Fingerprint);
private static void AddPViewCandidate(
ref StableRenderHash128 hash,
in CurrentRenderPViewCandidateFingerprint candidate)