Add sound emitter volume control and update runtime host for various controls
This commit is contained in:
@@ -215,6 +215,10 @@ export class RuntimeAudioSystem {
|
||||
this.playBufferedSound(soundEmitterId);
|
||||
}
|
||||
|
||||
hasSoundEmitter(soundEmitterId: string): boolean {
|
||||
return this.soundEmitters.has(soundEmitterId);
|
||||
}
|
||||
|
||||
stopSound(soundEmitterId: string) {
|
||||
this.pendingPlayEmitterIds.delete(soundEmitterId);
|
||||
|
||||
@@ -233,6 +237,17 @@ export class RuntimeAudioSystem {
|
||||
}
|
||||
}
|
||||
|
||||
setSoundEmitterVolume(soundEmitterId: string, volume: number) {
|
||||
const soundEmitter = this.soundEmitters.get(soundEmitterId);
|
||||
|
||||
if (soundEmitter === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
soundEmitter.entity.volume = volume;
|
||||
this.updateSoundEmitterVolume(soundEmitter);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
for (const soundEmitterId of this.soundEmitters.keys()) {
|
||||
this.stopSound(soundEmitterId);
|
||||
|
||||
@@ -44,8 +44,11 @@ import {
|
||||
type ControlEffect,
|
||||
type InteractionControlTargetRef,
|
||||
type LightControlTargetRef,
|
||||
type ModelInstanceControlTargetRef,
|
||||
type RuntimeResolvedControlChannelValue,
|
||||
type RuntimeResolvedDiscreteControlState
|
||||
type RuntimeResolvedDiscreteControlState,
|
||||
type SceneControlTargetRef,
|
||||
type SoundEmitterControlTargetRef
|
||||
} from "../controls/control-surface";
|
||||
import { buildBoxBrushDerivedMeshData } from "../geometry/box-brush-mesh";
|
||||
import {
|
||||
@@ -476,9 +479,9 @@ export class RuntimeHost {
|
||||
status: "loading",
|
||||
message: null
|
||||
});
|
||||
this.syncResolvedControlStateToRuntime(runtimeScene.control.resolved);
|
||||
this.applyWorld();
|
||||
this.rebuildLocalLights(runtimeScene.localLights);
|
||||
this.syncResolvedControlStateToRuntime(runtimeScene.control.resolved);
|
||||
this.rebuildBrushMeshes(runtimeScene.brushes);
|
||||
this.rebuildModelRenderObjects(
|
||||
runtimeScene.modelInstances,
|
||||
@@ -971,6 +974,7 @@ export class RuntimeHost {
|
||||
pointLight.position.y,
|
||||
pointLight.position.z
|
||||
);
|
||||
group.visible = pointLight.enabled;
|
||||
light.position.set(0, 0, 0);
|
||||
group.add(light);
|
||||
|
||||
@@ -1008,6 +1012,7 @@ export class RuntimeHost {
|
||||
spotLight.position.z
|
||||
);
|
||||
group.quaternion.copy(orientation);
|
||||
group.visible = spotLight.enabled;
|
||||
light.position.set(0, 0, 0);
|
||||
light.target.position.set(0, 1, 0);
|
||||
group.add(light);
|
||||
@@ -1035,12 +1040,37 @@ export class RuntimeHost {
|
||||
state: RuntimeResolvedDiscreteControlState
|
||||
) {
|
||||
switch (state.type) {
|
||||
case "actorPresence":
|
||||
this.applyActorPresenceControl(state.target.actorId, state.value);
|
||||
return;
|
||||
case "modelVisibility":
|
||||
this.applyModelInstanceVisibilityControl(state.target, state.value);
|
||||
return;
|
||||
case "soundPlayback":
|
||||
this.applySoundPlaybackControl(state.target, state.value);
|
||||
return;
|
||||
case "modelAnimationPlayback":
|
||||
this.applyModelAnimationPlaybackControl(
|
||||
state.target,
|
||||
state.clipName,
|
||||
state.loop
|
||||
);
|
||||
return;
|
||||
case "lightEnabled":
|
||||
this.applyLightEnabledControl(state.target, state.value);
|
||||
return;
|
||||
case "lightColor":
|
||||
this.applyLightColorControl(state.target, state.value);
|
||||
return;
|
||||
case "interactionEnabled":
|
||||
this.applyInteractionEnabledControl(state.target, state.value);
|
||||
return;
|
||||
case "ambientLightColor":
|
||||
this.applyAmbientLightColorControl(state.target, state.value);
|
||||
return;
|
||||
case "sunLightColor":
|
||||
this.applySunLightColorControl(state.target, state.value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1054,6 +1084,47 @@ export class RuntimeHost {
|
||||
channelValue.value
|
||||
);
|
||||
return;
|
||||
case "soundVolume":
|
||||
this.applySoundVolumeControl(
|
||||
channelValue.descriptor.target,
|
||||
channelValue.value
|
||||
);
|
||||
return;
|
||||
case "ambientLightIntensity":
|
||||
this.applyAmbientLightIntensityControl(
|
||||
channelValue.descriptor.target,
|
||||
channelValue.value
|
||||
);
|
||||
return;
|
||||
case "sunLightIntensity":
|
||||
this.applySunLightIntensityControl(
|
||||
channelValue.descriptor.target,
|
||||
channelValue.value
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private mutateRuntimeLightState(
|
||||
target: LightControlTargetRef,
|
||||
mutate: (
|
||||
light:
|
||||
| RuntimeSceneDefinition["localLights"]["pointLights"][number]
|
||||
| RuntimeSceneDefinition["localLights"]["spotLights"][number]
|
||||
) => void
|
||||
) {
|
||||
if (this.runtimeScene === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const lights =
|
||||
target.entityKind === "pointLight"
|
||||
? this.runtimeScene.localLights.pointLights
|
||||
: this.runtimeScene.localLights.spotLights;
|
||||
const light = lights.find((candidate) => candidate.entityId === target.entityId);
|
||||
|
||||
if (light !== undefined) {
|
||||
mutate(light);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1061,6 +1132,10 @@ export class RuntimeHost {
|
||||
target: LightControlTargetRef,
|
||||
enabled: boolean
|
||||
) {
|
||||
this.mutateRuntimeLightState(target, (light) => {
|
||||
light.enabled = enabled;
|
||||
});
|
||||
|
||||
const renderObjects = this.localLightObjects.get(target.entityId);
|
||||
|
||||
if (renderObjects === undefined) {
|
||||
@@ -1074,6 +1149,10 @@ export class RuntimeHost {
|
||||
target: LightControlTargetRef,
|
||||
intensity: number
|
||||
) {
|
||||
this.mutateRuntimeLightState(target, (light) => {
|
||||
light.intensity = intensity;
|
||||
});
|
||||
|
||||
const renderObjects = this.localLightObjects.get(target.entityId);
|
||||
|
||||
if (renderObjects === undefined) {
|
||||
@@ -1083,6 +1162,165 @@ export class RuntimeHost {
|
||||
renderObjects.light.intensity = intensity;
|
||||
}
|
||||
|
||||
private applyLightColorControl(target: LightControlTargetRef, colorHex: string) {
|
||||
this.mutateRuntimeLightState(target, (light) => {
|
||||
light.colorHex = colorHex;
|
||||
});
|
||||
|
||||
const renderObjects = this.localLightObjects.get(target.entityId);
|
||||
|
||||
if (renderObjects === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
renderObjects.light.color.set(colorHex);
|
||||
}
|
||||
|
||||
private applyAmbientLightIntensityControl(
|
||||
_target: SceneControlTargetRef,
|
||||
intensity: number
|
||||
) {
|
||||
if (this.runtimeScene === null || this.currentWorld === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runtimeScene.world.ambientLight.intensity = intensity;
|
||||
this.currentWorld.ambientLight.intensity = intensity;
|
||||
this.applyDayNightLighting();
|
||||
}
|
||||
|
||||
private applyAmbientLightColorControl(
|
||||
_target: SceneControlTargetRef,
|
||||
colorHex: string
|
||||
) {
|
||||
if (this.runtimeScene === null || this.currentWorld === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runtimeScene.world.ambientLight.colorHex = colorHex;
|
||||
this.currentWorld.ambientLight.colorHex = colorHex;
|
||||
this.applyDayNightLighting();
|
||||
}
|
||||
|
||||
private applySunLightIntensityControl(
|
||||
_target: SceneControlTargetRef,
|
||||
intensity: number
|
||||
) {
|
||||
if (this.runtimeScene === null || this.currentWorld === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runtimeScene.world.sunLight.intensity = intensity;
|
||||
this.currentWorld.sunLight.intensity = intensity;
|
||||
this.applyDayNightLighting();
|
||||
}
|
||||
|
||||
private applySunLightColorControl(
|
||||
_target: SceneControlTargetRef,
|
||||
colorHex: string
|
||||
) {
|
||||
if (this.runtimeScene === null || this.currentWorld === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.runtimeScene.world.sunLight.colorHex = colorHex;
|
||||
this.currentWorld.sunLight.colorHex = colorHex;
|
||||
this.applyDayNightLighting();
|
||||
}
|
||||
|
||||
private applyModelInstanceVisibilityControl(
|
||||
target: ModelInstanceControlTargetRef,
|
||||
visible: boolean
|
||||
) {
|
||||
if (this.runtimeScene !== null) {
|
||||
const modelInstance =
|
||||
this.runtimeScene.modelInstances.find(
|
||||
(candidate) => candidate.instanceId === target.modelInstanceId
|
||||
) ?? null;
|
||||
|
||||
if (modelInstance !== null) {
|
||||
modelInstance.visible = visible;
|
||||
}
|
||||
}
|
||||
|
||||
const renderGroup = this.modelRenderObjects.get(target.modelInstanceId);
|
||||
|
||||
if (renderGroup !== undefined) {
|
||||
renderGroup.visible = visible;
|
||||
}
|
||||
}
|
||||
|
||||
private applyModelAnimationPlaybackControl(
|
||||
target: ModelInstanceControlTargetRef,
|
||||
clipName: string | null,
|
||||
loop: boolean | undefined
|
||||
) {
|
||||
if (this.runtimeScene !== null) {
|
||||
const modelInstance =
|
||||
this.runtimeScene.modelInstances.find(
|
||||
(candidate) => candidate.instanceId === target.modelInstanceId
|
||||
) ?? null;
|
||||
|
||||
if (modelInstance !== null) {
|
||||
modelInstance.animationClipName = clipName ?? undefined;
|
||||
modelInstance.animationAutoplay = clipName !== null;
|
||||
modelInstance.animationLoop = clipName === null ? undefined : loop;
|
||||
}
|
||||
}
|
||||
|
||||
if (clipName === null) {
|
||||
this.applyStopAnimationAction(target.modelInstanceId);
|
||||
return;
|
||||
}
|
||||
|
||||
this.applyPlayAnimationAction(target.modelInstanceId, clipName, loop);
|
||||
}
|
||||
|
||||
private applySoundPlaybackControl(
|
||||
target: SoundEmitterControlTargetRef,
|
||||
playing: boolean,
|
||||
link: InteractionLink | null = null
|
||||
) {
|
||||
if (this.runtimeScene !== null) {
|
||||
const soundEmitter =
|
||||
this.runtimeScene.entities.soundEmitters.find(
|
||||
(candidate) => candidate.entityId === target.entityId
|
||||
) ?? null;
|
||||
|
||||
if (soundEmitter !== null) {
|
||||
soundEmitter.autoplay = playing;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.audioSystem.hasSoundEmitter(target.entityId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (playing) {
|
||||
this.audioSystem.playSound(target.entityId, link);
|
||||
} else {
|
||||
this.audioSystem.stopSound(target.entityId);
|
||||
}
|
||||
}
|
||||
|
||||
private applySoundVolumeControl(
|
||||
target: SoundEmitterControlTargetRef,
|
||||
volume: number
|
||||
) {
|
||||
if (this.runtimeScene !== null) {
|
||||
const soundEmitter =
|
||||
this.runtimeScene.entities.soundEmitters.find(
|
||||
(candidate) => candidate.entityId === target.entityId
|
||||
) ?? null;
|
||||
|
||||
if (soundEmitter !== null) {
|
||||
soundEmitter.volume = volume;
|
||||
}
|
||||
}
|
||||
|
||||
this.audioSystem.setSoundEmitterVolume(target.entityId, volume);
|
||||
}
|
||||
|
||||
private applyInteractionEnabledControl(
|
||||
target: InteractionControlTargetRef,
|
||||
enabled: boolean
|
||||
@@ -1150,20 +1388,26 @@ export class RuntimeHost {
|
||||
this.applyActorPresenceControl(effect.target.actorId, effect.active);
|
||||
break;
|
||||
case "playModelAnimation":
|
||||
this.applyPlayAnimationAction(
|
||||
effect.target.modelInstanceId,
|
||||
this.applyModelAnimationPlaybackControl(
|
||||
effect.target,
|
||||
effect.clipName,
|
||||
effect.loop
|
||||
);
|
||||
break;
|
||||
case "stopModelAnimation":
|
||||
this.applyStopAnimationAction(effect.target.modelInstanceId);
|
||||
this.applyModelAnimationPlaybackControl(effect.target, null, undefined);
|
||||
break;
|
||||
case "setModelInstanceVisible":
|
||||
this.applyModelInstanceVisibilityControl(effect.target, effect.visible);
|
||||
break;
|
||||
case "playSound":
|
||||
this.audioSystem.playSound(effect.target.entityId, link);
|
||||
this.applySoundPlaybackControl(effect.target, true, link);
|
||||
break;
|
||||
case "stopSound":
|
||||
this.audioSystem.stopSound(effect.target.entityId);
|
||||
this.applySoundPlaybackControl(effect.target, false);
|
||||
break;
|
||||
case "setSoundVolume":
|
||||
this.applySoundVolumeControl(effect.target, effect.volume);
|
||||
break;
|
||||
case "setInteractionEnabled":
|
||||
this.applyInteractionEnabledControl(effect.target, effect.enabled);
|
||||
@@ -1174,6 +1418,21 @@ export class RuntimeHost {
|
||||
case "setLightIntensity":
|
||||
this.applyLightIntensityControl(effect.target, effect.intensity);
|
||||
break;
|
||||
case "setLightColor":
|
||||
this.applyLightColorControl(effect.target, effect.colorHex);
|
||||
break;
|
||||
case "setAmbientLightIntensity":
|
||||
this.applyAmbientLightIntensityControl(effect.target, effect.intensity);
|
||||
break;
|
||||
case "setAmbientLightColor":
|
||||
this.applyAmbientLightColorControl(effect.target, effect.colorHex);
|
||||
break;
|
||||
case "setSunLightIntensity":
|
||||
this.applySunLightIntensityControl(effect.target, effect.intensity);
|
||||
break;
|
||||
case "setSunLightColor":
|
||||
this.applySunLightColorControl(effect.target, effect.colorHex);
|
||||
break;
|
||||
}
|
||||
|
||||
if (this.runtimeScene === null) {
|
||||
@@ -1498,7 +1757,11 @@ export class RuntimeHost {
|
||||
modelInstance.animationClipName
|
||||
);
|
||||
if (clip) {
|
||||
mixer.clipAction(clip).play();
|
||||
const action = mixer.clipAction(clip);
|
||||
action.loop =
|
||||
modelInstance.animationLoop === false ? LoopOnce : LoopRepeat;
|
||||
action.clampWhenFinished = modelInstance.animationLoop === false;
|
||||
action.reset().play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,6 +274,7 @@ export interface RuntimeSceneExit {
|
||||
|
||||
export interface RuntimePointLight {
|
||||
entityId: string;
|
||||
enabled: boolean;
|
||||
position: Vec3;
|
||||
colorHex: string;
|
||||
intensity: number;
|
||||
@@ -282,6 +283,7 @@ export interface RuntimePointLight {
|
||||
|
||||
export interface RuntimeSpotLight {
|
||||
entityId: string;
|
||||
enabled: boolean;
|
||||
position: Vec3;
|
||||
direction: Vec3;
|
||||
colorHex: string;
|
||||
@@ -305,6 +307,7 @@ export interface RuntimeModelInstance {
|
||||
scale: Vec3;
|
||||
animationClipName?: string;
|
||||
animationAutoplay?: boolean;
|
||||
animationLoop?: boolean;
|
||||
}
|
||||
|
||||
export interface RuntimePathPoint {
|
||||
@@ -676,7 +679,8 @@ function buildRuntimeModelInstance(
|
||||
rotationDegrees: cloneVec3(modelInstance.rotationDegrees),
|
||||
scale: cloneVec3(modelInstance.scale),
|
||||
animationClipName: modelInstance.animationClipName,
|
||||
animationAutoplay: modelInstance.animationAutoplay
|
||||
animationAutoplay: modelInstance.animationAutoplay,
|
||||
animationLoop: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -884,6 +888,50 @@ function buildRuntimeControlSurface(
|
||||
const resolved = createEmptyRuntimeResolvedControlState();
|
||||
const defaultSource = createDefaultResolvedControlSource();
|
||||
const seenActorIds = new Set<string>();
|
||||
const sceneTarget = createActiveSceneControlTargetRef();
|
||||
const ambientLightDescriptor =
|
||||
createAmbientLightIntensityControlChannelDescriptor({
|
||||
target: sceneTarget,
|
||||
defaultValue: document.world.ambientLight.intensity
|
||||
});
|
||||
const sunLightDescriptor = createSunLightIntensityControlChannelDescriptor({
|
||||
target: sceneTarget,
|
||||
defaultValue: document.world.sunLight.intensity
|
||||
});
|
||||
|
||||
targets.push(
|
||||
createControlTargetDescriptor(sceneTarget, [
|
||||
"ambientLightIntensity",
|
||||
"ambientLightColor",
|
||||
"sunLightIntensity",
|
||||
"sunLightColor"
|
||||
])
|
||||
);
|
||||
channels.push(ambientLightDescriptor, sunLightDescriptor);
|
||||
resolved.discrete.push(
|
||||
createResolvedAmbientLightColorState({
|
||||
target: sceneTarget,
|
||||
value: document.world.ambientLight.colorHex,
|
||||
source: defaultSource
|
||||
}),
|
||||
createResolvedSunLightColorState({
|
||||
target: sceneTarget,
|
||||
value: document.world.sunLight.colorHex,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
resolved.channels.push(
|
||||
createResolvedAmbientLightIntensityChannelValue({
|
||||
descriptor: ambientLightDescriptor,
|
||||
value: document.world.ambientLight.intensity,
|
||||
source: defaultSource
|
||||
}),
|
||||
createResolvedSunLightIntensityChannelValue({
|
||||
descriptor: sunLightDescriptor,
|
||||
value: document.world.sunLight.intensity,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
|
||||
for (const npc of collections.npcDefinitions) {
|
||||
if (seenActorIds.has(npc.actorId)) {
|
||||
@@ -907,17 +955,24 @@ function buildRuntimeControlSurface(
|
||||
target,
|
||||
defaultValue: pointLight.intensity
|
||||
});
|
||||
const sourceEntity = document.entities[pointLight.entityId];
|
||||
|
||||
targets.push(
|
||||
createControlTargetDescriptor(target, ["lightEnabled", "lightIntensity"])
|
||||
createControlTargetDescriptor(target, [
|
||||
"lightEnabled",
|
||||
"lightIntensity",
|
||||
"lightColor"
|
||||
])
|
||||
);
|
||||
channels.push(descriptor);
|
||||
resolved.discrete.push(
|
||||
createResolvedLightEnabledState({
|
||||
target,
|
||||
value:
|
||||
sourceEntity?.kind === "pointLight" ? sourceEntity.visible : true,
|
||||
value: pointLight.enabled,
|
||||
source: defaultSource
|
||||
}),
|
||||
createResolvedLightColorState({
|
||||
target,
|
||||
value: pointLight.colorHex,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
@@ -936,16 +991,24 @@ function buildRuntimeControlSurface(
|
||||
target,
|
||||
defaultValue: spotLight.intensity
|
||||
});
|
||||
const sourceEntity = document.entities[spotLight.entityId];
|
||||
|
||||
targets.push(
|
||||
createControlTargetDescriptor(target, ["lightEnabled", "lightIntensity"])
|
||||
createControlTargetDescriptor(target, [
|
||||
"lightEnabled",
|
||||
"lightIntensity",
|
||||
"lightColor"
|
||||
])
|
||||
);
|
||||
channels.push(descriptor);
|
||||
resolved.discrete.push(
|
||||
createResolvedLightEnabledState({
|
||||
target,
|
||||
value: sourceEntity?.kind === "spotLight" ? sourceEntity.visible : true,
|
||||
value: spotLight.enabled,
|
||||
source: defaultSource
|
||||
}),
|
||||
createResolvedLightColorState({
|
||||
target,
|
||||
value: spotLight.colorHex,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
@@ -963,11 +1026,29 @@ function buildRuntimeControlSurface(
|
||||
continue;
|
||||
}
|
||||
|
||||
const target = createSoundEmitterControlTargetRef(soundEmitter.entityId);
|
||||
const descriptor = createSoundVolumeControlChannelDescriptor({
|
||||
target,
|
||||
defaultValue: soundEmitter.volume
|
||||
});
|
||||
|
||||
targets.push(
|
||||
createControlTargetDescriptor(
|
||||
createSoundEmitterControlTargetRef(soundEmitter.entityId),
|
||||
["soundPlayback"]
|
||||
)
|
||||
createControlTargetDescriptor(target, ["soundPlayback", "soundVolume"])
|
||||
);
|
||||
channels.push(descriptor);
|
||||
resolved.discrete.push(
|
||||
createResolvedSoundPlaybackState({
|
||||
target,
|
||||
value: soundEmitter.autoplay,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
resolved.channels.push(
|
||||
createResolvedSoundVolumeChannelValue({
|
||||
descriptor,
|
||||
value: soundEmitter.volume,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1014,21 +1095,42 @@ function buildRuntimeControlSurface(
|
||||
authoredModelInstance === undefined
|
||||
? undefined
|
||||
: document.assets[authoredModelInstance.assetId];
|
||||
const target = createModelInstanceControlTargetRef(modelInstance.instanceId);
|
||||
const hasAnimationPlayback =
|
||||
asset !== undefined &&
|
||||
asset.kind === "model" &&
|
||||
asset.metadata.animationNames.length > 0;
|
||||
const capabilities: Array<"animationPlayback" | "modelVisibility"> = [
|
||||
"modelVisibility"
|
||||
];
|
||||
|
||||
if (
|
||||
asset === undefined ||
|
||||
asset.kind !== "model" ||
|
||||
asset.metadata.animationNames.length === 0
|
||||
) {
|
||||
continue;
|
||||
if (hasAnimationPlayback) {
|
||||
capabilities.unshift("animationPlayback");
|
||||
}
|
||||
|
||||
targets.push(
|
||||
createControlTargetDescriptor(
|
||||
createModelInstanceControlTargetRef(modelInstance.instanceId),
|
||||
["animationPlayback"]
|
||||
)
|
||||
targets.push(createControlTargetDescriptor(target, capabilities));
|
||||
resolved.discrete.push(
|
||||
createResolvedModelInstanceVisibilityState({
|
||||
target,
|
||||
value: modelInstance.visible,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
|
||||
if (hasAnimationPlayback) {
|
||||
resolved.discrete.push(
|
||||
createResolvedModelAnimationPlaybackState({
|
||||
target,
|
||||
clipName:
|
||||
modelInstance.animationAutoplay === true &&
|
||||
typeof modelInstance.animationClipName === "string"
|
||||
? modelInstance.animationClipName
|
||||
: null,
|
||||
loop: modelInstance.animationLoop,
|
||||
source: defaultSource
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return createRuntimeControlSurfaceDefinition({
|
||||
@@ -1070,6 +1172,7 @@ function buildRuntimeSceneCollections(
|
||||
case "pointLight":
|
||||
localLights.pointLights.push({
|
||||
entityId: entity.id,
|
||||
enabled: entity.visible,
|
||||
position: cloneVec3(entity.position),
|
||||
colorHex: entity.colorHex,
|
||||
intensity: entity.intensity,
|
||||
@@ -1079,6 +1182,7 @@ function buildRuntimeSceneCollections(
|
||||
case "spotLight":
|
||||
localLights.spotLights.push({
|
||||
entityId: entity.id,
|
||||
enabled: entity.visible,
|
||||
position: cloneVec3(entity.position),
|
||||
direction: cloneVec3(entity.direction),
|
||||
colorHex: entity.colorHex,
|
||||
|
||||
Reference in New Issue
Block a user