Refactor ViewportHost synchronization methods for improved robustness and state management of simulation elements (NPCs, lights, models)

This commit is contained in:
2026-04-27 16:07:05 +02:00
parent 3cb9935bdd
commit f9d247f235

View File

@@ -5778,14 +5778,26 @@ export class ViewportHost {
this.currentTransformPreviewTargetIds = nextPreviewTargetIds; this.currentTransformPreviewTargetIds = nextPreviewTargetIds;
} }
private syncSimulationLocalLights(runtimeScene: RuntimeSceneDefinition) { private collectActiveSimulationNpcEntityIds(
runtimeScene: RuntimeSceneDefinition | null
): Set<string> {
return new Set(
runtimeScene?.npcDefinitions
.filter((npc) => npc.active && npc.visible)
.map((npc) => npc.entityId) ?? []
);
}
private syncSimulationLocalLights(
runtimeScene: RuntimeSceneDefinition
): boolean {
for (const pointLight of runtimeScene.localLights.pointLights) { for (const pointLight of runtimeScene.localLights.pointLights) {
const renderObjects = this.localLightRenderObjects.get( const renderObjects = this.localLightRenderObjects.get(
pointLight.entityId pointLight.entityId
); );
if (renderObjects === undefined) { if (renderObjects === undefined) {
continue; return false;
} }
renderObjects.group.visible = renderObjects.group.visible =
@@ -5805,8 +5817,11 @@ export class ViewportHost {
spotLight.entityId spotLight.entityId
); );
if (renderObjects === undefined) { if (
continue; renderObjects === undefined ||
!(renderObjects.light instanceof SpotLight)
) {
return false;
} }
renderObjects.group.visible = renderObjects.group.visible =
@@ -5819,20 +5834,25 @@ export class ViewportHost {
renderObjects.light.color.set(spotLight.colorHex); renderObjects.light.color.set(spotLight.colorHex);
renderObjects.light.intensity = spotLight.intensity; renderObjects.light.intensity = spotLight.intensity;
renderObjects.light.distance = spotLight.distance; renderObjects.light.distance = spotLight.distance;
if (renderObjects.light instanceof SpotLight) { renderObjects.light.angle = (spotLight.angleDegrees * Math.PI) / 180;
renderObjects.light.angle = (spotLight.angleDegrees * Math.PI) / 180;
}
} }
return true;
} }
private syncSimulationLightVolumes(runtimeScene: RuntimeSceneDefinition) { private syncSimulationLightVolumes(
runtimeScene: RuntimeSceneDefinition
): boolean {
for (const lightVolume of runtimeScene.volumes.light) { for (const lightVolume of runtimeScene.volumes.light) {
const renderObjects = this.lightVolumeRenderObjects.get( const renderObjects = this.lightVolumeRenderObjects.get(
lightVolume.brushId lightVolume.brushId
); );
if (renderObjects === undefined) { if (
continue; renderObjects === undefined ||
renderObjects.lights.length !== lightVolume.lights.length
) {
return false;
} }
renderObjects.group.visible = renderObjects.group.visible =
@@ -5866,6 +5886,8 @@ export class ViewportHost {
); );
} }
} }
return true;
} }
private syncSimulationNpcs(runtimeScene: RuntimeSceneDefinition) { private syncSimulationNpcs(runtimeScene: RuntimeSceneDefinition) {
@@ -5873,6 +5895,10 @@ export class ViewportHost {
return; return;
} }
const nextActiveNpcEntityIds = this.collectActiveSimulationNpcEntityIds(
runtimeScene
);
for (const runtimeNpc of runtimeScene.npcDefinitions) { for (const runtimeNpc of runtimeScene.npcDefinitions) {
const authoredEntity = this.currentDocument.entities[runtimeNpc.entityId]; const authoredEntity = this.currentDocument.entities[runtimeNpc.entityId];
@@ -5881,6 +5907,9 @@ export class ViewportHost {
} }
const renderObjects = this.entityRenderObjects.get(runtimeNpc.entityId); const renderObjects = this.entityRenderObjects.get(runtimeNpc.entityId);
const wasActive = this.simulationActiveNpcEntityIds.has(
runtimeNpc.entityId
);
if (!runtimeNpc.active || !runtimeNpc.visible) { if (!runtimeNpc.active || !runtimeNpc.visible) {
if (renderObjects !== undefined) { if (renderObjects !== undefined) {
@@ -5891,6 +5920,8 @@ export class ViewportHost {
if (renderObjects === undefined) { if (renderObjects === undefined) {
this.rebuildEntityMarkerForId(runtimeNpc.entityId); this.rebuildEntityMarkerForId(runtimeNpc.entityId);
} else if (!wasActive) {
renderObjects.group.visible = true;
} }
const nextRenderObjects = this.entityRenderObjects.get( const nextRenderObjects = this.entityRenderObjects.get(
@@ -5906,6 +5937,8 @@ export class ViewportHost {
yawDegrees: runtimeNpc.yawDegrees yawDegrees: runtimeNpc.yawDegrees
}); });
} }
this.simulationActiveNpcEntityIds = nextActiveNpcEntityIds;
} }
private syncSimulationInteractables(runtimeScene: RuntimeSceneDefinition) { private syncSimulationInteractables(runtimeScene: RuntimeSceneDefinition) {
@@ -5926,18 +5959,22 @@ export class ViewportHost {
} }
} }
private syncSimulationModelInstances(runtimeScene: RuntimeSceneDefinition) { private syncSimulationModelInstances(
runtimeScene: RuntimeSceneDefinition
): boolean {
for (const modelInstance of runtimeScene.modelInstances) { for (const modelInstance of runtimeScene.modelInstances) {
const renderGroup = this.modelRenderObjects.get( const renderGroup = this.modelRenderObjects.get(
modelInstance.instanceId modelInstance.instanceId
); );
if (renderGroup === undefined) { if (renderGroup === undefined) {
continue; return false;
} }
renderGroup.visible = modelInstance.visible; renderGroup.visible = modelInstance.visible;
} }
return true;
} }
private rebuildLocalLights(document: SceneDocument) { private rebuildLocalLights(document: SceneDocument) {