@hology/core 0.0.264 → 0.0.266
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/effects/sequence/sequence-player.js +1 -1
- package/dist/effects/vfx/gpu-material-uniforms.d.ts +23 -0
- package/dist/effects/vfx/gpu-material-uniforms.js +4 -0
- package/dist/effects/vfx/gpu-sprite-runtime.js +1 -1
- package/dist/effects/vfx/vfx-actor.d.ts +6 -0
- package/dist/effects/vfx/vfx-actor.js +1 -1
- package/dist/effects/vfx/vfx-materializer.d.ts +1 -0
- package/dist/effects/vfx/vfx-materializer.js +1 -1
- package/dist/effects/vfx/vfx-param.js +1 -1
- package/dist/effects/vfx/vfx-render-preparation.d.ts +8 -0
- package/dist/effects/vfx/vfx-render-preparation.js +4 -0
- package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +53 -0
- package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
- package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
- package/dist/gameplay/ai/behavior-tree/behavior-tree.d.ts +33 -0
- package/dist/gameplay/ai/behavior-tree/behavior-tree.js +4 -0
- package/dist/gameplay/ai/behavior-tree/behavior-tree.test.d.ts +2 -0
- package/dist/gameplay/ai/behavior-tree/behavior-tree.test.js +4 -0
- package/dist/gameplay/ai/behavior-tree/bt.d.ts +92 -70
- package/dist/gameplay/ai/behavior-tree/bt.js +1 -1
- package/dist/gameplay/ai/behavior-tree/bt.test.d.ts +2 -0
- package/dist/gameplay/ai/behavior-tree/bt.test.js +4 -0
- package/dist/gameplay/ai/behavior-tree/move.d.ts +1 -0
- package/dist/gameplay/ai/behavior-tree/move.js +1 -1
- package/dist/gameplay/ai/index.d.ts +1 -0
- package/dist/gameplay/ai/index.js +1 -1
- package/dist/gameplay/animation/foot-contact-baker.d.ts +23 -0
- package/dist/gameplay/animation/foot-contact-baker.js +4 -0
- package/dist/gameplay/animation/foot-contact.d.ts +27 -0
- package/dist/gameplay/animation/foot-contact.js +4 -0
- package/dist/gameplay/animation/locomotion-body.d.ts +62 -0
- package/dist/gameplay/animation/locomotion-body.js +4 -0
- package/dist/gameplay/animation/pose-inertialization.d.ts +46 -0
- package/dist/gameplay/animation/pose-inertialization.js +4 -0
- package/dist/gameplay/animation/root-motion.js +1 -1
- package/dist/gameplay/index.d.ts +4 -0
- package/dist/gameplay/index.js +1 -1
- package/dist/gameplay/initiate.js +1 -1
- package/dist/gameplay/input/input-service.d.ts +4 -0
- package/dist/gameplay/input/input-service.js +1 -1
- package/dist/gameplay/rendering-host.d.ts +2 -1
- package/dist/gameplay/rendering-host.js +1 -1
- package/dist/gameplay/services/physics/physics-system.d.ts +7 -0
- package/dist/gameplay/services/physics/physics-system.js +1 -1
- package/dist/gameplay/services/render.d.ts +2 -0
- package/dist/gameplay/services/render.js +1 -1
- package/dist/rendering/webgpu-experimental-backend.d.ts +1 -1
- package/dist/rendering/webgpu-experimental-backend.js +1 -1
- package/dist/rendering.d.ts +4 -2
- package/dist/rendering.js +1 -1
- package/dist/scene/animation-binary.d.ts +6 -0
- package/dist/scene/animation-binary.js +4 -0
- package/dist/scene/asset-resource-loader.d.ts +3 -1
- package/dist/scene/asset-resource-loader.js +1 -1
- package/dist/scene/landscape/landscape-manager.d.ts +4 -1
- package/dist/scene/landscape/landscape-manager.js +1 -1
- package/dist/scene/landscape/landscape-static-draw-sets.d.ts +18 -0
- package/dist/scene/landscape/landscape-static-draw-sets.js +4 -0
- package/dist/scene/materializer.d.ts +2 -0
- package/dist/scene/materializer.js +1 -1
- package/dist/shader/shader.d.ts +8 -0
- package/dist/test/animation-binary.test.d.ts +2 -0
- package/dist/test/animation-binary.test.js +4 -0
- package/dist/test/character-foot-contact.test.d.ts +2 -0
- package/dist/test/character-foot-contact.test.js +4 -0
- package/dist/test/character-inertialization.test.d.ts +2 -0
- package/dist/test/character-inertialization.test.js +4 -0
- package/dist/test/character-movement-solve.test.d.ts +2 -0
- package/dist/test/character-movement-solve.test.js +4 -0
- package/dist/test/foot-contact.test.d.ts +2 -0
- package/dist/test/foot-contact.test.js +4 -0
- package/dist/test/gpu-material-uniforms.test.d.ts +2 -0
- package/dist/test/gpu-material-uniforms.test.js +4 -0
- package/dist/test/gpu-sprite-pipeline-cache.test.d.ts +2 -0
- package/dist/test/gpu-sprite-pipeline-cache.test.js +4 -0
- package/dist/test/input.test.js +1 -1
- package/dist/test/landscape-static-draw-sets.test.d.ts +2 -0
- package/dist/test/landscape-static-draw-sets.test.js +4 -0
- package/dist/test/locomotion-body.test.d.ts +2 -0
- package/dist/test/locomotion-body.test.js +4 -0
- package/dist/test/physics-ray-object.test.d.ts +2 -0
- package/dist/test/physics-ray-object.test.js +4 -0
- package/dist/test/pose-inertialization.test.d.ts +2 -0
- package/dist/test/pose-inertialization.test.js +4 -0
- package/dist/test/renderer-loading.test.d.ts +2 -0
- package/dist/test/renderer-loading.test.js +4 -0
- package/dist/test/rendering-host.test.js +1 -1
- package/dist/test/sequence-property-parameters.test.js +1 -1
- package/dist/test/sequence-vfx.test.js +1 -1
- package/dist/test/vfx-render-preparation.test.d.ts +2 -0
- package/dist/test/vfx-render-preparation.test.js +4 -0
- package/dist/utils/structs.d.ts +4 -0
- package/dist/utils/structs.js +4 -0
- package/package.json +4 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{BehaviorSubject as e,Subject as t}from"rxjs";import*as s from"three";import{AnimationMixer as a,Color as i,Euler as r,Object3D as n,Quaternion as o,Vector2 as l,Vector3 as c,Vector4 as h}from"three";import{VisualEffect as u}from"../../effects/vfx/vfx-param.js";import{hashVfxPreviewSeed as p}from"../../effects/vfx/seeded-random.js";import{BaseActor as d}from"../../gameplay/actors/actor.js";import f from"../../gameplay/actors/builtin/index.js";import{Prefab as m,PrefabOf as y}from"../../scene/objects/prefab.js";import{SerializedParamType as v}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as g,deserializeCustomParamValue as C,deserializeCustomParamValueSync as A}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as S}from"./audio-parameters.js";import{getMaterialSubTrackMatchMode as b,getMaterialSubTrackTarget as w,Sequence as P,isSequenceData as k}from"./sequence-data.js";import{getSequenceSubTrackDefinition as x,getSequenceTrackDefinition as T}from"./sequence-definitions.js";import{applyInterpolation as I,evaluateCustomParamValueKeyframes as M,evaluateNumericKeyframes as q,findKeyframeSpan as B}from"./sequence-value-lane.js";import{evaluateTransformPositionSpan as O}from"./sequence-transform.js";import{applyAnimationClipRootMotionAxisMask as F,buildRetimedAnimationClip as V,getAnimationClipRetimingSignature as E,isAnimationClipUsingRetiming as j}from"./sequence-animation-retiming.js";import*as L from"three/addons/utils/SkeletonUtils.js";import{CharacterAnimationComponent as _,getCharacterMovementLike as R}from"../../gameplay/actors/index.js";import{RootMotionClip as D}from"../../gameplay/animation/root-motion.js";import{markMaterialUniformValuesNeedUpdate as K}from"../../rendering/node-material-webgpu-resolver.js";import{getAnimationClipRigId as $,getAnimationRigIdFromObject as G,setAnimationClipRigId as N}from"../../gameplay/animation/retarget.js";import{hashCameraShakeSeed as U}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as W,shaderGraphPostProcessWeightUniformName as Q}from"../../shader/graph/index.js";export var SequencePlaybackState;!function(e){e.Stopped="stopped",e.Playing="playing",e.Paused="paused"}(SequencePlaybackState||(SequencePlaybackState={}));export class SequencePlayer{constructor(){this._state=new e(SequencePlaybackState.Stopped),this._time=new e(0),this._duration=0,this._timescale=1,this._loop=!1,this._externalTimeControl=!1,this._inEditor=!1,this.bindings=new Map,this.roleBindings=new Map,this.sequenceData=null,this.onComplete=new t,this.onLoop=new t,this.vfxCollisionEvent={trackId:"",clipId:"",vfxAssetId:"",emitterId:"",emitterName:"",position:new s.Vector3,normal:new s.Vector3},this.onTimeUpdate=this._time.asObservable(),this.onStateChange=this._state.asObservable(),this.loopCount=0,this.viewController=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.sequenceCameras=new Map,this.cameraPlayables=new Map,this.cameraBlendCamera=null,this.cameraBlendSource=null,this.cameraBlendOutSource=null,this.cameraOverrideHandle=null,this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null,this.activeCameraShakeClipKeys=new Set,this.nextCameraShakeClipKeys=new Set,this.activePostProcessClips=new Map,this.nextPostProcessClipKeys=new Set,this.sequenceLights=new Map,this.lightPlayables=new Map,this.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,this.externalRootMotionInterpolants=new WeakMap,this.audioByClip=new Map,this.activeAudioClips=new Set,this.audioGainNodes=new Map,this.audioStartInFlight=new Map,this.lastAudioStartAttemptTime=new Map,this.audioStartRetryIntervalSeconds=.25,this.world=null,this.assetLoader=null,this.actorFactory=null,this.vfxService=null,this.spawnedInstances=new Map,this.activeClips=new Set,this.pendingSpawns=new Set,this.vfxActors=new Map,this.activeVfxClips=new Set,this.locatorMarkers=new Map,this.clearCounter=0,this.propertyPathSegments=new Map,this.propertyResolutionCache=new Map,this.propertySnapshots=new Map,this.materialResolutionCache=new Map,this.materialSnapshots=new Map,this.visibilitySnapshots=new Map,this.audioFilters=new Map,this.audioPannerNodes=new Map,this.firedEvents=new Set,this.sequenceEventSyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e)},this.sequenceEventAsyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e),texture:e=>this.assetLoader?.getTextureByAssetId(e)??null,sampler2DNode:e=>this.assetLoader?.getTextureByAssetId(e)??null,object3D:async e=>{const t=await(this.assetLoader?.getModelByAssetId(e));return t?.scene??null},material:e=>this.assetLoader?.getMaterialByAssetId(e)??null,audioBuffer:e=>this.assetLoader?.getAudioByAssetId(e)??null,visualEffect:async e=>{if(!this.assetLoader||!this.actorFactory)return null;const t=await this.assetLoader.getAsset(e);return t?new u(this.actorFactory,t):null},prefab:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new y(new m(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,s)=>{t&&this.evaluateObjectTrack(e,t,s)},locator:(e,t,s)=>{t&&this.evaluateLocatorTrack(e,t,s)},camera:(e,t,s)=>this.evaluateCameraTrack(e,s),cameraShake:(e,t,s)=>this.evaluateCameraShakeTrack(e,s),postProcess:(e,t,s)=>this.evaluatePostProcessTrack(e,s),light:(e,t,s)=>this.evaluateLightTrack(e,s),audio:(e,t,s)=>this.evaluateAudioTrack(e,s),vfx:(e,t,s)=>this.evaluateVfxTrack(e,s),spawn:(e,t,s)=>this.evaluateSpawnTrack(e,t,s),group:(e,t,s)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,s)}},this.subTrackRuntimeEvaluators={transform:(e,t,s)=>{const a=this.getPlayableObject(t);a&&this.evaluateTransformSubTrack(e,a,s)},animation:(e,t,s)=>this.evaluateAnimationSubTrack(e,t,s),visibility:(e,t,s)=>{const a=this.getPlayableObject(t);a&&this.evaluateVisibilitySubTrack(e,a,s)},parameter:(e,t,s)=>this.evaluateParameterSubTrack(e,t.target||null,s),event:(e,t,s)=>this.evaluateEventSubTrack(e,t.target||null,s)}}get state(){return this._state.value}get time(){return this._time.value}get duration(){return this._duration}get timescale(){return this._timescale}set timescale(e){this._timescale=Math.max(.01,e)}get loop(){return this._loop}set loop(e){this._loop=e}get externalTimeControl(){return this._externalTimeControl}set externalTimeControl(e){this._externalTimeControl=e}get inEditor(){return this._inEditor}set inEditor(e){this._inEditor=e,this.updateLocatorMarkerVisibility()}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,e||this.releaseCameraOverride()}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId!==e&&(this._cameraControlTrackId=e,this.releaseCameraOverride())}setViewController(e){this.viewController&&this.viewController!==e&&this.viewController.clearCameraShakeContributionsForOwner(this),this.viewController=e}setWorld(e){this.world!==e&&(this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearSequenceLights(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.world=e,this.clearCounter++,this.vfxActors.clear(),this.spawnedInstances.clear(),this.bindings.clear(),this.activeClips.clear(),this.activeVfxClips.clear(),this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear(),this.loadingAudioBuffers.clear(),this.audioFilters.clear(),this.audioPannerNodes.clear(),this.pendingSpawns.clear(),this.propertyResolutionCache.clear(),this.materialResolutionCache.clear(),this.clearRetimedAnimationClipCache(),this._state.next(SequencePlaybackState.Stopped),this.sequenceData&&this.initializeLocatorBindings())}setAudioListener(e){this.audioListener=e}setAssetLoader(e){if(this.assetLoader=e,this.sequenceData){const e=this.clearCounter;this.preloadSequenceResources(this.sequenceData,e)}}setActorFactory(e){this.actorFactory=e}setVfxService(e){this.vfxService=e}load(e){if(this.stop(),this.clearCounter++,this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearSequenceLights(),this.sequenceData=e,this._duration=e.duration,this._loop=e.loop,this._timescale=e.playbackRate,this.clearRetimedAnimationClipCache(),this.bindings.clear(),this.initializeLocatorBindings(),this.loopCount=0,this.assetLoader){const t=this.clearCounter;this.preloadSequenceResources(e,t)}}preloadSequenceResources(e,t){return Promise.all([this.preloadAudioBuffersForSequence(e,t),this.preloadAnimationClipsForSequence(e,t)]).then(()=>{})}getAudioAssetIdsForSequence(e){const t=new Set;for(const s of e.tracks){if("audio"!==s.type)continue;const e=s;for(const s of e.clips??[])s.audioAssetId&&t.add(s.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const s=this.getAudioAssetIdsForSequence(e);0!==s.length&&await Promise.all(s.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let s=this.loadingAudioBuffers.get(e);s||(s=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,s));try{const a=await s;if(t!==this.clearCounter)return;this.audioBuffers.set(e,a)}catch(e){}finally{this.loadingAudioBuffers.get(e)===s&&this.loadingAudioBuffers.delete(e)}}))}async preloadAnimationClipsForSequence(e,t){this.assetLoader&&t===this.clearCounter&&await this.prepareAnimationClipsForBindings(e,t)}async prepare(){if(!this.sequenceData||!this.assetLoader)return;this.resolveBindings();const e=this.clearCounter;await Promise.all([this.prepareAnimationClipsForBindings(this.sequenceData,e),this.prepareVisualEffectsForSequence(this.sequenceData,e)])}async prepareVisualEffectsForSequence(e,t){if(await this.preloadVisualEffectsForSequence(e,t),t!==this.clearCounter||!this.vfxService||!this.world)return;const s=[];for(const t of oe(e.tracks))if("vfx"===t.type&&!t.muted)for(const e of t.clips??[])null!=e.vfxAssetId&&s.push({track:t,clip:e,key:this.getVfxClipKey(t,e)});await Promise.all(s.map(({track:e,clip:t,key:s})=>this.ensureVfxActor(e,t,s)))}async preloadVisualEffectsForSequence(e,t){if(!this.world||!this.actorFactory)return;const s=new Set;for(const t of oe(e.tracks))if("vfx"===t.type)for(const e of t.clips??[])null!=e.vfxAssetId&&s.add(e.vfxAssetId);if(0===s.size)return;const a=await Promise.all([...s].map(e=>this.assetLoader.getAsset(e)));if(t!==this.clearCounter)return;const i=a.filter(e=>null!=e&&null!=e.vfx).map(e=>new u(this.actorFactory,e));await this.world.preloadVisualEffects(i)}async prepareAnimationClipsForBindings(e,t){const s=[];for(const a of oe(e.tracks)){if(!("subTracks"in a))continue;const e=this.bindings.get(a.id),i=null==e?null:this.getPlayableObject(e);if(null==i)continue;const r=G(i);for(const e of a.subTracks)if("animation"===e.type)for(const a of e.clips){if(t!==this.clearCounter)return;if(null!=a.animationClipAssetId){const e=this.animationClipCacheKey(a.animationClipAssetId,r);s.push(this.ensureAnimationClip(a.animationClipAssetId,r).then(s=>{null!=s&&t===this.clearCounter&&j(a)&&(this.getPlayableAnimationClip(e,s,a,!1),a.rootMotion&&this.getPlayableAnimationClip(e,s,a,!0))}))}}}await Promise.all(s)}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const s of oe(this.sequenceData.tracks))"object"!==s.type||s.targetId!==e||s.role||this.createBinding(s,t)}unbindObject(e){if(this.sequenceData)for(const t of oe(this.sequenceData.tracks))"object"!==t.type||t.targetId!==e||t.role||this.removeBinding(t.id)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=le(e);if(!t||!this.sequenceData)return[];const s=[];for(const e of oe(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(le(e.bindingId)!==t)continue;const a=this.bindings.get(e.id),i=a?this.getPlayableObject(a):null;i&&(i.updateWorldMatrix(!0,!1),s.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:i.getWorldPosition(new c),rotation:i.getWorldQuaternion(new o),scale:i.getWorldScale(new c)}))}return s}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of oe(this.sequenceData.tracks)){if("locator"!==e.type||this.bindings.has(e.id))continue;const t=new n;t.name=e.name||"Locator",t.userData.sequenceLocatorTrackId=e.id,this.world?.scene&&null==t.parent&&this.world.scene.add(t);const s=ce(e.name);s.visible=this._inEditor,t.add(s),this.locatorMarkers.set(e.id,s),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())he(e);for(const e of this.bindings.values()){if("locator"!==e.track.type)continue;const t=this.getPlayableObject(e);t?.parent&&t.removeFromParent()}this.locatorMarkers.clear()}updateLocatorMarkerVisibility(){for(const e of this.locatorMarkers.values())e.visible=this._inEditor}disableLocatorInteraction(e){e.traverse(e=>{e.raycast=()=>{}})}resolveTrackBinding(e){if("object"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("spawn"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("group"===e.type)for(const t of e.childTracks)this.resolveTrackBinding(t)}createBinding(e,t){const s=t instanceof d?t.object:t,i=this.bindings.get(e.id),r=null!=i?i.target instanceof d?i.target.object:i.target:null,n=null!=i&&i.target===t&&r===s,o=e.subTracks.some(e=>"animation"===e.type);null==i||n||this.releaseBinding(i);const l=n?i:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,n||(l.originalTransform={position:s.position.clone(),rotation:s.rotation.clone(),scale:s.scale.clone()},l.originalParent=s.parent),o&&null==l.mixer?l.mixer=new a(s):o||(l.mixer=void 0),this.bindings.set(e.id,l)}removeBinding(e){const t=this.bindings.get(e);t&&(this.releaseBinding(t),this.bindings.delete(e))}releaseBinding(e){this.clearExternalRootMotionPreview(e);for(const[t,s]of e.activeActions.entries())e.charAnimActionKeys?.has(t)||s.stop();e.activeActions.clear(),e.mixer?.stopAllAction(),e.charAnimComponent?.stopSequenceAnimation(),e.charAnimComponent=void 0,e.charAnimActionKeys?.clear()}play(){this._state.value!==SequencePlaybackState.Playing&&this.sequenceData&&(this._state.value===SequencePlaybackState.Stopped&&(this._time.next(0),this.loopCount=0,this.resolveBindings(),this.captureOriginalTransforms()),this._state.next(SequencePlaybackState.Playing),this.evaluate(this._time.value),this.resumeVfx())}pause(){this._state.value===SequencePlaybackState.Playing&&(this._state.next(SequencePlaybackState.Paused),this.pauseAudio(),this.pauseVfx())}pauseAudio(){for(const e of this.audioByClip.values())e.pause()}pauseVfx(){for(const e of this.vfxActors.values())e.pause()}resumeVfx(){for(const[e,t]of this.vfxActors.entries())(this.activeVfxClips.has(e)||t.getParticleCount()>0)&&t.play()}cancel(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreAllVisibilitySnapshots(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects();for(const e of this.sequenceLights.values())e.visible=!1}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreAllVisibilitySnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects();for(const e of this.sequenceLights.values())e.visible=!1}restart(){this.stop(),this.play()}seek(e){const t=Math.max(0,Math.min(e,this._duration));t<this._time.value&&this.resetVfxForTimeReset(t),this._time.next(t),this.evaluate(t)}update(e){if(this._state.value!==SequencePlaybackState.Playing)return;if(!this.sequenceData)return;if(this._externalTimeControl){for(const t of this.bindings.values())t.charAnimComponent?t.charAnimComponent.evaluateExternalPose(e*this._timescale):t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale);return}const t=this._time.value+e*this._timescale;if(t>=this._duration){if(!this._loop)return this._time.next(this._duration),this.evaluate(this._duration),this.deactivateCharacterAnimationActions(),this.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreAllVisibilitySnapshots(),this._state.next(SequencePlaybackState.Stopped),void this.onComplete.next();{this.loopCount++;const e=t%this._duration;this.resetVfxForTimeReset(e),this._time.next(e),this.firedEvents.clear(),this.onLoop.next(this.loopCount)}}else this._time.next(t);this.evaluate(this._time.value);for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale)}evaluate(e){if(this.sequenceData){this.nextCameraShakeClipKeys.clear(),this.nextPostProcessClipKeys.clear();for(const e of this.sequenceLights.values())e.visible=!1;for(const t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===t.type||"light"===t.type||"spawn"===t.type||"vfx"===t.type)){const e=this.bindings.get(t.id);this.updateTrackParenting(t,e)}this.evaluateTrack(t,e)}this.updateCameraControl(e),this.syncCameraShakeContributions(),this.syncPostProcessEffects()}}evaluateTrack(e,t){if(e.muted)return;const s=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[T(e.type).runtimeEvaluator])(e,s,t)}evaluateObjectTrack(e,t,s){this.evaluateSubTracks(e.subTracks,t,s)}evaluateLocatorTrack(e,t,s){this.evaluateSubTracks(e.subTracks,t,s)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=oe(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,s){this._externalTimeControl&&this.beginExternalRootMotionPreview(t);for(const a of e){if(a.muted)continue;(0,this.subTrackRuntimeEvaluators[x(a.type).runtimeEvaluator])(a,t,s)}this._externalTimeControl&&this.applyExternalRootMotionPreview(t)}beginExternalRootMotionPreview(e){const t=e.externalRootMotionPreview;if(!t)return;const s=this.getPlayableObject(e);s&&s.position.sub(t.appliedOffset),t.appliedOffset.set(0,0,0),t.sampledOffset.set(0,0,0),t.root=null}sampleExternalRootMotionPreview(e,t,a,i){if(!t.motionTrack)return;let r=this.externalRootMotionInterpolants.get(t);r||(r=t.motionTrack.InterpolantFactoryMethodSmooth([]),this.externalRootMotionInterpolants.set(t,r));const n=e.externalRootMotionPreview??(e.externalRootMotionPreview={appliedOffset:new c,sampledOffset:new c,root:null}),o=Math.max(0,Math.min(i,t.duration)),l=Math.max(o,Math.min(a,t.duration));fe.fromArray(r.evaluate(o)),me.fromArray(r.evaluate(l)),n.sampledOffset.subVectors(me,fe),n.sampledOffset.y=0;const h=this.getPlayableObject(e),u=s.PropertyBinding.parseTrackName(t.motionTrack.name);n.root=h?.getObjectByName(u.nodeName)??h}applyExternalRootMotionPreview(e){const t=e.externalRootMotionPreview,s=this.getPlayableObject(e);t&&s&&t.root&&(t.root.getWorldScale(ye),t.appliedOffset.copy(t.sampledOffset).multiply(ye).applyQuaternion(s.quaternion),s.position.add(t.appliedOffset))}clearExternalRootMotionPreview(e){const t=e.externalRootMotionPreview,s=this.getPlayableObject(e);t&&s&&s.position.sub(t.appliedOffset),e.externalRootMotionPreview=void 0}evaluateTransformSubTrack(e,t,s){const a=e.keyframes;if(0===a.length)return;const{prev:i,next:r,prevIndex:n,nextIndex:o,t:l}=B(a,s);if(i)if(e.components.position&&O(a,n,o,l,t.position),r&&i!==r){const s=I(l,i.interpolation);e.components.rotation&&i.rotation&&r.rotation&&(ve.setFromEuler(Ce.fromArray([...i.rotation,"XYZ"])),ge.setFromEuler(Ae.fromArray([...r.rotation,"XYZ"])),t.quaternion.slerpQuaternions(ve,ge,s)),e.components.scale&&i.scale&&r.scale&&t.scale.lerpVectors(ue.fromArray(i.scale),pe.fromArray(r.scale),s)}else e.components.rotation&&i.rotation&&t.rotation.fromArray([...i.rotation,"XYZ"]),e.components.scale&&i.scale&&t.scale.fromArray(i.scale)}evaluateAnimationSubTrack(e,t,a){if(!t.mixer||!t.activeActions)return;const i=t.target instanceof d?t.target.object:t.target;if(i)for(const r of e.clips){const n=r.startTime+r.duration,o=a>=r.startTime&&a<n,l=`${e.id}-${r.id}`;let c=t.activeActions.get(l),h=!1;if(o){if(!c){h=!0;const e=r.animationClipAssetId;if(null==e)continue;const a=G(i),n=this.animationClipCacheKey(e,a),o=this.animationClips.get(n);if(null==o){this.ensureAnimationClip(e,a);continue}const u=this.prepareAnimationPlayback(n,o,r),p=t;let f=!1;if(t.target instanceof d){p.charAnimComponent||(p.charAnimComponent=t.target.getComponent(_)??void 0);const e=p.charAnimComponent;if(null!=e){const s=r.rootMotion?j(r)?this.getPlayableAnimationClip(n,o,r,!0):D.fromClip(u.clip,!1):u.clip;if(this._externalTimeControl)c=e.beginExternalAnimationControl(s,{timeScale:u.timeScale});else if(e.play(s,{inPlace:!r.rootMotion,loop:!1,priority:20,sequenceControlled:!0,timeScale:u.timeScale,fadeTime:r.fadeInDuration??.2,offset:u.startOffset}),c=e.getFullBodyAction(),r.rootMotion){const e=R(t.target);e&&e.setRootMotionAction(c,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(l,c),p.charAnimActionKeys||(p.charAnimActionKeys=new Set),p.charAnimActionKeys.add(l),f=!0}}f||(c=t.mixer.clipAction(u.clip),c.setLoop(s.LoopOnce,1),c.clampWhenFinished=!0,c.timeScale=u.timeScale,u.startOffset>0&&(c.time=u.startOffset),t.activeActions.set(l,c),c.play())}if(c){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const s=this.getAnimationPlaybackLocalTime(r,a),i=Math.min(s,c.getClip().duration);(h||Math.abs(c.time-i)>.001)&&(c.time=i,c.paused=!1,c.play(),e.charAnimComponent?e.charAnimComponent.evaluateExternalPose():t.mixer&&t.mixer.update(0)),r.rootMotion&&c.getClip()instanceof D&&this.sampleExternalRootMotionPreview(t,c.getClip(),i,j(r)?0:r.clipStartOffset)}else e.charAnimComponent?.endExternalControl()}}else c&&this.deactivateAnimationAction(t,l,c)}}deactivateAnimationAction(e,t,s){if(e.activeActions.delete(t),e.charAnimActionKeys?.has(t))return e.charAnimActionKeys.delete(t),void(0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.requestSequenceAnimationRelease(),e.charAnimComponent=void 0));s.stop(),this._externalTimeControl&&e.mixer&&e.mixer.update(0)}deactivateAnimationSubTracks(e,t){for(const s of e)if(!s.muted&&"animation"===s.type)for(const e of s.clips){const a=`${s.id}-${e.id}`,i=t.activeActions.get(a);i&&this.deactivateAnimationAction(t,a,i)}}deactivateCharacterAnimationActions(){for(const e of this.bindings.values())for(const t of[...e.charAnimActionKeys??[]]){const s=e.activeActions.get(t);s?this.deactivateAnimationAction(e,t,s):e.charAnimActionKeys?.delete(t)}}evaluateVisibilitySubTrack(e,t,s){const a=e.keyframes;if(0===a.length)return;let i=a[0];for(const e of a){if(!(e.time<=s))break;i=e}this.visibilitySnapshots.has(t)||this.visibilitySnapshots.set(t,{visible:t.visible}),t.visible=i.visible}evaluatePropertySubTrack(e,t,s){const a=M(e.keyframes,s,{min:e.range?.[0],max:e.range?.[1],stepOnly:X(e)});a&&this.applyResolvedPropertyValue(e,t,a)}evaluateParameterSubTrack(e,t,s){if("audioParameter"===e.type)return;const a=M(e.keyframes,s,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:X(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:z(e)}:{});a&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,a):this.applyResolvedPropertyValue(e,t,a))}evaluateEventSubTrack(e,t,s){if(t instanceof d&&this._state.value===SequencePlaybackState.Playing)for(const a of e.events){const i=`${e.id}-${a.id}`;if(s>=a.time&&!this.firedEvents.has(i)){if(this.firedEvents.add(i),a.editorOnly&&!this._inEditor)continue;if(!a.functionName)continue;const e=t[a.functionName];"function"==typeof e?this.invokeSequenceEvent(t,a.functionName,e,a.arguments??[]):console.warn(`Sequence event method '${a.functionName}' not found on actor`)}else a.time>s&&this.firedEvents.delete(i)}}evaluateCameraTrack(e,t){const s=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,s),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,s),t),s.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const s of e.clips??[]){if(!this.isCameraShakeClipActive(s,t))continue;const e=t-s.startTime,a=s.id;this.nextCameraShakeClipKeys.add(a),this.viewController.setCameraShakeContribution(this,a,s,e,s.seed??U(s.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader){for(const s of e.clips??[]){if(!this.isPostProcessClipActive(s,t))continue;const a=this.getPostProcessClipKey(e,s);this.nextPostProcessClipKeys.add(a),this.ensurePostProcessClipEffect(e,s,a);const i=this.activePostProcessClips.get(a);i?.handle&&(i.handle.stage=e.stage,i.handle.priority=e.priority,i.handle.enabled=!0,this.applyPostProcessClipWeight(i.handle,s,t))}this.evaluatePostProcessMaterialSubTracks(e,t)}}evaluatePostProcessMaterialSubTracks(e,t){for(const s of e.subTracks){if(s.muted||"material"!==s.type)continue;const a=M(s.keyframes,t,{min:s.range?.[0],max:s.range?.[1],stepOnly:z(s)});a&&this.applyPostProcessMaterialValue(e.id,s,a)}}evaluateLightTrack(e,t){const s=this.ensureSequenceLight(e);if(this.applyLightTrackSettings(e,s),s.visible=(e.clips??[]).some(e=>t>=e.startTime&&t<e.startTime+e.duration),!s.visible)return;let a=this.lightPlayables.get(e.id);a||(a={target:s},this.lightPlayables.set(e.id,a)),this.evaluateSubTracks(e.subTracks,a,t)}ensureSequenceLight(e){let t=this.sequenceLights.get(e.id);return t?null==t.parent&&this.world?.scene.add(t):(t=new s.PointLight,t.name=e.name||"Sequence Point Light",t.userData.sequenceLightTrackId=e.id,t.visible=!1,this.sequenceLights.set(e.id,t),this.world?.scene.add(t)),t}applyLightTrackSettings(e,t){t.color.set(e.color??"#ffffff"),t.intensity=Math.max(0,e.intensity??10),t.distance=Math.max(0,e.distance??10),t.decay=Math.max(0,e.decay??2),t.castShadow=e.castShadow??!1,t.userData.volumetricIntensity=Math.max(0,e.volumetricIntensity??0)}clearSequenceLights(){for(const e of this.sequenceLights.values())e.removeFromParent(),e.dispose();this.sequenceLights.clear(),this.lightPlayables.clear()}applyPostProcessMaterialValue(e,t,s){if("shaderUniform"===w(t)&&t.uniformName)for(const a of this.activePostProcessClips.values()){if(a.trackId!==e||!a.handle)continue;const i=a.handle.material,r=i.uniforms?.[t.uniformName];if(!r)continue;const n=Z(r.value,s);n.applied&&(r.value=n.value,i.uniformsNeedUpdate=!0,K(i))}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,s){const a=t.shaderGraphAssetId;if(!a)return void this.releasePostProcessClipEffect(s);const i=JSON.stringify(t.shaderGraphParams??{}),r=this.activePostProcessClips.get(s);if(r?.assetId===a&&r.paramsSignature===i)return;this.releasePostProcessClipEffect(s);const n={key:s,trackId:e.id,clipId:t.id,assetId:a,paramsSignature:i,version:this.clearCounter};this.activePostProcessClips.set(s,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,s){if(this.assetLoader&&this.viewController)try{const a=await this.assetLoader.getShaderGraphByAssetId(s.assetId);if(!this.isPostProcessClipEntryCurrent(s))return;if("postProcess"!==a.target)return console.warn(`Sequence post-process clip references shader graph "${s.assetId}" with target "${a.target}"`),void this.releasePostProcessClipEffect(s.key);const i=await this.assetLoader.prepareShaderGraphParameters(a,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(s))return;const r=W(a,{parameters:i});if(!this.isPostProcessClipEntryCurrent(s))return void r.dispose();s.handle=this.viewController.addPostProcessEffect(r,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(s.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(s)&&this.releasePostProcessClipEffect(s.key),console.error(`Failed to create post-process effect for clip ${t.id}:`,e)}}isPostProcessClipEntryCurrent(e){return this.clearCounter===e.version&&this.activePostProcessClips.get(e.key)===e}applyPostProcessClipWeight(e,t,s){const a=e.material.uniforms?.[Q];null!=a&&(a.value=this.getPostProcessClipWeight(t,s),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const s=Math.max(0,t-e.startTime),a=Math.max(0,e.startTime+e.duration-t);let i=1;const r=Math.max(0,e.fadeInDuration??0);r>0&&(i=Math.min(i,s/r));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(i=Math.min(i,a/n)),Math.max(0,Math.min(1,i))}syncPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.nextPostProcessClipKeys.has(e)||this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}clearPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}releasePostProcessClipEffect(e){const t=this.activePostProcessClips.get(e);if(t&&(this.activePostProcessClips.delete(e),t.handle)){const e=t.handle.material;t.handle.dispose(),e.dispose()}}getCameraPlayable(e,t){let s=this.cameraPlayables.get(e.id);return s?s.target=t:(s={target:t},this.cameraPlayables.set(e.id,s)),s}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const a=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new s.PerspectiveCamera(a.fov??60,this.getCurrentCameraAspect(),a.near??.1,a.far??1e3),t.name=e.name||"Sequence Camera",t.userData.sequenceCameraTrackId=e.id,t.layers.mask=this.viewController?.getBaseCamera().layers.mask??t.layers.mask,this.sequenceCameras.set(e.id,t),this.world?.scene.add(t)}return t}clearSequenceCameras(){this.releaseCameraOverride();for(const e of this.sequenceCameras.values())e.removeFromParent();this.sequenceCameras.clear(),this.cameraPlayables.clear()}applyCameraTrackSettings(e,t){const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=s.fov??60,t.near=s.near??.1,t.far=s.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof s.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof s.PerspectiveCamera&&Number.isFinite(t.aspect)&&t.aspect>0?t.aspect:1}updateCameraControl(e){if(!this._cameraControlEnabled||!this.viewController||!this.sequenceData)return void this.releaseCameraOverride();const t=this.findActiveCameraShot(e);if(t)return void this.updateActiveCameraShot(t,e);const s=this.findBlendOutCameraShot(e);s?this.updateCameraBlendOut(s,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const s of oe(this.sequenceData.tracks)){if("camera"!==s.type||s.muted||!this.isCameraControlTrackEligible(s))continue;const a=s.clips??[];for(const i of a)this.isCameraClipActive(i,e)&&(t={track:s,clip:i,camera:this.ensureSequenceCamera(s),key:this.getCameraClipKey(s,i)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const s of oe(this.sequenceData.tracks)){if("camera"!==s.type||s.muted||!this.isCameraControlTrackEligible(s))continue;const a=s.clips??[];for(const i of a){const a=Math.max(0,i.blendOutDuration??0);if(a<=0)continue;const r=this.getCameraClipEnd(i);e>=r&&e<r+a&&(t={track:s,clip:i,camera:this.ensureSequenceCamera(s),key:this.getCameraClipKey(s,i)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const s=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const a=Math.max(0,e.clip.blendInDuration??0),i=a<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/a,e.clip);i>=1?this.copyCameraState(e.camera,s):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,s,i),s.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const s=this.ensureCameraBlendCamera();if(this.cameraBlendOutClipKey!==e.key){const t=this.activeCameraClipKey===e.key?this.viewController.getSourceCamera():e.camera;this.copyCameraState(t,this.ensureCameraBlendOutSource()),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=e.key}const a=this.getCameraClipEnd(e.clip),i=Math.max(0,e.clip.blendOutDuration??0),r=i<=0?1:this.evaluateCameraBlendAlpha((t-a)/i,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),s,r),s.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new s.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new s.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new s.PerspectiveCamera),this.cameraBlendOutSource}ensureCameraOverride(){this.viewController&&!this.cameraOverrideHandle&&(this.cameraOverrideHandle=this.viewController.pushCameraOverride(this.ensureCameraBlendCamera(),this))}releaseCameraOverride(){this.cameraOverrideHandle?.release(),this.cameraOverrideHandle=null,this.viewController?.releaseCameraOverridesForOwner(this),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null}isCameraClipActive(e,t){return t>=e.startTime&&t<this.getCameraClipEnd(e)}getCameraClipEnd(e){return e.startTime+Math.max(0,e.duration)}isCameraShakeClipActive(e,t){return t>=e.startTime&&t<this.getCameraShakeClipEnd(e)}getCameraShakeClipEnd(e){return e.startTime+Math.max(0,e.duration)}getCameraClipKey(e,t){return`${e.id}-${t.id}`}evaluateCameraBlendAlpha(e,t){return I(Math.max(0,Math.min(1,e)),t.blendInterpolation??"cubic")}syncCameraShakeContributions(){if(!this.viewController)return this.activeCameraShakeClipKeys.clear(),void this.nextCameraShakeClipKeys.clear();for(const e of this.activeCameraShakeClipKeys)this.nextCameraShakeClipKeys.has(e)||this.viewController.removeCameraShakeContribution(this,e);this.activeCameraShakeClipKeys.clear();for(const e of this.nextCameraShakeClipKeys)this.activeCameraShakeClipKeys.add(e);this.nextCameraShakeClipKeys.clear()}clearCameraShakeContributions(){this.activeCameraShakeClipKeys.clear(),this.nextCameraShakeClipKeys.clear(),this.viewController?.clearCameraShakeContributionsForOwner(this)}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(ue)),t.quaternion.copy(e.getWorldQuaternion(ve)),t.scale.copy(e.getWorldScale(pe)),e instanceof s.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect):t.aspect=this.getCurrentCameraAspect(),t.layers.mask=e.layers.mask}blendCameraState(e,t,a,i){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),a.position.lerpVectors(e.getWorldPosition(ue),t.getWorldPosition(pe),i),a.quaternion.slerpQuaternions(e.getWorldQuaternion(ve),t.getWorldQuaternion(ge),i),a.scale.lerpVectors(e.getWorldScale(ue),t.getWorldScale(pe),i),e instanceof s.PerspectiveCamera&&t instanceof s.PerspectiveCamera?(a.fov=e.fov+(t.fov-e.fov)*i,a.near=e.near+(t.near-e.near)*i,a.far=e.far+(t.far-e.far)*i,a.aspect=t.aspect):t instanceof s.PerspectiveCamera?(a.fov=t.fov,a.near=t.near,a.far=t.far,a.aspect=t.aspect):a.aspect=this.getCurrentCameraAspect(),a.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const s=this._state.value===SequencePlaybackState.Playing,a=this.evaluateAudioSubTracks(e,t);e.volume;for(const i of e.clips){const r=i.startTime+i.duration,n=t>=i.startTime&&t<r,o=`${e.id}-${i.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),s){const s=this.audioByClip.get(o);s&&s.isPlaying||this.tryStartAudioClip(e,i,o,t,a)}const r=this.audioByClip.get(o);r&&this.applyAudioParameters(r,e,i,o,t,a)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,s,a,i){if(this.audioStartInFlight.has(s))return;const r=this.lastAudioStartAttemptTime.get(s);if(void 0!==r&&a-r<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(s,a);const n=this.playAudioClip(e,t,s,a,i).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(s)===n&&this.audioStartInFlight.delete(s)});this.audioStartInFlight.set(s,n)}applyAudioParameters(e,t,a,i,r,n){const o=n.volume??1,l=Math.random(),c=a.volumeRandomization?(2*l-1)*a.volumeRandomization:0;let h=1;const u=r-a.startTime;u<a.fadeInDuration&&a.fadeInDuration>0?h=u/a.fadeInDuration:u>a.duration-a.fadeOutDuration&&a.fadeOutDuration>0&&(h=(a.duration-u)/a.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(a.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(a.pitchRandomization){d+=(2*Math.random()-1)*a.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(a.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const a=this.audioListener.context,r=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(i);if(void 0!==o||void 0!==l)c||(c=a.createBiquadFilter(),this.audioFilters.set(i,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),r.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(i)}const h=n.pan;if(!t.spatial&&e instanceof s.Audio&&void 0!==h&&"function"==typeof a.createStereoPanner){let e=this.audioPannerNodes.get(i);e||(e=a.createStereoPanner(),this.audioPannerNodes.set(i,e)),e.pan.value=h,r.push(e)}else{const e=this.audioPannerNodes.get(i);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(i)}}e.setFilters(r)}t.spatial&&e instanceof s.PositionalAudio?this.updatePositionalAudioTransform(e,t,a,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,a,i){let r=null,n=null;const o=a.attachedToTrackId||t.parent?.trackId,l=a.attachmentSocketName||t.parent?.socketName;if(o){const e=this.sequenceData?.tracks.find(e=>e.id===o);if(e){const t=this.getActiveObjectsForTrack(e);if(t.length>0){const e=t[0];if(r=ue,n=ve,e.getWorldPosition(r),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(r),t.getWorldQuaternion(n))}}}}if(r&&n){const t="number"==typeof i?s.MathUtils.clamp(i,0,1):1;if(t<1&&this.audioListener){const e=de;this.audioListener.getWorldPosition(e),r=r.clone().lerp(e,1-t)}e.position.copy(r),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,a,i,r){if(!this.assetLoader||!t.audioAssetId||null==this.audioListener)return;if("suspended"===this.audioListener.context.state)try{await this.audioListener.context.resume()}catch(e){return void console.warn("Failed to resume audio context:",e)}this.stopAudioClip(a);const n=this.clearCounter;try{let i=this.audioBuffers.get(t.audioAssetId);if(!i){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{i=await e,this.audioBuffers.set(t.audioAssetId,i)}finally{this.loadingAudioBuffers.delete(t.audioAssetId)}}if(n!==this.clearCounter)return;const o=this._time.value,l=t.startTime+t.duration;if(!(o>=t.startTime&&o<l))return;const c=Math.max(0,o-t.startTime),h=t.clipStartOffset+c*t.playbackRate;if(h>=i.duration||c>=t.duration)return;let u=this.audioByClip.get(a);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(a),u=void 0),!u){if(p){const e=new s.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new s.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(a,u)}Math.min((t.duration-c)/t.playbackRate,(i.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,i.duration)),u.setLoop(!0),u.setBuffer(i),this.applyAudioParameters(u,e,t,a,o,r),u.isPlaying||u.play()}catch(e){console.error(`Failed to play audio clip ${t.id}:`,e)}}stopAudioClip(e){const t=this.audioByClip.get(e);if(t){try{t.isPlaying&&t.stop()}catch(e){}t.parent&&t.parent.remove(t),this.audioByClip.delete(e)}const s=this.audioGainNodes.get(e);s&&(s.disconnect(),this.audioGainNodes.delete(e));const a=this.audioFilters.get(e);if(a){try{a.disconnect()}catch{}this.audioFilters.delete(e)}const i=this.audioPannerNodes.get(e);if(i){try{i.disconnect()}catch{}this.audioPannerNodes.delete(e)}}stopAllAudio(){for(const e of this.audioByClip.keys())this.stopAudioClip(e);this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear()}evaluateVfxTrack(e,t){if(!this.vfxService||!this.world||!e.clips||0===e.clips.length)return;if(this.shouldPreviewVfxAtSeekTime())return void this.previewVfxTrackAtSeekTime(e,t);const s=new Set,a=new Map,i=!e.parent||null!=this.getTrackParentObject(e);for(const r of e.clips){const n=this.getVfxClipKey(e,r);a.set(n,r),this.isVfxClipActiveAtTime(r,t)&&i&&s.add(n)}const r=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(s.has(t)||r.push(t));for(const e of r)this.activeVfxClips.delete(e);for(const[i,r]of a.entries()){const a=this.vfxActors.get(i);s.has(i)&&!this.activeVfxClips.has(i)?(this.activeVfxClips.add(i),this.ensureVfxActor(e,r,i)):s.has(i)&&a?this.updateVfxTransform(e,a,t):a&&this.applyInactiveVfxClipBehavior(r,a,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}isVfxClipActiveAtTime(e,t){const s=e.startTime+e.duration;return t>=e.startTime&&t<s}shouldPreviewVfxAtSeekTime(){return this._externalTimeControl&&this._inEditor&&this._state.value!==SequencePlaybackState.Playing}previewVfxTrackAtSeekTime(e,t){const s=new Set,a=!e.parent||null!=this.getTrackParentObject(e);for(const i of e.clips){const r=this.getVfxClipKey(e,i),n=this.vfxActors.get(r);this.isVfxClipActiveAtTime(i,t)&&a&&s.add(r),t<i.startTime||!a?n?.clearPreview():n?this.previewVfxActorAtSeekTime(e,i,n,t):this.ensureVfxActor(e,i,r)}for(const t of[...this.activeVfxClips])t.startsWith(`${e.id}-`)&&!s.has(t)&&this.activeVfxClips.delete(t);for(const e of s)this.activeVfxClips.add(e)}previewVfxActorAtSeekTime(e,t,s,a){const i=t.startTime+t.duration;this.updateVfxTransform(e,s,Math.min(a,i)),s.previewAt(a-t.startTime,t.duration,t.endBehavior,t.expireWithinSeconds,p(this.getVfxClipKey(e,t)))}resetVfxForTimeReset(e){const t=new Set;if(this.sequenceData)for(const s of oe(this.sequenceData.tracks))if("vfx"===s.type)for(const a of s.clips??[])this.isVfxClipActiveAtTime(a,e)&&t.add(this.getVfxClipKey(s,a));this.activeVfxClips.clear();for(const[e,s]of this.vfxActors.entries())t.has(e)||(s.restart(),s.stop(),s.pause())}applyInactiveVfxClipBehavior(e,t,s){const a=e.endBehavior??"finish";if("finish"===a)return void t.stop();if("kill"===a)return void t.applyClipEndBehavior(a);const i=e.startTime+e.duration,r=Math.max(s-i,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-r);t.applyClipEndBehavior(a,o)}async ensureVfxActor(e,t,s){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(s)){const a=this.vfxActors.get(s);return!this.isVfxClipActiveAtTime(t,this._time.value)||e.parent&&null==this.getTrackParentObject(e)?void this.activeVfxClips.delete(s):(this.updateVfxTransform(e,a,this._time.value),this.updateTrackParenting(e,this.bindings.get(e.id)),a.restart(),void a.play())}const a=this.clearCounter;try{const i=this._inEditor&&this._externalTimeControl?{backend:"cpu"}:void 0,r=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene,i);if(a!==this.clearCounter)return void(this.world&&this.world.removeActor(r));const{position:n,rotation:o,scale:l}=this.getVfxTransform(e,t.startTime);if(r.object.position.copy(n),r.object.rotation.copy(o),r.object.scale.copy(l),r.onCollision=s=>{if(this._state.value!==SequencePlaybackState.Playing||null==this.onVfxCollision)return;const a=this.vfxCollisionEvent;a.trackId=e.id,a.clipId=t.id,a.vfxAssetId=t.vfxAssetId,a.emitterId=s.emitterId,a.emitterName=s.emitterName,a.position.copy(s.position),a.normal.copy(s.normal),this.onVfxCollision(a)},this.vfxActors.set(s,r),e.parent&&null==this.getTrackParentObject(e))return void this.activeVfxClips.delete(s);this.updateTrackParenting(e,this.bindings.get(e.id)),this.shouldPreviewVfxAtSeekTime()?this.previewVfxActorAtSeekTime(e,t,r,this._time.value):this._state.value===SequencePlaybackState.Playing&&this.isVfxClipActiveAtTime(t,this._time.value)&&r.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const s=new c,a=new r,i=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:r,prevIndex:l,nextIndex:c,t:h}=B(n.keyframes,t);if(n.components.position&&O(n.keyframes,l,c,h,s),e&&(e.rotation&&a.fromArray([...e.rotation,"XYZ"]),e.scale&&i.fromArray(e.scale)),r&&e!==r&&e.time!==r.time){const t=I(h,e.interpolation);if(e.rotation&&r.rotation){ve.setFromEuler(Ce.fromArray([...e.rotation,"XYZ"])),ge.setFromEuler(Ae.fromArray([...r.rotation,"XYZ"]));const s=new o;s.slerpQuaternions(ve,ge,t),a.setFromQuaternion(s)}e.scale&&r.scale&&i.lerpVectors(ue.fromArray(e.scale),pe.fromArray(r.scale),t)}}else s.fromArray(e.position),a.fromArray([...e.rotation,"XYZ"]),i.fromArray(e.scale);return{position:s,rotation:a,scale:i}}updateVfxTransform(e,t,s){const{position:a,rotation:i,scale:r}=this.getVfxTransform(e,s);t.object.position.copy(a),t.object.rotation.copy(i),t.object.scale.copy(r)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const s=f[e];return s||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,s,a){if(!this.world||!e.actorType)return null;const i=this.resolveActorType(e.actorType);if(!i)return null;try{return await this.world.spawnActor(i,s,a)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,s,a){if(!this.world||!this.assetLoader||!e.prefabId)return null;try{const t=await this.assetLoader.getPrefabById(e.prefabId);if(!t)return null;return await this.world.spawnPrefab(t,s,a)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,s,a){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),i=await this.assetLoader.getModelByAssetId(e.meshId),r=L.clone(i.scene);if(r.position.copy(s),r.rotation.copy(a),t){await this.assetLoader.applyMaterials(t,r);const e=t.mesh?.rescale;null!=e&&1!==e&&r.scale.multiplyScalar(e)}return this.world.scene.add(r),r}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(this.restoreVisibilitySnapshotsForInstance(e),this.restorePropertySnapshotsForInstance(e),this.restoreMaterialSnapshotsForInstance(e),this.world)switch(e?.type){case"actor":this.world.removeActor(e.instance);break;case"prefab":this.world.removePrefab(e.instance);break;case"mesh":this.world.scene.remove(e.instance)}}despawnAll(){for(const e of this.spawnedInstances.values())this.despawnInstance(e);this.spawnedInstances.clear(),this.activeClips.clear(),this.pendingSpawns.clear()}getInitialTransform(e,t,s){const a=new c,i=new r,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,prevIndex:t,nextIndex:r,t:o}=B(n.keyframes,s);n.components.position&&O(n.keyframes,t,r,o,a),e&&e.rotation&&i.fromArray([...e.rotation,"XYZ"])}else t.initialPosition&&a.fromArray(t.initialPosition),t.initialRotation&&i.fromArray([...t.initialRotation,"XYZ"]);return{position:a,rotation:i}}evaluateSpawnTrack(e,t,s){if(!e.clips||0===e.clips.length)return;const a=t||this.bindings.get(e.id);if(a&&a.target)for(const t of e.clips){const i=t.startTime+t.duration,r=s>=t.startTime&&s<i,n=`${e.id}-${t.id}`;if(r){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:a.target}));(a.target instanceof d?a.target.object:a.target)&&this.evaluateSubTracks(e.subTracks,a,s)}else if(this.activeClips.has(n)){e.clips.some(e=>e!==t&&s>=e.startTime&&s<e.startTime+e.duration)||this.deactivateAnimationSubTracks(e.subTracks,a),this.clearExternalRootMotionPreview(a),this.restorePropertySnapshotsForTarget(a.target),this.restoreMaterialSnapshotsForTarget(a.target),this.restoreVisibilitySnapshotForObject(this.getPlayableObject(a)),this.activeClips.delete(n),this.spawnedInstances.delete(n)}}else for(const t of e.clips){const a=t.startTime+t.duration,i=s>=t.startTime&&s<a,r=`${e.id}-${t.id}`,n=this.spawnedInstances.has(r),o=this.pendingSpawns.has(r);if(!i||n||o){if(i&&n){const t=this.spawnedInstances.get(r);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,s)}else if(!i&&n){const e=this.spawnedInstances.get(r);e&&(this.despawnInstance(e),this.spawnedInstances.delete(r),this.activeClips.delete(r))}}else{const{position:s,rotation:a}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(r),this.spawnForClip(e,t,s,a,r)}}}getInstanceObject(e){switch(e.type){case"actor":return e.instance.object;case"prefab":return e.instance.mainActor?.object||e.instance.object;case"mesh":return e.instance;case"proxy":return e.target instanceof d?e.target.object:e.target;default:return null}}async spawnForClip(e,t,s,i,r){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const a=await this.spawnActorForClip(e,t,s,i);a&&(o={type:"actor",instance:a});break;case"prefab":const r=await this.spawnPrefabForClip(e,t,s,i);r&&(o={type:"prefab",instance:r});break;case"mesh":const n=await this.spawnMeshForClip(e,t,s,i);n&&(o={type:"mesh",instance:n})}if(n!==this.clearCounter)return void(o&&this.despawnInstance(o));const l=this._time.value,c=l>=t.startTime&&l<t.startTime+t.duration;if(o&&c){const t=this.getInstanceObject(o);"proxy"===o.type||("actor"===o.type?o.target=o.instance:"prefab"===o.type?o.target=o.instance.mainActor||o.instance.object:o.target=t);e.subTracks.some(e=>"animation"===e.type)&&t&&(o.mixer=new a(t),o.activeActions=new Map),this.spawnedInstances.set(r,o),this.activeClips.add(r)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(r)}}getPlayableObject(e){return e.target instanceof d?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,s){if(!t||!e.propertyPath)return;const a=this.getPropertyResolution(t,e);if(!a)return;const i=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,i,a);const n=function(e,t){switch(t.type){case v.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.Vector2:return J(e,t.value);case v.Vector3:return ee(e,t.value);case v.Vector4:return te(e,t.value);case v.Euler:return function(e,t){const s=ae(t,3);if(!s)return{applied:!1};const a=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof r)return e.set(s[0],s[1],s[2],a),{applied:!0,value:e};return{applied:!0,value:new r(s[0],s[1],s[2],a)}}(e,t.value);case v.Color:return se(e,t.value);default:return{applied:!1}}}(a.owner[a.key],s);n.applied&&(a.owner[a.key]=n.value)}getPropertyResolution(e,t){const s=e,a=this.getPropertySnapshotKey(t);let i=this.propertyResolutionCache.get(s);if(i||(i=new Map,this.propertyResolutionCache.set(s,i)),i.has(a))return i.get(a)??null;const r=this.getPropertyPathSegments(t.propertyPath);if(0===r.length)return i.set(a,null),null;let n=e;for(let e=0;e<r.length-1;e++){if(!Y(n))return i.set(a,null),null;n=n[r[e]]}if(!Y(n))return i.set(a,null),null;const o={owner:n,key:r[r.length-1]};return i.set(a,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const s=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,s),s}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,s){const a=e;let i=this.propertySnapshots.get(a);if(i||(i=new Map,this.propertySnapshots.set(a,i)),i.has(t))return;const r=s.owner[s.key];i.set(t,{resolution:s,hadOwnProperty:Object.prototype.hasOwnProperty.call(s.owner,s.key),value:r,valueSnapshot:re(r)})}restorePropertySnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restorePropertySnapshotsForTarget(e.instance);break;case"prefab":this.restorePropertySnapshotsForTarget(e.target??null),this.restorePropertySnapshotsForTarget(e.instance.mainActor??null),this.restorePropertySnapshotsForTarget(e.instance.object);break;case"proxy":this.restorePropertySnapshotsForTarget(e.target)}}restorePropertySnapshotsForTarget(e){if(!e)return;const t=e,s=this.propertySnapshots.get(t);if(s){for(const e of s.values())ne(e);this.propertySnapshots.delete(t),this.propertyResolutionCache.delete(t)}}restoreAllPropertySnapshots(){for(const e of Array.from(this.propertySnapshots.keys()))this.restorePropertySnapshotsForTarget(e)}restoreMaterialSnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restoreMaterialSnapshotsForTarget(e.instance);break;case"prefab":this.restoreMaterialSnapshotsForTarget(e.target??null),this.restoreMaterialSnapshotsForTarget(e.instance.mainActor??null),this.restoreMaterialSnapshotsForTarget(e.instance.object);break;case"proxy":this.restoreMaterialSnapshotsForTarget(e.target)}}restoreMaterialSnapshotsForTarget(e){if(!e)return;const t=e;this.materialResolutionCache.delete(t);const s=this.materialSnapshots.get(t);if(s){for(const e of s.values())null==e.materialIndex?e.owner.material=e.originalMaterial:Array.isArray(e.owner.material)&&(e.owner.material[e.materialIndex]=e.originalMaterial),e.controlledMaterial!==e.originalMaterial&&e.controlledMaterial.dispose();this.materialSnapshots.delete(t)}}restoreAllMaterialSnapshots(){for(const e of Array.from(this.materialSnapshots.keys()))this.restoreMaterialSnapshotsForTarget(e)}restoreVisibilitySnapshotForObject(e){if(!e)return;const t=this.visibilitySnapshots.get(e);t&&(e.visible=t.visible,this.visibilitySnapshots.delete(e))}restoreVisibilitySnapshotsForInstance(e){this.restoreVisibilitySnapshotForObject(this.getInstanceObject(e))}restoreAllVisibilitySnapshots(){for(const e of Array.from(this.visibilitySnapshots.keys()))this.restoreVisibilitySnapshotForObject(e)}applyResolvedMaterialValue(e,t,s){if(!t)return;if("asset"===b(e)&&!e.materialAssetId)return;if("outlineVisibility"===w(e))return void this.applyResolvedMaterialOutlineVisibility(e,t,s);if(!e.uniformName)return;const a=this.getMaterialSlotResolutions(t,e);for(const i of a){const a=this.ensureSequenceControlledMaterial(t,i),r=a.uniforms?.[e.uniformName];if(!r)continue;const n=Z(r.value,s);n.applied&&(r.value=n.value,a.uniformsNeedUpdate=!0,K(a))}}applyResolvedMaterialOutlineVisibility(e,t,s){if(s.type!==v.Boolean||"boolean"!=typeof s.value)return;const a=this.getMaterialSlotResolutions(t,e);for(const e of a){const a=this.ensureSequenceControlledMaterial(t,e),i=a.userData?.outlineParameters;null!=i&&(i.visible=s.value)}}getMaterialSlotResolutions(e,t){const s=e,a=b(t),i=w(t),r=`${t.id}:${i}:${a}:${t.materialAssetId??""}:${t.uniformName}`;let n=this.materialResolutionCache.get(s);n||(n=new Map,this.materialResolutionCache.set(s,n));const o=n.get(r);if(o)return o;const l=e instanceof d?e.object:e,c=[];return l.traverse(e=>{const s=e.material;if(Array.isArray(s))for(let a=0;a<s.length;a++){const i=s[a];H(i,t)&&c.push({owner:e,materialIndex:a,material:i,key:`${e.uuid}:${a}`})}else H(s,t)&&c.push({owner:e,materialIndex:null,material:s,key:`${e.uuid}:material`})}),n.set(r,c),c}ensureSequenceControlledMaterial(e,t){const s=e;let a=this.materialSnapshots.get(s);a||(a=new Map,this.materialSnapshots.set(s,a));const i=a.get(t.key);if(i)return i.controlledMaterial;const r=t.material.clone();return r.userData={...t.material.userData??{}},null!=t.material.userData?.outlineParameters&&(r.userData.outlineParameters={...t.material.userData.outlineParameters}),null==t.materialIndex?t.owner.material=r:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=r),a.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:r}),r}animationClipCacheKey(e,t){return`${e}|${t??""}`}async ensureAnimationClip(e,t){if(!this.assetLoader)return null;const s=this.animationClipCacheKey(e,t),a=this.animationClips.get(s);if(a)return a;const i=this.loadingAnimationClips.get(s);if(i)return i;const r=(async()=>{try{const a=await this.assetLoader.getAnimationClipForTargetByAssetId(e,t);return a&&this.animationClips.set(s,a),a}catch(s){return console.error(`Failed to load animation clip for asset ${e}`+(null==t?"":` and target rig ${t}`)+":",s),null}finally{this.loadingAnimationClips.get(s)===r&&this.loadingAnimationClips.delete(s)}})();return this.loadingAnimationClips.set(s,r),r}prepareAnimationPlayback(e,t,s){if(!j(s)){let e=t;return s.clipEndOffset>0&&(e=e.clone(),N(e,$(t)),e.duration=Math.max(0,e.duration-s.clipEndOffset)),s.rootMotion&&(e=F(e,s)),{clip:e,timeScale:s.playbackRate*this._timescale,startOffset:s.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,s,!1),timeScale:1*this._timescale,startOffset:0}}getPlayableAnimationClip(e,t,s,a){if(!j(s)){const e=s.rootMotion?F(t,s):t;return a?D.fromClip(e,!1):e}const i=`${s.id}:${a?"root":"base"}`,r=`${E(s)}|${a?"root":"base"}`,n=this.retimedAnimationClips.get(i);if(n&&n.assetId===e&&n.signature===r)return n.clip;const o=V(t,s),l=s.rootMotion?F(o,s):o,c=a?D.fromClip(l,!1):l;return this.retimedAnimationClips.set(i,{assetId:e,signature:r,clip:c}),c}getAnimationPlaybackLocalTime(e,t){const s=Math.max(0,t-e.startTime);return j(e)?s:s*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,s]of this.retimedAnimationClips.entries())s.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof d?e.target.object:e.target;t&&(e.originalTransform={position:t.position.clone(),rotation:t.rotation.clone(),scale:t.scale.clone()})}}restoreOriginalTransforms(){for(const e of this.bindings.values())if(e.originalTransform){const t=e.target instanceof d?e.target.object:e.target;t&&(t.position.copy(e.originalTransform.position),t.rotation.copy(e.originalTransform.rotation),t.scale.copy(e.originalTransform.scale))}}stopAllAnimations(){for(const e of this.bindings.values()){for(const[t,s]of e.activeActions.entries())e.charAnimActionKeys?.has(t)||s.stop();e.activeActions.clear(),e.mixer&&e.mixer.stopAllAction(),e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0),e.charAnimActionKeys?.clear()}}stopAllVfx(){for(const e of this.vfxActors.values())e.paused||e.stop();this.activeVfxClips.clear()}dispose(){if(this.stop(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearSequenceLights(),this.bindings.clear(),this.roleBindings.clear(),this.sequenceData=null,this.world)for(const e of this.vfxActors.values())this.world.removeActor(e);this.vfxActors.clear(),this.stopAllAudio(),this.audioBuffers.clear(),this.loadingAudioBuffers.clear(),this.animationClips.clear(),this.loadingAnimationClips.clear(),this.clearRetimedAnimationClipCache(),this.audioByClip.clear()}updateTrackParenting(e,t){const s=this.getActiveObjectsForTrack(e);if(0===s.length)return;const a="spawn"===e.type&&null!=t?.target,i=this.getTrackParentObject(e);for(const r of s)i?r.parent!==i&&(i.add(r),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=i)):t?.currentParent&&t.currentParent===r.parent?this.restoreObjectParent(t,r):r.parent&&r.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&!a&&this.world?.scene.attach(r)}getTrackParentObject(e){let t=null;const s=e.parent?.trackId;if(s){const a=this.sequenceData?oe(this.sequenceData.tracks).find(e=>e.id===s):void 0;if(a){const s=this.getActiveObjectsForTrack(a);if(s.length>0&&(t=s[0],e.parent?.socketName)){const s=this.findSocket(t,e.parent.socketName);s&&(t=s)}}}if(!t&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const s=this.roleBindings.get(e.parentRole);if(t=s instanceof d?s.object:s,e.parentRoleSocketName){const s=this.findSocket(t,e.parentRoleSocketName);s&&(t=s)}}return t}findSocket(e,t){if(e.name===t)return e;if(e instanceof s.SkinnedMesh){const s=e.skeleton.bones.find(e=>e.name===t);if(s)return s}return e.getObjectByName(t)||null}getActiveObjectsForTrack(e){if("object"===e.type){const t=this.bindings.get(e.id);if(t&&t.target)return[t.target instanceof d?t.target.object:t.target]}else if("locator"===e.type){const t=this.bindings.get(e.id);if(t&&t.target instanceof n)return[t.target]}else{if("camera"===e.type)return[this.ensureSequenceCamera(e)];if("light"===e.type)return[this.ensureSequenceLight(e)];if("spawn"===e.type){const t=[];for(const[s,a]of this.spawnedInstances)if(s.startsWith(e.id+"-")&&this.activeClips.has(s)){const e=this.getInstanceObject(a);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const s of this.activeVfxClips)if(s.startsWith(e.id+"-")){const e=this.vfxActors.get(s);e&&t.push(e.object)}return t}}return[]}restoreObjectParent(e,t){e.originalParent?e.originalParent.add(t):this.world&&this.world.scene.add(t),e.currentParent=void 0}restoreOriginalParents(){for(const e of this.bindings.values())if(e.currentParent){const t=e.target instanceof d?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const s={};for(const a of e.subTracks)if("audioParameter"===a.type){const e=a,i=S(e.parameter),r=q(e.keyframes,t,{min:i.min,max:i.max});void 0!==r&&(s[e.parameter]=r)}return s}stringToRandom(e){let t=0;for(let s=0;s<e.length;s++){t=(t<<5)-t+e.charCodeAt(s),t&=t}const s=1e4*Math.sin(t);return s-Math.floor(s)}async refreshAsset(e){let t=!1;this.assetLoader?.clearCacheById(e),this.animationClips.delete(e),this.loadingAnimationClips.delete(e),this.clearRetimedAnimationClipCache(e),this.vfxService?.clearPool(e),t=this.refreshVfxActorsForAssetIds(new Set([e]))||t;for(const[s,a]of this.activePostProcessClips.entries())a.assetId===e&&(this.releasePostProcessClipEffect(s),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const s=await this.getAssetOrNull(e);return"shaderGraph"===s?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[s,a]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(s,e)&&(this.world&&this.world.removeActor(a),this.vfxActors.delete(s),this.activeVfxClips.delete(s),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const s of t)if(e.endsWith(`-${s}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[s,a]of this.spawnedInstances.entries())e.has(s)&&(this.despawnInstance(a),this.spawnedInstances.delete(s),this.activeClips.delete(s),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const s of oe(this.sequenceData.tracks))if("spawn"===s.type&&(s.prefabId===e||s.meshId===e))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const s=this.refreshVfxActorsForAssetIds(t),a=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return s||a}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const s=new Map;for(const a of oe(this.sequenceData.tracks))if("vfx"===a.type)for(const i of a.clips)null==i.vfxAssetId||t.has(i.vfxAssetId)||await this.assetUsesShaderGraph(i.vfxAssetId,e,s)&&t.add(i.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const s=new Map;for(const a of oe(this.sequenceData.tracks))if("spawn"===a.type&&await this.spawnTrackUsesShaderGraph(a,e,s))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,s){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,s))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,s))return!0;for(const a of e.subTracks??[])if("material"===a.type&&null!=a.materialAssetId&&await this.assetUsesShaderGraph(a.materialAssetId,t,s))return!0;return!1}assetUsesShaderGraph(e,t,s,a=new Set){if(e===t)return Promise.resolve(!0);if(a.has(e))return Promise.resolve(!1);if(s.has(e))return s.get(e);const i=this.assetUsesShaderGraphUncached(e,t,s,a);return s.set(e,i),i}async assetUsesShaderGraphUncached(e,t,s,a){if(a.has(e))return!1;const i=await this.getAssetOrNull(e);if(null==i)return!1;const r=new Set(a);return r.add(e),!!this.materialAssetUsesShaderGraph(i,t)||("mesh"===i.type?this.materialAssignmentsUseShaderGraph(i.materialAssignments,t,s,r):"prefab"===i.type?this.sceneObjectsUseShaderGraph(i.prefab?.objects,t,s,r):"vfx"===i.type&&this.vfxAssetUsesShaderGraph(i,t,s,r))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,s,a){for(const i of e??[])if(null!=i.materialId&&"null"!==i.materialId&&await this.assetUsesShaderGraph(i.materialId,t,s,a))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,s,a){for(const i of e??[]){if(await this.materialAssignmentsUseShaderGraph(i.materialAssignments,t,s,a))return!0;if(null!=i.assetId&&("asset_mesh"===i.type||"prefab"===i.type||"vfx"===i.type)&&await this.assetUsesShaderGraph(i.assetId,t,s,a))return!0;if(await this.sceneObjectsUseShaderGraph(i.children,t,s,a))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,s,a){for(const i of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(i,t,s,a))return!0;return!1}async emitterUsesShaderGraph(e,t,s,a){if(await this.emitterOutputUsesShaderGraph(e.output,t,s,a))return!0;for(const i of e.children??[])if(await this.emitterUsesShaderGraph(i,t,s,a))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,s,a){const i=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===i&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==i||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,s,a))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,s,a){let i=!1;for(let e=0;e<a.length;e++)if(g(a[e])){i=!0;break}if(i)try{const t=new Array(a.length);for(let e=0;e<a.length;e++)t[e]=C(a[e],this.sequenceEventAsyncResolvers);const i=await Promise.all(t);await s.call(e,...i)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(a.length);for(let e=0;e<a.length;e++)t[e]=A(a[e],this.sequenceEventSyncResolvers);s.call(e,...t)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}}resolveSequenceEventActorReference(e){if(!this.world||null==e)return null;const t=e,s="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==s)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===s)return e}return null}resolveSequenceEventSequence(e){return k(e)?new P(e):this.assetLoader&&"string"==typeof e?this.assetLoader.getSequenceById(e):null}async resolveSequenceEventAnimationClip(e){const t="string"==typeof e?e:"object"==typeof e&&null!=e?e.assetId??null:null;return null!=t&&this.assetLoader?this.assetLoader.getAnimationClipByAssetId(t):null}}function X(e){return e.options?.length>0||e.propertyType===v.Boolean||e.propertyType===v.String}function z(e){return"outlineVisibility"===w(e)||e.valueType===v.Boolean||e.valueType===v.String}function Y(e){return"object"==typeof e&&null!=e||"function"==typeof e}function Z(e,t){switch(t.type){case v.Number:return function(e){if("number"==typeof e)return Number.isFinite(e)?{applied:!0,value:e}:{applied:!1};if("string"==typeof e){const t=parseFloat(e);return Number.isFinite(t)?{applied:!0,value:t}:{applied:!1}}return{applied:!1}}(t.value);case v.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.Vector2:return J(e,t.value);case v.Vector3:return ee(e,t.value);case v.Vector4:return te(e,t.value);case v.Color:return function(e,t){if(e instanceof c){const s=Se.set(0);return ie(s,t)?(e.set(s.r,s.g,s.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const s=Se.set(0);return ie(s,t)?(e.set(s.r,s.g,s.b,e.w),{applied:!0,value:e}):{applied:!1}}return se(e,t)}(e,t.value);default:return{applied:!1}}}function H(e,t){const a=b(t);return!!function(e){return e instanceof s.Material||!0===e?.isMaterial}(e)&&(("asset"!==a||e.userData?.assetId===t.materialAssetId)&&("outlineVisibility"===w(t)?null!=e.userData?.outlineParameters:null!=e.uniforms?.[t.uniformName]))}function J(e,t){const s=ae(t,2);return s?e instanceof l?(e.fromArray(s),{applied:!0,value:e}):{applied:!0,value:new l(s[0],s[1])}:{applied:!1}}function ee(e,t){const s=ae(t,3);return s?e instanceof c?(e.fromArray(s),{applied:!0,value:e}):{applied:!0,value:new c(s[0],s[1],s[2])}:{applied:!1}}function te(e,t){const s=ae(t,4);return s?e instanceof h?(e.fromArray(s),{applied:!0,value:e}):{applied:!0,value:new h(s[0],s[1],s[2],s[3])}:{applied:!1}}function se(e,t){if(e instanceof i)return ie(e,t)?{applied:!0,value:e}:{applied:!1};const s=new i;return ie(s,t)?{applied:!0,value:s}:{applied:!1}}function ae(e,t){if(!Array.isArray(e)||e.length<t)return null;const s=new Array(t);for(let a=0;a<t;a++){if("number"!=typeof e[a])return null;s[a]=e[a]}return s}function ie(e,t){return t instanceof i||"string"==typeof t||"number"==typeof t?(e.set(t),!0):!!(Array.isArray(t)&&t.length>=3)&&(e.setRGB("number"==typeof t[0]?t[0]:0,"number"==typeof t[1]?t[1]:0,"number"==typeof t[2]?t[2]:0),!0)}function re(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof i||e instanceof r)return e.clone()}function ne(e){const{owner:t,key:s}=e.resolution;e.hadOwnProperty?(!function(e,t){if(e instanceof l&&t instanceof l)return e.copy(t),!0;if(e instanceof c&&t instanceof c)return e.copy(t),!0;if(e instanceof h&&t instanceof h)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0;if(e instanceof r&&t instanceof r)return e.copy(t),!0}(e.value,e.valueSnapshot),t[s]=e.value):delete t[s]}function oe(e){const t=[];for(const s of e)t.push(s),"group"===s.type&&t.push(...oe(s.childTracks));return t}function le(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function ce(e){const t=new s.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const a=new s.AxesHelper(.35);a.renderOrder=1e3;const i=Array.isArray(a.material)?a.material:[a.material];for(const e of i)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(a);const r=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const a=t.getContext("2d");if(!a)return null;a.clearRect(0,0,t.width,t.height),a.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,s,a,i,r){const n=t+a,o=s+i;e.beginPath(),e.moveTo(t+r,s),e.lineTo(n-r,s),e.quadraticCurveTo(n,s,n,s+r),e.lineTo(n,o-r),e.quadraticCurveTo(n,o,n-r,o),e.lineTo(t+r,o),e.quadraticCurveTo(t,o,t,o-r),e.lineTo(t,s+r),e.quadraticCurveTo(t,s,t+r,s),e.closePath()}(a,0,8,t.width,48,8),a.fill(),a.font="24px sans-serif",a.textAlign="center",a.textBaseline="middle",a.fillStyle="#f8fafc",a.fillText(e||"Locator",t.width/2,t.height/2);const i=new s.CanvasTexture(t);i.needsUpdate=!0;const r=new s.SpriteMaterial({map:i,transparent:!0,depthTest:!1});r.toneMapped=!1;const n=new s.Sprite(r);return n.scale.set(.9,.225,1),n}(e);return r&&(r.position.set(0,.45,0),r.renderOrder=1001,t.add(r)),t.traverse(e=>{e.raycast=()=>{}}),t}function he(e){e.traverse(e=>{const t=e.material;if(Array.isArray(t))for(const e of t)e?.dispose?.(),e?.map?.dispose?.();else t?.dispose?.(),t?.map?.dispose?.()})}const ue=new c,pe=new c,de=new c,fe=new c,me=new c,ye=new c,ve=new o,ge=new o,Ce=new r,Ae=new r,Se=new i;/*
|
|
1
|
+
import{BehaviorSubject as e,Subject as t}from"rxjs";import*as s from"three";import{AnimationMixer as a,Color as i,Euler as r,Object3D as n,Quaternion as o,Vector2 as l,Vector3 as c,Vector4 as h}from"three";import{VisualEffect as u}from"../../effects/vfx/vfx-param.js";import{hashVfxPreviewSeed as p}from"../../effects/vfx/seeded-random.js";import{BaseActor as d}from"../../gameplay/actors/actor.js";import f from"../../gameplay/actors/builtin/index.js";import{Prefab as m,PrefabOf as y}from"../../scene/objects/prefab.js";import{SerializedParamType as v}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as g,deserializeCustomParamValue as C,deserializeCustomParamValueSync as A}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as S}from"./audio-parameters.js";import{getMaterialSubTrackMatchMode as b,getMaterialSubTrackTarget as w,Sequence as P,isSequenceData as k}from"./sequence-data.js";import{getSequenceSubTrackDefinition as x,getSequenceTrackDefinition as T}from"./sequence-definitions.js";import{applyInterpolation as I,evaluateCustomParamValueKeyframes as M,evaluateNumericKeyframes as q,findKeyframeSpan as B}from"./sequence-value-lane.js";import{evaluateTransformPositionSpan as O}from"./sequence-transform.js";import{applyAnimationClipRootMotionAxisMask as F,buildRetimedAnimationClip as V,getAnimationClipRetimingSignature as E,isAnimationClipUsingRetiming as j}from"./sequence-animation-retiming.js";import*as L from"three/addons/utils/SkeletonUtils.js";import{CharacterAnimationComponent as _,getCharacterMovementLike as R}from"../../gameplay/actors/index.js";import{RootMotionClip as D}from"../../gameplay/animation/root-motion.js";import{markMaterialUniformValuesNeedUpdate as K,setMaterialUniformValuesAutoUpdate as $}from"../../rendering/node-material-webgpu-resolver.js";import{getAnimationClipRigId as G,getAnimationRigIdFromObject as N,setAnimationClipRigId as U}from"../../gameplay/animation/retarget.js";import{hashCameraShakeSeed as W}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as Q,shaderGraphPostProcessWeightUniformName as X}from"../../shader/graph/index.js";export var SequencePlaybackState;!function(e){e.Stopped="stopped",e.Playing="playing",e.Paused="paused"}(SequencePlaybackState||(SequencePlaybackState={}));export class SequencePlayer{constructor(){this._state=new e(SequencePlaybackState.Stopped),this._time=new e(0),this._duration=0,this._timescale=1,this._loop=!1,this._externalTimeControl=!1,this._inEditor=!1,this.bindings=new Map,this.roleBindings=new Map,this.sequenceData=null,this.onComplete=new t,this.onLoop=new t,this.vfxCollisionEvent={trackId:"",clipId:"",vfxAssetId:"",emitterId:"",emitterName:"",position:new s.Vector3,normal:new s.Vector3},this.onTimeUpdate=this._time.asObservable(),this.onStateChange=this._state.asObservable(),this.loopCount=0,this.viewController=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.sequenceCameras=new Map,this.cameraPlayables=new Map,this.cameraBlendCamera=null,this.cameraBlendSource=null,this.cameraBlendOutSource=null,this.cameraOverrideHandle=null,this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null,this.activeCameraShakeClipKeys=new Set,this.nextCameraShakeClipKeys=new Set,this.activePostProcessClips=new Map,this.nextPostProcessClipKeys=new Set,this.sequenceLights=new Map,this.lightPlayables=new Map,this.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,this.externalRootMotionInterpolants=new WeakMap,this.audioByClip=new Map,this.activeAudioClips=new Set,this.audioGainNodes=new Map,this.audioStartInFlight=new Map,this.lastAudioStartAttemptTime=new Map,this.audioStartRetryIntervalSeconds=.25,this.world=null,this.assetLoader=null,this.actorFactory=null,this.vfxService=null,this.spawnedInstances=new Map,this.activeClips=new Set,this.pendingSpawns=new Set,this.vfxActors=new Map,this.activeVfxClips=new Set,this.locatorMarkers=new Map,this.clearCounter=0,this.propertyPathSegments=new Map,this.propertyResolutionCache=new Map,this.propertySnapshots=new Map,this.materialResolutionCache=new Map,this.materialSnapshots=new Map,this.visibilitySnapshots=new Map,this.audioFilters=new Map,this.audioPannerNodes=new Map,this.firedEvents=new Set,this.sequenceEventSyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e)},this.sequenceEventAsyncResolvers={actor:e=>this.resolveSequenceEventActorReference(e),texture:e=>this.assetLoader?.getTextureByAssetId(e)??null,sampler2DNode:e=>this.assetLoader?.getTextureByAssetId(e)??null,object3D:async e=>{const t=await(this.assetLoader?.getModelByAssetId(e));return t?.scene??null},material:e=>this.assetLoader?.getMaterialByAssetId(e)??null,audioBuffer:e=>this.assetLoader?.getAudioByAssetId(e)??null,visualEffect:async e=>{if(!this.assetLoader||!this.actorFactory)return null;const t=await this.assetLoader.getAsset(e);return t?new u(this.actorFactory,t):null},prefab:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new y(new m(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,s)=>{t&&this.evaluateObjectTrack(e,t,s)},locator:(e,t,s)=>{t&&this.evaluateLocatorTrack(e,t,s)},camera:(e,t,s)=>this.evaluateCameraTrack(e,s),cameraShake:(e,t,s)=>this.evaluateCameraShakeTrack(e,s),postProcess:(e,t,s)=>this.evaluatePostProcessTrack(e,s),light:(e,t,s)=>this.evaluateLightTrack(e,s),audio:(e,t,s)=>this.evaluateAudioTrack(e,s),vfx:(e,t,s)=>this.evaluateVfxTrack(e,s),spawn:(e,t,s)=>this.evaluateSpawnTrack(e,t,s),group:(e,t,s)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,s)}},this.subTrackRuntimeEvaluators={transform:(e,t,s)=>{const a=this.getPlayableObject(t);a&&this.evaluateTransformSubTrack(e,a,s)},animation:(e,t,s)=>this.evaluateAnimationSubTrack(e,t,s),visibility:(e,t,s)=>{const a=this.getPlayableObject(t);a&&this.evaluateVisibilitySubTrack(e,a,s)},parameter:(e,t,s)=>this.evaluateParameterSubTrack(e,t.target||null,s),event:(e,t,s)=>this.evaluateEventSubTrack(e,t.target||null,s)}}get state(){return this._state.value}get time(){return this._time.value}get duration(){return this._duration}get timescale(){return this._timescale}set timescale(e){this._timescale=Math.max(.01,e)}get loop(){return this._loop}set loop(e){this._loop=e}get externalTimeControl(){return this._externalTimeControl}set externalTimeControl(e){this._externalTimeControl=e}get inEditor(){return this._inEditor}set inEditor(e){this._inEditor=e,this.updateLocatorMarkerVisibility()}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,e||this.releaseCameraOverride()}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId!==e&&(this._cameraControlTrackId=e,this.releaseCameraOverride())}setViewController(e){this.viewController&&this.viewController!==e&&this.viewController.clearCameraShakeContributionsForOwner(this),this.viewController=e}setWorld(e){this.world!==e&&(this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearSequenceLights(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.world=e,this.clearCounter++,this.vfxActors.clear(),this.spawnedInstances.clear(),this.bindings.clear(),this.activeClips.clear(),this.activeVfxClips.clear(),this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear(),this.loadingAudioBuffers.clear(),this.audioFilters.clear(),this.audioPannerNodes.clear(),this.pendingSpawns.clear(),this.propertyResolutionCache.clear(),this.materialResolutionCache.clear(),this.clearRetimedAnimationClipCache(),this._state.next(SequencePlaybackState.Stopped),this.sequenceData&&this.initializeLocatorBindings())}setAudioListener(e){this.audioListener=e}setAssetLoader(e){if(this.assetLoader=e,this.sequenceData){const e=this.clearCounter;this.preloadSequenceResources(this.sequenceData,e)}}setActorFactory(e){this.actorFactory=e}setVfxService(e){this.vfxService=e}load(e){if(this.stop(),this.clearCounter++,this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearSequenceLights(),this.sequenceData=e,this._duration=e.duration,this._loop=e.loop,this._timescale=e.playbackRate,this.clearRetimedAnimationClipCache(),this.bindings.clear(),this.initializeLocatorBindings(),this.loopCount=0,this.assetLoader){const t=this.clearCounter;this.preloadSequenceResources(e,t)}}preloadSequenceResources(e,t){return Promise.all([this.preloadAudioBuffersForSequence(e,t),this.preloadAnimationClipsForSequence(e,t)]).then(()=>{})}getAudioAssetIdsForSequence(e){const t=new Set;for(const s of e.tracks){if("audio"!==s.type)continue;const e=s;for(const s of e.clips??[])s.audioAssetId&&t.add(s.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const s=this.getAudioAssetIdsForSequence(e);0!==s.length&&await Promise.all(s.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let s=this.loadingAudioBuffers.get(e);s||(s=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,s));try{const a=await s;if(t!==this.clearCounter)return;this.audioBuffers.set(e,a)}catch(e){}finally{this.loadingAudioBuffers.get(e)===s&&this.loadingAudioBuffers.delete(e)}}))}async preloadAnimationClipsForSequence(e,t){this.assetLoader&&t===this.clearCounter&&await this.prepareAnimationClipsForBindings(e,t)}async prepare(){if(!this.sequenceData||!this.assetLoader)return;this.resolveBindings();const e=this.clearCounter;await Promise.all([this.prepareAnimationClipsForBindings(this.sequenceData,e),this.prepareVisualEffectsForSequence(this.sequenceData,e)])}async prepareVisualEffectsForSequence(e,t){if(await this.preloadVisualEffectsForSequence(e,t),t!==this.clearCounter||!this.vfxService||!this.world)return;const s=[];for(const t of le(e.tracks))if("vfx"===t.type&&!t.muted)for(const e of t.clips??[])null!=e.vfxAssetId&&s.push({track:t,clip:e,key:this.getVfxClipKey(t,e)});await Promise.all(s.map(({track:e,clip:t,key:s})=>this.ensureVfxActor(e,t,s))),t===this.clearCounter&&await Promise.all(s.map(({key:e})=>this.vfxActors.get(e)?.prepareRendering()))}async preloadVisualEffectsForSequence(e,t){if(!this.world||!this.actorFactory)return;const s=new Set;for(const t of le(e.tracks))if("vfx"===t.type)for(const e of t.clips??[])null!=e.vfxAssetId&&s.add(e.vfxAssetId);if(0===s.size)return;const a=await Promise.all([...s].map(e=>this.assetLoader.getAsset(e)));if(t!==this.clearCounter)return;const i=a.filter(e=>null!=e&&null!=e.vfx).map(e=>new u(this.actorFactory,e));await this.world.preloadVisualEffects(i)}async prepareAnimationClipsForBindings(e,t){const s=[];for(const a of le(e.tracks)){if(!("subTracks"in a))continue;const e=this.bindings.get(a.id),i=null==e?null:this.getPlayableObject(e);if(null==i)continue;const r=N(i);for(const e of a.subTracks)if("animation"===e.type)for(const a of e.clips){if(t!==this.clearCounter)return;if(null!=a.animationClipAssetId){const e=this.animationClipCacheKey(a.animationClipAssetId,r);s.push(this.ensureAnimationClip(a.animationClipAssetId,r).then(s=>{null!=s&&t===this.clearCounter&&j(a)&&(this.getPlayableAnimationClip(e,s,a,!1),a.rootMotion&&this.getPlayableAnimationClip(e,s,a,!0))}))}}}await Promise.all(s)}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const s of le(this.sequenceData.tracks))"object"!==s.type||s.targetId!==e||s.role||this.createBinding(s,t)}unbindObject(e){if(this.sequenceData)for(const t of le(this.sequenceData.tracks))"object"!==t.type||t.targetId!==e||t.role||this.removeBinding(t.id)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=ce(e);if(!t||!this.sequenceData)return[];const s=[];for(const e of le(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(ce(e.bindingId)!==t)continue;const a=this.bindings.get(e.id),i=a?this.getPlayableObject(a):null;i&&(i.updateWorldMatrix(!0,!1),s.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:i.getWorldPosition(new c),rotation:i.getWorldQuaternion(new o),scale:i.getWorldScale(new c)}))}return s}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of le(this.sequenceData.tracks)){if("locator"!==e.type||this.bindings.has(e.id))continue;const t=new n;t.name=e.name||"Locator",t.userData.sequenceLocatorTrackId=e.id,this.world?.scene&&null==t.parent&&this.world.scene.add(t);const s=he(e.name);s.visible=this._inEditor,t.add(s),this.locatorMarkers.set(e.id,s),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())ue(e);for(const e of this.bindings.values()){if("locator"!==e.track.type)continue;const t=this.getPlayableObject(e);t?.parent&&t.removeFromParent()}this.locatorMarkers.clear()}updateLocatorMarkerVisibility(){for(const e of this.locatorMarkers.values())e.visible=this._inEditor}disableLocatorInteraction(e){e.traverse(e=>{e.raycast=()=>{}})}resolveTrackBinding(e){if("object"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("spawn"===e.type){const t=e;t.role&&this.roleBindings.has(t.role)&&this.createBinding(e,this.roleBindings.get(t.role))}else if("group"===e.type)for(const t of e.childTracks)this.resolveTrackBinding(t)}createBinding(e,t){const s=t instanceof d?t.object:t,i=this.bindings.get(e.id),r=null!=i?i.target instanceof d?i.target.object:i.target:null,n=null!=i&&i.target===t&&r===s,o=e.subTracks.some(e=>"animation"===e.type);null==i||n||this.releaseBinding(i);const l=n?i:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,n||(l.originalTransform={position:s.position.clone(),rotation:s.rotation.clone(),scale:s.scale.clone()},l.originalParent=s.parent),o&&null==l.mixer?l.mixer=new a(s):o||(l.mixer=void 0),this.bindings.set(e.id,l)}removeBinding(e){const t=this.bindings.get(e);t&&(this.releaseBinding(t),this.bindings.delete(e))}releaseBinding(e){this.clearExternalRootMotionPreview(e);for(const[t,s]of e.activeActions.entries())e.charAnimActionKeys?.has(t)||s.stop();e.activeActions.clear(),e.mixer?.stopAllAction(),e.charAnimComponent?.stopSequenceAnimation(),e.charAnimComponent=void 0,e.charAnimActionKeys?.clear()}play(){this._state.value!==SequencePlaybackState.Playing&&this.sequenceData&&(this._state.value===SequencePlaybackState.Stopped&&(this._time.next(0),this.loopCount=0,this.resolveBindings(),this.captureOriginalTransforms()),this._state.next(SequencePlaybackState.Playing),this.evaluate(this._time.value),this.resumeVfx())}pause(){this._state.value===SequencePlaybackState.Playing&&(this._state.next(SequencePlaybackState.Paused),this.pauseAudio(),this.pauseVfx())}pauseAudio(){for(const e of this.audioByClip.values())e.pause()}pauseVfx(){for(const e of this.vfxActors.values())e.pause()}resumeVfx(){for(const[e,t]of this.vfxActors.entries())(this.activeVfxClips.has(e)||t.getParticleCount()>0)&&t.play()}cancel(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreAllVisibilitySnapshots(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects();for(const e of this.sequenceLights.values())e.visible=!1}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreAllVisibilitySnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects();for(const e of this.sequenceLights.values())e.visible=!1}restart(){this.stop(),this.play()}seek(e){const t=Math.max(0,Math.min(e,this._duration));t<this._time.value&&this.resetVfxForTimeReset(t),this._time.next(t),this.evaluate(t)}update(e){if(this._state.value!==SequencePlaybackState.Playing)return;if(!this.sequenceData)return;if(this._externalTimeControl){for(const t of this.bindings.values())t.charAnimComponent?t.charAnimComponent.evaluateExternalPose(e*this._timescale):t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale);return}const t=this._time.value+e*this._timescale;if(t>=this._duration){if(!this._loop)return this._time.next(this._duration),this.evaluate(this._duration),this.deactivateCharacterAnimationActions(),this.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreAllVisibilitySnapshots(),this._state.next(SequencePlaybackState.Stopped),void this.onComplete.next();{this.loopCount++;const e=t%this._duration;this.resetVfxForTimeReset(e),this._time.next(e),this.firedEvents.clear(),this.onLoop.next(this.loopCount)}}else this._time.next(t);this.evaluate(this._time.value);for(const t of this.bindings.values())t.mixer&&t.mixer.update(e*this._timescale);for(const t of this.spawnedInstances.values())t.mixer&&t.mixer.update(e*this._timescale)}evaluate(e){if(this.sequenceData){this.nextCameraShakeClipKeys.clear(),this.nextPostProcessClipKeys.clear();for(const e of this.sequenceLights.values())e.visible=!1;for(const t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===t.type||"light"===t.type||"spawn"===t.type||"vfx"===t.type)){const e=this.bindings.get(t.id);this.updateTrackParenting(t,e)}this.evaluateTrack(t,e)}this.updateCameraControl(e),this.syncCameraShakeContributions(),this.syncPostProcessEffects()}}evaluateTrack(e,t){if(e.muted)return;const s=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[T(e.type).runtimeEvaluator])(e,s,t)}evaluateObjectTrack(e,t,s){this.evaluateSubTracks(e.subTracks,t,s)}evaluateLocatorTrack(e,t,s){this.evaluateSubTracks(e.subTracks,t,s)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=le(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,s){this._externalTimeControl&&this.beginExternalRootMotionPreview(t);for(const a of e){if(a.muted)continue;(0,this.subTrackRuntimeEvaluators[x(a.type).runtimeEvaluator])(a,t,s)}this._externalTimeControl&&this.applyExternalRootMotionPreview(t)}beginExternalRootMotionPreview(e){const t=e.externalRootMotionPreview;if(!t)return;const s=this.getPlayableObject(e);s&&s.position.sub(t.appliedOffset),t.appliedOffset.set(0,0,0),t.sampledOffset.set(0,0,0),t.root=null}sampleExternalRootMotionPreview(e,t,a,i){if(!t.motionTrack)return;let r=this.externalRootMotionInterpolants.get(t);r||(r=t.motionTrack.InterpolantFactoryMethodSmooth([]),this.externalRootMotionInterpolants.set(t,r));const n=e.externalRootMotionPreview??(e.externalRootMotionPreview={appliedOffset:new c,sampledOffset:new c,root:null}),o=Math.max(0,Math.min(i,t.duration)),l=Math.max(o,Math.min(a,t.duration));me.fromArray(r.evaluate(o)),ye.fromArray(r.evaluate(l)),n.sampledOffset.subVectors(ye,me),n.sampledOffset.y=0;const h=this.getPlayableObject(e),u=s.PropertyBinding.parseTrackName(t.motionTrack.name);n.root=h?.getObjectByName(u.nodeName)??h}applyExternalRootMotionPreview(e){const t=e.externalRootMotionPreview,s=this.getPlayableObject(e);t&&s&&t.root&&(t.root.getWorldScale(ve),t.appliedOffset.copy(t.sampledOffset).multiply(ve).applyQuaternion(s.quaternion),s.position.add(t.appliedOffset))}clearExternalRootMotionPreview(e){const t=e.externalRootMotionPreview,s=this.getPlayableObject(e);t&&s&&s.position.sub(t.appliedOffset),e.externalRootMotionPreview=void 0}evaluateTransformSubTrack(e,t,s){const a=e.keyframes;if(0===a.length)return;const{prev:i,next:r,prevIndex:n,nextIndex:o,t:l}=B(a,s);if(i)if(e.components.position&&O(a,n,o,l,t.position),r&&i!==r){const s=I(l,i.interpolation);e.components.rotation&&i.rotation&&r.rotation&&(ge.setFromEuler(Ae.fromArray([...i.rotation,"XYZ"])),Ce.setFromEuler(Se.fromArray([...r.rotation,"XYZ"])),t.quaternion.slerpQuaternions(ge,Ce,s)),e.components.scale&&i.scale&&r.scale&&t.scale.lerpVectors(pe.fromArray(i.scale),de.fromArray(r.scale),s)}else e.components.rotation&&i.rotation&&t.rotation.fromArray([...i.rotation,"XYZ"]),e.components.scale&&i.scale&&t.scale.fromArray(i.scale)}evaluateAnimationSubTrack(e,t,a){if(!t.mixer||!t.activeActions)return;const i=t.target instanceof d?t.target.object:t.target;if(i)for(const r of e.clips){const n=r.startTime+r.duration,o=a>=r.startTime&&a<n,l=`${e.id}-${r.id}`;let c=t.activeActions.get(l),h=!1;if(o){if(!c){h=!0;const e=r.animationClipAssetId;if(null==e)continue;const a=N(i),n=this.animationClipCacheKey(e,a),o=this.animationClips.get(n);if(null==o){this.ensureAnimationClip(e,a);continue}const u=this.prepareAnimationPlayback(n,o,r),p=t;let f=!1;if(t.target instanceof d){p.charAnimComponent||(p.charAnimComponent=t.target.getComponent(_)??void 0);const e=p.charAnimComponent;if(null!=e){const s=r.rootMotion?j(r)?this.getPlayableAnimationClip(n,o,r,!0):D.fromClip(u.clip,!1):u.clip;if(this._externalTimeControl)c=e.beginExternalAnimationControl(s,{timeScale:u.timeScale});else if(e.play(s,{inPlace:!r.rootMotion,loop:!1,priority:20,sequenceControlled:!0,timeScale:u.timeScale,fadeTime:r.fadeInDuration??.2,offset:u.startOffset}),c=e.getFullBodyAction(),r.rootMotion){const e=R(t.target);e&&e.setRootMotionAction(c,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(l,c),p.charAnimActionKeys||(p.charAnimActionKeys=new Set),p.charAnimActionKeys.add(l),f=!0}}f||(c=t.mixer.clipAction(u.clip),c.setLoop(s.LoopOnce,1),c.clampWhenFinished=!0,c.timeScale=u.timeScale,u.startOffset>0&&(c.time=u.startOffset),t.activeActions.set(l,c),c.play())}if(c){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const s=this.getAnimationPlaybackLocalTime(r,a),i=Math.min(s,c.getClip().duration);(h||Math.abs(c.time-i)>.001)&&(c.time=i,c.paused=!1,c.play(),e.charAnimComponent?e.charAnimComponent.evaluateExternalPose():t.mixer&&t.mixer.update(0)),r.rootMotion&&c.getClip()instanceof D&&this.sampleExternalRootMotionPreview(t,c.getClip(),i,j(r)?0:r.clipStartOffset)}else e.charAnimComponent?.endExternalControl()}}else c&&this.deactivateAnimationAction(t,l,c)}}deactivateAnimationAction(e,t,s){if(e.activeActions.delete(t),e.charAnimActionKeys?.has(t))return e.charAnimActionKeys.delete(t),void(0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.requestSequenceAnimationRelease(),e.charAnimComponent=void 0));s.stop(),this._externalTimeControl&&e.mixer&&e.mixer.update(0)}deactivateAnimationSubTracks(e,t){for(const s of e)if(!s.muted&&"animation"===s.type)for(const e of s.clips){const a=`${s.id}-${e.id}`,i=t.activeActions.get(a);i&&this.deactivateAnimationAction(t,a,i)}}deactivateCharacterAnimationActions(){for(const e of this.bindings.values())for(const t of[...e.charAnimActionKeys??[]]){const s=e.activeActions.get(t);s?this.deactivateAnimationAction(e,t,s):e.charAnimActionKeys?.delete(t)}}evaluateVisibilitySubTrack(e,t,s){const a=e.keyframes;if(0===a.length)return;let i=a[0];for(const e of a){if(!(e.time<=s))break;i=e}this.visibilitySnapshots.has(t)||this.visibilitySnapshots.set(t,{visible:t.visible}),t.visible=i.visible}evaluatePropertySubTrack(e,t,s){const a=M(e.keyframes,s,{min:e.range?.[0],max:e.range?.[1],stepOnly:z(e)});a&&this.applyResolvedPropertyValue(e,t,a)}evaluateParameterSubTrack(e,t,s){if("audioParameter"===e.type)return;const a=M(e.keyframes,s,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:z(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:Y(e)}:{});a&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,a):this.applyResolvedPropertyValue(e,t,a))}evaluateEventSubTrack(e,t,s){if(t instanceof d&&this._state.value===SequencePlaybackState.Playing)for(const a of e.events){const i=`${e.id}-${a.id}`;if(s>=a.time&&!this.firedEvents.has(i)){if(this.firedEvents.add(i),a.editorOnly&&!this._inEditor)continue;if(!a.functionName)continue;const e=t[a.functionName];"function"==typeof e?this.invokeSequenceEvent(t,a.functionName,e,a.arguments??[]):console.warn(`Sequence event method '${a.functionName}' not found on actor`)}else a.time>s&&this.firedEvents.delete(i)}}evaluateCameraTrack(e,t){const s=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,s),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,s),t),s.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const s of e.clips??[]){if(!this.isCameraShakeClipActive(s,t))continue;const e=t-s.startTime,a=s.id;this.nextCameraShakeClipKeys.add(a),this.viewController.setCameraShakeContribution(this,a,s,e,s.seed??W(s.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader){for(const s of e.clips??[]){if(!this.isPostProcessClipActive(s,t))continue;const a=this.getPostProcessClipKey(e,s);this.nextPostProcessClipKeys.add(a),this.ensurePostProcessClipEffect(e,s,a);const i=this.activePostProcessClips.get(a);i?.handle&&(i.handle.stage=e.stage,i.handle.priority=e.priority,i.handle.enabled=!0,this.applyPostProcessClipWeight(i.handle,s,t))}this.evaluatePostProcessMaterialSubTracks(e,t)}}evaluatePostProcessMaterialSubTracks(e,t){for(const s of e.subTracks){if(s.muted||"material"!==s.type)continue;const a=M(s.keyframes,t,{min:s.range?.[0],max:s.range?.[1],stepOnly:Y(s)});a&&this.applyPostProcessMaterialValue(e.id,s,a)}}evaluateLightTrack(e,t){const s=this.ensureSequenceLight(e);if(this.applyLightTrackSettings(e,s),s.visible=(e.clips??[]).some(e=>t>=e.startTime&&t<e.startTime+e.duration),!s.visible)return;let a=this.lightPlayables.get(e.id);a||(a={target:s},this.lightPlayables.set(e.id,a)),this.evaluateSubTracks(e.subTracks,a,t)}ensureSequenceLight(e){let t=this.sequenceLights.get(e.id);return t?null==t.parent&&this.world?.scene.add(t):(t=new s.PointLight,t.name=e.name||"Sequence Point Light",t.userData.sequenceLightTrackId=e.id,t.visible=!1,this.sequenceLights.set(e.id,t),this.world?.scene.add(t)),t}applyLightTrackSettings(e,t){t.color.set(e.color??"#ffffff"),t.intensity=Math.max(0,e.intensity??10),t.distance=Math.max(0,e.distance??10),t.decay=Math.max(0,e.decay??2),t.castShadow=e.castShadow??!1,t.userData.volumetricIntensity=Math.max(0,e.volumetricIntensity??0)}clearSequenceLights(){for(const e of this.sequenceLights.values())e.removeFromParent(),e.dispose();this.sequenceLights.clear(),this.lightPlayables.clear()}applyPostProcessMaterialValue(e,t,s){if("shaderUniform"===w(t)&&t.uniformName)for(const a of this.activePostProcessClips.values()){if(a.trackId!==e||!a.handle)continue;const i=a.handle.material,r=i.uniforms?.[t.uniformName];if(!r)continue;const n=H(r.value,s);n.applied&&(r.value=n.value,i.uniformsNeedUpdate=!0,K(i))}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,s){const a=t.shaderGraphAssetId;if(!a)return void this.releasePostProcessClipEffect(s);const i=JSON.stringify(t.shaderGraphParams??{}),r=this.activePostProcessClips.get(s);if(r?.assetId===a&&r.paramsSignature===i)return;this.releasePostProcessClipEffect(s);const n={key:s,trackId:e.id,clipId:t.id,assetId:a,paramsSignature:i,version:this.clearCounter};this.activePostProcessClips.set(s,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,s){if(this.assetLoader&&this.viewController)try{const a=await this.assetLoader.getShaderGraphByAssetId(s.assetId);if(!this.isPostProcessClipEntryCurrent(s))return;if("postProcess"!==a.target)return console.warn(`Sequence post-process clip references shader graph "${s.assetId}" with target "${a.target}"`),void this.releasePostProcessClipEffect(s.key);const i=await this.assetLoader.prepareShaderGraphParameters(a,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(s))return;const r=Q(a,{parameters:i});if(!this.isPostProcessClipEntryCurrent(s))return void r.dispose();s.handle=this.viewController.addPostProcessEffect(r,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(s.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(s)&&this.releasePostProcessClipEffect(s.key),console.error(`Failed to create post-process effect for clip ${t.id}:`,e)}}isPostProcessClipEntryCurrent(e){return this.clearCounter===e.version&&this.activePostProcessClips.get(e.key)===e}applyPostProcessClipWeight(e,t,s){const a=e.material.uniforms?.[X];null!=a&&(a.value=this.getPostProcessClipWeight(t,s),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const s=Math.max(0,t-e.startTime),a=Math.max(0,e.startTime+e.duration-t);let i=1;const r=Math.max(0,e.fadeInDuration??0);r>0&&(i=Math.min(i,s/r));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(i=Math.min(i,a/n)),Math.max(0,Math.min(1,i))}syncPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.nextPostProcessClipKeys.has(e)||this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}clearPostProcessEffects(){for(const e of Array.from(this.activePostProcessClips.keys()))this.releasePostProcessClipEffect(e);this.nextPostProcessClipKeys.clear()}releasePostProcessClipEffect(e){const t=this.activePostProcessClips.get(e);if(t&&(this.activePostProcessClips.delete(e),t.handle)){const e=t.handle.material;t.handle.dispose(),e.dispose()}}getCameraPlayable(e,t){let s=this.cameraPlayables.get(e.id);return s?s.target=t:(s={target:t},this.cameraPlayables.set(e.id,s)),s}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const a=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new s.PerspectiveCamera(a.fov??60,this.getCurrentCameraAspect(),a.near??.1,a.far??1e3),t.name=e.name||"Sequence Camera",t.userData.sequenceCameraTrackId=e.id,t.layers.mask=this.viewController?.getBaseCamera().layers.mask??t.layers.mask,this.sequenceCameras.set(e.id,t),this.world?.scene.add(t)}return t}clearSequenceCameras(){this.releaseCameraOverride();for(const e of this.sequenceCameras.values())e.removeFromParent();this.sequenceCameras.clear(),this.cameraPlayables.clear()}applyCameraTrackSettings(e,t){const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=s.fov??60,t.near=s.near??.1,t.far=s.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof s.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof s.PerspectiveCamera&&Number.isFinite(t.aspect)&&t.aspect>0?t.aspect:1}updateCameraControl(e){if(!this._cameraControlEnabled||!this.viewController||!this.sequenceData)return void this.releaseCameraOverride();const t=this.findActiveCameraShot(e);if(t)return void this.updateActiveCameraShot(t,e);const s=this.findBlendOutCameraShot(e);s?this.updateCameraBlendOut(s,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const s of le(this.sequenceData.tracks)){if("camera"!==s.type||s.muted||!this.isCameraControlTrackEligible(s))continue;const a=s.clips??[];for(const i of a)this.isCameraClipActive(i,e)&&(t={track:s,clip:i,camera:this.ensureSequenceCamera(s),key:this.getCameraClipKey(s,i)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const s of le(this.sequenceData.tracks)){if("camera"!==s.type||s.muted||!this.isCameraControlTrackEligible(s))continue;const a=s.clips??[];for(const i of a){const a=Math.max(0,i.blendOutDuration??0);if(a<=0)continue;const r=this.getCameraClipEnd(i);e>=r&&e<r+a&&(t={track:s,clip:i,camera:this.ensureSequenceCamera(s),key:this.getCameraClipKey(s,i)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const s=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const a=Math.max(0,e.clip.blendInDuration??0),i=a<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/a,e.clip);i>=1?this.copyCameraState(e.camera,s):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,s,i),s.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const s=this.ensureCameraBlendCamera();if(this.cameraBlendOutClipKey!==e.key){const t=this.activeCameraClipKey===e.key?this.viewController.getSourceCamera():e.camera;this.copyCameraState(t,this.ensureCameraBlendOutSource()),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=e.key}const a=this.getCameraClipEnd(e.clip),i=Math.max(0,e.clip.blendOutDuration??0),r=i<=0?1:this.evaluateCameraBlendAlpha((t-a)/i,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),s,r),s.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new s.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new s.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new s.PerspectiveCamera),this.cameraBlendOutSource}ensureCameraOverride(){this.viewController&&!this.cameraOverrideHandle&&(this.cameraOverrideHandle=this.viewController.pushCameraOverride(this.ensureCameraBlendCamera(),this))}releaseCameraOverride(){this.cameraOverrideHandle?.release(),this.cameraOverrideHandle=null,this.viewController?.releaseCameraOverridesForOwner(this),this.activeCameraClipKey=null,this.cameraBlendOutClipKey=null}isCameraClipActive(e,t){return t>=e.startTime&&t<this.getCameraClipEnd(e)}getCameraClipEnd(e){return e.startTime+Math.max(0,e.duration)}isCameraShakeClipActive(e,t){return t>=e.startTime&&t<this.getCameraShakeClipEnd(e)}getCameraShakeClipEnd(e){return e.startTime+Math.max(0,e.duration)}getCameraClipKey(e,t){return`${e.id}-${t.id}`}evaluateCameraBlendAlpha(e,t){return I(Math.max(0,Math.min(1,e)),t.blendInterpolation??"cubic")}syncCameraShakeContributions(){if(!this.viewController)return this.activeCameraShakeClipKeys.clear(),void this.nextCameraShakeClipKeys.clear();for(const e of this.activeCameraShakeClipKeys)this.nextCameraShakeClipKeys.has(e)||this.viewController.removeCameraShakeContribution(this,e);this.activeCameraShakeClipKeys.clear();for(const e of this.nextCameraShakeClipKeys)this.activeCameraShakeClipKeys.add(e);this.nextCameraShakeClipKeys.clear()}clearCameraShakeContributions(){this.activeCameraShakeClipKeys.clear(),this.nextCameraShakeClipKeys.clear(),this.viewController?.clearCameraShakeContributionsForOwner(this)}copyCameraState(e,t){e.updateWorldMatrix(!0,!1),t.position.copy(e.getWorldPosition(pe)),t.quaternion.copy(e.getWorldQuaternion(ge)),t.scale.copy(e.getWorldScale(de)),e instanceof s.PerspectiveCamera?(t.fov=e.fov,t.near=e.near,t.far=e.far,t.aspect=e.aspect):t.aspect=this.getCurrentCameraAspect(),t.layers.mask=e.layers.mask}blendCameraState(e,t,a,i){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),a.position.lerpVectors(e.getWorldPosition(pe),t.getWorldPosition(de),i),a.quaternion.slerpQuaternions(e.getWorldQuaternion(ge),t.getWorldQuaternion(Ce),i),a.scale.lerpVectors(e.getWorldScale(pe),t.getWorldScale(de),i),e instanceof s.PerspectiveCamera&&t instanceof s.PerspectiveCamera?(a.fov=e.fov+(t.fov-e.fov)*i,a.near=e.near+(t.near-e.near)*i,a.far=e.far+(t.far-e.far)*i,a.aspect=t.aspect):t instanceof s.PerspectiveCamera?(a.fov=t.fov,a.near=t.near,a.far=t.far,a.aspect=t.aspect):a.aspect=this.getCurrentCameraAspect(),a.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const s=this._state.value===SequencePlaybackState.Playing,a=this.evaluateAudioSubTracks(e,t);e.volume;for(const i of e.clips){const r=i.startTime+i.duration,n=t>=i.startTime&&t<r,o=`${e.id}-${i.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),s){const s=this.audioByClip.get(o);s&&s.isPlaying||this.tryStartAudioClip(e,i,o,t,a)}const r=this.audioByClip.get(o);r&&this.applyAudioParameters(r,e,i,o,t,a)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,s,a,i){if(this.audioStartInFlight.has(s))return;const r=this.lastAudioStartAttemptTime.get(s);if(void 0!==r&&a-r<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(s,a);const n=this.playAudioClip(e,t,s,a,i).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(s)===n&&this.audioStartInFlight.delete(s)});this.audioStartInFlight.set(s,n)}applyAudioParameters(e,t,a,i,r,n){const o=n.volume??1,l=Math.random(),c=a.volumeRandomization?(2*l-1)*a.volumeRandomization:0;let h=1;const u=r-a.startTime;u<a.fadeInDuration&&a.fadeInDuration>0?h=u/a.fadeInDuration:u>a.duration-a.fadeOutDuration&&a.fadeOutDuration>0&&(h=(a.duration-u)/a.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(a.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(a.pitchRandomization){d+=(2*Math.random()-1)*a.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(a.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const a=this.audioListener.context,r=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(i);if(void 0!==o||void 0!==l)c||(c=a.createBiquadFilter(),this.audioFilters.set(i,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),r.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(i)}const h=n.pan;if(!t.spatial&&e instanceof s.Audio&&void 0!==h&&"function"==typeof a.createStereoPanner){let e=this.audioPannerNodes.get(i);e||(e=a.createStereoPanner(),this.audioPannerNodes.set(i,e)),e.pan.value=h,r.push(e)}else{const e=this.audioPannerNodes.get(i);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(i)}}e.setFilters(r)}t.spatial&&e instanceof s.PositionalAudio?this.updatePositionalAudioTransform(e,t,a,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,a,i){let r=null,n=null;const o=a.attachedToTrackId||t.parent?.trackId,l=a.attachmentSocketName||t.parent?.socketName;if(o){const e=this.sequenceData?.tracks.find(e=>e.id===o);if(e){const t=this.getActiveObjectsForTrack(e);if(t.length>0){const e=t[0];if(r=pe,n=ge,e.getWorldPosition(r),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(r),t.getWorldQuaternion(n))}}}}if(r&&n){const t="number"==typeof i?s.MathUtils.clamp(i,0,1):1;if(t<1&&this.audioListener){const e=fe;this.audioListener.getWorldPosition(e),r=r.clone().lerp(e,1-t)}e.position.copy(r),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,a,i,r){if(!this.assetLoader||!t.audioAssetId||null==this.audioListener)return;if("suspended"===this.audioListener.context.state)try{await this.audioListener.context.resume()}catch(e){return void console.warn("Failed to resume audio context:",e)}this.stopAudioClip(a);const n=this.clearCounter;try{let i=this.audioBuffers.get(t.audioAssetId);if(!i){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{i=await e,this.audioBuffers.set(t.audioAssetId,i)}finally{this.loadingAudioBuffers.delete(t.audioAssetId)}}if(n!==this.clearCounter)return;const o=this._time.value,l=t.startTime+t.duration;if(!(o>=t.startTime&&o<l))return;const c=Math.max(0,o-t.startTime),h=t.clipStartOffset+c*t.playbackRate;if(h>=i.duration||c>=t.duration)return;let u=this.audioByClip.get(a);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(a),u=void 0),!u){if(p){const e=new s.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new s.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(a,u)}Math.min((t.duration-c)/t.playbackRate,(i.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,i.duration)),u.setLoop(!0),u.setBuffer(i),this.applyAudioParameters(u,e,t,a,o,r),u.isPlaying||u.play()}catch(e){console.error(`Failed to play audio clip ${t.id}:`,e)}}stopAudioClip(e){const t=this.audioByClip.get(e);if(t){try{t.isPlaying&&t.stop()}catch(e){}t.parent&&t.parent.remove(t),this.audioByClip.delete(e)}const s=this.audioGainNodes.get(e);s&&(s.disconnect(),this.audioGainNodes.delete(e));const a=this.audioFilters.get(e);if(a){try{a.disconnect()}catch{}this.audioFilters.delete(e)}const i=this.audioPannerNodes.get(e);if(i){try{i.disconnect()}catch{}this.audioPannerNodes.delete(e)}}stopAllAudio(){for(const e of this.audioByClip.keys())this.stopAudioClip(e);this.activeAudioClips.clear(),this.audioStartInFlight.clear(),this.lastAudioStartAttemptTime.clear()}evaluateVfxTrack(e,t){if(!this.vfxService||!this.world||!e.clips||0===e.clips.length)return;if(this.shouldPreviewVfxAtSeekTime())return void this.previewVfxTrackAtSeekTime(e,t);const s=new Set,a=new Map,i=!e.parent||null!=this.getTrackParentObject(e);for(const r of e.clips){const n=this.getVfxClipKey(e,r);a.set(n,r),this.isVfxClipActiveAtTime(r,t)&&i&&s.add(n)}const r=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(s.has(t)||r.push(t));for(const e of r)this.activeVfxClips.delete(e);for(const[i,r]of a.entries()){const a=this.vfxActors.get(i);s.has(i)&&!this.activeVfxClips.has(i)?(this.activeVfxClips.add(i),this.ensureVfxActor(e,r,i)):s.has(i)&&a?this.updateVfxTransform(e,a,t):a&&this.applyInactiveVfxClipBehavior(r,a,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}isVfxClipActiveAtTime(e,t){const s=e.startTime+e.duration;return t>=e.startTime&&t<s}shouldPreviewVfxAtSeekTime(){return this._externalTimeControl&&this._inEditor&&this._state.value!==SequencePlaybackState.Playing}previewVfxTrackAtSeekTime(e,t){const s=new Set,a=!e.parent||null!=this.getTrackParentObject(e);for(const i of e.clips){const r=this.getVfxClipKey(e,i),n=this.vfxActors.get(r);this.isVfxClipActiveAtTime(i,t)&&a&&s.add(r),t<i.startTime||!a?n?.clearPreview():n?this.previewVfxActorAtSeekTime(e,i,n,t):this.ensureVfxActor(e,i,r)}for(const t of[...this.activeVfxClips])t.startsWith(`${e.id}-`)&&!s.has(t)&&this.activeVfxClips.delete(t);for(const e of s)this.activeVfxClips.add(e)}previewVfxActorAtSeekTime(e,t,s,a){const i=t.startTime+t.duration;this.updateVfxTransform(e,s,Math.min(a,i)),s.previewAt(a-t.startTime,t.duration,t.endBehavior,t.expireWithinSeconds,p(this.getVfxClipKey(e,t)))}resetVfxForTimeReset(e){const t=new Set;if(this.sequenceData)for(const s of le(this.sequenceData.tracks))if("vfx"===s.type)for(const a of s.clips??[])this.isVfxClipActiveAtTime(a,e)&&t.add(this.getVfxClipKey(s,a));this.activeVfxClips.clear();for(const[e,s]of this.vfxActors.entries())t.has(e)||(s.restart(),s.stop(),s.pause())}applyInactiveVfxClipBehavior(e,t,s){const a=e.endBehavior??"finish";if("finish"===a)return void t.stop();if("kill"===a)return void t.applyClipEndBehavior(a);const i=e.startTime+e.duration,r=Math.max(s-i,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-r);t.applyClipEndBehavior(a,o)}async ensureVfxActor(e,t,s){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(s)){const a=this.vfxActors.get(s);return!this.isVfxClipActiveAtTime(t,this._time.value)||e.parent&&null==this.getTrackParentObject(e)?void this.activeVfxClips.delete(s):(this.updateVfxTransform(e,a,this._time.value),this.updateTrackParenting(e,this.bindings.get(e.id)),a.restart(),void a.play())}const a=this.clearCounter;try{const i=this._inEditor&&this._externalTimeControl?{backend:"cpu"}:void 0,r=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene,i);if(a!==this.clearCounter)return void(this.world&&this.world.removeActor(r));const{position:n,rotation:o,scale:l}=this.getVfxTransform(e,t.startTime);if(r.object.position.copy(n),r.object.rotation.copy(o),r.object.scale.copy(l),r.onCollision=s=>{if(this._state.value!==SequencePlaybackState.Playing||null==this.onVfxCollision)return;const a=this.vfxCollisionEvent;a.trackId=e.id,a.clipId=t.id,a.vfxAssetId=t.vfxAssetId,a.emitterId=s.emitterId,a.emitterName=s.emitterName,a.position.copy(s.position),a.normal.copy(s.normal),this.onVfxCollision(a)},this.vfxActors.set(s,r),e.parent&&null==this.getTrackParentObject(e))return void this.activeVfxClips.delete(s);this.updateTrackParenting(e,this.bindings.get(e.id)),this.shouldPreviewVfxAtSeekTime()?this.previewVfxActorAtSeekTime(e,t,r,this._time.value):this._state.value===SequencePlaybackState.Playing&&this.isVfxClipActiveAtTime(t,this._time.value)&&r.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const s=new c,a=new r,i=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:r,prevIndex:l,nextIndex:c,t:h}=B(n.keyframes,t);if(n.components.position&&O(n.keyframes,l,c,h,s),e&&(e.rotation&&a.fromArray([...e.rotation,"XYZ"]),e.scale&&i.fromArray(e.scale)),r&&e!==r&&e.time!==r.time){const t=I(h,e.interpolation);if(e.rotation&&r.rotation){ge.setFromEuler(Ae.fromArray([...e.rotation,"XYZ"])),Ce.setFromEuler(Se.fromArray([...r.rotation,"XYZ"]));const s=new o;s.slerpQuaternions(ge,Ce,t),a.setFromQuaternion(s)}e.scale&&r.scale&&i.lerpVectors(pe.fromArray(e.scale),de.fromArray(r.scale),t)}}else s.fromArray(e.position),a.fromArray([...e.rotation,"XYZ"]),i.fromArray(e.scale);return{position:s,rotation:a,scale:i}}updateVfxTransform(e,t,s){const{position:a,rotation:i,scale:r}=this.getVfxTransform(e,s);t.object.position.copy(a),t.object.rotation.copy(i),t.object.scale.copy(r)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const s=f[e];return s||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,s,a){if(!this.world||!e.actorType)return null;const i=this.resolveActorType(e.actorType);if(!i)return null;try{return await this.world.spawnActor(i,s,a)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,s,a){if(!this.world||!this.assetLoader||!e.prefabId)return null;try{const t=await this.assetLoader.getPrefabById(e.prefabId);if(!t)return null;return await this.world.spawnPrefab(t,s,a)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,s,a){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),i=await this.assetLoader.getModelByAssetId(e.meshId),r=L.clone(i.scene);if(r.position.copy(s),r.rotation.copy(a),t){await this.assetLoader.applyMaterials(t,r);const e=t.mesh?.rescale;null!=e&&1!==e&&r.scale.multiplyScalar(e)}return this.world.scene.add(r),r}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(this.restoreVisibilitySnapshotsForInstance(e),this.restorePropertySnapshotsForInstance(e),this.restoreMaterialSnapshotsForInstance(e),this.world)switch(e?.type){case"actor":this.world.removeActor(e.instance);break;case"prefab":this.world.removePrefab(e.instance);break;case"mesh":this.world.scene.remove(e.instance)}}despawnAll(){for(const e of this.spawnedInstances.values())this.despawnInstance(e);this.spawnedInstances.clear(),this.activeClips.clear(),this.pendingSpawns.clear()}getInitialTransform(e,t,s){const a=new c,i=new r,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,prevIndex:t,nextIndex:r,t:o}=B(n.keyframes,s);n.components.position&&O(n.keyframes,t,r,o,a),e&&e.rotation&&i.fromArray([...e.rotation,"XYZ"])}else t.initialPosition&&a.fromArray(t.initialPosition),t.initialRotation&&i.fromArray([...t.initialRotation,"XYZ"]);return{position:a,rotation:i}}evaluateSpawnTrack(e,t,s){if(!e.clips||0===e.clips.length)return;const a=t||this.bindings.get(e.id);if(a&&a.target)for(const t of e.clips){const i=t.startTime+t.duration,r=s>=t.startTime&&s<i,n=`${e.id}-${t.id}`;if(r){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:a.target}));(a.target instanceof d?a.target.object:a.target)&&this.evaluateSubTracks(e.subTracks,a,s)}else if(this.activeClips.has(n)){e.clips.some(e=>e!==t&&s>=e.startTime&&s<e.startTime+e.duration)||this.deactivateAnimationSubTracks(e.subTracks,a),this.clearExternalRootMotionPreview(a),this.restorePropertySnapshotsForTarget(a.target),this.restoreMaterialSnapshotsForTarget(a.target),this.restoreVisibilitySnapshotForObject(this.getPlayableObject(a)),this.activeClips.delete(n),this.spawnedInstances.delete(n)}}else for(const t of e.clips){const a=t.startTime+t.duration,i=s>=t.startTime&&s<a,r=`${e.id}-${t.id}`,n=this.spawnedInstances.has(r),o=this.pendingSpawns.has(r);if(!i||n||o){if(i&&n){const t=this.spawnedInstances.get(r);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,s)}else if(!i&&n){const e=this.spawnedInstances.get(r);e&&(this.despawnInstance(e),this.spawnedInstances.delete(r),this.activeClips.delete(r))}}else{const{position:s,rotation:a}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(r),this.spawnForClip(e,t,s,a,r)}}}getInstanceObject(e){switch(e.type){case"actor":return e.instance.object;case"prefab":return e.instance.mainActor?.object||e.instance.object;case"mesh":return e.instance;case"proxy":return e.target instanceof d?e.target.object:e.target;default:return null}}async spawnForClip(e,t,s,i,r){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const a=await this.spawnActorForClip(e,t,s,i);a&&(o={type:"actor",instance:a});break;case"prefab":const r=await this.spawnPrefabForClip(e,t,s,i);r&&(o={type:"prefab",instance:r});break;case"mesh":const n=await this.spawnMeshForClip(e,t,s,i);n&&(o={type:"mesh",instance:n})}if(n!==this.clearCounter)return void(o&&this.despawnInstance(o));const l=this._time.value,c=l>=t.startTime&&l<t.startTime+t.duration;if(o&&c){const t=this.getInstanceObject(o);"proxy"===o.type||("actor"===o.type?o.target=o.instance:"prefab"===o.type?o.target=o.instance.mainActor||o.instance.object:o.target=t);e.subTracks.some(e=>"animation"===e.type)&&t&&(o.mixer=new a(t),o.activeActions=new Map),this.spawnedInstances.set(r,o),this.activeClips.add(r)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(r)}}getPlayableObject(e){return e.target instanceof d?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,s){if(!t||!e.propertyPath)return;const a=this.getPropertyResolution(t,e);if(!a)return;const i=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,i,a);const n=function(e,t){switch(t.type){case v.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.Vector2:return ee(e,t.value);case v.Vector3:return te(e,t.value);case v.Vector4:return se(e,t.value);case v.Euler:return function(e,t){const s=ie(t,3);if(!s)return{applied:!1};const a=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof r)return e.set(s[0],s[1],s[2],a),{applied:!0,value:e};return{applied:!0,value:new r(s[0],s[1],s[2],a)}}(e,t.value);case v.Color:return ae(e,t.value);default:return{applied:!1}}}(a.owner[a.key],s);n.applied&&(a.owner[a.key]=n.value)}getPropertyResolution(e,t){const s=e,a=this.getPropertySnapshotKey(t);let i=this.propertyResolutionCache.get(s);if(i||(i=new Map,this.propertyResolutionCache.set(s,i)),i.has(a))return i.get(a)??null;const r=this.getPropertyPathSegments(t.propertyPath);if(0===r.length)return i.set(a,null),null;let n=e;for(let e=0;e<r.length-1;e++){if(!Z(n))return i.set(a,null),null;n=n[r[e]]}if(!Z(n))return i.set(a,null),null;const o={owner:n,key:r[r.length-1]};return i.set(a,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const s=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,s),s}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,s){const a=e;let i=this.propertySnapshots.get(a);if(i||(i=new Map,this.propertySnapshots.set(a,i)),i.has(t))return;const r=s.owner[s.key];i.set(t,{resolution:s,hadOwnProperty:Object.prototype.hasOwnProperty.call(s.owner,s.key),value:r,valueSnapshot:ne(r)})}restorePropertySnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restorePropertySnapshotsForTarget(e.instance);break;case"prefab":this.restorePropertySnapshotsForTarget(e.target??null),this.restorePropertySnapshotsForTarget(e.instance.mainActor??null),this.restorePropertySnapshotsForTarget(e.instance.object);break;case"proxy":this.restorePropertySnapshotsForTarget(e.target)}}restorePropertySnapshotsForTarget(e){if(!e)return;const t=e,s=this.propertySnapshots.get(t);if(s){for(const e of s.values())oe(e);this.propertySnapshots.delete(t),this.propertyResolutionCache.delete(t)}}restoreAllPropertySnapshots(){for(const e of Array.from(this.propertySnapshots.keys()))this.restorePropertySnapshotsForTarget(e)}restoreMaterialSnapshotsForInstance(e){switch(e.type){case"actor":case"mesh":this.restoreMaterialSnapshotsForTarget(e.instance);break;case"prefab":this.restoreMaterialSnapshotsForTarget(e.target??null),this.restoreMaterialSnapshotsForTarget(e.instance.mainActor??null),this.restoreMaterialSnapshotsForTarget(e.instance.object);break;case"proxy":this.restoreMaterialSnapshotsForTarget(e.target)}}restoreMaterialSnapshotsForTarget(e){if(!e)return;const t=e;this.materialResolutionCache.delete(t);const s=this.materialSnapshots.get(t);if(s){for(const e of s.values())null==e.materialIndex?e.owner.material=e.originalMaterial:Array.isArray(e.owner.material)&&(e.owner.material[e.materialIndex]=e.originalMaterial),e.controlledMaterial!==e.originalMaterial&&e.controlledMaterial.dispose();this.materialSnapshots.delete(t)}}restoreAllMaterialSnapshots(){for(const e of Array.from(this.materialSnapshots.keys()))this.restoreMaterialSnapshotsForTarget(e)}restoreVisibilitySnapshotForObject(e){if(!e)return;const t=this.visibilitySnapshots.get(e);t&&(e.visible=t.visible,this.visibilitySnapshots.delete(e))}restoreVisibilitySnapshotsForInstance(e){this.restoreVisibilitySnapshotForObject(this.getInstanceObject(e))}restoreAllVisibilitySnapshots(){for(const e of Array.from(this.visibilitySnapshots.keys()))this.restoreVisibilitySnapshotForObject(e)}applyResolvedMaterialValue(e,t,s){if(!t)return;if("asset"===b(e)&&!e.materialAssetId)return;if("outlineVisibility"===w(e))return void this.applyResolvedMaterialOutlineVisibility(e,t,s);if(!e.uniformName)return;const a=this.getMaterialSlotResolutions(t,e);for(const i of a){const a=this.ensureSequenceControlledMaterial(t,i),r=a.uniforms?.[e.uniformName];if(!r)continue;const n=H(r.value,s);n.applied&&(r.value=n.value,a.uniformsNeedUpdate=!0,K(a))}}applyResolvedMaterialOutlineVisibility(e,t,s){if(s.type!==v.Boolean||"boolean"!=typeof s.value)return;const a=this.getMaterialSlotResolutions(t,e);for(const e of a){const a=this.ensureSequenceControlledMaterial(t,e),i=a.userData?.outlineParameters;null!=i&&(i.visible=s.value)}}getMaterialSlotResolutions(e,t){const s=e,a=b(t),i=w(t),r=`${t.id}:${i}:${a}:${t.materialAssetId??""}:${t.uniformName}`;let n=this.materialResolutionCache.get(s);n||(n=new Map,this.materialResolutionCache.set(s,n));const o=n.get(r);if(o)return o;const l=e instanceof d?e.object:e,c=[];return l.traverse(e=>{const s=e.material;if(Array.isArray(s))for(let a=0;a<s.length;a++){const i=s[a];J(i,t)&&c.push({owner:e,materialIndex:a,material:i,key:`${e.uuid}:${a}`})}else J(s,t)&&c.push({owner:e,materialIndex:null,material:s,key:`${e.uuid}:material`})}),n.set(r,c),c}ensureSequenceControlledMaterial(e,t){const s=e;let a=this.materialSnapshots.get(s);a||(a=new Map,this.materialSnapshots.set(s,a));const i=a.get(t.key);if(i)return i.controlledMaterial;const r=t.material.clone();return $(r,!1!==t.material.uniformValuesAutoUpdate),r.userData={...t.material.userData??{}},null!=t.material.userData?.outlineParameters&&(r.userData.outlineParameters={...t.material.userData.outlineParameters}),null==t.materialIndex?t.owner.material=r:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=r),a.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:r}),r}animationClipCacheKey(e,t){return`${e}|${t??""}`}async ensureAnimationClip(e,t){if(!this.assetLoader)return null;const s=this.animationClipCacheKey(e,t),a=this.animationClips.get(s);if(a)return a;const i=this.loadingAnimationClips.get(s);if(i)return i;const r=(async()=>{try{const a=await this.assetLoader.getAnimationClipForTargetByAssetId(e,t);return a&&this.animationClips.set(s,a),a}catch(s){return console.error(`Failed to load animation clip for asset ${e}`+(null==t?"":` and target rig ${t}`)+":",s),null}finally{this.loadingAnimationClips.get(s)===r&&this.loadingAnimationClips.delete(s)}})();return this.loadingAnimationClips.set(s,r),r}prepareAnimationPlayback(e,t,s){if(!j(s)){let e=t;return s.clipEndOffset>0&&(e=e.clone(),U(e,G(t)),e.duration=Math.max(0,e.duration-s.clipEndOffset)),s.rootMotion&&(e=F(e,s)),{clip:e,timeScale:s.playbackRate*this._timescale,startOffset:s.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,s,!1),timeScale:1*this._timescale,startOffset:0}}getPlayableAnimationClip(e,t,s,a){if(!j(s)){const e=s.rootMotion?F(t,s):t;return a?D.fromClip(e,!1):e}const i=`${s.id}:${a?"root":"base"}`,r=`${E(s)}|${a?"root":"base"}`,n=this.retimedAnimationClips.get(i);if(n&&n.assetId===e&&n.signature===r)return n.clip;const o=V(t,s),l=s.rootMotion?F(o,s):o,c=a?D.fromClip(l,!1):l;return this.retimedAnimationClips.set(i,{assetId:e,signature:r,clip:c}),c}getAnimationPlaybackLocalTime(e,t){const s=Math.max(0,t-e.startTime);return j(e)?s:s*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,s]of this.retimedAnimationClips.entries())s.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof d?e.target.object:e.target;t&&(e.originalTransform={position:t.position.clone(),rotation:t.rotation.clone(),scale:t.scale.clone()})}}restoreOriginalTransforms(){for(const e of this.bindings.values())if(e.originalTransform){const t=e.target instanceof d?e.target.object:e.target;t&&(t.position.copy(e.originalTransform.position),t.rotation.copy(e.originalTransform.rotation),t.scale.copy(e.originalTransform.scale))}}stopAllAnimations(){for(const e of this.bindings.values()){for(const[t,s]of e.activeActions.entries())e.charAnimActionKeys?.has(t)||s.stop();e.activeActions.clear(),e.mixer&&e.mixer.stopAllAction(),e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0),e.charAnimActionKeys?.clear()}}stopAllVfx(){for(const e of this.vfxActors.values())e.paused||e.stop();this.activeVfxClips.clear()}dispose(){if(this.stop(),this.clearLocatorBindings(),this.clearSequenceCameras(),this.clearSequenceLights(),this.bindings.clear(),this.roleBindings.clear(),this.sequenceData=null,this.world)for(const e of this.vfxActors.values())this.world.removeActor(e);this.vfxActors.clear(),this.stopAllAudio(),this.audioBuffers.clear(),this.loadingAudioBuffers.clear(),this.animationClips.clear(),this.loadingAnimationClips.clear(),this.clearRetimedAnimationClipCache(),this.audioByClip.clear()}updateTrackParenting(e,t){const s=this.getActiveObjectsForTrack(e);if(0===s.length)return;const a="spawn"===e.type&&null!=t?.target,i=this.getTrackParentObject(e);for(const r of s)i?r.parent!==i&&(i.add(r),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=i)):t?.currentParent&&t.currentParent===r.parent?this.restoreObjectParent(t,r):r.parent&&r.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&!a&&this.world?.scene.attach(r)}getTrackParentObject(e){let t=null;const s=e.parent?.trackId;if(s){const a=this.sequenceData?le(this.sequenceData.tracks).find(e=>e.id===s):void 0;if(a){const s=this.getActiveObjectsForTrack(a);if(s.length>0&&(t=s[0],e.parent?.socketName)){const s=this.findSocket(t,e.parent.socketName);s&&(t=s)}}}if(!t&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const s=this.roleBindings.get(e.parentRole);if(t=s instanceof d?s.object:s,e.parentRoleSocketName){const s=this.findSocket(t,e.parentRoleSocketName);s&&(t=s)}}return t}findSocket(e,t){if(e.name===t)return e;if(e instanceof s.SkinnedMesh){const s=e.skeleton.bones.find(e=>e.name===t);if(s)return s}return e.getObjectByName(t)||null}getActiveObjectsForTrack(e){if("object"===e.type){const t=this.bindings.get(e.id);if(t&&t.target)return[t.target instanceof d?t.target.object:t.target]}else if("locator"===e.type){const t=this.bindings.get(e.id);if(t&&t.target instanceof n)return[t.target]}else{if("camera"===e.type)return[this.ensureSequenceCamera(e)];if("light"===e.type)return[this.ensureSequenceLight(e)];if("spawn"===e.type){const t=[];for(const[s,a]of this.spawnedInstances)if(s.startsWith(e.id+"-")&&this.activeClips.has(s)){const e=this.getInstanceObject(a);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const s of this.activeVfxClips)if(s.startsWith(e.id+"-")){const e=this.vfxActors.get(s);e&&t.push(e.object)}return t}}return[]}restoreObjectParent(e,t){e.originalParent?e.originalParent.add(t):this.world&&this.world.scene.add(t),e.currentParent=void 0}restoreOriginalParents(){for(const e of this.bindings.values())if(e.currentParent){const t=e.target instanceof d?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const s={};for(const a of e.subTracks)if("audioParameter"===a.type){const e=a,i=S(e.parameter),r=q(e.keyframes,t,{min:i.min,max:i.max});void 0!==r&&(s[e.parameter]=r)}return s}stringToRandom(e){let t=0;for(let s=0;s<e.length;s++){t=(t<<5)-t+e.charCodeAt(s),t&=t}const s=1e4*Math.sin(t);return s-Math.floor(s)}async refreshAsset(e){let t=!1;this.assetLoader?.clearCacheById(e),this.animationClips.delete(e),this.loadingAnimationClips.delete(e),this.clearRetimedAnimationClipCache(e),this.vfxService?.clearPool(e),t=this.refreshVfxActorsForAssetIds(new Set([e]))||t;for(const[s,a]of this.activePostProcessClips.entries())a.assetId===e&&(this.releasePostProcessClipEffect(s),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const s=await this.getAssetOrNull(e);return"shaderGraph"===s?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[s,a]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(s,e)&&(this.world&&this.world.removeActor(a),this.vfxActors.delete(s),this.activeVfxClips.delete(s),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const s of t)if(e.endsWith(`-${s}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[s,a]of this.spawnedInstances.entries())e.has(s)&&(this.despawnInstance(a),this.spawnedInstances.delete(s),this.activeClips.delete(s),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const s of le(this.sequenceData.tracks))if("spawn"===s.type&&(s.prefabId===e||s.meshId===e))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const s=this.refreshVfxActorsForAssetIds(t),a=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return s||a}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const s=new Map;for(const a of le(this.sequenceData.tracks))if("vfx"===a.type)for(const i of a.clips)null==i.vfxAssetId||t.has(i.vfxAssetId)||await this.assetUsesShaderGraph(i.vfxAssetId,e,s)&&t.add(i.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const s=new Map;for(const a of le(this.sequenceData.tracks))if("spawn"===a.type&&await this.spawnTrackUsesShaderGraph(a,e,s))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,s){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,s))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,s))return!0;for(const a of e.subTracks??[])if("material"===a.type&&null!=a.materialAssetId&&await this.assetUsesShaderGraph(a.materialAssetId,t,s))return!0;return!1}assetUsesShaderGraph(e,t,s,a=new Set){if(e===t)return Promise.resolve(!0);if(a.has(e))return Promise.resolve(!1);if(s.has(e))return s.get(e);const i=this.assetUsesShaderGraphUncached(e,t,s,a);return s.set(e,i),i}async assetUsesShaderGraphUncached(e,t,s,a){if(a.has(e))return!1;const i=await this.getAssetOrNull(e);if(null==i)return!1;const r=new Set(a);return r.add(e),!!this.materialAssetUsesShaderGraph(i,t)||("mesh"===i.type?this.materialAssignmentsUseShaderGraph(i.materialAssignments,t,s,r):"prefab"===i.type?this.sceneObjectsUseShaderGraph(i.prefab?.objects,t,s,r):"vfx"===i.type&&this.vfxAssetUsesShaderGraph(i,t,s,r))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,s,a){for(const i of e??[])if(null!=i.materialId&&"null"!==i.materialId&&await this.assetUsesShaderGraph(i.materialId,t,s,a))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,s,a){for(const i of e??[]){if(await this.materialAssignmentsUseShaderGraph(i.materialAssignments,t,s,a))return!0;if(null!=i.assetId&&("asset_mesh"===i.type||"prefab"===i.type||"vfx"===i.type)&&await this.assetUsesShaderGraph(i.assetId,t,s,a))return!0;if(await this.sceneObjectsUseShaderGraph(i.children,t,s,a))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,s,a){for(const i of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(i,t,s,a))return!0;return!1}async emitterUsesShaderGraph(e,t,s,a){if(await this.emitterOutputUsesShaderGraph(e.output,t,s,a))return!0;for(const i of e.children??[])if(await this.emitterUsesShaderGraph(i,t,s,a))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,s,a){const i=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===i&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==i||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,s,a))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,s,a){let i=!1;for(let e=0;e<a.length;e++)if(g(a[e])){i=!0;break}if(i)try{const t=new Array(a.length);for(let e=0;e<a.length;e++)t[e]=C(a[e],this.sequenceEventAsyncResolvers);const i=await Promise.all(t);await s.call(e,...i)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(a.length);for(let e=0;e<a.length;e++)t[e]=A(a[e],this.sequenceEventSyncResolvers);s.call(e,...t)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}}resolveSequenceEventActorReference(e){if(!this.world||null==e)return null;const t=e,s="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==s)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===s)return e}return null}resolveSequenceEventSequence(e){return k(e)?new P(e):this.assetLoader&&"string"==typeof e?this.assetLoader.getSequenceById(e):null}async resolveSequenceEventAnimationClip(e){const t="string"==typeof e?e:"object"==typeof e&&null!=e?e.assetId??null:null;return null!=t&&this.assetLoader?this.assetLoader.getAnimationClipByAssetId(t):null}}function z(e){return e.options?.length>0||e.propertyType===v.Boolean||e.propertyType===v.String}function Y(e){return"outlineVisibility"===w(e)||e.valueType===v.Boolean||e.valueType===v.String}function Z(e){return"object"==typeof e&&null!=e||"function"==typeof e}function H(e,t){switch(t.type){case v.Number:return function(e){if("number"==typeof e)return Number.isFinite(e)?{applied:!0,value:e}:{applied:!1};if("string"==typeof e){const t=parseFloat(e);return Number.isFinite(t)?{applied:!0,value:t}:{applied:!1}}return{applied:!1}}(t.value);case v.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case v.Vector2:return ee(e,t.value);case v.Vector3:return te(e,t.value);case v.Vector4:return se(e,t.value);case v.Color:return function(e,t){if(e instanceof c){const s=be.set(0);return re(s,t)?(e.set(s.r,s.g,s.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const s=be.set(0);return re(s,t)?(e.set(s.r,s.g,s.b,e.w),{applied:!0,value:e}):{applied:!1}}return ae(e,t)}(e,t.value);default:return{applied:!1}}}function J(e,t){const a=b(t);return!!function(e){return e instanceof s.Material||!0===e?.isMaterial}(e)&&(("asset"!==a||e.userData?.assetId===t.materialAssetId)&&("outlineVisibility"===w(t)?null!=e.userData?.outlineParameters:null!=e.uniforms?.[t.uniformName]))}function ee(e,t){const s=ie(t,2);return s?e instanceof l?(e.fromArray(s),{applied:!0,value:e}):{applied:!0,value:new l(s[0],s[1])}:{applied:!1}}function te(e,t){const s=ie(t,3);return s?e instanceof c?(e.fromArray(s),{applied:!0,value:e}):{applied:!0,value:new c(s[0],s[1],s[2])}:{applied:!1}}function se(e,t){const s=ie(t,4);return s?e instanceof h?(e.fromArray(s),{applied:!0,value:e}):{applied:!0,value:new h(s[0],s[1],s[2],s[3])}:{applied:!1}}function ae(e,t){if(e instanceof i)return re(e,t)?{applied:!0,value:e}:{applied:!1};const s=new i;return re(s,t)?{applied:!0,value:s}:{applied:!1}}function ie(e,t){if(!Array.isArray(e)||e.length<t)return null;const s=new Array(t);for(let a=0;a<t;a++){if("number"!=typeof e[a])return null;s[a]=e[a]}return s}function re(e,t){return t instanceof i||"string"==typeof t||"number"==typeof t?(e.set(t),!0):!!(Array.isArray(t)&&t.length>=3)&&(e.setRGB("number"==typeof t[0]?t[0]:0,"number"==typeof t[1]?t[1]:0,"number"==typeof t[2]?t[2]:0),!0)}function ne(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof i||e instanceof r)return e.clone()}function oe(e){const{owner:t,key:s}=e.resolution;e.hadOwnProperty?(!function(e,t){if(e instanceof l&&t instanceof l)return e.copy(t),!0;if(e instanceof c&&t instanceof c)return e.copy(t),!0;if(e instanceof h&&t instanceof h)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0;if(e instanceof r&&t instanceof r)return e.copy(t),!0}(e.value,e.valueSnapshot),t[s]=e.value):delete t[s]}function le(e){const t=[];for(const s of e)t.push(s),"group"===s.type&&t.push(...le(s.childTracks));return t}function ce(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function he(e){const t=new s.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const a=new s.AxesHelper(.35);a.renderOrder=1e3;const i=Array.isArray(a.material)?a.material:[a.material];for(const e of i)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(a);const r=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const a=t.getContext("2d");if(!a)return null;a.clearRect(0,0,t.width,t.height),a.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,s,a,i,r){const n=t+a,o=s+i;e.beginPath(),e.moveTo(t+r,s),e.lineTo(n-r,s),e.quadraticCurveTo(n,s,n,s+r),e.lineTo(n,o-r),e.quadraticCurveTo(n,o,n-r,o),e.lineTo(t+r,o),e.quadraticCurveTo(t,o,t,o-r),e.lineTo(t,s+r),e.quadraticCurveTo(t,s,t+r,s),e.closePath()}(a,0,8,t.width,48,8),a.fill(),a.font="24px sans-serif",a.textAlign="center",a.textBaseline="middle",a.fillStyle="#f8fafc",a.fillText(e||"Locator",t.width/2,t.height/2);const i=new s.CanvasTexture(t);i.needsUpdate=!0;const r=new s.SpriteMaterial({map:i,transparent:!0,depthTest:!1});r.toneMapped=!1;const n=new s.Sprite(r);return n.scale.set(.9,.225,1),n}(e);return r&&(r.position.set(0,.45,0),r.renderOrder=1001,t.add(r)),t.traverse(e=>{e.raycast=()=>{}}),t}function ue(e){e.traverse(e=>{const t=e.material;if(Array.isArray(t))for(const e of t)e?.dispose?.(),e?.map?.dispose?.();else t?.dispose?.(),t?.map?.dispose?.()})}const pe=new c,de=new c,fe=new c,me=new c,ye=new c,ve=new c,ge=new o,Ce=new o,Ae=new r,Se=new r,be=new i;/*
|
|
2
2
|
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
3
|
* See the LICENSE.md file for details.
|
|
4
4
|
*/
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { WebGpuMaterialUniform } from 'three-shader-graph';
|
|
2
|
+
export declare function materialUniformLayout(uniforms: Record<string, WebGpuMaterialUniform>): {
|
|
3
|
+
entries: {
|
|
4
|
+
name: string;
|
|
5
|
+
uniform: WebGpuMaterialUniform;
|
|
6
|
+
offset: number;
|
|
7
|
+
size: number;
|
|
8
|
+
}[];
|
|
9
|
+
byteLength: number;
|
|
10
|
+
};
|
|
11
|
+
/** Packing storage belongs to a compiled shader resource with a fixed uniform layout. */
|
|
12
|
+
export declare class GpuMaterialUniformData {
|
|
13
|
+
readonly data: ArrayBuffer;
|
|
14
|
+
private readonly layout;
|
|
15
|
+
private readonly view;
|
|
16
|
+
private readonly floats;
|
|
17
|
+
private readonly bits;
|
|
18
|
+
private readonly previous;
|
|
19
|
+
constructor(uniforms: Record<string, WebGpuMaterialUniform>);
|
|
20
|
+
/** Sync live values without allocating; returns whether GPU-visible bytes changed. */
|
|
21
|
+
update(uniforms: Record<string, WebGpuMaterialUniform>): boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=gpu-material-uniforms.d.ts.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import*as t from"three";export function materialUniformLayout(t){let e=0;return{entries:Object.entries(t).map(([t,s])=>{const[i,a]=function(t){switch(t){case"f32":case"i32":case"u32":return[4,4];case"vec2<f32>":return[8,8];case"vec3<f32>":return[16,12];case"vec4<f32>":return[16,16];case"mat3x3<f32>":return[16,48];case"mat4x4<f32>":return[16,64]}}(s.type);e=Math.ceil(e/i)*i;const o={name:t,uniform:s,offset:e,size:a};return e+=a,o}),byteLength:Math.max(16,16*Math.ceil(e/16))}}export class GpuMaterialUniformData{constructor(t){this.layout=materialUniformLayout(t),this.data=new ArrayBuffer(this.layout.byteLength),this.view=new DataView(this.data),this.floats=new Float32Array(this.data),this.bits=new Uint32Array(this.data),this.previous=new Uint32Array(this.bits.length),this.update(t)}update(e){this.floats.fill(0);for(const s of this.layout.entries){const i=e[s.name].value,a=s.offset/4,o=s.uniform.type;if("number"==typeof i||"boolean"==typeof i){const t="boolean"==typeof i?i?1:0:i;"i32"===o?this.view.setInt32(s.offset,t,!0):"u32"===o?this.view.setUint32(s.offset,t,!0):this.floats[a]=t}else if(Array.isArray(i)||"elements"in i){const t=Array.isArray(i)?i:i.elements,e="mat3x3<f32>"===o?9:s.size/4;for(let i=0;i<Math.min(e,t.length);i++){const e="mat3x3<f32>"===o?4*Math.floor(i/3)+i%3:i;"i32"===o?this.view.setInt32(s.offset,t[i],!0):"u32"===o?this.view.setUint32(s.offset,t[i],!0):this.floats[a+e]=t[i]}}else i instanceof t.Color?(this.floats[a]=i.r,this.floats[a+1]=i.g,this.floats[a+2]=i.b):(i instanceof t.Vector2||i instanceof t.Vector3||i instanceof t.Vector4)&&(this.floats[a]=i.x,this.floats[a+1]=i.y,(i instanceof t.Vector3||i instanceof t.Vector4)&&(this.floats[a+2]=i.z),i instanceof t.Vector4&&(this.floats[a+3]=i.w))}let s=!1;for(let t=0;t<this.bits.length;t++)s||(s=this.bits[t]!==this.previous[t]),this.previous[t]=this.bits[t];return s}}/*
|
|
2
|
+
* Copyright (©) 2026 Hology Interactive AB. All rights reserved.
|
|
3
|
+
* See the LICENSE.md file for details.
|
|
4
|
+
*/
|