Improve simulation state management and synchronization using versioning and membership signatures

This commit is contained in:
2026-04-27 16:06:43 +02:00
parent cdacd88abe
commit 3cb9935bdd

View File

@@ -1075,10 +1075,21 @@ export class ViewportHost {
updateSimulation( updateSimulation(
runtimeScene: RuntimeSceneDefinition | null, runtimeScene: RuntimeSceneDefinition | null,
clock: RuntimeClockState | null clock: RuntimeClockState | null,
versionInfo?: ViewportSimulationVersionInfo
) { ) {
this.currentSimulationScene = runtimeScene; this.currentSimulationScene = runtimeScene;
this.currentSimulationClock = clock; this.currentSimulationClock = clock;
this.currentSimulationSceneVersion =
versionInfo?.sceneVersion ?? this.currentSimulationSceneVersion + 1;
this.currentSimulationFrameVersion =
versionInfo?.frameVersion ?? this.currentSimulationFrameVersion + 1;
this.currentSimulationMembershipSignatures =
createViewportSimulationMembershipSignatures(runtimeScene);
this.simulationActiveNpcEntityIds = this.collectActiveSimulationNpcEntityIds(
runtimeScene
);
this.simulationSceneIdentityMismatchWarned = false;
this.simulationInteractableEnabledById.clear(); this.simulationInteractableEnabledById.clear();
this.applyWorld(); this.applyWorld();
@@ -1094,25 +1105,74 @@ export class ViewportHost {
updateSimulationFrame( updateSimulationFrame(
runtimeScene: RuntimeSceneDefinition | null, runtimeScene: RuntimeSceneDefinition | null,
clock: RuntimeClockState | null clock: RuntimeClockState | null,
versionInfo?: ViewportSimulationVersionInfo
) { ) {
if (this.currentSimulationScene !== runtimeScene) { if (
this.updateSimulation(runtimeScene, clock); this.currentSimulationScene !== runtimeScene &&
return; !this.simulationSceneIdentityMismatchWarned
) {
console.warn(
"Viewport simulation frame received a new runtime scene object without a scene-version change. Continuing on the incremental frame path."
);
this.simulationSceneIdentityMismatchWarned = true;
} }
this.currentSimulationScene = runtimeScene;
this.currentSimulationClock = clock; this.currentSimulationClock = clock;
this.currentSimulationSceneVersion =
versionInfo?.sceneVersion ?? this.currentSimulationSceneVersion;
this.currentSimulationFrameVersion =
versionInfo?.frameVersion ?? this.currentSimulationFrameVersion + 1;
this.applyWorld(); this.applyWorld();
if (this.currentDocument === null || runtimeScene === null) { if (this.currentDocument === null || runtimeScene === null) {
return; return;
} }
this.syncSimulationLocalLights(runtimeScene); const nextMembershipSignatures =
this.syncSimulationLightVolumes(runtimeScene); createViewportSimulationMembershipSignatures(runtimeScene);
if (
nextMembershipSignatures.localLights !==
this.currentSimulationMembershipSignatures.localLights
) {
this.rebuildLocalLights(this.currentDocument);
} else if (!this.syncSimulationLocalLights(runtimeScene)) {
this.rebuildLocalLights(this.currentDocument);
}
if (
nextMembershipSignatures.lightVolumes !==
this.currentSimulationMembershipSignatures.lightVolumes
) {
this.rebuildLightVolumes(this.currentDocument);
} else if (!this.syncSimulationLightVolumes(runtimeScene)) {
this.rebuildLightVolumes(this.currentDocument);
}
this.syncSimulationNpcs(runtimeScene); this.syncSimulationNpcs(runtimeScene);
this.syncSimulationInteractables(runtimeScene);
this.syncSimulationModelInstances(runtimeScene); if (
nextMembershipSignatures.interactables !==
this.currentSimulationMembershipSignatures.interactables
) {
this.simulationInteractableEnabledById.clear();
this.rebuildEntityMarkers(this.currentDocument, this.currentSelection);
} else {
this.syncSimulationInteractables(runtimeScene);
}
if (
nextMembershipSignatures.modelInstances !==
this.currentSimulationMembershipSignatures.modelInstances
) {
this.rebuildModelInstances(this.currentDocument, this.currentSelection);
} else if (!this.syncSimulationModelInstances(runtimeScene)) {
this.rebuildModelInstances(this.currentDocument, this.currentSelection);
}
this.currentSimulationMembershipSignatures = nextMembershipSignatures;
} }
updateSelection(selection: EditorSelection, activeSelectionId: string | null) { updateSelection(selection: EditorSelection, activeSelectionId: string | null) {