@hology/core 0.0.210 → 0.0.212

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.
Files changed (129) hide show
  1. package/dist/effects/sequence/sequence-player.js +1 -1
  2. package/dist/effects/vfx/initializsers.d.ts +8 -1
  3. package/dist/effects/vfx/initializsers.js +1 -1
  4. package/dist/effects/vfx/vfx-collision-behaviour.js +1 -1
  5. package/dist/effects/vfx/vfx-defs.d.ts +10 -1
  6. package/dist/effects/vfx/vfx-defs.js +1 -1
  7. package/dist/effects/vfx/vfx-materializer.js +1 -1
  8. package/dist/effects/vfx/vfx-renderers.d.ts +1 -0
  9. package/dist/effects/vfx/vfx-renderers.js +1 -1
  10. package/dist/gameplay/actors/actor.d.ts +23 -1
  11. package/dist/gameplay/actors/actor.js +1 -1
  12. package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
  13. package/dist/gameplay/actors/builtin/components/character/character-movement-like.d.ts +23 -0
  14. package/dist/gameplay/actors/builtin/components/character/character-movement-like.js +4 -0
  15. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.d.ts +26 -0
  16. package/dist/gameplay/actors/builtin/components/character/character-movement-policy.js +4 -0
  17. package/dist/gameplay/actors/builtin/components/character/character-movement.d.ts +145 -55
  18. package/dist/gameplay/actors/builtin/components/character/character-movement.js +1 -1
  19. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.d.ts +125 -0
  20. package/dist/gameplay/actors/builtin/components/character/net-character-movement-protocol.js +4 -0
  21. package/dist/gameplay/actors/builtin/components/character/old-character-movement.d.ts +100 -0
  22. package/dist/gameplay/actors/builtin/components/character/old-character-movement.js +4 -0
  23. package/dist/gameplay/actors/builtin/components/index.d.ts +2 -0
  24. package/dist/gameplay/actors/builtin/components/index.js +1 -1
  25. package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
  26. package/dist/gameplay/actors/camera/third-person-camera-component.d.ts +3 -0
  27. package/dist/gameplay/actors/camera/third-person-camera-component.js +1 -1
  28. package/dist/gameplay/actors/component.js +1 -1
  29. package/dist/gameplay/actors/controller/actor-controller.d.ts +16 -0
  30. package/dist/gameplay/actors/controller/actor-controller.js +4 -0
  31. package/dist/gameplay/actors/factory.d.ts +3 -0
  32. package/dist/gameplay/actors/factory.js +1 -1
  33. package/dist/gameplay/actors/index.d.ts +4 -0
  34. package/dist/gameplay/actors/index.js +1 -1
  35. package/dist/gameplay/actors/internal/component-init.js +1 -1
  36. package/dist/gameplay/ai/behavior-tree/move.d.ts +2 -2
  37. package/dist/gameplay/index.d.ts +3 -1
  38. package/dist/gameplay/index.js +1 -1
  39. package/dist/gameplay/initiate.d.ts +4 -0
  40. package/dist/gameplay/initiate.js +1 -1
  41. package/dist/gameplay/net/browser/index.d.ts +147 -0
  42. package/dist/gameplay/net/browser/index.js +4 -0
  43. package/dist/gameplay/net/index.d.ts +7 -0
  44. package/dist/gameplay/net/index.js +4 -0
  45. package/dist/gameplay/net/net-connection.d.ts +25 -0
  46. package/dist/gameplay/net/net-connection.js +4 -0
  47. package/dist/gameplay/net/net-session.d.ts +70 -0
  48. package/dist/gameplay/net/net-session.js +4 -0
  49. package/dist/gameplay/net/service/net-actor-role.d.ts +12 -0
  50. package/dist/gameplay/net/service/net-actor-role.js +4 -0
  51. package/dist/gameplay/net/service/net-decorator.d.ts +29 -0
  52. package/dist/gameplay/net/service/net-decorator.js +4 -0
  53. package/dist/gameplay/net/service/net-serializer.d.ts +15 -0
  54. package/dist/gameplay/net/service/net-serializer.js +4 -0
  55. package/dist/gameplay/net/service/net-service.d.ts +171 -0
  56. package/dist/gameplay/net/service/net-service.js +4 -0
  57. package/dist/gameplay/net/service/net-utils.d.ts +8 -0
  58. package/dist/gameplay/net/service/net-utils.js +4 -0
  59. package/dist/gameplay/net/service/replication.d.ts +31 -0
  60. package/dist/gameplay/net/service/replication.js +4 -0
  61. package/dist/gameplay/net/service/rpc-decorator.d.ts +21 -0
  62. package/dist/gameplay/net/service/rpc-decorator.js +4 -0
  63. package/dist/gameplay/net/service/rpc.d.ts +35 -0
  64. package/dist/gameplay/net/service/rpc.js +4 -0
  65. package/dist/gameplay/services/asset-loader.d.ts +3 -2
  66. package/dist/gameplay/services/asset-loader.js +1 -1
  67. package/dist/gameplay/services/physics/abstract-physics-system.d.ts +1 -1
  68. package/dist/gameplay/services/physics/physics-system.d.ts +4 -2
  69. package/dist/gameplay/services/physics/physics-system.js +1 -1
  70. package/dist/gameplay/services/world.d.ts +13 -2
  71. package/dist/gameplay/services/world.js +1 -1
  72. package/dist/rendering/color-pass.js +1 -1
  73. package/dist/rendering.d.ts +2 -0
  74. package/dist/rendering.js +1 -1
  75. package/dist/scene/asset-resource-loader.js +1 -1
  76. package/dist/scene/batched-mesh-2.d.ts +9 -0
  77. package/dist/scene/batched-mesh-2.js +1 -1
  78. package/dist/scene/bootstrap.d.ts +2 -0
  79. package/dist/scene/bootstrap.js +1 -1
  80. package/dist/scene/custom-param-runtime-types.js +1 -1
  81. package/dist/scene/landscape/landscape-manager.d.ts +2 -1
  82. package/dist/scene/landscape/landscape-manager.js +1 -1
  83. package/dist/scene/materializer.d.ts +50 -1
  84. package/dist/scene/materializer.js +1 -1
  85. package/dist/scene/model.d.ts +2 -0
  86. package/dist/scene/scatter/painted-scatter-manager.d.ts +45 -0
  87. package/dist/scene/scatter/painted-scatter-manager.js +4 -0
  88. package/dist/scene/scatter/scatter-limits.d.ts +2 -0
  89. package/dist/scene/scatter/scatter-limits.js +4 -0
  90. package/dist/scene/scatter/surface-scatter-manager.js +1 -1
  91. package/dist/scene/storage/storage.d.ts +1 -1
  92. package/dist/scene/storage/storage.js +1 -1
  93. package/dist/shader/builtin/standard-shader.js +1 -1
  94. package/dist/shader/builtin/toon-shader.js +1 -1
  95. package/dist/shader/builtin/unlit-shader.js +1 -1
  96. package/dist/shader/color-layer.js +1 -1
  97. package/dist/shader/graph/compiler.d.ts +7 -4
  98. package/dist/shader/graph/compiler.js +1 -1
  99. package/dist/shader/graph/model.d.ts +1 -1
  100. package/dist/shader/graph/model.js +1 -1
  101. package/dist/shader/graph/parameters.js +1 -1
  102. package/dist/shader/parameter.d.ts +1 -1
  103. package/dist/shader/parameter.js +1 -1
  104. package/dist/shader/sprite-shader.js +1 -1
  105. package/dist/shader-nodes/depth.js +1 -1
  106. package/dist/shader-nodes/scene-sample.js +1 -1
  107. package/dist/test/batched-mesh-2.test.d.ts +2 -0
  108. package/dist/test/batched-mesh-2.test.js +4 -0
  109. package/dist/test/browser-net-session.test.d.ts +2 -0
  110. package/dist/test/browser-net-session.test.js +4 -0
  111. package/dist/test/first-person-camera-component.test.js +1 -1
  112. package/dist/test/net-character-movement.test.d.ts +2 -0
  113. package/dist/test/net-character-movement.test.js +4 -0
  114. package/dist/test/net-property-snapshot.test.d.ts +2 -0
  115. package/dist/test/net-property-snapshot.test.js +4 -0
  116. package/dist/test/painted-scatter-manager.test.d.ts +2 -0
  117. package/dist/test/painted-scatter-manager.test.js +4 -0
  118. package/dist/test/runtime-param-type-inference.test.js +1 -1
  119. package/dist/test/sequence-animation-retiming.test.js +1 -1
  120. package/dist/test/sequence-post-process.test.js +1 -1
  121. package/dist/test/shader-graph.test.js +1 -1
  122. package/dist/test/vfx-random-color-initializer.test.d.ts +2 -0
  123. package/dist/test/vfx-random-color-initializer.test.js +4 -0
  124. package/dist/test/world-prefab-spawn.test.d.ts +2 -0
  125. package/dist/test/world-prefab-spawn.test.js +4 -0
  126. package/dist/utils/three/placeholder-texture.d.ts +3 -0
  127. package/dist/utils/three/placeholder-texture.js +4 -0
  128. package/package.json +10 -2
  129. package/tsconfig.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import{BehaviorSubject as e,Subject as t}from"rxjs";import*as a from"three";import{AnimationMixer as s,Color as r,Euler as i,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{BaseActor as p}from"../../gameplay/actors/actor.js";import d from"../../gameplay/actors/builtin/index.js";import{Prefab as f,PrefabOf as m}from"../../scene/objects/prefab.js";import{SerializedParamType as y}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as C,deserializeCustomParamValue as v,deserializeCustomParamValueSync as g}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as A}from"./audio-parameters.js";import{getMaterialSubTrackMatchMode as S,Sequence as w}from"./sequence-data.js";import{getSequenceSubTrackDefinition as P,getSequenceTrackDefinition as b}from"./sequence-definitions.js";import{applyInterpolation as k,evaluateCustomParamValueKeyframes as x,evaluateNumericKeyframes as T,findKeyframeSpan as I}from"./sequence-value-lane.js";import{buildRetimedAnimationClip as M,getAnimationClipRetimingSignature as q,isAnimationClipUsingRetiming as B}from"./sequence-animation-retiming.js";import{SkeletonUtils as O}from"three-stdlib";import{CharacterAnimationComponent as F,CharacterMovementComponent as E}from"../../gameplay/actors/index.js";import{RootMotionClip as j}from"../../gameplay/animation/root-motion.js";import{hashCameraShakeSeed as L}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as _,shaderGraphPostProcessWeightUniformName as R}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.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.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,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.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 f(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(new f(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,a)=>{t&&this.evaluateObjectTrack(e,t,a)},locator:(e,t,a)=>{t&&this.evaluateLocatorTrack(e,t,a)},camera:(e,t,a)=>this.evaluateCameraTrack(e,a),cameraShake:(e,t,a)=>this.evaluateCameraShakeTrack(e,a),postProcess:(e,t,a)=>this.evaluatePostProcessTrack(e,a),audio:(e,t,a)=>this.evaluateAudioTrack(e,a),vfx:(e,t,a)=>this.evaluateVfxTrack(e,a),spawn:(e,t,a)=>this.evaluateSpawnTrack(e,t,a),group:(e,t,a)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,a)}},this.subTrackRuntimeEvaluators={transform:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateTransformSubTrack(e,s,a)},animation:(e,t,a)=>this.evaluateAnimationSubTrack(e,t,a),visibility:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateVisibilitySubTrack(e,s,a)},parameter:(e,t,a)=>this.evaluateParameterSubTrack(e,t.target||null,a),event:(e,t,a)=>this.evaluateEventSubTrack(e,t.target||null,a)}}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.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.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 a of e.tracks){if("audio"!==a.type)continue;const e=a;for(const a of e.clips??[])a.audioAssetId&&t.add(a.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const a=this.getAudioAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let a=this.loadingAudioBuffers.get(e);a||(a=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,a));try{const s=await a;if(t!==this.clearCounter)return;this.audioBuffers.set(e,s)}catch(e){}finally{this.loadingAudioBuffers.get(e)===a&&this.loadingAudioBuffers.delete(e)}}))}getAnimationClipAssetIdsForSequence(e){const t=new Set;for(const a of H(e.tracks))if("subTracks"in a)for(const e of a.subTracks)if("animation"===e.type)for(const a of e.clips)a.animationClipAssetId&&t.add(a.animationClipAssetId);return[...t]}async preloadAnimationClipsForSequence(e,t){if(!this.assetLoader)return;const a=this.getAnimationClipAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{t===this.clearCounter&&await this.ensureAnimationClip(e)}))}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const a of this.sequenceData.tracks)"object"===a.type&&a.targetId===e&&this.createBinding(a,t)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=J(e);if(!t||!this.sequenceData)return[];const a=[];for(const e of H(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(J(e.bindingId)!==t)continue;const s=this.bindings.get(e.id),r=s?this.getPlayableObject(s):null;r&&(r.updateWorldMatrix(!0,!1),a.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:r.getWorldPosition(new c),rotation:r.getWorldQuaternion(new o),scale:r.getWorldScale(new c)}))}return a}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of H(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 a=ee(e.name);a.visible=this._inEditor,t.add(a),this.locatorMarkers.set(e.id,a),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())te(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 a=t instanceof p?t.object:t,r=this.bindings.get(e.id),i=null!=r?r.target instanceof p?r.target.object:r.target:null,n=null!=r&&r.target===t&&i===a,o=e.subTracks.some(e=>"animation"===e.type);if(null!=r&&!n){for(const e of r.activeActions.values())e.stop();r.activeActions.clear(),r.mixer?.stopAllAction(),r.charAnimComponent?.stopSequenceAnimation(),r.charAnimComponent=void 0,r.charAnimActionKeys?.clear()}const l=n?r:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,l.originalTransform={position:a.position.clone(),rotation:a.rotation.clone(),scale:a.scale.clone()},l.originalParent=a.parent,o&&null==l.mixer?l.mixer=new s(a):o||(l.mixer=void 0),this.bindings.set(e.id,l)}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.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}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.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.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),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 t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===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 a=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[b(e.type).runtimeEvaluator])(e,a,t)}evaluateObjectTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}evaluateLocatorTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=H(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,a){for(const s of e){if(s.muted)continue;(0,this.subTrackRuntimeEvaluators[P(s.type).runtimeEvaluator])(s,t,a)}}evaluateTransformSubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;const{prev:r,next:i,t:n}=I(s,a);if(r)if(i&&r!==i){const a=k(n,r.interpolation);e.components.position&&r.position&&i.position&&t.position.lerpVectors(ae.fromArray(r.position),se.fromArray(i.position),a),e.components.rotation&&r.rotation&&i.rotation&&(ie.setFromEuler(oe.fromArray([...r.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"])),t.quaternion.slerpQuaternions(ie,ne,a)),e.components.scale&&r.scale&&i.scale&&t.scale.lerpVectors(ae.fromArray(r.scale),se.fromArray(i.scale),a)}else e.components.position&&r.position&&t.position.fromArray(r.position),e.components.rotation&&r.rotation&&t.rotation.fromArray([...r.rotation,"XYZ"]),e.components.scale&&r.scale&&t.scale.fromArray(r.scale)}evaluateAnimationSubTrack(e,t,s){if(!t.mixer||!t.activeActions)return;if(t.target instanceof p?t.target.object:t.target)for(const r of e.clips){const i=r.startTime+r.duration,n=s>=r.startTime&&s<i,o=`${e.id}-${r.id}`;let l=t.activeActions.get(o),c=!1;if(n){if(!l){c=!0;const e=r.animationClipAssetId;if(null==e)continue;const s=this.animationClips.get(e);if(null==s){this.ensureAnimationClip(e);continue}const i=this.prepareAnimationPlayback(e,s,r),n=t;let h=!1;if(t.target instanceof p){n.charAnimComponent||(n.charAnimComponent=t.target.getComponent(F)??void 0);const a=n.charAnimComponent;if(null!=a){const c=r.rootMotion?B(r)?this.getPlayableAnimationClip(e,s,r,!0):j.fromClip(i.clip,!1):i.clip;if(this._externalTimeControl)l=a.beginExternalAnimationControl(c,{timeScale:i.timeScale});else if(a.play(c,{inPlace:!r.rootMotion,loop:!1,priority:20,timeScale:i.timeScale,fadeTime:r.fadeInDuration??.2,offset:i.startOffset}),l=a.getFullBodyAction(),r.rootMotion){const e=t.target.getComponent(E);e&&e.setRootMotionAction(l,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(o,l),n.charAnimActionKeys||(n.charAnimActionKeys=new Set),n.charAnimActionKeys.add(o),h=!0}}h||(l=t.mixer.clipAction(i.clip),l.setLoop(a.LoopOnce,1),l.clampWhenFinished=!0,l.timeScale=i.timeScale,i.startOffset>0&&(l.time=i.startOffset),t.activeActions.set(o,l),l.play())}if(l){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const a=this.getAnimationPlaybackLocalTime(r,s),i=Math.min(a,l.getClip().duration);(c||Math.abs(l.time-i)>.001)&&(l.time=i,l.paused=!1,l.play(),e.charAnimComponent?e.charAnimComponent.getMixer()?.update(0):t.mixer&&t.mixer.update(0))}else e.charAnimComponent?.endExternalControl()}}else if(l){t.activeActions.delete(o);const e=t;e.charAnimActionKeys?.has(o)?(e.charAnimActionKeys.delete(o),l.stop(),0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0)):(l.stop(),this._externalTimeControl&&t.mixer&&t.mixer.update(0))}}}evaluateVisibilitySubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;let r=s[0];for(const e of s){if(!(e.time<=a))break;r=e}t.visible=r.visible}evaluatePropertySubTrack(e,t,a){const s=x(e.keyframes,a,{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)});s&&this.applyResolvedPropertyValue(e,t,s)}evaluateParameterSubTrack(e,t,a){if("audioParameter"===e.type)return;const s=x(e.keyframes,a,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:D(e)}:{});s&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,s):this.applyResolvedPropertyValue(e,t,s))}evaluateEventSubTrack(e,t,a){if(t instanceof p&&this._state.value===SequencePlaybackState.Playing)for(const s of e.events){const r=`${e.id}-${s.id}`;if(a>=s.time&&!this.firedEvents.has(r)){if(this.firedEvents.add(r),s.editorOnly&&!this._inEditor)continue;if(!s.functionName)continue;const e=t[s.functionName];"function"==typeof e?this.invokeSequenceEvent(t,s.functionName,e,s.arguments??[]):console.warn(`Sequence event method '${s.functionName}' not found on actor`)}else s.time>a&&this.firedEvents.delete(r)}}evaluateCameraTrack(e,t){const a=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,a),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,a),t),a.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const a of e.clips??[]){if(!this.isCameraShakeClipActive(a,t))continue;const e=t-a.startTime,s=a.id;this.nextCameraShakeClipKeys.add(s),this.viewController.setCameraShakeContribution(this,s,a,e,a.seed??L(a.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader){for(const a of e.clips??[]){if(!this.isPostProcessClipActive(a,t))continue;const s=this.getPostProcessClipKey(e,a);this.nextPostProcessClipKeys.add(s),this.ensurePostProcessClipEffect(e,a,s);const r=this.activePostProcessClips.get(s);r?.handle&&(r.handle.stage=e.stage,r.handle.priority=e.priority,r.handle.enabled=!0,this.applyPostProcessClipWeight(r.handle,a,t))}this.evaluatePostProcessMaterialSubTracks(e,t)}}evaluatePostProcessMaterialSubTracks(e,t){for(const a of e.subTracks){if(a.muted||"material"!==a.type)continue;const s=x(a.keyframes,t,{min:a.range?.[0],max:a.range?.[1],stepOnly:D(a)});s&&this.applyPostProcessMaterialValue(e.id,a,s)}}applyPostProcessMaterialValue(e,t,a){if(t.uniformName)for(const s of this.activePostProcessClips.values()){if(s.trackId!==e||!s.handle)continue;const r=s.handle.material,i=r.uniforms?.[t.uniformName];if(!i)continue;const n=G(i.value,a);n.applied&&(i.value=n.value,r.uniformsNeedUpdate=!0)}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,a){const s=t.shaderGraphAssetId;if(!s)return void this.releasePostProcessClipEffect(a);const r=JSON.stringify(t.shaderGraphParams??{}),i=this.activePostProcessClips.get(a);if(i?.assetId===s&&i.paramsSignature===r)return;this.releasePostProcessClipEffect(a);const n={key:a,trackId:e.id,clipId:t.id,assetId:s,paramsSignature:r,version:this.clearCounter};this.activePostProcessClips.set(a,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,a){if(this.assetLoader&&this.viewController)try{const s=await this.assetLoader.getShaderGraphByAssetId(a.assetId);if(!this.isPostProcessClipEntryCurrent(a))return;if("postProcess"!==s.target)return console.warn(`Sequence post-process clip references shader graph "${a.assetId}" with target "${s.target}"`),void this.releasePostProcessClipEffect(a.key);const r=await this.assetLoader.prepareShaderGraphParameters(s,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(a))return;const i=_(s,{parameters:r});if(!this.isPostProcessClipEntryCurrent(a))return void i.dispose();a.handle=this.viewController.addPostProcessEffect(i,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(a.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(a)&&this.releasePostProcessClipEffect(a.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,a){const s=e.material.uniforms?.[R];null!=s&&(s.value=this.getPostProcessClipWeight(t,a),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const a=Math.max(0,t-e.startTime),s=Math.max(0,e.startTime+e.duration-t);let r=1;const i=Math.max(0,e.fadeInDuration??0);i>0&&(r=Math.min(r,a/i));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(r=Math.min(r,s/n)),Math.max(0,Math.min(1,r))}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 a=this.cameraPlayables.get(e.id);return a?a.target=t:(a={target:t},this.cameraPlayables.set(e.id,a)),a}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new a.PerspectiveCamera(s.fov??60,this.getCurrentCameraAspect(),s.near??.1,s.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 a=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=a.fov??60,t.near=a.near??.1,t.far=a.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof a.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof a.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 a=this.findBlendOutCameraShot(e);a?this.updateCameraBlendOut(a,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s)this.isCameraClipActive(r,e)&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s){const s=Math.max(0,r.blendOutDuration??0);if(s<=0)continue;const i=this.getCameraClipEnd(r);e>=i&&e<i+s&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const s=Math.max(0,e.clip.blendInDuration??0),r=s<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/s,e.clip);r>=1?this.copyCameraState(e.camera,a):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,a,r),a.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const a=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 s=this.getCameraClipEnd(e.clip),r=Math.max(0,e.clip.blendOutDuration??0),i=r<=0?1:this.evaluateCameraBlendAlpha((t-s)/r,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),a,i),a.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new a.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new a.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new a.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 k(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(ae)),t.quaternion.copy(e.getWorldQuaternion(ie)),t.scale.copy(e.getWorldScale(se)),e instanceof a.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,s,r){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),s.position.lerpVectors(e.getWorldPosition(ae),t.getWorldPosition(se),r),s.quaternion.slerpQuaternions(e.getWorldQuaternion(ie),t.getWorldQuaternion(ne),r),s.scale.lerpVectors(e.getWorldScale(ae),t.getWorldScale(se),r),e instanceof a.PerspectiveCamera&&t instanceof a.PerspectiveCamera?(s.fov=e.fov+(t.fov-e.fov)*r,s.near=e.near+(t.near-e.near)*r,s.far=e.far+(t.far-e.far)*r,s.aspect=t.aspect):t instanceof a.PerspectiveCamera?(s.fov=t.fov,s.near=t.near,s.far=t.far,s.aspect=t.aspect):s.aspect=this.getCurrentCameraAspect(),s.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const a=this._state.value===SequencePlaybackState.Playing,s=this.evaluateAudioSubTracks(e,t);e.volume;for(const r of e.clips){const i=r.startTime+r.duration,n=t>=r.startTime&&t<i,o=`${e.id}-${r.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),a){const a=this.audioByClip.get(o);a&&a.isPlaying||this.tryStartAudioClip(e,r,o,t,s)}const i=this.audioByClip.get(o);i&&this.applyAudioParameters(i,e,r,o,t,s)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,a,s,r){if(this.audioStartInFlight.has(a))return;const i=this.lastAudioStartAttemptTime.get(a);if(void 0!==i&&s-i<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(a,s);const n=this.playAudioClip(e,t,a,s,r).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(a)===n&&this.audioStartInFlight.delete(a)});this.audioStartInFlight.set(a,n)}applyAudioParameters(e,t,s,r,i,n){const o=n.volume??1,l=Math.random(),c=s.volumeRandomization?(2*l-1)*s.volumeRandomization:0;let h=1;const u=i-s.startTime;u<s.fadeInDuration&&s.fadeInDuration>0?h=u/s.fadeInDuration:u>s.duration-s.fadeOutDuration&&s.fadeOutDuration>0&&(h=(s.duration-u)/s.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(s.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(s.pitchRandomization){d+=(2*Math.random()-1)*s.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(s.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const s=this.audioListener.context,i=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(r);if(void 0!==o||void 0!==l)c||(c=s.createBiquadFilter(),this.audioFilters.set(r,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),i.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(r)}const h=n.pan;if(!t.spatial&&e instanceof a.Audio&&void 0!==h&&"function"==typeof s.createStereoPanner){let e=this.audioPannerNodes.get(r);e||(e=s.createStereoPanner(),this.audioPannerNodes.set(r,e)),e.pan.value=h,i.push(e)}else{const e=this.audioPannerNodes.get(r);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(r)}}e.setFilters(i)}t.spatial&&e instanceof a.PositionalAudio?this.updatePositionalAudioTransform(e,t,s,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,s,r){let i=null,n=null;const o=s.attachedToTrackId||t.parent?.trackId,l=s.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(i=ae,n=ie,e.getWorldPosition(i),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(i),t.getWorldQuaternion(n))}}}}if(i&&n){const t="number"==typeof r?a.MathUtils.clamp(r,0,1):1;if(t<1&&this.audioListener){const e=re;this.audioListener.getWorldPosition(e),i=i.clone().lerp(e,1-t)}e.position.copy(i),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,s,r,i){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(s);const n=this.clearCounter;try{let r=this.audioBuffers.get(t.audioAssetId);if(!r){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{r=await e,this.audioBuffers.set(t.audioAssetId,r)}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>=r.duration||c>=t.duration)return;let u=this.audioByClip.get(s);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(s),u=void 0),!u){if(p){const e=new a.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new a.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(s,u)}Math.min((t.duration-c)/t.playbackRate,(r.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,r.duration)),u.setLoop(!0),u.setBuffer(r),this.applyAudioParameters(u,e,t,s,o,i),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 a=this.audioGainNodes.get(e);a&&(a.disconnect(),this.audioGainNodes.delete(e));const s=this.audioFilters.get(e);if(s){try{s.disconnect()}catch{}this.audioFilters.delete(e)}const r=this.audioPannerNodes.get(e);if(r){try{r.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;const a=new Set,s=new Map;for(const r of e.clips){const i=this.getVfxClipKey(e,r);s.set(i,r),this.isVfxClipActiveAtTime(r,t)&&a.add(i)}const r=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(a.has(t)||r.push(t));for(const e of r)this.activeVfxClips.delete(e);for(const[r,i]of s.entries()){const s=this.vfxActors.get(r);a.has(r)&&!this.activeVfxClips.has(r)?(this.activeVfxClips.add(r),this.ensureVfxActor(e,i,r)):a.has(r)&&s?(this.updateVfxTransform(e,s,t),this._state.value===SequencePlaybackState.Playing&&s.play()):s&&this.applyInactiveVfxClipBehavior(i,s,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}isVfxClipActiveAtTime(e,t){const a=e.startTime+e.duration;return t>=e.startTime&&t<a}resetVfxForTimeReset(e){const t=new Set;if(this.sequenceData)for(const a of H(this.sequenceData.tracks))if("vfx"===a.type)for(const s of a.clips??[])this.isVfxClipActiveAtTime(s,e)&&t.add(this.getVfxClipKey(a,s));this.activeVfxClips.clear();for(const[e,a]of this.vfxActors.entries())t.has(e)||(a.restart(),a.stop(),a.pause())}applyInactiveVfxClipBehavior(e,t,a){const s=e.endBehavior??"finish";if("finish"===s)return void t.stop();if("kill"===s)return void t.applyClipEndBehavior(s);const r=e.startTime+e.duration,i=Math.max(a-r,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-i);t.applyClipEndBehavior(s,o)}async ensureVfxActor(e,t,a){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(a)){const e=this.vfxActors.get(a);return e.restart(),void e.play()}const s=this.clearCounter;try{const r=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene);if(s!==this.clearCounter)return void(this.world&&this.world.removeActor(r));const{position:i,rotation:n,scale:o}=this.getVfxTransform(e,t.startTime);r.object.position.copy(i),r.object.rotation.copy(n),r.object.scale.copy(o),this.vfxActors.set(a,r),this._state.value===SequencePlaybackState.Playing&&r.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const a=new c,s=new i,r=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:i,t:l}=I(n.keyframes,t);if(e&&(e.position&&a.fromArray(e.position),e.rotation&&s.fromArray([...e.rotation,"XYZ"]),e.scale&&r.fromArray(e.scale)),i&&e!==i&&e.time!==i.time){const t=k(l,e.interpolation);if(e.position&&i.position&&a.lerpVectors(ae.fromArray(e.position),se.fromArray(i.position),t),e.rotation&&i.rotation){ie.setFromEuler(oe.fromArray([...e.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"]));const a=new o;a.slerpQuaternions(ie,ne,t),s.setFromQuaternion(a)}e.scale&&i.scale&&r.lerpVectors(ae.fromArray(e.scale),se.fromArray(i.scale),t)}}else a.fromArray(e.position),s.fromArray([...e.rotation,"XYZ"]),r.fromArray(e.scale);return{position:a,rotation:s,scale:r}}updateVfxTransform(e,t,a){const{position:s,rotation:r,scale:i}=this.getVfxTransform(e,a);t.object.position.copy(s),t.object.rotation.copy(r),t.object.scale.copy(i)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const a=d[e];return a||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,a,s){if(!this.world||!e.actorType)return null;const r=this.resolveActorType(e.actorType);if(!r)return null;try{return await this.world.spawnActor(r,a,s)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,a,s){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,a,s)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),r=await this.assetLoader.getModelByAssetId(e.meshId),i=O.clone(r.scene);if(i.position.copy(a),i.rotation.copy(s),t){await this.assetLoader.applyMaterials(t,i);const e=t.mesh?.rescale;null!=e&&1!==e&&i.scale.multiplyScalar(e)}return this.world.scene.add(i),i}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(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,a){const s=new c,r=new i,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e}=I(n.keyframes,a);e&&(e.position&&s.fromArray(e.position),e.rotation&&r.fromArray([...e.rotation,"XYZ"]))}else t.initialPosition&&s.fromArray(t.initialPosition),t.initialRotation&&r.fromArray([...t.initialRotation,"XYZ"]);return{position:s,rotation:r}}evaluateSpawnTrack(e,t,a){if(!e.clips||0===e.clips.length)return;const s=t||this.bindings.get(e.id);if(s&&s.target)for(const t of e.clips){const r=t.startTime+t.duration,i=a>=t.startTime&&a<r,n=`${e.id}-${t.id}`;if(i){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:s.target}));(s.target instanceof p?s.target.object:s.target)&&this.evaluateSubTracks(e.subTracks,s,a)}else this.activeClips.has(n)&&(this.restorePropertySnapshotsForTarget(s.target),this.restoreMaterialSnapshotsForTarget(s.target),this.activeClips.delete(n),this.spawnedInstances.delete(n))}else for(const t of e.clips){const s=t.startTime+t.duration,r=a>=t.startTime&&a<s,i=`${e.id}-${t.id}`,n=this.spawnedInstances.has(i),o=this.pendingSpawns.has(i);if(!r||n||o){if(r&&n){const t=this.spawnedInstances.get(i);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,a)}else if(!r&&n){const e=this.spawnedInstances.get(i);e&&(this.despawnInstance(e),this.spawnedInstances.delete(i),this.activeClips.delete(i))}}else{const{position:a,rotation:s}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(i),this.spawnForClip(e,t,a,s,i)}}}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 p?e.target.object:e.target;default:return null}}async spawnForClip(e,t,a,r,i){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const s=await this.spawnActorForClip(e,t,a,r);s&&(o={type:"actor",instance:s});break;case"prefab":const i=await this.spawnPrefabForClip(e,t,a,r);i&&(o={type:"prefab",instance:i});break;case"mesh":const n=await this.spawnMeshForClip(e,t,a,r);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 s(t),o.activeActions=new Map),this.spawnedInstances.set(i,o),this.activeClips.add(i)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(i)}}getPlayableObject(e){return e.target instanceof p?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,a){if(!t||!e.propertyPath)return;const s=this.getPropertyResolution(t,e);if(!s)return;const r=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,r,s);const n=function(e,t){switch(t.type){case y.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Euler:return function(e,t){const a=Q(t,3);if(!a)return{applied:!1};const s=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof i)return e.set(a[0],a[1],a[2],s),{applied:!0,value:e};return{applied:!0,value:new i(a[0],a[1],a[2],s)}}(e,t.value);case y.Color:return X(e,t.value);default:return{applied:!1}}}(s.owner[s.key],a);n.applied&&(s.owner[s.key]=n.value)}getPropertyResolution(e,t){const a=e,s=this.getPropertySnapshotKey(t);let r=this.propertyResolutionCache.get(a);if(r||(r=new Map,this.propertyResolutionCache.set(a,r)),r.has(s))return r.get(s)??null;const i=this.getPropertyPathSegments(t.propertyPath);if(0===i.length)return r.set(s,null),null;let n=e;for(let e=0;e<i.length-1;e++){if(!K(n))return r.set(s,null),null;n=n[i[e]]}if(!K(n))return r.set(s,null),null;const o={owner:n,key:i[i.length-1]};return r.set(s,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const a=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,a),a}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,a){const s=e;let r=this.propertySnapshots.get(s);if(r||(r=new Map,this.propertySnapshots.set(s,r)),r.has(t))return;const i=a.owner[a.key];r.set(t,{resolution:a,hadOwnProperty:Object.prototype.hasOwnProperty.call(a.owner,a.key),value:i,valueSnapshot:Z(i)})}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,a=this.propertySnapshots.get(t);if(a){for(const e of a.values())z(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 a=this.materialSnapshots.get(t);if(a){for(const e of a.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)}applyResolvedMaterialValue(e,t,a){if(!t||!e.uniformName)return;if("asset"===S(e)&&!e.materialAssetId)return;const s=this.getMaterialSlotResolutions(t,e);for(const r of s){const s=this.ensureSequenceControlledMaterial(t,r),i=s.uniforms?.[e.uniformName];if(!i)continue;const n=G(i.value,a);n.applied&&(i.value=n.value,s.uniformsNeedUpdate=!0)}}getMaterialSlotResolutions(e,t){const a=e,s=S(t),r=`${t.id}:${s}:${t.materialAssetId??""}:${t.uniformName}`;let i=this.materialResolutionCache.get(a);i||(i=new Map,this.materialResolutionCache.set(a,i));const n=i.get(r);if(n)return n;const o=e instanceof p?e.object:e,l=[];return o.traverse(e=>{const a=e.material;if(Array.isArray(a))for(let s=0;s<a.length;s++){const r=a[s];$(r,t)&&l.push({owner:e,materialIndex:s,material:r,key:`${e.uuid}:${s}`})}else $(a,t)&&l.push({owner:e,materialIndex:null,material:a,key:`${e.uuid}:material`})}),i.set(r,l),l}ensureSequenceControlledMaterial(e,t){const a=e;let s=this.materialSnapshots.get(a);s||(s=new Map,this.materialSnapshots.set(a,s));const r=s.get(t.key);if(r)return r.controlledMaterial;const i=t.material.clone();return i.userData={...t.material.userData??{}},null==t.materialIndex?t.owner.material=i:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=i),s.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:i}),i}async ensureAnimationClip(e){if(!this.assetLoader)return null;const t=this.animationClips.get(e);if(t)return t;const a=this.loadingAnimationClips.get(e);if(a)return a;const s=(async()=>{try{const t=await this.assetLoader.getAnimationClipByAssetId(e);return t&&this.animationClips.set(e,t),t}catch(t){return console.error(`Failed to load animation clip for asset ${e}:`,t),null}finally{this.loadingAnimationClips.get(e)===s&&this.loadingAnimationClips.delete(e)}})();return this.loadingAnimationClips.set(e,s),s}prepareAnimationPlayback(e,t,a){if(!B(a)){let e=t;return a.clipEndOffset>0&&(e=e.clone(),e.duration=Math.max(0,e.duration-a.clipEndOffset)),{clip:e,timeScale:a.playbackRate,startOffset:a.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,a,!1),timeScale:1,startOffset:0}}getPlayableAnimationClip(e,t,a,s){if(!B(a))return s?j.fromClip(t,!1):t;const r=`${a.id}:${s?"root":"base"}`,i=`${q(a)}|${s?"root":"base"}`,n=this.retimedAnimationClips.get(r);if(n&&n.assetId===e&&n.signature===i)return n.clip;const o=M(t,a),l=s?j.fromClip(o,!1):o;return this.retimedAnimationClips.set(r,{assetId:e,signature:i,clip:l}),l}getAnimationPlaybackLocalTime(e,t){const a=Math.max(0,t-e.startTime);return B(e)?a:a*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,a]of this.retimedAnimationClips.entries())a.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof p?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 p?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 of e.activeActions.values())t.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.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 a=this.getActiveObjectsForTrack(e);if(0===a.length)return;let s=null;const r=e.parent?.trackId;if(r){const t=this.sequenceData?H(this.sequenceData.tracks).find(e=>e.id===r):void 0;if(t){const a=this.getActiveObjectsForTrack(t);if(a.length>0&&(s=a[0],e.parent?.socketName)){const t=this.findSocket(s,e.parent.socketName);t&&(s=t)}}}if(!s&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const t=this.roleBindings.get(e.parentRole);if(s=t instanceof p?t.object:t,e.parentRoleSocketName){const t=this.findSocket(s,e.parentRoleSocketName);t&&(s=t)}}for(const r of a)s?r.parent!==s&&(s.add(r),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=s)):t?.currentParent&&t.currentParent===r.parent?this.restoreObjectParent(t,r):r.parent&&r.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&this.world?.scene.add(r)}findSocket(e,t){if(e.name===t)return e;if(e instanceof a.SkinnedMesh){const a=e.skeleton.bones.find(e=>e.name===t);if(a)return a}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 p?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("spawn"===e.type){const t=[];for(const[a,s]of this.spawnedInstances)if(a.startsWith(e.id+"-")&&this.activeClips.has(a)){const e=this.getInstanceObject(s);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const a of this.activeVfxClips)if(a.startsWith(e.id+"-")){const e=this.vfxActors.get(a);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 p?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const a={};for(const s of e.subTracks)if("audioParameter"===s.type){const e=s,r=A(e.parameter),i=T(e.keyframes,t,{min:r.min,max:r.max});void 0!==i&&(a[e.parameter]=i)}return a}stringToRandom(e){let t=0;for(let a=0;a<e.length;a++){t=(t<<5)-t+e.charCodeAt(a),t&=t}const a=1e4*Math.sin(t);return a-Math.floor(a)}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[a,s]of this.activePostProcessClips.entries())s.assetId===e&&(this.releasePostProcessClipEffect(a),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const a=await this.getAssetOrNull(e);return"shaderGraph"===a?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[a,s]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(a,e)&&(this.world&&this.world.removeActor(s),this.vfxActors.delete(a),this.activeVfxClips.delete(a),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const a of t)if(e.endsWith(`-${a}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[a,s]of this.spawnedInstances.entries())e.has(a)&&(this.despawnInstance(s),this.spawnedInstances.delete(a),this.activeClips.delete(a),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const a of H(this.sequenceData.tracks))if("spawn"===a.type&&(a.prefabId===e||a.meshId===e))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const a=this.refreshVfxActorsForAssetIds(t),s=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return a||s}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("vfx"===s.type)for(const r of s.clips)null==r.vfxAssetId||t.has(r.vfxAssetId)||await this.assetUsesShaderGraph(r.vfxAssetId,e,a)&&t.add(r.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("spawn"===s.type&&await this.spawnTrackUsesShaderGraph(s,e,a))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,a){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,a))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,a))return!0;for(const s of e.subTracks??[])if("material"===s.type&&null!=s.materialAssetId&&await this.assetUsesShaderGraph(s.materialAssetId,t,a))return!0;return!1}assetUsesShaderGraph(e,t,a,s=new Set){if(e===t)return Promise.resolve(!0);if(s.has(e))return Promise.resolve(!1);if(a.has(e))return a.get(e);const r=this.assetUsesShaderGraphUncached(e,t,a,s);return a.set(e,r),r}async assetUsesShaderGraphUncached(e,t,a,s){if(s.has(e))return!1;const r=await this.getAssetOrNull(e);if(null==r)return!1;const i=new Set(s);return i.add(e),!!this.materialAssetUsesShaderGraph(r,t)||("mesh"===r.type?this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,i):"prefab"===r.type?this.sceneObjectsUseShaderGraph(r.prefab?.objects,t,a,i):"vfx"===r.type&&this.vfxAssetUsesShaderGraph(r,t,a,i))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,a,s){for(const r of e??[])if(null!=r.materialId&&"null"!==r.materialId&&await this.assetUsesShaderGraph(r.materialId,t,a,s))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,a,s){for(const r of e??[]){if(await this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,s))return!0;if(null!=r.assetId&&("asset_mesh"===r.type||"prefab"===r.type||"vfx"===r.type)&&await this.assetUsesShaderGraph(r.assetId,t,a,s))return!0;if(await this.sceneObjectsUseShaderGraph(r.children,t,a,s))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,a,s){for(const r of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterUsesShaderGraph(e,t,a,s){if(await this.emitterOutputUsesShaderGraph(e.output,t,a,s))return!0;for(const r of e.children??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,a,s){const r=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===r&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==r||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,a,s))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,a,s){let r=!1;for(let e=0;e<s.length;e++)if(C(s[e])){r=!0;break}if(r)try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=v(s[e],this.sequenceEventAsyncResolvers);const r=await Promise.all(t);await a.call(e,...r)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=g(s[e],this.sequenceEventSyncResolvers);a.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,a="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==a)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===a)return e}return null}resolveSequenceEventSequence(e){return function(e){return"object"==typeof e&&null!=e&&"duration"in e&&"tracks"in e}(e)?new w(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 V(e){return e.options?.length>0||e.propertyType===y.Boolean||e.propertyType===y.String}function D(e){return e.valueType===y.Boolean||e.valueType===y.String}function K(e){return"object"==typeof e&&null!=e||"function"==typeof e}function G(e,t){switch(t.type){case y.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 y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Color:return function(e,t){if(e instanceof c){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b,e.w),{applied:!0,value:e}):{applied:!1}}return X(e,t)}(e,t.value);default:return{applied:!1}}}function $(e,t){const s=S(t);return function(e){return e instanceof a.Material||!0===e?.isMaterial}(e)&&null!=e.uniforms?.[t.uniformName]&&("parameterName"===s||e.userData?.assetId===t.materialAssetId)}function N(e,t){const a=Q(t,2);return a?e instanceof l?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new l(a[0],a[1])}:{applied:!1}}function U(e,t){const a=Q(t,3);return a?e instanceof c?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new c(a[0],a[1],a[2])}:{applied:!1}}function W(e,t){const a=Q(t,4);return a?e instanceof h?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new h(a[0],a[1],a[2],a[3])}:{applied:!1}}function X(e,t){if(e instanceof r)return Y(e,t)?{applied:!0,value:e}:{applied:!1};const a=new r;return Y(a,t)?{applied:!0,value:a}:{applied:!1}}function Q(e,t){if(!Array.isArray(e)||e.length<t)return null;const a=new Array(t);for(let s=0;s<t;s++){if("number"!=typeof e[s])return null;a[s]=e[s]}return a}function Y(e,t){return t instanceof r||"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 Z(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof r||e instanceof i)return e.clone()}function z(e){const{owner:t,key:a}=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 r&&t instanceof r)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0}(e.value,e.valueSnapshot),t[a]=e.value):delete t[a]}function H(e){const t=[];for(const a of e)t.push(a),"group"===a.type&&t.push(...H(a.childTracks));return t}function J(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function ee(e){const t=new a.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const s=new a.AxesHelper(.35);s.renderOrder=1e3;const r=Array.isArray(s.material)?s.material:[s.material];for(const e of r)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(s);const i=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const s=t.getContext("2d");if(!s)return null;s.clearRect(0,0,t.width,t.height),s.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,a,s,r,i){const n=t+s,o=a+r;e.beginPath(),e.moveTo(t+i,a),e.lineTo(n-i,a),e.quadraticCurveTo(n,a,n,a+i),e.lineTo(n,o-i),e.quadraticCurveTo(n,o,n-i,o),e.lineTo(t+i,o),e.quadraticCurveTo(t,o,t,o-i),e.lineTo(t,a+i),e.quadraticCurveTo(t,a,t+i,a),e.closePath()}(s,0,8,t.width,48,8),s.fill(),s.font="24px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillStyle="#f8fafc",s.fillText(e||"Locator",t.width/2,t.height/2);const r=new a.CanvasTexture(t);r.needsUpdate=!0;const i=new a.SpriteMaterial({map:r,transparent:!0,depthTest:!1});i.toneMapped=!1;const n=new a.Sprite(i);return n.scale.set(.9,.225,1),n}(e);return i&&(i.position.set(0,.45,0),i.renderOrder=1001,t.add(i)),t.traverse(e=>{e.raycast=()=>{}}),t}function te(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 ae=new c,se=new c,re=new c,ie=new o,ne=new o,oe=new i,le=new i,ce=new r;/*
1
+ import{BehaviorSubject as e,Subject as t}from"rxjs";import*as a from"three";import{AnimationMixer as s,Color as r,Euler as i,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{BaseActor as p}from"../../gameplay/actors/actor.js";import d from"../../gameplay/actors/builtin/index.js";import{Prefab as f,PrefabOf as m}from"../../scene/objects/prefab.js";import{SerializedParamType as y}from"../../scene/model.js";import{customParamValueNeedsAsyncResolution as C,deserializeCustomParamValue as v,deserializeCustomParamValueSync as g}from"../../scene/custom-param-deserialize.js";import{getAudioParameterDefinition as A}from"./audio-parameters.js";import{getMaterialSubTrackMatchMode as S,Sequence as w}from"./sequence-data.js";import{getSequenceSubTrackDefinition as P,getSequenceTrackDefinition as b}from"./sequence-definitions.js";import{applyInterpolation as k,evaluateCustomParamValueKeyframes as x,evaluateNumericKeyframes as T,findKeyframeSpan as I}from"./sequence-value-lane.js";import{buildRetimedAnimationClip as M,getAnimationClipRetimingSignature as q,isAnimationClipUsingRetiming as B}from"./sequence-animation-retiming.js";import{SkeletonUtils as O}from"three-stdlib";import{CharacterAnimationComponent as F,getCharacterMovementLike as E}from"../../gameplay/actors/index.js";import{RootMotionClip as j}from"../../gameplay/animation/root-motion.js";import{hashCameraShakeSeed as L}from"../../gameplay/services/camera-shake.js";import{buildShaderGraphPostProcessMaterial as _,shaderGraphPostProcessWeightUniformName as R}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.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.audioListener=null,this.audioBuffers=new Map,this.loadingAudioBuffers=new Map,this.animationClips=new Map,this.loadingAnimationClips=new Map,this.retimedAnimationClips=new Map,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.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 f(t.asset):null},prefabActor:async e=>{const t=await(this.assetLoader?.getPrefabById(e));return t?new m(new f(t.asset)):null},sequence:e=>this.resolveSequenceEventSequence(e),animationClip:e=>this.resolveSequenceEventAnimationClip(e)},this.trackRuntimeEvaluators={object:(e,t,a)=>{t&&this.evaluateObjectTrack(e,t,a)},locator:(e,t,a)=>{t&&this.evaluateLocatorTrack(e,t,a)},camera:(e,t,a)=>this.evaluateCameraTrack(e,a),cameraShake:(e,t,a)=>this.evaluateCameraShakeTrack(e,a),postProcess:(e,t,a)=>this.evaluatePostProcessTrack(e,a),audio:(e,t,a)=>this.evaluateAudioTrack(e,a),vfx:(e,t,a)=>this.evaluateVfxTrack(e,a),spawn:(e,t,a)=>this.evaluateSpawnTrack(e,t,a),group:(e,t,a)=>{if("group"===e.type)for(const t of e.childTracks)this.evaluateTrack(t,a)}},this.subTrackRuntimeEvaluators={transform:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateTransformSubTrack(e,s,a)},animation:(e,t,a)=>this.evaluateAnimationSubTrack(e,t,a),visibility:(e,t,a)=>{const s=this.getPlayableObject(t);s&&this.evaluateVisibilitySubTrack(e,s,a)},parameter:(e,t,a)=>this.evaluateParameterSubTrack(e,t.target||null,a),event:(e,t,a)=>this.evaluateEventSubTrack(e,t.target||null,a)}}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.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.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 a of e.tracks){if("audio"!==a.type)continue;const e=a;for(const a of e.clips??[])a.audioAssetId&&t.add(a.audioAssetId)}return[...t]}async preloadAudioBuffersForSequence(e,t){if(!this.assetLoader)return;const a=this.getAudioAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{if(t!==this.clearCounter)return;if(this.audioBuffers.has(e))return;let a=this.loadingAudioBuffers.get(e);a||(a=this.assetLoader.getAudioByAssetId(e),this.loadingAudioBuffers.set(e,a));try{const s=await a;if(t!==this.clearCounter)return;this.audioBuffers.set(e,s)}catch(e){}finally{this.loadingAudioBuffers.get(e)===a&&this.loadingAudioBuffers.delete(e)}}))}getAnimationClipAssetIdsForSequence(e){const t=new Set;for(const a of H(e.tracks))if("subTracks"in a)for(const e of a.subTracks)if("animation"===e.type)for(const a of e.clips)a.animationClipAssetId&&t.add(a.animationClipAssetId);return[...t]}async preloadAnimationClipsForSequence(e,t){if(!this.assetLoader)return;const a=this.getAnimationClipAssetIdsForSequence(e);0!==a.length&&await Promise.all(a.map(async e=>{t===this.clearCounter&&await this.ensureAnimationClip(e)}))}bindRole(e,t){this.roleBindings.set(e,t),this.sequenceData&&this.resolveBindings()}bindObject(e,t){if(this.sequenceData)for(const a of this.sequenceData.tracks)"object"===a.type&&a.targetId===e&&this.createBinding(a,t)}getLocator(e){return this.getLocators(e)[0]??null}getLocators(e){const t=J(e);if(!t||!this.sequenceData)return[];const a=[];for(const e of H(this.sequenceData.tracks)){if("locator"!==e.type)continue;if(J(e.bindingId)!==t)continue;const s=this.bindings.get(e.id),r=s?this.getPlayableObject(s):null;r&&(r.updateWorldMatrix(!0,!1),a.push({trackId:e.id,name:e.name,bindingId:e.bindingId,position:r.getWorldPosition(new c),rotation:r.getWorldQuaternion(new o),scale:r.getWorldScale(new c)}))}return a}resolveBindings(){if(this.sequenceData)for(const e of this.sequenceData.tracks)this.resolveTrackBinding(e)}initializeLocatorBindings(){if(this.sequenceData)for(const e of H(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 a=ee(e.name);a.visible=this._inEditor,t.add(a),this.locatorMarkers.set(e.id,a),this.disableLocatorInteraction(t),this.createBinding(e,t)}}clearLocatorBindings(){for(const e of this.locatorMarkers.values())te(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 a=t instanceof p?t.object:t,r=this.bindings.get(e.id),i=null!=r?r.target instanceof p?r.target.object:r.target:null,n=null!=r&&r.target===t&&i===a,o=e.subTracks.some(e=>"animation"===e.type);if(null!=r&&!n){for(const e of r.activeActions.values())e.stop();r.activeActions.clear(),r.mixer?.stopAllAction(),r.charAnimComponent?.stopSequenceAnimation(),r.charAnimComponent=void 0,r.charAnimActionKeys?.clear()}const l=n?r:{track:e,target:t,activeActions:new Map};l.track=e,l.target=t,l.originalTransform={position:a.position.clone(),rotation:a.rotation.clone(),scale:a.scale.clone()},l.originalParent=a.parent,o&&null==l.mixer?l.mixer=new s(a):o||(l.mixer=void 0),this.bindings.set(e.id,l)}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.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}stop(){this._state.next(SequencePlaybackState.Stopped),this._time.next(0),this.clearCounter++,this.loopCount=0,this.pauseAudio(),this.releaseCameraOverride(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),this.restoreOriginalTransforms(),this.restoreOriginalParents(),this.stopAllAudio(),this.stopAllAnimations(),this.despawnAll(),this.stopAllVfx(),this.firedEvents.clear(),this.clearCameraShakeContributions(),this.clearPostProcessEffects()}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.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.releaseCameraOverride(),this.clearCameraShakeContributions(),this.clearPostProcessEffects(),this.restoreAllPropertySnapshots(),this.restoreAllMaterialSnapshots(),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 t of this.sequenceData.tracks){if(!t.muted&&("object"===t.type||"locator"===t.type||"camera"===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 a=this.bindings.get(e.id);(0,this.trackRuntimeEvaluators[b(e.type).runtimeEvaluator])(e,a,t)}evaluateObjectTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}evaluateLocatorTrack(e,t,a){this.evaluateSubTracks(e.subTracks,t,a)}getActiveTrackObjects(e){if(!this.sequenceData)return[];const t=H(this.sequenceData.tracks).find(t=>t.id===e);return t?this.getActiveObjectsForTrack(t):[]}evaluateSubTracks(e,t,a){for(const s of e){if(s.muted)continue;(0,this.subTrackRuntimeEvaluators[P(s.type).runtimeEvaluator])(s,t,a)}}evaluateTransformSubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;const{prev:r,next:i,t:n}=I(s,a);if(r)if(i&&r!==i){const a=k(n,r.interpolation);e.components.position&&r.position&&i.position&&t.position.lerpVectors(ae.fromArray(r.position),se.fromArray(i.position),a),e.components.rotation&&r.rotation&&i.rotation&&(ie.setFromEuler(oe.fromArray([...r.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"])),t.quaternion.slerpQuaternions(ie,ne,a)),e.components.scale&&r.scale&&i.scale&&t.scale.lerpVectors(ae.fromArray(r.scale),se.fromArray(i.scale),a)}else e.components.position&&r.position&&t.position.fromArray(r.position),e.components.rotation&&r.rotation&&t.rotation.fromArray([...r.rotation,"XYZ"]),e.components.scale&&r.scale&&t.scale.fromArray(r.scale)}evaluateAnimationSubTrack(e,t,s){if(!t.mixer||!t.activeActions)return;if(t.target instanceof p?t.target.object:t.target)for(const r of e.clips){const i=r.startTime+r.duration,n=s>=r.startTime&&s<i,o=`${e.id}-${r.id}`;let l=t.activeActions.get(o),c=!1;if(n){if(!l){c=!0;const e=r.animationClipAssetId;if(null==e)continue;const s=this.animationClips.get(e);if(null==s){this.ensureAnimationClip(e);continue}const i=this.prepareAnimationPlayback(e,s,r),n=t;let h=!1;if(t.target instanceof p){n.charAnimComponent||(n.charAnimComponent=t.target.getComponent(F)??void 0);const a=n.charAnimComponent;if(null!=a){const c=r.rootMotion?B(r)?this.getPlayableAnimationClip(e,s,r,!0):j.fromClip(i.clip,!1):i.clip;if(this._externalTimeControl)l=a.beginExternalAnimationControl(c,{timeScale:i.timeScale});else if(a.play(c,{inPlace:!r.rootMotion,loop:!1,priority:20,timeScale:i.timeScale,fadeTime:r.fadeInDuration??.2,offset:i.startOffset}),l=a.getFullBodyAction(),r.rootMotion){const e=E(t.target);e&&e.setRootMotionAction(l,{cancelWithJump:e.allowRootMotionJumpCancel,onJumpCancel:()=>this.cancel()})}t.activeActions.set(o,l),n.charAnimActionKeys||(n.charAnimActionKeys=new Set),n.charAnimActionKeys.add(o),h=!0}}h||(l=t.mixer.clipAction(i.clip),l.setLoop(a.LoopOnce,1),l.clampWhenFinished=!0,l.timeScale=i.timeScale,i.startOffset>0&&(l.time=i.startOffset),t.activeActions.set(o,l),l.play())}if(l){const e=t;if(this._externalTimeControl){e.charAnimComponent?.beginExternalControl();const a=this.getAnimationPlaybackLocalTime(r,s),i=Math.min(a,l.getClip().duration);(c||Math.abs(l.time-i)>.001)&&(l.time=i,l.paused=!1,l.play(),e.charAnimComponent?e.charAnimComponent.getMixer()?.update(0):t.mixer&&t.mixer.update(0))}else e.charAnimComponent?.endExternalControl()}}else if(l){t.activeActions.delete(o);const e=t;e.charAnimActionKeys?.has(o)?(e.charAnimActionKeys.delete(o),l.stop(),0===e.charAnimActionKeys.size&&e.charAnimComponent&&(e.charAnimComponent.stopSequenceAnimation(),e.charAnimComponent=void 0)):(l.stop(),this._externalTimeControl&&t.mixer&&t.mixer.update(0))}}}evaluateVisibilitySubTrack(e,t,a){const s=e.keyframes;if(0===s.length)return;let r=s[0];for(const e of s){if(!(e.time<=a))break;r=e}t.visible=r.visible}evaluatePropertySubTrack(e,t,a){const s=x(e.keyframes,a,{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)});s&&this.applyResolvedPropertyValue(e,t,s)}evaluateParameterSubTrack(e,t,a){if("audioParameter"===e.type)return;const s=x(e.keyframes,a,"property"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:V(e)}:"material"===e.type?{min:e.range?.[0],max:e.range?.[1],stepOnly:D(e)}:{});s&&("property"!==e.type?this.applyResolvedMaterialValue(e,t,s):this.applyResolvedPropertyValue(e,t,s))}evaluateEventSubTrack(e,t,a){if(t instanceof p&&this._state.value===SequencePlaybackState.Playing)for(const s of e.events){const r=`${e.id}-${s.id}`;if(a>=s.time&&!this.firedEvents.has(r)){if(this.firedEvents.add(r),s.editorOnly&&!this._inEditor)continue;if(!s.functionName)continue;const e=t[s.functionName];"function"==typeof e?this.invokeSequenceEvent(t,s.functionName,e,s.arguments??[]):console.warn(`Sequence event method '${s.functionName}' not found on actor`)}else s.time>a&&this.firedEvents.delete(r)}}evaluateCameraTrack(e,t){const a=this.ensureSequenceCamera(e);this.applyCameraTrackSettings(e,a),this.evaluateSubTracks(e.subTracks,this.getCameraPlayable(e,a),t),a.updateProjectionMatrix()}evaluateCameraShakeTrack(e,t){if(this.viewController)for(const a of e.clips??[]){if(!this.isCameraShakeClipActive(a,t))continue;const e=t-a.startTime,s=a.id;this.nextCameraShakeClipKeys.add(s),this.viewController.setCameraShakeContribution(this,s,a,e,a.seed??L(a.id))}}evaluatePostProcessTrack(e,t){if(this.viewController&&this.assetLoader){for(const a of e.clips??[]){if(!this.isPostProcessClipActive(a,t))continue;const s=this.getPostProcessClipKey(e,a);this.nextPostProcessClipKeys.add(s),this.ensurePostProcessClipEffect(e,a,s);const r=this.activePostProcessClips.get(s);r?.handle&&(r.handle.stage=e.stage,r.handle.priority=e.priority,r.handle.enabled=!0,this.applyPostProcessClipWeight(r.handle,a,t))}this.evaluatePostProcessMaterialSubTracks(e,t)}}evaluatePostProcessMaterialSubTracks(e,t){for(const a of e.subTracks){if(a.muted||"material"!==a.type)continue;const s=x(a.keyframes,t,{min:a.range?.[0],max:a.range?.[1],stepOnly:D(a)});s&&this.applyPostProcessMaterialValue(e.id,a,s)}}applyPostProcessMaterialValue(e,t,a){if(t.uniformName)for(const s of this.activePostProcessClips.values()){if(s.trackId!==e||!s.handle)continue;const r=s.handle.material,i=r.uniforms?.[t.uniformName];if(!i)continue;const n=G(i.value,a);n.applied&&(i.value=n.value,r.uniformsNeedUpdate=!0)}}isPostProcessClipActive(e,t){return t>=e.startTime&&t<e.startTime+e.duration}getPostProcessClipKey(e,t){return`${e.id}-${t.id}`}ensurePostProcessClipEffect(e,t,a){const s=t.shaderGraphAssetId;if(!s)return void this.releasePostProcessClipEffect(a);const r=JSON.stringify(t.shaderGraphParams??{}),i=this.activePostProcessClips.get(a);if(i?.assetId===s&&i.paramsSignature===r)return;this.releasePostProcessClipEffect(a);const n={key:a,trackId:e.id,clipId:t.id,assetId:s,paramsSignature:r,version:this.clearCounter};this.activePostProcessClips.set(a,n),this.loadPostProcessClipEffect(e,t,n)}async loadPostProcessClipEffect(e,t,a){if(this.assetLoader&&this.viewController)try{const s=await this.assetLoader.getShaderGraphByAssetId(a.assetId);if(!this.isPostProcessClipEntryCurrent(a))return;if("postProcess"!==s.target)return console.warn(`Sequence post-process clip references shader graph "${a.assetId}" with target "${s.target}"`),void this.releasePostProcessClipEffect(a.key);const r=await this.assetLoader.prepareShaderGraphParameters(s,t.shaderGraphParams??{});if(!this.isPostProcessClipEntryCurrent(a))return;const i=_(s,{parameters:r});if(!this.isPostProcessClipEntryCurrent(a))return void i.dispose();a.handle=this.viewController.addPostProcessEffect(i,{stage:e.stage,priority:e.priority,enabled:!0}),this.applyPostProcessClipWeight(a.handle,t,this._time.value)}catch(e){this.isPostProcessClipEntryCurrent(a)&&this.releasePostProcessClipEffect(a.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,a){const s=e.material.uniforms?.[R];null!=s&&(s.value=this.getPostProcessClipWeight(t,a),e.material.uniformsNeedUpdate=!0)}getPostProcessClipWeight(e,t){const a=Math.max(0,t-e.startTime),s=Math.max(0,e.startTime+e.duration-t);let r=1;const i=Math.max(0,e.fadeInDuration??0);i>0&&(r=Math.min(r,a/i));const n=Math.max(0,e.fadeOutDuration??0);return n>0&&(r=Math.min(r,s/n)),Math.max(0,Math.min(1,r))}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 a=this.cameraPlayables.get(e.id);return a?a.target=t:(a={target:t},this.cameraPlayables.set(e.id,a)),a}ensureSequenceCamera(e){let t=this.sequenceCameras.get(e.id);if(t)null==t.parent&&this.world?.scene.add(t);else{const s=e.cameraSettings??{fov:60,near:.1,far:1e3};t=new a.PerspectiveCamera(s.fov??60,this.getCurrentCameraAspect(),s.near??.1,s.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 a=e.cameraSettings??{fov:60,near:.1,far:1e3};t.fov=a.fov??60,t.near=a.near??.1,t.far=a.far??1e3,t.aspect=this.getCurrentCameraAspect()}getCurrentCameraAspect(){const e=this.viewController?.getBaseCamera();if(e instanceof a.PerspectiveCamera&&Number.isFinite(e.aspect)&&e.aspect>0)return e.aspect;const t=this.viewController?.getSourceCamera();return t instanceof a.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 a=this.findBlendOutCameraShot(e);a?this.updateCameraBlendOut(a,e):this.releaseCameraOverride()}findActiveCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s)this.isCameraClipActive(r,e)&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}return t}findBlendOutCameraShot(e){if(!this.sequenceData)return null;let t=null;for(const a of H(this.sequenceData.tracks)){if("camera"!==a.type||a.muted||!this.isCameraControlTrackEligible(a))continue;const s=a.clips??[];for(const r of s){const s=Math.max(0,r.blendOutDuration??0);if(s<=0)continue;const i=this.getCameraClipEnd(r);e>=i&&e<i+s&&(t={track:a,clip:r,camera:this.ensureSequenceCamera(a),key:this.getCameraClipKey(a,r)})}}return t}isCameraControlTrackEligible(e){return null==this._cameraControlTrackId||e.id===this._cameraControlTrackId}updateActiveCameraShot(e,t){if(!this.viewController)return;const a=this.ensureCameraBlendCamera();this.activeCameraClipKey!==e.key&&(this.copyCameraState(this.viewController.getSourceCamera(),this.ensureCameraBlendSource()),this.activeCameraClipKey=e.key,this.cameraBlendOutClipKey=null);const s=Math.max(0,e.clip.blendInDuration??0),r=s<=0?1:this.evaluateCameraBlendAlpha((t-e.clip.startTime)/s,e.clip);r>=1?this.copyCameraState(e.camera,a):this.blendCameraState(this.ensureCameraBlendSource(),e.camera,a,r),a.updateProjectionMatrix(),this.ensureCameraOverride()}updateCameraBlendOut(e,t){if(!this.viewController)return;const a=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 s=this.getCameraClipEnd(e.clip),r=Math.max(0,e.clip.blendOutDuration??0),i=r<=0?1:this.evaluateCameraBlendAlpha((t-s)/r,e.clip);this.blendCameraState(this.ensureCameraBlendOutSource(),this.viewController.getBaseCamera(),a,i),a.updateProjectionMatrix(),this.ensureCameraOverride()}ensureCameraBlendCamera(){return this.cameraBlendCamera||(this.cameraBlendCamera=new a.PerspectiveCamera(60,this.getCurrentCameraAspect(),.1,1e3),this.cameraBlendCamera.name="Sequence Camera Blend"),this.cameraBlendCamera}ensureCameraBlendSource(){return this.cameraBlendSource||(this.cameraBlendSource=new a.PerspectiveCamera),this.cameraBlendSource}ensureCameraBlendOutSource(){return this.cameraBlendOutSource||(this.cameraBlendOutSource=new a.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 k(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(ae)),t.quaternion.copy(e.getWorldQuaternion(ie)),t.scale.copy(e.getWorldScale(se)),e instanceof a.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,s,r){e.updateWorldMatrix(!0,!1),t.updateWorldMatrix(!0,!1),s.position.lerpVectors(e.getWorldPosition(ae),t.getWorldPosition(se),r),s.quaternion.slerpQuaternions(e.getWorldQuaternion(ie),t.getWorldQuaternion(ne),r),s.scale.lerpVectors(e.getWorldScale(ae),t.getWorldScale(se),r),e instanceof a.PerspectiveCamera&&t instanceof a.PerspectiveCamera?(s.fov=e.fov+(t.fov-e.fov)*r,s.near=e.near+(t.near-e.near)*r,s.far=e.far+(t.far-e.far)*r,s.aspect=t.aspect):t instanceof a.PerspectiveCamera?(s.fov=t.fov,s.near=t.near,s.far=t.far,s.aspect=t.aspect):s.aspect=this.getCurrentCameraAspect(),s.layers.mask=t.layers.mask}evaluateAudioTrack(e,t){if(!this.assetLoader||!e.clips||0===e.clips.length)return;const a=this._state.value===SequencePlaybackState.Playing,s=this.evaluateAudioSubTracks(e,t);e.volume;for(const r of e.clips){const i=r.startTime+r.duration,n=t>=r.startTime&&t<i,o=`${e.id}-${r.id}`;if(n){if(this.activeAudioClips.has(o)||this.activeAudioClips.add(o),a){const a=this.audioByClip.get(o);a&&a.isPlaying||this.tryStartAudioClip(e,r,o,t,s)}const i=this.audioByClip.get(o);i&&this.applyAudioParameters(i,e,r,o,t,s)}else this.activeAudioClips.has(o)&&(this.activeAudioClips.delete(o),this.lastAudioStartAttemptTime.delete(o),this.audioStartInFlight.delete(o),this.stopAudioClip(o))}}tryStartAudioClip(e,t,a,s,r){if(this.audioStartInFlight.has(a))return;const i=this.lastAudioStartAttemptTime.get(a);if(void 0!==i&&s-i<this.audioStartRetryIntervalSeconds)return;this.lastAudioStartAttemptTime.set(a,s);const n=this.playAudioClip(e,t,a,s,r).catch(()=>{}).finally(()=>{this.audioStartInFlight.get(a)===n&&this.audioStartInFlight.delete(a)});this.audioStartInFlight.set(a,n)}applyAudioParameters(e,t,s,r,i,n){const o=n.volume??1,l=Math.random(),c=s.volumeRandomization?(2*l-1)*s.volumeRandomization:0;let h=1;const u=i-s.startTime;u<s.fadeInDuration&&s.fadeInDuration>0?h=u/s.fadeInDuration:u>s.duration-s.fadeOutDuration&&s.fadeOutDuration>0&&(h=(s.duration-u)/s.fadeOutDuration);const p=Math.max(0,(t.volume??1)*o*(s.volume+c)*h);e.setVolume(p);let d=n.detune??0;if(s.pitchRandomization){d+=(2*Math.random()-1)*s.pitchRandomization}if(e.setDetune(d),e.hasPlaybackControl&&e.setPlaybackRate(s.playbackRate*this.timescale),this.audioListener&&this.audioListener.context){const s=this.audioListener.context,i=[],o=n.lowpass,l=n.highpass;let c=this.audioFilters.get(r);if(void 0!==o||void 0!==l)c||(c=s.createBiquadFilter(),this.audioFilters.set(r,c)),void 0!==o?(c.type="lowpass",c.frequency.value=o):void 0!==l&&(c.type="highpass",c.frequency.value=l),i.push(c);else if(c){try{c.disconnect()}catch{}this.audioFilters.delete(r)}const h=n.pan;if(!t.spatial&&e instanceof a.Audio&&void 0!==h&&"function"==typeof s.createStereoPanner){let e=this.audioPannerNodes.get(r);e||(e=s.createStereoPanner(),this.audioPannerNodes.set(r,e)),e.pan.value=h,i.push(e)}else{const e=this.audioPannerNodes.get(r);if(e){try{e.disconnect()}catch{}this.audioPannerNodes.delete(r)}}e.setFilters(i)}t.spatial&&e instanceof a.PositionalAudio?this.updatePositionalAudioTransform(e,t,s,n.spatialBlend):void 0!==n.pan&&this.audioListener}updatePositionalAudioTransform(e,t,s,r){let i=null,n=null;const o=s.attachedToTrackId||t.parent?.trackId,l=s.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(i=ae,n=ie,e.getWorldPosition(i),e.getWorldQuaternion(n),l){const t=this.findSocket(e,l);t&&(t.getWorldPosition(i),t.getWorldQuaternion(n))}}}}if(i&&n){const t="number"==typeof r?a.MathUtils.clamp(r,0,1):1;if(t<1&&this.audioListener){const e=re;this.audioListener.getWorldPosition(e),i=i.clone().lerp(e,1-t)}e.position.copy(i),e.quaternion.copy(n),e.updateMatrixWorld()}}async playAudioClip(e,t,s,r,i){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(s);const n=this.clearCounter;try{let r=this.audioBuffers.get(t.audioAssetId);if(!r){let e=this.loadingAudioBuffers.get(t.audioAssetId);e||(e=this.assetLoader.getAudioByAssetId(t.audioAssetId),this.loadingAudioBuffers.set(t.audioAssetId,e));try{r=await e,this.audioBuffers.set(t.audioAssetId,r)}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>=r.duration||c>=t.duration)return;let u=this.audioByClip.get(s);const p=!0===e.spatial,d=u&&!0===u.isPositionalAudio;if(u&&p!==d&&(u.isPlaying&&u.stop(),u.disconnect(),this.audioByClip.delete(s),u=void 0),!u){if(p){const e=new a.PositionalAudio(this.audioListener);e.setRefDistance(10),e.setRolloffFactor(1),u=e}else u=new a.Audio(this.audioListener);this.world&&this.world.scene.add(u),this.audioByClip.set(s,u)}Math.min((t.duration-c)/t.playbackRate,(r.duration-h)/t.playbackRate);u.setLoopStart(t.clipStartOffset),u.setLoopEnd(Math.min(t.clipStartOffset+t.duration,r.duration)),u.setLoop(!0),u.setBuffer(r),this.applyAudioParameters(u,e,t,s,o,i),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 a=this.audioGainNodes.get(e);a&&(a.disconnect(),this.audioGainNodes.delete(e));const s=this.audioFilters.get(e);if(s){try{s.disconnect()}catch{}this.audioFilters.delete(e)}const r=this.audioPannerNodes.get(e);if(r){try{r.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;const a=new Set,s=new Map;for(const r of e.clips){const i=this.getVfxClipKey(e,r);s.set(i,r),this.isVfxClipActiveAtTime(r,t)&&a.add(i)}const r=[];for(const t of this.activeVfxClips)t.startsWith(`${e.id}-`)&&(a.has(t)||r.push(t));for(const e of r)this.activeVfxClips.delete(e);for(const[r,i]of s.entries()){const s=this.vfxActors.get(r);a.has(r)&&!this.activeVfxClips.has(r)?(this.activeVfxClips.add(r),this.ensureVfxActor(e,i,r)):a.has(r)&&s?(this.updateVfxTransform(e,s,t),this._state.value===SequencePlaybackState.Playing&&s.play()):s&&this.applyInactiveVfxClipBehavior(i,s,t)}}getVfxClipKey(e,t){return`${e.id}-${t.id}-${t.vfxAssetId}`}isVfxClipActiveAtTime(e,t){const a=e.startTime+e.duration;return t>=e.startTime&&t<a}resetVfxForTimeReset(e){const t=new Set;if(this.sequenceData)for(const a of H(this.sequenceData.tracks))if("vfx"===a.type)for(const s of a.clips??[])this.isVfxClipActiveAtTime(s,e)&&t.add(this.getVfxClipKey(a,s));this.activeVfxClips.clear();for(const[e,a]of this.vfxActors.entries())t.has(e)||(a.restart(),a.stop(),a.pause())}applyInactiveVfxClipBehavior(e,t,a){const s=e.endBehavior??"finish";if("finish"===s)return void t.stop();if("kill"===s)return void t.applyClipEndBehavior(s);const r=e.startTime+e.duration,i=Math.max(a-r,0),n=Math.max(0,e.expireWithinSeconds??.25),o=Math.max(0,n-i);t.applyClipEndBehavior(s,o)}async ensureVfxActor(e,t,a){if(!this.vfxService||!t.vfxAssetId)return;if(this.vfxActors.has(a)){const e=this.vfxActors.get(a);return e.restart(),void e.play()}const s=this.clearCounter;try{const r=await this.vfxService.createFromAssetId(t.vfxAssetId,this.world.scene);if(s!==this.clearCounter)return void(this.world&&this.world.removeActor(r));const{position:i,rotation:n,scale:o}=this.getVfxTransform(e,t.startTime);r.object.position.copy(i),r.object.rotation.copy(n),r.object.scale.copy(o),this.vfxActors.set(a,r),this._state.value===SequencePlaybackState.Playing&&r.play()}catch(e){console.error(`Failed to create VFX actor for clip ${t.id}:`,e)}}getVfxTransform(e,t){const a=new c,s=new i,r=new c(1,1,1),n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e,next:i,t:l}=I(n.keyframes,t);if(e&&(e.position&&a.fromArray(e.position),e.rotation&&s.fromArray([...e.rotation,"XYZ"]),e.scale&&r.fromArray(e.scale)),i&&e!==i&&e.time!==i.time){const t=k(l,e.interpolation);if(e.position&&i.position&&a.lerpVectors(ae.fromArray(e.position),se.fromArray(i.position),t),e.rotation&&i.rotation){ie.setFromEuler(oe.fromArray([...e.rotation,"XYZ"])),ne.setFromEuler(le.fromArray([...i.rotation,"XYZ"]));const a=new o;a.slerpQuaternions(ie,ne,t),s.setFromQuaternion(a)}e.scale&&i.scale&&r.lerpVectors(ae.fromArray(e.scale),se.fromArray(i.scale),t)}}else a.fromArray(e.position),s.fromArray([...e.rotation,"XYZ"]),r.fromArray(e.scale);return{position:a,rotation:s,scale:r}}updateVfxTransform(e,t,a){const{position:s,rotation:r,scale:i}=this.getVfxTransform(e,a);t.object.position.copy(s),t.object.rotation.copy(r),t.object.scale.copy(i)}resolveActorType(e){const t=this.actorFactory.classes[e];if(null!=t)return t;const a=d[e];return a||(console.warn(`Could not resolve actor type: ${e}`),null)}async spawnActorForClip(e,t,a,s){if(!this.world||!e.actorType)return null;const r=this.resolveActorType(e.actorType);if(!r)return null;try{return await this.world.spawnActor(r,a,s)}catch(t){return console.error(`Failed to spawn actor ${e.actorType}:`,t),null}}async spawnPrefabForClip(e,t,a,s){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,a,s)}catch(t){return console.error(`Failed to spawn prefab ${e.prefabId}:`,t),null}}async spawnMeshForClip(e,t,a,s){if(!this.world||!this.assetLoader||!e.meshId)return null;try{const t=await this.assetLoader.getAsset(e.meshId),r=await this.assetLoader.getModelByAssetId(e.meshId),i=O.clone(r.scene);if(i.position.copy(a),i.rotation.copy(s),t){await this.assetLoader.applyMaterials(t,i);const e=t.mesh?.rescale;null!=e&&1!==e&&i.scale.multiplyScalar(e)}return this.world.scene.add(i),i}catch(t){return console.error(`Failed to spawn mesh ${e.meshId}:`,t),null}}despawnInstance(e){if(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,a){const s=new c,r=new i,n=e.subTracks.find(e=>"transform"===e.type);if(n&&n.keyframes.length>0){const{prev:e}=I(n.keyframes,a);e&&(e.position&&s.fromArray(e.position),e.rotation&&r.fromArray([...e.rotation,"XYZ"]))}else t.initialPosition&&s.fromArray(t.initialPosition),t.initialRotation&&r.fromArray([...t.initialRotation,"XYZ"]);return{position:s,rotation:r}}evaluateSpawnTrack(e,t,a){if(!e.clips||0===e.clips.length)return;const s=t||this.bindings.get(e.id);if(s&&s.target)for(const t of e.clips){const r=t.startTime+t.duration,i=a>=t.startTime&&a<r,n=`${e.id}-${t.id}`;if(i){this.activeClips.has(n)||(this.activeClips.add(n),this.spawnedInstances.set(n,{type:"proxy",target:s.target}));(s.target instanceof p?s.target.object:s.target)&&this.evaluateSubTracks(e.subTracks,s,a)}else this.activeClips.has(n)&&(this.restorePropertySnapshotsForTarget(s.target),this.restoreMaterialSnapshotsForTarget(s.target),this.activeClips.delete(n),this.spawnedInstances.delete(n))}else for(const t of e.clips){const s=t.startTime+t.duration,r=a>=t.startTime&&a<s,i=`${e.id}-${t.id}`,n=this.spawnedInstances.has(i),o=this.pendingSpawns.has(i);if(!r||n||o){if(r&&n){const t=this.spawnedInstances.get(i);t&&"proxy"!==t.type&&this.evaluateSubTracks(e.subTracks,t,a)}else if(!r&&n){const e=this.spawnedInstances.get(i);e&&(this.despawnInstance(e),this.spawnedInstances.delete(i),this.activeClips.delete(i))}}else{const{position:a,rotation:s}=this.getInitialTransform(e,t,t.startTime);this.pendingSpawns.add(i),this.spawnForClip(e,t,a,s,i)}}}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 p?e.target.object:e.target;default:return null}}async spawnForClip(e,t,a,r,i){const n=this.clearCounter;let o=null;try{switch(e.spawnType){case"actor":const s=await this.spawnActorForClip(e,t,a,r);s&&(o={type:"actor",instance:s});break;case"prefab":const i=await this.spawnPrefabForClip(e,t,a,r);i&&(o={type:"prefab",instance:i});break;case"mesh":const n=await this.spawnMeshForClip(e,t,a,r);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 s(t),o.activeActions=new Map),this.spawnedInstances.set(i,o),this.activeClips.add(i)}else o&&this.despawnInstance(o)}finally{this.pendingSpawns.delete(i)}}getPlayableObject(e){return e.target instanceof p?e.target.object:e.target??null}applyResolvedPropertyValue(e,t,a){if(!t||!e.propertyPath)return;const s=this.getPropertyResolution(t,e);if(!s)return;const r=this.getPropertySnapshotKey(e);this.capturePropertySnapshot(t,r,s);const n=function(e,t){switch(t.type){case y.Number:return"number"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.String:return"string"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Euler:return function(e,t){const a=Q(t,3);if(!a)return{applied:!1};const s=Array.isArray(t)&&"string"==typeof t[3]?t[3]:"XYZ";if(e instanceof i)return e.set(a[0],a[1],a[2],s),{applied:!0,value:e};return{applied:!0,value:new i(a[0],a[1],a[2],s)}}(e,t.value);case y.Color:return X(e,t.value);default:return{applied:!1}}}(s.owner[s.key],a);n.applied&&(s.owner[s.key]=n.value)}getPropertyResolution(e,t){const a=e,s=this.getPropertySnapshotKey(t);let r=this.propertyResolutionCache.get(a);if(r||(r=new Map,this.propertyResolutionCache.set(a,r)),r.has(s))return r.get(s)??null;const i=this.getPropertyPathSegments(t.propertyPath);if(0===i.length)return r.set(s,null),null;let n=e;for(let e=0;e<i.length-1;e++){if(!K(n))return r.set(s,null),null;n=n[i[e]]}if(!K(n))return r.set(s,null),null;const o={owner:n,key:i[i.length-1]};return r.set(s,o),o}getPropertyPathSegments(e){const t=this.propertyPathSegments.get(e);if(t)return t;const a=e.split(".").map(e=>e.trim()).filter(Boolean);return this.propertyPathSegments.set(e,a),a}getPropertySnapshotKey(e){return`${e.id}:${e.propertyPath}`}capturePropertySnapshot(e,t,a){const s=e;let r=this.propertySnapshots.get(s);if(r||(r=new Map,this.propertySnapshots.set(s,r)),r.has(t))return;const i=a.owner[a.key];r.set(t,{resolution:a,hadOwnProperty:Object.prototype.hasOwnProperty.call(a.owner,a.key),value:i,valueSnapshot:Z(i)})}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,a=this.propertySnapshots.get(t);if(a){for(const e of a.values())z(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 a=this.materialSnapshots.get(t);if(a){for(const e of a.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)}applyResolvedMaterialValue(e,t,a){if(!t||!e.uniformName)return;if("asset"===S(e)&&!e.materialAssetId)return;const s=this.getMaterialSlotResolutions(t,e);for(const r of s){const s=this.ensureSequenceControlledMaterial(t,r),i=s.uniforms?.[e.uniformName];if(!i)continue;const n=G(i.value,a);n.applied&&(i.value=n.value,s.uniformsNeedUpdate=!0)}}getMaterialSlotResolutions(e,t){const a=e,s=S(t),r=`${t.id}:${s}:${t.materialAssetId??""}:${t.uniformName}`;let i=this.materialResolutionCache.get(a);i||(i=new Map,this.materialResolutionCache.set(a,i));const n=i.get(r);if(n)return n;const o=e instanceof p?e.object:e,l=[];return o.traverse(e=>{const a=e.material;if(Array.isArray(a))for(let s=0;s<a.length;s++){const r=a[s];$(r,t)&&l.push({owner:e,materialIndex:s,material:r,key:`${e.uuid}:${s}`})}else $(a,t)&&l.push({owner:e,materialIndex:null,material:a,key:`${e.uuid}:material`})}),i.set(r,l),l}ensureSequenceControlledMaterial(e,t){const a=e;let s=this.materialSnapshots.get(a);s||(s=new Map,this.materialSnapshots.set(a,s));const r=s.get(t.key);if(r)return r.controlledMaterial;const i=t.material.clone();return i.userData={...t.material.userData??{}},null==t.materialIndex?t.owner.material=i:Array.isArray(t.owner.material)&&(t.owner.material[t.materialIndex]=i),s.set(t.key,{owner:t.owner,materialIndex:t.materialIndex,originalMaterial:t.material,controlledMaterial:i}),i}async ensureAnimationClip(e){if(!this.assetLoader)return null;const t=this.animationClips.get(e);if(t)return t;const a=this.loadingAnimationClips.get(e);if(a)return a;const s=(async()=>{try{const t=await this.assetLoader.getAnimationClipByAssetId(e);return t&&this.animationClips.set(e,t),t}catch(t){return console.error(`Failed to load animation clip for asset ${e}:`,t),null}finally{this.loadingAnimationClips.get(e)===s&&this.loadingAnimationClips.delete(e)}})();return this.loadingAnimationClips.set(e,s),s}prepareAnimationPlayback(e,t,a){if(!B(a)){let e=t;return a.clipEndOffset>0&&(e=e.clone(),e.duration=Math.max(0,e.duration-a.clipEndOffset)),{clip:e,timeScale:a.playbackRate,startOffset:a.clipStartOffset}}return{clip:this.getPlayableAnimationClip(e,t,a,!1),timeScale:1,startOffset:0}}getPlayableAnimationClip(e,t,a,s){if(!B(a))return s?j.fromClip(t,!1):t;const r=`${a.id}:${s?"root":"base"}`,i=`${q(a)}|${s?"root":"base"}`,n=this.retimedAnimationClips.get(r);if(n&&n.assetId===e&&n.signature===i)return n.clip;const o=M(t,a),l=s?j.fromClip(o,!1):o;return this.retimedAnimationClips.set(r,{assetId:e,signature:i,clip:l}),l}getAnimationPlaybackLocalTime(e,t){const a=Math.max(0,t-e.startTime);return B(e)?a:a*e.playbackRate+e.clipStartOffset}clearRetimedAnimationClipCache(e){if(null!=e)for(const[t,a]of this.retimedAnimationClips.entries())a.assetId===e&&this.retimedAnimationClips.delete(t);else this.retimedAnimationClips.clear()}captureOriginalTransforms(){for(const e of this.bindings.values()){const t=e.target instanceof p?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 p?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 of e.activeActions.values())t.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.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 a=this.getActiveObjectsForTrack(e);if(0===a.length)return;let s=null;const r=e.parent?.trackId;if(r){const t=this.sequenceData?H(this.sequenceData.tracks).find(e=>e.id===r):void 0;if(t){const a=this.getActiveObjectsForTrack(t);if(a.length>0&&(s=a[0],e.parent?.socketName)){const t=this.findSocket(s,e.parent.socketName);t&&(s=t)}}}if(!s&&"camera"===e.type&&e.parentRole&&this.roleBindings.has(e.parentRole)){const t=this.roleBindings.get(e.parentRole);if(s=t instanceof p?t.object:t,e.parentRoleSocketName){const t=this.findSocket(s,e.parentRoleSocketName);t&&(s=t)}}for(const r of a)s?r.parent!==s&&(s.add(r),!t||"object"!==e.type&&"locator"!==e.type||(t.currentParent=s)):t?.currentParent&&t.currentParent===r.parent?this.restoreObjectParent(t,r):r.parent&&r.parent!==this.world?.scene&&"object"!==e.type&&"locator"!==e.type&&this.world?.scene.add(r)}findSocket(e,t){if(e.name===t)return e;if(e instanceof a.SkinnedMesh){const a=e.skeleton.bones.find(e=>e.name===t);if(a)return a}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 p?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("spawn"===e.type){const t=[];for(const[a,s]of this.spawnedInstances)if(a.startsWith(e.id+"-")&&this.activeClips.has(a)){const e=this.getInstanceObject(s);e&&t.push(e)}return t}if("vfx"===e.type){const t=[];for(const a of this.activeVfxClips)if(a.startsWith(e.id+"-")){const e=this.vfxActors.get(a);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 p?e.target.object:e.target;t&&this.restoreObjectParent(e,t)}}evaluateAudioSubTracks(e,t){const a={};for(const s of e.subTracks)if("audioParameter"===s.type){const e=s,r=A(e.parameter),i=T(e.keyframes,t,{min:r.min,max:r.max});void 0!==i&&(a[e.parameter]=i)}return a}stringToRandom(e){let t=0;for(let a=0;a<e.length;a++){t=(t<<5)-t+e.charCodeAt(a),t&=t}const a=1e4*Math.sin(t);return a-Math.floor(a)}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[a,s]of this.activePostProcessClips.entries())s.assetId===e&&(this.releasePostProcessClipEffect(a),t=!0);t=this.refreshSpawnedInstancesForClipKeys(this.getSpawnClipKeysForAsset(e))||t;const a=await this.getAssetOrNull(e);return"shaderGraph"===a?.type&&(t=await this.refreshShaderGraphDependentAssets(e)||t),t}refreshVfxActorsForAssetIds(e){let t=!1;for(const[a,s]of this.vfxActors.entries())this.vfxClipKeyUsesAnyAsset(a,e)&&(this.world&&this.world.removeActor(s),this.vfxActors.delete(a),this.activeVfxClips.delete(a),t=!0);return t}vfxClipKeyUsesAnyAsset(e,t){for(const a of t)if(e.endsWith(`-${a}`))return!0;return!1}refreshSpawnedInstancesForClipKeys(e){let t=!1;for(const[a,s]of this.spawnedInstances.entries())e.has(a)&&(this.despawnInstance(s),this.spawnedInstances.delete(a),this.activeClips.delete(a),t=!0);return t}getSpawnClipKeysForAsset(e){const t=new Set;if(!this.sequenceData)return t;for(const a of H(this.sequenceData.tracks))if("spawn"===a.type&&(a.prefabId===e||a.meshId===e))for(const e of a.clips)t.add(`${a.id}-${e.id}`);return t}async refreshShaderGraphDependentAssets(e){const t=await this.findSequenceVfxAssetIdsUsingShaderGraph(e);for(const e of t)this.vfxService?.clearPool(e);const a=this.refreshVfxActorsForAssetIds(t),s=this.refreshSpawnedInstancesForClipKeys(await this.findSpawnClipKeysUsingShaderGraph(e));return a||s}async findSequenceVfxAssetIdsUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("vfx"===s.type)for(const r of s.clips)null==r.vfxAssetId||t.has(r.vfxAssetId)||await this.assetUsesShaderGraph(r.vfxAssetId,e,a)&&t.add(r.vfxAssetId);return t}async findSpawnClipKeysUsingShaderGraph(e){const t=new Set;if(!this.sequenceData)return t;const a=new Map;for(const s of H(this.sequenceData.tracks))if("spawn"===s.type&&await this.spawnTrackUsesShaderGraph(s,e,a))for(const e of s.clips)t.add(`${s.id}-${e.id}`);return t}async spawnTrackUsesShaderGraph(e,t,a){if(null!=e.meshId&&await this.assetUsesShaderGraph(e.meshId,t,a))return!0;if(null!=e.prefabId&&await this.assetUsesShaderGraph(e.prefabId,t,a))return!0;for(const s of e.subTracks??[])if("material"===s.type&&null!=s.materialAssetId&&await this.assetUsesShaderGraph(s.materialAssetId,t,a))return!0;return!1}assetUsesShaderGraph(e,t,a,s=new Set){if(e===t)return Promise.resolve(!0);if(s.has(e))return Promise.resolve(!1);if(a.has(e))return a.get(e);const r=this.assetUsesShaderGraphUncached(e,t,a,s);return a.set(e,r),r}async assetUsesShaderGraphUncached(e,t,a,s){if(s.has(e))return!1;const r=await this.getAssetOrNull(e);if(null==r)return!1;const i=new Set(s);return i.add(e),!!this.materialAssetUsesShaderGraph(r,t)||("mesh"===r.type?this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,i):"prefab"===r.type?this.sceneObjectsUseShaderGraph(r.prefab?.objects,t,a,i):"vfx"===r.type&&this.vfxAssetUsesShaderGraph(r,t,a,i))}materialAssetUsesShaderGraph(e,t){return"shaderGraph"===e.type?e.id===t:"asset"===e.material?.shaderGraph?.source&&e.material.shaderGraph.assetId===t}async materialAssignmentsUseShaderGraph(e,t,a,s){for(const r of e??[])if(null!=r.materialId&&"null"!==r.materialId&&await this.assetUsesShaderGraph(r.materialId,t,a,s))return!0;return!1}async sceneObjectsUseShaderGraph(e,t,a,s){for(const r of e??[]){if(await this.materialAssignmentsUseShaderGraph(r.materialAssignments,t,a,s))return!0;if(null!=r.assetId&&("asset_mesh"===r.type||"prefab"===r.type||"vfx"===r.type)&&await this.assetUsesShaderGraph(r.assetId,t,a,s))return!0;if(await this.sceneObjectsUseShaderGraph(r.children,t,a,s))return!0}return!1}async vfxAssetUsesShaderGraph(e,t,a,s){for(const r of e.vfx?.emitters??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterUsesShaderGraph(e,t,a,s){if(await this.emitterOutputUsesShaderGraph(e.output,t,a,s))return!0;for(const r of e.children??[])if(await this.emitterUsesShaderGraph(r,t,a,s))return!0;return!1}async emitterOutputUsesShaderGraph(e,t,a,s){const r=e.materialSource??("asset"===e.shaderGraph?.source?"shaderGraph":void 0);return"shaderGraph"===r&&"asset"===e.shaderGraph?.source&&e.shaderGraph.assetId===t||!("material"!==r||!("material"in e)||null==e.material||!await this.assetUsesShaderGraph(e.material,t,a,s))}async getAssetOrNull(e){if(!this.assetLoader)return null;try{return await this.assetLoader.getAsset(e)??null}catch{return null}}async invokeSequenceEvent(e,t,a,s){let r=!1;for(let e=0;e<s.length;e++)if(C(s[e])){r=!0;break}if(r)try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=v(s[e],this.sequenceEventAsyncResolvers);const r=await Promise.all(t);await a.call(e,...r)}catch(e){console.error(`Failed to call sequence event ${t}:`,e)}else try{const t=new Array(s.length);for(let e=0;e<s.length;e++)t[e]=g(s[e],this.sequenceEventSyncResolvers);a.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,a="object"==typeof t&&null!=t?.id?t.id:"string"==typeof t?t:null;if(null==a)return null;for(const e of this.world.actors){const t=e.object.userData.src??e.object.userData._src;if(t?.id===a)return e}return null}resolveSequenceEventSequence(e){return function(e){return"object"==typeof e&&null!=e&&"duration"in e&&"tracks"in e}(e)?new w(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 V(e){return e.options?.length>0||e.propertyType===y.Boolean||e.propertyType===y.String}function D(e){return e.valueType===y.Boolean||e.valueType===y.String}function K(e){return"object"==typeof e&&null!=e||"function"==typeof e}function G(e,t){switch(t.type){case y.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 y.Boolean:return"boolean"==typeof t.value?{applied:!0,value:t.value}:{applied:!1};case y.Vector2:return N(e,t.value);case y.Vector3:return U(e,t.value);case y.Vector4:return W(e,t.value);case y.Color:return function(e,t){if(e instanceof c){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b),{applied:!0,value:e}):{applied:!1}}if(e instanceof h){const a=ce.set(0);return Y(a,t)?(e.set(a.r,a.g,a.b,e.w),{applied:!0,value:e}):{applied:!1}}return X(e,t)}(e,t.value);default:return{applied:!1}}}function $(e,t){const s=S(t);return function(e){return e instanceof a.Material||!0===e?.isMaterial}(e)&&null!=e.uniforms?.[t.uniformName]&&("parameterName"===s||e.userData?.assetId===t.materialAssetId)}function N(e,t){const a=Q(t,2);return a?e instanceof l?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new l(a[0],a[1])}:{applied:!1}}function U(e,t){const a=Q(t,3);return a?e instanceof c?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new c(a[0],a[1],a[2])}:{applied:!1}}function W(e,t){const a=Q(t,4);return a?e instanceof h?(e.fromArray(a),{applied:!0,value:e}):{applied:!0,value:new h(a[0],a[1],a[2],a[3])}:{applied:!1}}function X(e,t){if(e instanceof r)return Y(e,t)?{applied:!0,value:e}:{applied:!1};const a=new r;return Y(a,t)?{applied:!0,value:a}:{applied:!1}}function Q(e,t){if(!Array.isArray(e)||e.length<t)return null;const a=new Array(t);for(let s=0;s<t;s++){if("number"!=typeof e[s])return null;a[s]=e[s]}return a}function Y(e,t){return t instanceof r||"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 Z(e){if(e instanceof l||e instanceof c||e instanceof h||e instanceof r||e instanceof i)return e.clone()}function z(e){const{owner:t,key:a}=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 r&&t instanceof r)return e.copy(t),!0;if(e instanceof i&&t instanceof i)return e.copy(t),!0}(e.value,e.valueSnapshot),t[a]=e.value):delete t[a]}function H(e){const t=[];for(const a of e)t.push(a),"group"===a.type&&t.push(...H(a.childTracks));return t}function J(e){if("string"!=typeof e)return null;const t=e.trim();return t.length>0?t:null}function ee(e){const t=new a.Group;t.name=`SequenceLocatorMarker:${e}`,t.renderOrder=1e3;const s=new a.AxesHelper(.35);s.renderOrder=1e3;const r=Array.isArray(s.material)?s.material:[s.material];for(const e of r)e.depthTest=!1,e.transparent=!0,e.opacity=.9,e.toneMapped=!1;t.add(s);const i=function(e){if("undefined"==typeof document)return null;const t=document.createElement("canvas");t.width=256,t.height=64;const s=t.getContext("2d");if(!s)return null;s.clearRect(0,0,t.width,t.height),s.fillStyle="rgba(16, 18, 24, 0.78)",function(e,t,a,s,r,i){const n=t+s,o=a+r;e.beginPath(),e.moveTo(t+i,a),e.lineTo(n-i,a),e.quadraticCurveTo(n,a,n,a+i),e.lineTo(n,o-i),e.quadraticCurveTo(n,o,n-i,o),e.lineTo(t+i,o),e.quadraticCurveTo(t,o,t,o-i),e.lineTo(t,a+i),e.quadraticCurveTo(t,a,t+i,a),e.closePath()}(s,0,8,t.width,48,8),s.fill(),s.font="24px sans-serif",s.textAlign="center",s.textBaseline="middle",s.fillStyle="#f8fafc",s.fillText(e||"Locator",t.width/2,t.height/2);const r=new a.CanvasTexture(t);r.needsUpdate=!0;const i=new a.SpriteMaterial({map:r,transparent:!0,depthTest:!1});i.toneMapped=!1;const n=new a.Sprite(i);return n.scale.set(.9,.225,1),n}(e);return i&&(i.position.set(0,.45,0),i.renderOrder=1001,t.add(i)),t.traverse(e=>{e.raycast=()=>{}}),t}function te(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 ae=new c,se=new c,re=new c,ie=new o,ne=new o,oe=new i,le=new i,ce=new r;/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import { Vector3 } from "three";
1
+ import { Vector3, Color } from "three";
2
2
  import { Emitter, Particle, Initializer } from "@hology/nebula";
3
3
  export declare class DefaultInitializer extends Initializer {
4
4
  init(emitter: Emitter, particle: Particle): void;
@@ -31,6 +31,13 @@ export declare class RandomScale extends Initializer {
31
31
  setRange(min: number, max: number): void;
32
32
  initialize(particle: Particle): void;
33
33
  }
34
+ export declare class RandomColor extends Initializer {
35
+ private readonly min;
36
+ private readonly max;
37
+ constructor(min: string | Color, max: string | Color);
38
+ setRange(min: string | Color, max: string | Color): void;
39
+ initialize(particle: Particle): void;
40
+ }
34
41
  export declare class InitialScaleComponents extends Initializer {
35
42
  private scale;
36
43
  constructor(scale: Vector3);
@@ -1,4 +1,4 @@
1
- import{Vector3 as t,Quaternion as e,Euler as i}from"three";import{Span as s,Initializer as o}from"@hology/nebula";export class DefaultInitializer extends o{init(t,e){e.parent=t}initialize(t){}}export class Rotation extends o{constructor(t){super(),this.rotation=t}setRotation(t){this.rotation=t.clone()}initialize(t){"number"!=typeof t.rotation&&t.rotation.copy(this.rotation)}}export const randomRotationAxis=["XYZ","X","Y","Z"];export class RandomRotation extends o{constructor(t){super(),this.axis=t}initialize(t){switch(this.axis){case"XYZ":t.rotation.set(this.randomAngle(),this.randomAngle(),this.randomAngle());break;case"X":t.rotation.x=this.randomAngle();break;case"Y":t.rotation.y=this.randomAngle();break;case"Z":t.rotation.z=this.randomAngle()}}randomAngle(){return 2*Math.PI*Math.random()}}export class InitialScale extends o{constructor(t){super(),this.scale=t}setScale(t){this.scale=t}initialize(t){t.scale=this.scale}}export class RandomScale extends o{constructor(t,e){super(),this.min=t,this.max=e}setRange(t,e){this.min=t,this.max=e}initialize(t){t.scale=l(this.min,this.max)}}export class InitialScaleComponents extends o{constructor(t){super(),this.scale=t}setScaleComponents(t){this.scale=t.clone()}initialize(t){t.transform.initialScale=this.scale.clone()}}export class AdditiveVelocity extends o{constructor(t,e){super(),this.min=t,this.max=e}initialize(t){const e=h(this.min),i=null!=this.max?h(this.max):void 0;t.velocity.x+=null!=i?l(e.x,i.x):e.x,t.velocity.y+=null!=i?l(e.y,i.y):e.y,t.velocity.z+=null!=i?l(e.z,i.z):e.z}}export class RandomDirection extends o{constructor(t){super(),this.speed=t}setSpeed(t){this.speed=t}initialize(t){c.set(2*Math.random()-1,2*Math.random()-1,2*Math.random()-1).normalize().multiplyScalar(this.speed),t.velocity.x+=c.x,t.velocity.y+=c.y,t.velocity.z+=c.z}}export class RandomVelocity extends o{constructor(t,e){super(),this.min=t,this.max=e,this.x=new s(this.min.x,this.max.x),this.y=new s(this.min.y,this.max.y),this.z=new s(this.min.z,this.max.z)}initialize(t){t.velocity.x+=this.x.getValue(),t.velocity.y+=this.y.getValue(),t.velocity.z+=this.z.getValue()}}export const alignRotationAxes=["+X","-X","+Y","-Y","+Z","-Z"];export const alignRotationModes=["AwayFromCenter","TowardsCenter","AlongVelocity"];export class AlignRotation extends o{constructor(e,i,s=new t,o=new t){super(),this.axis=e,this.mode=i,this.offset=s,this.center=o,this.axisVec=new t(0,1,0),this.setAxis(e)}setAxis(t){switch(t){case"+X":this.axisVec.set(1,0,0);break;case"-X":this.axisVec.set(-1,0,0);break;case"+Y":this.axisVec.set(0,1,0);break;case"-Y":this.axisVec.set(0,-1,0);break;case"+Z":this.axisVec.set(0,0,1);break;case"-Z":this.axisVec.set(0,0,-1)}}initialize(t){if("number"!=typeof t.rotation){switch(this.mode){case"AwayFromCenter":c.copy(t.position).sub(this.center).normalize();break;case"TowardsCenter":c.copy(t.position).sub(this.center).normalize().multiplyScalar(-1);break;case"AlongVelocity":c.copy(t.velocity).normalize()}c.lengthSq()<1e-4&&c.set(0,1,0),n.setFromUnitVectors(this.axisVec,c),this.offset.lengthSq()>0&&(a.setFromEuler(r.set(this.offset.x,this.offset.y,this.offset.z)),n.multiply(a)),r.setFromQuaternion(n),t.rotation.x=r.x,t.rotation.y=r.y,t.rotation.z=r.z}}}const n=new e,a=new e,r=new i,c=new t;function l(t,e){return Math.random()*(e-t)+t}function h(t){return"function"==typeof t?t():t}/*
1
+ import{Vector3 as t,Quaternion as e,Euler as i,Color as s}from"three";import{Span as o,Initializer as n}from"@hology/nebula";export class DefaultInitializer extends n{init(t,e){e.parent=t}initialize(t){}}export class Rotation extends n{constructor(t){super(),this.rotation=t}setRotation(t){this.rotation=t.clone()}initialize(t){"number"!=typeof t.rotation&&t.rotation.copy(this.rotation)}}export const randomRotationAxis=["XYZ","X","Y","Z"];export class RandomRotation extends n{constructor(t){super(),this.axis=t}initialize(t){switch(this.axis){case"XYZ":t.rotation.set(this.randomAngle(),this.randomAngle(),this.randomAngle());break;case"X":t.rotation.x=this.randomAngle();break;case"Y":t.rotation.y=this.randomAngle();break;case"Z":t.rotation.z=this.randomAngle()}}randomAngle(){return 2*Math.PI*Math.random()}}export class InitialScale extends n{constructor(t){super(),this.scale=t}setScale(t){this.scale=t}initialize(t){t.scale=this.scale}}export class RandomScale extends n{constructor(t,e){super(),this.min=t,this.max=e}setRange(t,e){this.min=t,this.max=e}initialize(t){t.scale=h(this.min,this.max)}}export class RandomColor extends n{constructor(t,e){super(),this.min=new s,this.max=new s,this.setRange(t,e)}setRange(t,e){this.min.set(t),this.max.set(e)}initialize(t){const e=Math.random();t.color.r=h(this.min.r,this.max.r,e),t.color.g=h(this.min.g,this.max.g,e),t.color.b=h(this.min.b,this.max.b,e),t.useColor=!0}}export class InitialScaleComponents extends n{constructor(t){super(),this.scale=t}setScaleComponents(t){this.scale=t.clone()}initialize(t){t.transform.initialScale=this.scale.clone()}}export class AdditiveVelocity extends n{constructor(t,e){super(),this.min=t,this.max=e}initialize(t){const e=m(this.min),i=null!=this.max?m(this.max):void 0;t.velocity.x+=null!=i?h(e.x,i.x):e.x,t.velocity.y+=null!=i?h(e.y,i.y):e.y,t.velocity.z+=null!=i?h(e.z,i.z):e.z}}export class RandomDirection extends n{constructor(t){super(),this.speed=t}setSpeed(t){this.speed=t}initialize(t){l.set(2*Math.random()-1,2*Math.random()-1,2*Math.random()-1).normalize().multiplyScalar(this.speed),t.velocity.x+=l.x,t.velocity.y+=l.y,t.velocity.z+=l.z}}export class RandomVelocity extends n{constructor(t,e){super(),this.min=t,this.max=e,this.x=new o(this.min.x,this.max.x),this.y=new o(this.min.y,this.max.y),this.z=new o(this.min.z,this.max.z)}initialize(t){t.velocity.x+=this.x.getValue(),t.velocity.y+=this.y.getValue(),t.velocity.z+=this.z.getValue()}}export const alignRotationAxes=["+X","-X","+Y","-Y","+Z","-Z"];export const alignRotationModes=["AwayFromCenter","TowardsCenter","AlongVelocity"];export class AlignRotation extends n{constructor(e,i,s=new t,o=new t){super(),this.axis=e,this.mode=i,this.offset=s,this.center=o,this.axisVec=new t(0,1,0),this.setAxis(e)}setAxis(t){switch(t){case"+X":this.axisVec.set(1,0,0);break;case"-X":this.axisVec.set(-1,0,0);break;case"+Y":this.axisVec.set(0,1,0);break;case"-Y":this.axisVec.set(0,-1,0);break;case"+Z":this.axisVec.set(0,0,1);break;case"-Z":this.axisVec.set(0,0,-1)}}initialize(t){if("number"!=typeof t.rotation){switch(this.mode){case"AwayFromCenter":l.copy(t.position).sub(this.center).normalize();break;case"TowardsCenter":l.copy(t.position).sub(this.center).normalize().multiplyScalar(-1);break;case"AlongVelocity":l.copy(t.velocity).normalize()}l.lengthSq()<1e-4&&l.set(0,1,0),a.setFromUnitVectors(this.axisVec,l),this.offset.lengthSq()>0&&(r.setFromEuler(c.set(this.offset.x,this.offset.y,this.offset.z)),a.multiply(r)),c.setFromQuaternion(a),t.rotation.x=c.x,t.rotation.y=c.y,t.rotation.z=c.z}}}const a=new e,r=new e,c=new i,l=new t;function h(t,e,i=Math.random()){return i*(e-t)+t}function m(t){return"function"==typeof t?t():t}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import{Behaviour as o,Emitter as t}from"@hology/nebula";import{RayTestResult as i}from"../../gameplay/services/physics/physics-system.js";import{Color as l,Vector3 as e}from"three";export class WorldCollisionBehaviour extends o{constructor(o,t=0,i=0,l=0){super(),this.physics=o,this.bounce=t,this.friction=i,this.lifeLoss=l}initialize(o){null==o.old.rayFrom?o.old.rayFrom=new e:o.old.rayFrom.set(0,0,0),o.old.rayLength=-1,null==o.old.hitNormal?o.old.hitNormal=new e:o.old.hitNormal.set(0,0,0),o.old.hitDistance=-1}mutate(o,i,l){if(0===o.velocity.length())return;const e=r(),c=.5*o.scale*.5;a.copy(o.velocity).normalize(),s.copy(o.velocity).multiplyScalar(i);const d=h.copy(o.old.velocity).normalize(),m=o.old.rayFrom,p=o.old.hitDistance,u=o.old.hitNormal,f=o.old.rayLength;if(d.dot(a)>.99&&o.position.distanceTo(m)+c<f)p>0?(e.hasHit=!0,e.distance=p-m.distanceTo(o.position),e.hitNormal.copy(u)):e.hasHit=!1;else{const t=15;n.copy(o.position).addScaledVector(o.velocity,i*t).addScaledVector(a,c),this.physics.rayTest(o.position,n,e),o.old.rayFrom.copy(o.position),o.old.hitDistance=e.hasHit?e.distance:-1,o.old.hitNormal.copy(e.hitNormal),o.old.rayLength=o.position.distanceTo(n)}var v,w,N;e.hasHit&&s.length()+c>e.distance&&(o.acceleration.set(0,0,0),this.bounce>0?(v=o.velocity,w=e.hitNormal,N=this.bounce,o.velocity.copy(v).sub(y.copy(w).multiplyScalar(2*v.dot(w))).multiplyScalar(N)):function(o,t,i=.95,l){const e=y.copy(t).multiplyScalar(o.dot(t)),s=l.sub(e).multiplyScalar(1-i)}(o.velocity,e.hitNormal,this.friction,o.velocity),o.old.hitDistance=-1,o.parent instanceof t&&o.parent.dispatch("PARTICLE_COLLISION",o),this.lifeLoss>0&&setTimeout(()=>{o.life-=this.lifeLoss+30},30))}}const s=new e,a=new e,n=new e;let c=null;function r(){return null===c&&(c=new i),c}new e;const h=new e,y=new e;(new l).setRGB(Math.random(),Math.random(),Math.random());/*
1
+ import{Behaviour as o,Emitter as t}from"@hology/nebula";import{RayTestResult as i}from"../../gameplay/services/physics/physics-system.js";import{Color as l,Vector3 as e}from"three";export class WorldCollisionBehaviour extends o{constructor(o,t=0,l=0,e=0){super(),this.physics=o,this.bounce=t,this.friction=l,this.lifeLoss=e,null==c&&(c=new i)}initialize(o){null==o.old.rayFrom?o.old.rayFrom=new e:o.old.rayFrom.set(0,0,0),o.old.rayLength=-1,null==o.old.hitNormal?o.old.hitNormal=new e:o.old.hitNormal.set(0,0,0),o.old.hitDistance=-1}mutate(o,i,l){if(0===o.velocity.length())return;const e=r(),c=.5*o.scale*.5;a.copy(o.velocity).normalize(),s.copy(o.velocity).multiplyScalar(i);const d=h.copy(o.old.velocity).normalize(),m=o.old.rayFrom,p=o.old.hitDistance,u=o.old.hitNormal,f=o.old.rayLength;if(d.dot(a)>.99&&o.position.distanceTo(m)+c<f)p>0?(e.hasHit=!0,e.distance=p-m.distanceTo(o.position),e.hitNormal.copy(u)):e.hasHit=!1;else{const t=15;n.copy(o.position).addScaledVector(o.velocity,i*t).addScaledVector(a,c),this.physics.rayTest(o.position,n,e),o.old.rayFrom.copy(o.position),o.old.hitDistance=e.hasHit?e.distance:-1,o.old.hitNormal.copy(e.hitNormal),o.old.rayLength=o.position.distanceTo(n)}var v,w,N;e.hasHit&&s.length()+c>e.distance&&(o.acceleration.set(0,0,0),this.bounce>0?(v=o.velocity,w=e.hitNormal,N=this.bounce,o.velocity.copy(v).sub(y.copy(w).multiplyScalar(2*v.dot(w))).multiplyScalar(N)):function(o,t,i=.95,l){const e=y.copy(t).multiplyScalar(o.dot(t)),s=l.sub(e).multiplyScalar(1-i)}(o.velocity,e.hitNormal,this.friction,o.velocity),o.old.hitDistance=-1,o.parent instanceof t&&o.parent.dispatch("PARTICLE_COLLISION",o),this.lifeLoss>0&&setTimeout(()=>{o.life-=this.lifeLoss+30},30))}}const s=new e,a=new e,n=new e;let c=null;function r(){return null===c&&(c=new i),c}new e;const h=new e,y=new e;(new l).setRGB(Math.random(),Math.random(),Math.random());/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,7 +1,7 @@
1
1
  import { AnimationClip, Vector2, Vector3 } from "three";
2
2
  import { Alpha, Attraction, Behaviour, Color as ChangeColor, Force, Gravity, Initializer, Life, Mass, Position, RadialVelocity, RandomDrift, Repulsion, Rotate } from "@hology/nebula";
3
3
  import { Disperse, FollowParent, LinearDamping, MoveOverLife, RotatePosition, Scale, ScaleComponents } from './behaviours.js';
4
- import { AdditiveVelocity, InitialScale, InitialScaleComponents, RandomDirection, RandomScale, Rotation } from './initializsers.js';
4
+ import { AdditiveVelocity, InitialScale, InitialScaleComponents, RandomColor, RandomDirection, RandomScale, Rotation } from './initializsers.js';
5
5
  import { Curve2 } from "../../utils/curve.js";
6
6
  import { VfxBindingAdapter, VfxBindingMode, VfxBoundBehaviourDefinition, VfxBoundInitializerDefinition } from "./vfx-binding-runtime.js";
7
7
  type HexColor = `#${string}`;
@@ -193,6 +193,14 @@ declare class RandomScaleDef extends BaseIniDef<RandomScaleDef> {
193
193
  bindingAdapter: VfxBindingAdapter<RandomScale>;
194
194
  make(params?: ParamsType<this>): Initializer;
195
195
  }
196
+ declare class RandomColorDef extends BaseIniDef<RandomColorDef> {
197
+ parameters: {
198
+ a: ShapeParameterDef<`#${string}`>;
199
+ b: ShapeParameterDef<`#${string}`>;
200
+ };
201
+ bindingAdapter: VfxBindingAdapter<RandomColor>;
202
+ make(params?: ParamsType<this>): Initializer;
203
+ }
196
204
  declare class InitialScaleComponentsDef extends BaseIniDef<InitialScaleComponentsDef> {
197
205
  parameters: {
198
206
  scale: ShapeParameterDef<Vector3>;
@@ -374,6 +382,7 @@ declare const vfxInitializsers: {
374
382
  scale: InitialScaleDef;
375
383
  scaleComponents: InitialScaleComponentsDef;
376
384
  randomScale: RandomScaleDef;
385
+ randomColor: RandomColorDef;
377
386
  mass: MassDef;
378
387
  velocity: VelocityDef;
379
388
  randomVelocity: RandomVelocityDef;
@@ -1,4 +1,4 @@
1
- import{LoopOnce as e,LoopPingPong as t,LoopRepeat as s,MathUtils as n,Vector2 as r,Vector3 as a}from"three";import{Alpha as i,Attraction as o,BoxZone as c,CircleZone as p,Color as u,ease as d,Force as m,Gravity as l,Life as w,LineZone as h,Mass as f,Position as x,RadialVelocity as g,RandomDrift as b,Repulsion as y,Rotate as k,Vector3D as v}from"@hology/nebula";import{AnimationBehavior as A,AxisDirection as z,AxisPlane as R,Disperse as L,FollowParent as D,LinearDamping as C,MoveOverLife as S,OrientAlongVelocity as T,RotatePosition as V,Scale as j,ScaleComponents as Y}from"./behaviours.js";import{AdditiveVelocity as B,AlignRotation as F,alignRotationAxes as O,alignRotationModes as P,InitialScale as X,InitialScaleComponents as Z,RandomDirection as I,RandomRotation as M,randomRotationAxis as K,RandomScale as W,Rotation as q}from"./initializsers.js";import{PointZone as E,SphereZone as G}from"./zones.js";import{WorldCollisionBehaviour as H}from"./vfx-collision-behaviour.js";import{Curve2 as J}from"../../utils/curve.js";import{liveBindingAdapter as N,spawnBindingAdapter as Q}from"./vfx-binding-runtime.js";class U{build(e={}){const t=ce(e,this.parameters);return this.make(t)}}class ${build(e={}){const t=ce(e,this.parameters);return this.make(t)}}function _(e,t,s){return{type:"number",default:e,float:!0,min:t,max:s}}function ee(e,t,s,n){return{..._(e,s,n),bindable:t}}function te(e){return{type:"boolean",default:e}}function se(e){return{type:"vec3",default:(new a).fromArray(e)}}function ne(e,t){return{...se(e),bindable:t}}function re(e){return{type:"color",default:e}}function ae(e,t){return{...re(e),bindable:t}}function ie(e,t){return{type:"select",opts:e,default:t}}function oe(){return{type:"curve",default:J.linear()}}function ce(e,t){const s={};for(let n in t)null==e[n]?s[n]=t[n].default:s[n]=e[n];return s}function pe(e){return new v(e.x,e.y,e.z)}function ue(e){return new a(n.degToRad(e.x),n.degToRad(e.y),n.degToRad(e.z))}function de(e){const{x:t,y:s,z:n}=e;return new E(t,s,n)}function me(e,t){const{x:s,y:n,z:r}=e,{x:a,y:i,z:o}=t;return new c(s,n,r,a,i,o)}function le(e,t,s=!1){const{x:n,y:r,z:a}=e;return new G(n,r,a,t,s)}function we(e,t){return new h(e.x,e.y,e.z,t.x,t.y,t.z)}function he(e,t,s,r=0){return new p(e.x,e.y,e.z,s,r,n.degToRad(t.x),n.degToRad(t.y),n.degToRad(t.z))}function fe(e){return t=>e.getY(t)}const xe={lifetime:new class extends ${constructor(){super(...arguments),this.parameters={duration:ee(1,"spawn",0,1e5)},this.bindingAdapter=Q((e,t)=>{e.resetLife(t.duration)})}make(e={}){return new w(e.duration)}},randomLifetime:new class extends ${constructor(){super(...arguments),this.parameters={minDuration:ee(1,"spawn",0,1e5),maxDuration:ee(2,"spawn",0,1e5)},this.bindingAdapter=Q((e,t)=>{e.resetLife(t.minDuration,t.maxDuration)})}make(e={}){return new w(e.minDuration,e.maxDuration)}},positionPoint:new class extends ${constructor(){super(...arguments),this.parameters={position:ne([0,0,0],"spawn")},this.bindingAdapter=Q((e,t)=>{e.reset(de(t.position))})}make(e={}){return new x(de(e.position))}},positionBox:new class extends ${constructor(){super(...arguments),this.parameters={position:ne([0,0,0],"spawn"),dimensions:ne([0,0,0],"spawn")},this.bindingAdapter=Q((e,t)=>{e.reset(me(t.position,t.dimensions))})}make(e={}){return new x(me(e.position,e.dimensions))}},positionSphere:new class extends ${constructor(){super(...arguments),this.parameters={position:ne([0,0,0],"spawn"),radius:ee(1,"spawn"),surface:te(!1)},this.bindingAdapter=Q((e,t)=>{e.reset(le(t.position,t.radius,t.surface))})}make(e={}){return new x(le(e.position,e.radius,e.surface))}},positionLine:new class extends ${constructor(){super(...arguments),this.parameters={a:ne([0,0,0],"spawn"),b:ne([0,0,1],"spawn")},this.bindingAdapter=Q((e,t)=>{e.reset(we(t.a,t.b))})}make(e={}){return new x(we(e.a,e.b))}},positionCircle:new class extends ${constructor(){super(...arguments),this.parameters={position:ne([0,0,0],"spawn"),rotation:ne([0,0,0],"spawn"),radius:ee(1,"spawn",0,1e4)},this.bindingAdapter=Q((e,t)=>{e.reset(he(t.position,t.rotation,t.radius))})}make(e={}){return new x(he(e.position,e.rotation,e.radius))}},positionRing:new class extends ${constructor(){super(...arguments),this.parameters={position:ne([0,0,0],"spawn"),rotation:ne([0,0,0],"spawn"),radius:ee(1,"spawn",0,1e4),thickness:ee(.2,"spawn",0,1e4)},this.bindingAdapter=Q((e,t)=>{e.reset(he(t.position,t.rotation,t.radius,Math.max(t.thickness,1e-4)))})}make(e={}){return new x(he(e.position,e.rotation,e.radius,Math.max(e.thickness,1e-4)))}},rotation:new class extends ${constructor(){super(...arguments),this.parameters={rotation:ne([0,0,0],"spawn")},this.bindingAdapter=Q((e,t)=>{e.setRotation(ue(t.rotation))})}make(e={}){return new q(ue(e.rotation))}},randomRotation:new class extends ${constructor(){super(...arguments),this.parameters={axis:ie(K,"XYZ")}}make(e={}){return new M(e.axis)}},scale:new class extends ${constructor(){super(...arguments),this.parameters={scale:ee(1,"spawn")},this.bindingAdapter=Q((e,t)=>{e.setScale(t.scale)})}make(e={}){return new X(e.scale)}},scaleComponents:new class extends ${constructor(){super(...arguments),this.parameters={scale:ne([1,1,1],"spawn")},this.bindingAdapter=Q((e,t)=>{e.setScaleComponents(t.scale)})}make(e={}){return new Z(e.scale)}},randomScale:new class extends ${constructor(){super(...arguments),this.parameters={min:ee(1,"spawn"),max:ee(1,"spawn")},this.bindingAdapter=Q((e,t)=>{e.setRange(t.min,t.max)})}make(e={}){return new W(e.min,e.max)}},mass:new class extends ${constructor(){super(...arguments),this.parameters={min:ee(1,"spawn")},this.bindingAdapter=Q((e,t)=>{e.resetMass(t.min)})}make(e={}){return new f(e.min)}},velocity:new class extends ${constructor(){super(...arguments),this.parameters={velocity:ne([0,0,0],"spawn")},this.bindingAdapter={buildBound:e=>new B(()=>e.get("velocity"))}}make(e={}){const{x:t,y:s,z:n}=e.velocity;return new B(new a(t,s,n))}},randomVelocity:new class extends ${constructor(){super(...arguments),this.parameters={min:ne([0,0,0],"spawn"),max:ne([0,0,0],"spawn")},this.bindingAdapter={buildBound:e=>new B(()=>e.get("min"),()=>e.get("max"))}}make(e={}){return new B(e.min,e.max)}},radialVelocity:new class extends ${constructor(){super(...arguments),this.parameters={speed:ee(1,"spawn"),direction:ne([0,1,0],"spawn"),spread:ee(0,"spawn")},this.bindingAdapter=Q((e,t)=>{e.resetRadialVelocity(t.speed,pe(t.direction),t.spread)})}make(e={}){return new g(e.speed,pe(e.direction),e.spread)}},randomDirection:new class extends ${constructor(){super(...arguments),this.parameters={speed:ee(1,"spawn")},this.bindingAdapter=Q((e,t)=>{e.setSpeed(t.speed)})}make(e={}){return new I(e.speed)}},alignRotation:new class extends ${constructor(){super(...arguments),this.parameters={mode:ie(P,"AwayFromCenter"),axis:ie(O,"+Y"),offset:se([0,0,0]),center:se([0,0,0])}}make(e={}){return new F(e.axis,e.mode,ue(e.offset),e.center)}}},ge={force:new class extends U{constructor(){super(...arguments),this.parameters={force:ne([0,0,0],"live"),ease:oe()},this.bindingAdapter=N((e,t)=>{const s=t.force;e.setForce(s.x,s.y,s.z)})}make(e={}){return new m(e.force.x,e.force.y,e.force.z,void 0,fe(e.ease))}},gravity:new class extends U{constructor(){super(...arguments),this.parameters={gravity:ee(8,"live"),easing:oe()},this.bindingAdapter=N((e,t)=>{e.setForce(0,-t.gravity,0)})}make(e={}){return new l(e.gravity,void 0,fe(e.easing))}},repulsion:new class extends U{constructor(){super(...arguments),this.parameters={target:ne([0,0,0],"live"),force:ee(1,"live"),radius:ee(1,"live"),easing:oe()},this.bindingAdapter=N((e,t)=>{e.resetAttraction(pe(t.target),t.force,t.radius)})}make(e={}){const t=pe(e.target);return new y(t,e.force,e.radius,void 0,fe(e.easing))}},attraction:new class extends U{constructor(){super(...arguments),this.parameters={target:ne([0,0,0],"live"),force:ee(1,"live"),radius:ee(1,"live"),easing:oe()},this.bindingAdapter=N((e,t)=>{e.resetAttraction(pe(t.target),t.force,t.radius)})}make(e={}){const t=pe(e.target);return new o(t,e.force,e.radius,void 0,fe(e.easing))}},scale:new class extends U{constructor(){super(...arguments),this.parameters={a:ee(1,"spawn"),b:ee(1,"spawn"),ease:oe()},this.bindingAdapter=Q((e,t)=>{e.setScaleRange(t.a,t.b)})}make(e={}){return new j(e.a,e.b,fe(e.ease))}},scaleComponents:new class extends U{constructor(){super(...arguments),this.parameters={a:ne([1,1,1],"spawn"),b:ne([1,1,1],"spawn"),ease:oe()},this.bindingAdapter=Q((e,t)=>{e.setScaleRange(t.a,t.b)})}make(e={}){return new Y(e.a,e.b,fe(e.ease))}},randomDrift:new class extends U{constructor(){super(...arguments),this.parameters={drift:ne([1,1,1],"live"),delay:ee(0,"live"),ease:oe()},this.bindingAdapter=N((e,t)=>{const s=t.drift;e.setDrift(s.x,s.y,s.z,t.delay)})}make(e={}){return new b(e.drift.x,e.drift.y,e.drift.z,e.delay,void 0,fe(e.ease))}},disperse:new class extends U{constructor(){super(...arguments),this.parameters={distance:ee(1,"spawn"),axis:ie(["XYZ","XZ","XY","YZ"],"XYZ"),ease:oe()},this.bindingAdapter=Q((e,t)=>{e.setDistance(t.distance)})}make(e={}){return new L(e.distance,R[e.axis.toLowerCase()],fe(e.ease))}},rotate:new class extends U{constructor(){super(...arguments),this.parameters={rotation:ne([0,0,0],"spawn"),ease:oe()},this.bindingAdapter=Q((e,t)=>{const s=ue(t.rotation);e.resetRotation(s.x,s.y,s.z)})}make(e={}){const t=ue(e.rotation);return new k(t.x,t.y,t.z,void 0,fe(e.ease))}},rotateAdd:new class extends U{constructor(){super(...arguments),this.parameters={rotation:ne([0,0,0],"spawn")},this.bindingAdapter=Q((e,t)=>{const s=ue(t.rotation);e.resetRotation(s.x,s.y,s.z)})}make(e={}){const t=ue(e.rotation),s=new k(t.x,t.y,t.z,void 0);return s.rotationType="add",s}},changeColor:new class extends U{constructor(){super(...arguments),this.parameters={a:ae("#ffffff","spawn"),b:ae("#ffffff","spawn"),ease:oe()},this.bindingAdapter=Q((e,t)=>{e.resetColor(t.a,t.b)})}make(e={}){return new u(e.a,e.b,void 0,fe(e.ease))}},changeOpacity:new class extends U{constructor(){super(...arguments),this.parameters={a:ee(1,"spawn",0,1),b:ee(0,"spawn",0,1),ease:oe()},this.bindingAdapter=Q((e,t)=>{e.resetAlpha(t.a,t.b)})}make(e={}){return new i(e.a,e.b,void 0,fe(e.ease))}},vortex:new class extends U{constructor(){super(...arguments),this.parameters={axis:ne([0,1,0],"live"),amount:ee(1,"live")},this.bindingAdapter=N((e,t)=>{e.setAxisAngle(t.axis,t.amount)})}make(e={}){return new V(e.axis,e.amount)}},moveTo:new class extends U{constructor(){super(...arguments),this.parameters={target:ne([0,1,0],"live"),ease:oe()},this.bindingAdapter=N((e,t)=>{const s=t.target;e.setTarget(s.x,s.y,s.z)})}make(e={}){return new S(e.target.x,e.target.y,e.target.z,fe(e.ease))}},linearDamping:new class extends U{constructor(){super(...arguments),this.parameters={factor:ee(.1,"live",0,1e3)},this.bindingAdapter=N((e,t)=>{e.setFactor(t.factor)})}make(e={}){return new C(e.factor)}},followParent:new class extends U{constructor(){super(...arguments),this.parameters={speed:ee(0,"live")},this.bindingAdapter=N((e,t)=>{e.setSpeed(t.speed)})}make(e={}){return new D(e.speed)}},worldCollision:new class extends U{constructor(){super(...arguments),this.parameters={friction:_(1,0,1),bounce:_(1,0,1),lifeLoss:_(0,0)}}make(e={}){return new H(null,e.bounce,e.friction,e.lifeLoss)}},animation:new class extends U{constructor(){super(...arguments),this.parameters={clip:{type:"animationclip",default:null},timeScale:_(1,0,10),weight:_(1,0,1),loop:ie(["Once","Repeat","PingPong"],"Once"),clampWhenFinished:{...te(!0),requires:{loop:"Once"}}}}make(n={}){let r=e;return"Repeat"===n.loop?r=s:"PingPong"===n.loop&&(r=t),new A(n.clip,n.timeScale,n.weight,r,n.clampWhenFinished,d.easeLinear)}}};export const VfxInitializserLibrary=xe;export const VfxInitializserLibraryKeys=Object.keys(VfxInitializserLibrary);export const VfxBehaviourLibrary=ge;export const VfxBehaviourLibraryKeys=Object.keys(VfxBehaviourLibrary);/*
1
+ import{LoopOnce as e,LoopPingPong as t,LoopRepeat as s,MathUtils as n,Vector2 as r,Vector3 as a}from"three";import{Alpha as i,Attraction as o,BoxZone as c,CircleZone as p,Color as u,ease as d,Force as m,Gravity as l,Life as w,LineZone as f,Mass as h,Position as x,RadialVelocity as g,RandomDrift as b,Repulsion as y,Rotate as k,Vector3D as v}from"@hology/nebula";import{AnimationBehavior as A,AxisDirection as z,AxisPlane as R,Disperse as L,FollowParent as C,LinearDamping as D,MoveOverLife as S,OrientAlongVelocity as T,RotatePosition as V,Scale as j,ScaleComponents as Y}from"./behaviours.js";import{AdditiveVelocity as B,AlignRotation as F,alignRotationAxes as O,alignRotationModes as P,InitialScale as X,InitialScaleComponents as Z,RandomColor as I,RandomDirection as M,RandomRotation as K,randomRotationAxis as W,RandomScale as q,Rotation as E}from"./initializsers.js";import{PointZone as G,SphereZone as H}from"./zones.js";import{WorldCollisionBehaviour as J}from"./vfx-collision-behaviour.js";import{Curve2 as N}from"../../utils/curve.js";import{liveBindingAdapter as Q,spawnBindingAdapter as U}from"./vfx-binding-runtime.js";class ${build(e={}){const t=pe(e,this.parameters);return this.make(t)}}class _{build(e={}){const t=pe(e,this.parameters);return this.make(t)}}function ee(e,t,s){return{type:"number",default:e,float:!0,min:t,max:s}}function te(e,t,s,n){return{...ee(e,s,n),bindable:t}}function se(e){return{type:"boolean",default:e}}function ne(e){return{type:"vec3",default:(new a).fromArray(e)}}function re(e,t){return{...ne(e),bindable:t}}function ae(e){return{type:"color",default:e}}function ie(e,t){return{...ae(e),bindable:t}}function oe(e,t){return{type:"select",opts:e,default:t}}function ce(){return{type:"curve",default:N.linear()}}function pe(e,t){const s={};for(let n in t)null==e[n]?s[n]=t[n].default:s[n]=e[n];return s}function ue(e){return new v(e.x,e.y,e.z)}function de(e){return new a(n.degToRad(e.x),n.degToRad(e.y),n.degToRad(e.z))}function me(e){const{x:t,y:s,z:n}=e;return new G(t,s,n)}function le(e,t){const{x:s,y:n,z:r}=e,{x:a,y:i,z:o}=t;return new c(s,n,r,a,i,o)}function we(e,t,s=!1){const{x:n,y:r,z:a}=e;return new H(n,r,a,t,s)}function fe(e,t){return new f(e.x,e.y,e.z,t.x,t.y,t.z)}function he(e,t,s,r=0){return new p(e.x,e.y,e.z,s,r,n.degToRad(t.x),n.degToRad(t.y),n.degToRad(t.z))}function xe(e){return t=>e.getY(t)}const ge={lifetime:new class extends _{constructor(){super(...arguments),this.parameters={duration:te(1,"spawn",0,1e5)},this.bindingAdapter=U((e,t)=>{e.resetLife(t.duration)})}make(e={}){return new w(e.duration)}},randomLifetime:new class extends _{constructor(){super(...arguments),this.parameters={minDuration:te(1,"spawn",0,1e5),maxDuration:te(2,"spawn",0,1e5)},this.bindingAdapter=U((e,t)=>{e.resetLife(t.minDuration,t.maxDuration)})}make(e={}){return new w(e.minDuration,e.maxDuration)}},positionPoint:new class extends _{constructor(){super(...arguments),this.parameters={position:re([0,0,0],"spawn")},this.bindingAdapter=U((e,t)=>{e.reset(me(t.position))})}make(e={}){return new x(me(e.position))}},positionBox:new class extends _{constructor(){super(...arguments),this.parameters={position:re([0,0,0],"spawn"),dimensions:re([0,0,0],"spawn")},this.bindingAdapter=U((e,t)=>{e.reset(le(t.position,t.dimensions))})}make(e={}){return new x(le(e.position,e.dimensions))}},positionSphere:new class extends _{constructor(){super(...arguments),this.parameters={position:re([0,0,0],"spawn"),radius:te(1,"spawn"),surface:se(!1)},this.bindingAdapter=U((e,t)=>{e.reset(we(t.position,t.radius,t.surface))})}make(e={}){return new x(we(e.position,e.radius,e.surface))}},positionLine:new class extends _{constructor(){super(...arguments),this.parameters={a:re([0,0,0],"spawn"),b:re([0,0,1],"spawn")},this.bindingAdapter=U((e,t)=>{e.reset(fe(t.a,t.b))})}make(e={}){return new x(fe(e.a,e.b))}},positionCircle:new class extends _{constructor(){super(...arguments),this.parameters={position:re([0,0,0],"spawn"),rotation:re([0,0,0],"spawn"),radius:te(1,"spawn",0,1e4)},this.bindingAdapter=U((e,t)=>{e.reset(he(t.position,t.rotation,t.radius))})}make(e={}){return new x(he(e.position,e.rotation,e.radius))}},positionRing:new class extends _{constructor(){super(...arguments),this.parameters={position:re([0,0,0],"spawn"),rotation:re([0,0,0],"spawn"),radius:te(1,"spawn",0,1e4),thickness:te(.2,"spawn",0,1e4)},this.bindingAdapter=U((e,t)=>{e.reset(he(t.position,t.rotation,t.radius,Math.max(t.thickness,1e-4)))})}make(e={}){return new x(he(e.position,e.rotation,e.radius,Math.max(e.thickness,1e-4)))}},rotation:new class extends _{constructor(){super(...arguments),this.parameters={rotation:re([0,0,0],"spawn")},this.bindingAdapter=U((e,t)=>{e.setRotation(de(t.rotation))})}make(e={}){return new E(de(e.rotation))}},randomRotation:new class extends _{constructor(){super(...arguments),this.parameters={axis:oe(W,"XYZ")}}make(e={}){return new K(e.axis)}},scale:new class extends _{constructor(){super(...arguments),this.parameters={scale:te(1,"spawn")},this.bindingAdapter=U((e,t)=>{e.setScale(t.scale)})}make(e={}){return new X(e.scale)}},scaleComponents:new class extends _{constructor(){super(...arguments),this.parameters={scale:re([1,1,1],"spawn")},this.bindingAdapter=U((e,t)=>{e.setScaleComponents(t.scale)})}make(e={}){return new Z(e.scale)}},randomScale:new class extends _{constructor(){super(...arguments),this.parameters={min:te(1,"spawn"),max:te(1,"spawn")},this.bindingAdapter=U((e,t)=>{e.setRange(t.min,t.max)})}make(e={}){return new q(e.min,e.max)}},randomColor:new class extends _{constructor(){super(...arguments),this.parameters={a:ie("#ffffff","spawn"),b:ie("#ffffff","spawn")},this.bindingAdapter=U((e,t)=>{e.setRange(t.a,t.b)})}make(e={}){return new I(e.a,e.b)}},mass:new class extends _{constructor(){super(...arguments),this.parameters={min:te(1,"spawn")},this.bindingAdapter=U((e,t)=>{e.resetMass(t.min)})}make(e={}){return new h(e.min)}},velocity:new class extends _{constructor(){super(...arguments),this.parameters={velocity:re([0,0,0],"spawn")},this.bindingAdapter={buildBound:e=>new B(()=>e.get("velocity"))}}make(e={}){const{x:t,y:s,z:n}=e.velocity;return new B(new a(t,s,n))}},randomVelocity:new class extends _{constructor(){super(...arguments),this.parameters={min:re([0,0,0],"spawn"),max:re([0,0,0],"spawn")},this.bindingAdapter={buildBound:e=>new B(()=>e.get("min"),()=>e.get("max"))}}make(e={}){return new B(e.min,e.max)}},radialVelocity:new class extends _{constructor(){super(...arguments),this.parameters={speed:te(1,"spawn"),direction:re([0,1,0],"spawn"),spread:te(0,"spawn")},this.bindingAdapter=U((e,t)=>{e.resetRadialVelocity(t.speed,ue(t.direction),t.spread)})}make(e={}){return new g(e.speed,ue(e.direction),e.spread)}},randomDirection:new class extends _{constructor(){super(...arguments),this.parameters={speed:te(1,"spawn")},this.bindingAdapter=U((e,t)=>{e.setSpeed(t.speed)})}make(e={}){return new M(e.speed)}},alignRotation:new class extends _{constructor(){super(...arguments),this.parameters={mode:oe(P,"AwayFromCenter"),axis:oe(O,"+Y"),offset:ne([0,0,0]),center:ne([0,0,0])}}make(e={}){return new F(e.axis,e.mode,de(e.offset),e.center)}}},be={force:new class extends ${constructor(){super(...arguments),this.parameters={force:re([0,0,0],"live"),ease:ce()},this.bindingAdapter=Q((e,t)=>{const s=t.force;e.setForce(s.x,s.y,s.z)})}make(e={}){return new m(e.force.x,e.force.y,e.force.z,void 0,xe(e.ease))}},gravity:new class extends ${constructor(){super(...arguments),this.parameters={gravity:te(8,"live"),easing:ce()},this.bindingAdapter=Q((e,t)=>{e.setForce(0,-t.gravity,0)})}make(e={}){return new l(e.gravity,void 0,xe(e.easing))}},repulsion:new class extends ${constructor(){super(...arguments),this.parameters={target:re([0,0,0],"live"),force:te(1,"live"),radius:te(1,"live"),easing:ce()},this.bindingAdapter=Q((e,t)=>{e.resetAttraction(ue(t.target),t.force,t.radius)})}make(e={}){const t=ue(e.target);return new y(t,e.force,e.radius,void 0,xe(e.easing))}},attraction:new class extends ${constructor(){super(...arguments),this.parameters={target:re([0,0,0],"live"),force:te(1,"live"),radius:te(1,"live"),easing:ce()},this.bindingAdapter=Q((e,t)=>{e.resetAttraction(ue(t.target),t.force,t.radius)})}make(e={}){const t=ue(e.target);return new o(t,e.force,e.radius,void 0,xe(e.easing))}},scale:new class extends ${constructor(){super(...arguments),this.parameters={a:te(1,"spawn"),b:te(1,"spawn"),ease:ce()},this.bindingAdapter=U((e,t)=>{e.setScaleRange(t.a,t.b)})}make(e={}){return new j(e.a,e.b,xe(e.ease))}},scaleComponents:new class extends ${constructor(){super(...arguments),this.parameters={a:re([1,1,1],"spawn"),b:re([1,1,1],"spawn"),ease:ce()},this.bindingAdapter=U((e,t)=>{e.setScaleRange(t.a,t.b)})}make(e={}){return new Y(e.a,e.b,xe(e.ease))}},randomDrift:new class extends ${constructor(){super(...arguments),this.parameters={drift:re([1,1,1],"live"),delay:te(0,"live"),ease:ce()},this.bindingAdapter=Q((e,t)=>{const s=t.drift;e.setDrift(s.x,s.y,s.z,t.delay)})}make(e={}){return new b(e.drift.x,e.drift.y,e.drift.z,e.delay,void 0,xe(e.ease))}},disperse:new class extends ${constructor(){super(...arguments),this.parameters={distance:te(1,"spawn"),axis:oe(["XYZ","XZ","XY","YZ"],"XYZ"),ease:ce()},this.bindingAdapter=U((e,t)=>{e.setDistance(t.distance)})}make(e={}){return new L(e.distance,R[e.axis.toLowerCase()],xe(e.ease))}},rotate:new class extends ${constructor(){super(...arguments),this.parameters={rotation:re([0,0,0],"spawn"),ease:ce()},this.bindingAdapter=U((e,t)=>{const s=de(t.rotation);e.resetRotation(s.x,s.y,s.z)})}make(e={}){const t=de(e.rotation);return new k(t.x,t.y,t.z,void 0,xe(e.ease))}},rotateAdd:new class extends ${constructor(){super(...arguments),this.parameters={rotation:re([0,0,0],"spawn")},this.bindingAdapter=U((e,t)=>{const s=de(t.rotation);e.resetRotation(s.x,s.y,s.z)})}make(e={}){const t=de(e.rotation),s=new k(t.x,t.y,t.z,void 0);return s.rotationType="add",s}},changeColor:new class extends ${constructor(){super(...arguments),this.parameters={a:ie("#ffffff","spawn"),b:ie("#ffffff","spawn"),ease:ce()},this.bindingAdapter=U((e,t)=>{e.resetColor(t.a,t.b)})}make(e={}){return new u(e.a,e.b,void 0,xe(e.ease))}},changeOpacity:new class extends ${constructor(){super(...arguments),this.parameters={a:te(1,"spawn",0,1),b:te(0,"spawn",0,1),ease:ce()},this.bindingAdapter=U((e,t)=>{e.resetAlpha(t.a,t.b)})}make(e={}){return new i(e.a,e.b,void 0,xe(e.ease))}},vortex:new class extends ${constructor(){super(...arguments),this.parameters={axis:re([0,1,0],"live"),amount:te(1,"live")},this.bindingAdapter=Q((e,t)=>{e.setAxisAngle(t.axis,t.amount)})}make(e={}){return new V(e.axis,e.amount)}},moveTo:new class extends ${constructor(){super(...arguments),this.parameters={target:re([0,1,0],"live"),ease:ce()},this.bindingAdapter=Q((e,t)=>{const s=t.target;e.setTarget(s.x,s.y,s.z)})}make(e={}){return new S(e.target.x,e.target.y,e.target.z,xe(e.ease))}},linearDamping:new class extends ${constructor(){super(...arguments),this.parameters={factor:te(.1,"live",0,1e3)},this.bindingAdapter=Q((e,t)=>{e.setFactor(t.factor)})}make(e={}){return new D(e.factor)}},followParent:new class extends ${constructor(){super(...arguments),this.parameters={speed:te(0,"live")},this.bindingAdapter=Q((e,t)=>{e.setSpeed(t.speed)})}make(e={}){return new C(e.speed)}},worldCollision:new class extends ${constructor(){super(...arguments),this.parameters={friction:ee(1,0,1),bounce:ee(1,0,1),lifeLoss:ee(0,0)}}make(e={}){return new J(null,e.bounce,e.friction,e.lifeLoss)}},animation:new class extends ${constructor(){super(...arguments),this.parameters={clip:{type:"animationclip",default:null},timeScale:ee(1,0,10),weight:ee(1,0,1),loop:oe(["Once","Repeat","PingPong"],"Once"),clampWhenFinished:{...se(!0),requires:{loop:"Once"}}}}make(n={}){let r=e;return"Repeat"===n.loop?r=s:"PingPong"===n.loop&&(r=t),new A(n.clip,n.timeScale,n.weight,r,n.clampWhenFinished,d.easeLinear)}}};export const VfxInitializserLibrary=ge;export const VfxInitializserLibraryKeys=Object.keys(VfxInitializserLibrary);export const VfxBehaviourLibrary=be;export const VfxBehaviourLibraryKeys=Object.keys(VfxBehaviourLibrary);/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,4 +1,4 @@
1
- import e,{Behaviour as t,Body as a,Emitter as r,Rate as s}from"@hology/nebula";import*as i from"three";import{Object3D as n}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as p,UniformFloatNode as u,UniformVec3Node as h,Vec3ExpressionNode as d,Vec4Node as m,attributeFloat as f,attributeVec3 as y,attributeVec4 as g,attributes as w,clamp as b,float as v,glslFunction as E,lambertMaterial as A,log as M,pow as x,rgb as P,rgba as S,smoothstep as I,standardMaterial as T,textureSampler2d as C,uniformFloat as R,uniforms as B,varying as k,varyingAttributes as j,varyingVec3 as D,varyingVec4 as G}from"three-shader-graph";import{prepareClassParameters as V,prepareShaderGraphParameters as F,prepareShapeParameters as z}from"../../scene/materializer.js";import{SerializedParamType as L}from"../../scene/model.js";import{ShapeLibrary as O}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as W,linearEyeDepth as Q}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as H,particleTimeUniformName as U,particleUniforms as q,particleVelcoityUniformName as J}from"../../shader-nodes/particle.js";import{sampleFlipbook as N}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as X}from"./initializsers.js";import{DelayRate as _,OnceRate as K}from"./rates.js";import{StretchedSprite as Y}from"./stretched-sprite.js";import{ThreeBlendingMode as Z}from"./vfx-asset.js";import{VfxBehaviourLibrary as $,VfxInitializserLibrary as ee}from"./vfx-defs.js";import{MultiRenderer as te}from"./vfx-renderers.js";import{WorldCollisionBehaviour as ae}from"./vfx-collision-behaviour.js";import{getSpritePosition as re,SpriteNodeShaderMaterial as se}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ie}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as ne}from"../../shader/builtin/decal-standard-shader.js";import{createBoundBehaviour as oe,createBoundInitializer as le}from"./vfx-binding-runtime.js";import{buildShaderGraphMaterial as ce}from"../../shader/graph/index.js";export async function materializeVfx(t,a,r,s,o,l,c,p,u){let h=a;for(;null!=h.parent;)h=h.parent;const d=new n;d.name="particle system local",a.add(d);const m=new n;m.name="particle system world";const f=new te(m,d,i,s),y=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await pe(e,r,c,p,y,o,l,u,a);return t.setParentRecursive(y),t.emit()}))).forEach(e=>y.addEmitter(e)),y.addRenderer(f).emit({onEnd:()=>{}}),{container:m,system:y,dispose:()=>{m.removeFromParent(),d.removeFromParent(),f.dispose()}}}async function pe(e,t,r,p,v,x,P,T,D){const V=function(e){let t;switch(e.rate.type){case"continuous":t=new _(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new K(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new s(0,1/0)}return t}(e);let F;switch(e.output.type){case"decal":F=new a(await async function(e,t,a,r,s){if("shaderGraph"===me(e)){const t=await de(e,"decal",a,r,s);if(null!=t){const a=new i.Mesh(new i.BoxGeometry(1,1,1),t);return null!=e.renderOrder&&(a.renderOrder=e.renderOrder),a}}const n=!1!==e.unlit?new ie:new ne;n.color=new i.Color(e.color),n instanceof ie?n.intensity=e.intensity??1:n.emissiveIntensity=e.intensity??1;if(e.colorMap){const a=await t.getTexture(e.colorMap);n.colorMap=a}if(e.alphaMap){const a=await t.getTexture(e.alphaMap);n.alphaMap=a}const o=n.build();o.blending=Z[e.blendingMode]??i.NormalBlending,o.transparent=!0,o.side=i.BackSide,o.depthTest=!1,null!=o&&!0===e.bloom&&(o.userData.hasBloom=!0);o.defines.IS_PARTICLE="";const l=new i.BoxGeometry(1,1,1),c=new i.Mesh(l,o);null!=e.renderOrder&&(c.renderOrder=e.renderOrder);return c}(e.output,t,r,p,P));break;case"sprite":F=new a(await async function(e,t,a,r,s){let n=null;const o=me(e);"shaderGraph"===o&&(n=await de(e,"sprite",a,r,s));null==n&&"shader"===o&&null!=e.shader&&(n=await he(e,t,s));null==n&&(n=await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):ue,r=C(a);let s=r.sample(j.uv);e.flipbook?.enabled&&(s=N(r,w.uv,e.flipbook.columns,e.flipbook.rows,q.time,e.flipbook.fps,e.flipbook.mode));const n=new u("rotation",0),o=new h("color").rgb,l=R("opacity",1),c=Q.subtract(W).divide(Q);let p=l;switch(e.opacityChannel??"red"){case"none":break;case"red":p=p.multiply(s.r);break;case"alpha":p=p.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=b(c,0,1e3);p=p.multiply(I(0,.2*e.softness,t))}const d=re(n),m=S(o.multiply(s.rgb).multiplyScalar(e.intensity??1),p);var f=new se({color:m,emissive:m.rgb.multiplyScalar(p),transparent:!0,position:d,alphaTest:1e-4,uniforms:{color:{value:new i.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=Z[e.blendingMode]??i.NormalBlending,f}(e,t));fe(n,e);const l=new i.Mesh(new i.PlaneGeometry(1,1),n);return l.name="sprite",l}(e.output,t,r,p,P));break;case"stretchedSprite":F=new a(await async function(e,t){"shaderGraph"===me(e)&&console.warn("Shader graph materials are not supported for stretched sprite VFX outputs yet. Falling back to the default stretched sprite material.");const a=null!=e.texture?await t.getTexture(e.texture):ue,r=C(a).sample(j.uv),s=G(new l("color")),n=s.rgb.multiply(r.rgb);let o=s.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(r.r);break;case"alpha":o=o.multiply(r.a)}if("number"==typeof e.softness&&e.softness>0){const t=Q.subtract(W).divide(M(Q)),a=b(t,0,1e3);o=o.multiply(I(0,.2*e.softness,a))}const c=E(m,{position:w.position,offset:y("offset"),modelViewMatrix:B.modelViewMatrix,velocity:g("velocity"),size:y("size"),rotation:f("rotation")},"\n float lengthFactor = velocity.w;\n float avgSize = (size.x + size.y) * 0.5;\n\n vec4 mvPosition = modelViewMatrix * vec4( offset , 1.0 );\n vec3 viewVelocity = normalMatrix * velocity.xyz;\n float vlength = length(viewVelocity); \n mvPosition.xyz += position.y * normalize(cross(mvPosition.xyz, viewVelocity)) * avgSize; \n mvPosition.xyz -= (position.x + 0.5) * viewVelocity * (1.0 + lengthFactor / vlength) * avgSize;\n return projectionMatrix * mvPosition;\n ");var p=new se({color:S(n.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:c,uniforms:{color:{value:new i.Color(e.color)}}});null!=p&&!0===e.bloom&&(p.userData.hasBloom=!0);p.blending=Z[e.blendingMode]??i.NormalBlending;const u=new Y(new i.PlaneGeometry(1,1),p);return u.scaleFactor=e.scale,u}(e.output,t));break;case"shape":F=new a(await async function(e,t,a,r,s){if(null==e.shape)return console.log("Shape is null"),new n;const l=O[e.shape];if(null==l)return console.error(`No shape with type ${e.shape}`),new n;const p=z(e.params??{}),u=l.geometry(p);let h=null;const m=me(e);"shaderGraph"===m&&(h=await de(e,"surface",a,r,s));null==h&&"shader"===m&&null!=e.shader&&(h=await he(e,t,s));null==h&&(h="material"===m&&null!=e.material?ye(await t.getMaterial(e.material)):function(){const e=k(new d("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:A({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}());return fe(h,e),new i.Mesh(u,h)}(e.output,t,r,p,P));break;case"mesh":F=new a(await async function(e,t,a,r,s){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new n;const o=await t.getMesh(e.assetId),l=await t.getAsset(e.assetId),c=me(e);if("shaderGraph"===c||"shader"===c||"material"===c){let n;"shaderGraph"===c?n=await de(e,"surface",a,r,s):"shader"===c&&null!=e.shader?n=await he(e,t,s):"material"===c&&null!=e.material&&(n=ye(await t.getMaterial(e.material))),fe(n,e),o.traverse(e=>{e instanceof i.Mesh&&null!=n&&(e.material=n)})}else{const e=[];if(null!=l.materialAssignments)for(const a of l.materialAssignments)o.traverse(r=>{r instanceof i.Mesh&&r.material instanceof i.Material&&r.material.color instanceof i.Color&&(r.material.name!=a.name&&null!=a.name||"#"+r.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>r.material=e)))});await Promise.all(e)}const p=[];if(o.traverse(e=>{e instanceof i.Mesh&&p.push(e)}),1===p.length){const e=p[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return o}(e.output,t,r,p,P));break;case"trail":{const s="shaderGraph"===me(e.output)?await de(e.output,"trail",r,p,P,{trailBillboard:e.output.billboard??!1}):null;F=new a({type:"trail",taper:e.output.taper,headGeometry:null,material:s instanceof i.ShaderMaterial?s:void 0,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1});break}default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const H=new we(D);H.parent=v,H.setRate(V),H._space=e.output.space;const U=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=ee[e.type]).map(async e=>{const t=ee[e.type],a=await z(e.params??{});return le(t,e.params??{},a,T)}));U.push(F,new X),H.addInitializers(U);const J=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=$[e.type]).map(async e=>{const t=$[e.type];for(const[a,r]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&r.type!==L.Curve&&(r.type=L.Curve);const a=await z(e.params??{},r,p);return oe(t,e.params??{},a,T)}).sort((e,t)=>e instanceof ae?1:0));J.push(new ge);for(const e of J)e instanceof ae&&(e.physics=x);H.addBehaviours(J);for(const a of e.children??[]){const e=await pe(a,t,r,p,v,x,P,T,D),s=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=H.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&H.childEmitters.splice(e,1),null!=t.parentParticle&&(n.delete(t.parentParticle.id),t.parentParticle=null),s.release(t)},t}),i=H.eventDispatcher,n=new Map;H.bindEmitterEvent=!0,i.addEventListener("PARTICLE_DEAD",e=>{const t=n.get(e.id);null!=t&&(H.detachChildEmitterFromParticle(t,e),n.delete(e.id))});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}i.addEventListener(o,e=>{const t=s.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),H.childEmitters.push(t),n.set(e.id,t),t.parentParticle=e,t.system=H.system,t.emit()})}return H}const ue=(new i.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function he(e,t,a){const r=a.get(e.shader);if(null==r)return console.error("No shader exists with name "+e.shader),new i.Material;const s=new r.type,n=await V(e.shaderParams??{},r.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0,void 0,s);return Object.assign(s,n),s.build()}async function de(e,t,a,r,s,i={}){const n=e.shaderGraph;if("asset"!==n?.source||null==n.assetId)return console.warn(`Missing shader graph asset reference for ${e.type} VFX output`),null;const o=await a.getAsset(n.assetId),l=o?.shaderGraph;if(null==l)return console.warn(`Missing shader graph asset "${n.assetId}" for ${e.type} VFX output`),null;if(l.target!==t)return console.warn(`Shader graph "${o.name}" targets "${l.target}" but ${e.type} VFX output expects "${t}"`),null;try{const t=await F(e.shaderGraphParams??{},l,a,r,void 0,s.shaders),o=ce(l,{parameters:t,trailBillboard:i.trailBillboard});return o.userData.customShaderName=`shaderGraph:${n.assetId}`,fe(o,e),o}catch(e){return console.log("Shader graph VFX runtime error: "+e,e),null}}function me(e){return null!=e.materialSource?e.materialSource:"asset"===e.shaderGraph?.source?"shaderGraph":"shader"in e&&null!=e.shader?"shader":"mesh"!==e.type&&"shape"!==e.type||null==e.material?"default":"material"}function fe(e,t){null!=e&&("bloom"in t&&!0===t.bloom&&(e.userData.hasBloom=!0),"sprite"===t.type?(e.blending=Z[t.blendingMode]??i.NormalBlending,!0===t.lockY&&e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.LOCK_Y_AXIS="")):"decal"===t.type&&(e.blending=Z[t.blendingMode]??i.NormalBlending,e.transparent=!0,e.side=i.BackSide,e.depthTest=!1,e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE="")))}function ye(e){const t=k(new d("instanceColor")).rgb;let a,r=k(new o("particleData")).x;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial){let s=t.multiply(P(e.color));null!=e.map&&(s=s.multiply(C(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(r=r.multiply(C(e.alphaMap).sample(j.uv).r)),e instanceof i.MeshStandardMaterial?a=new c({color:T({color:s,emissive:P(e.emissive),emissiveIntensity:v(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshLambertMaterial?a=new c({color:A({color:s}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshBasicMaterial&&(a=new c({color:s.rgb.rgba(r),emissive:s.rgb,transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class ge extends t{initialize(e){e.body instanceof i.Object3D&&e.body.traverse(e=>{if(e instanceof i.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[H]||null!=t.uniforms[U]||t.uniforms[J])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof n&&e.target.traverse(t=>{if(t instanceof i.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[H]&&(a.uniforms[H].value=this.energy),null!=a.uniforms[U]&&(a.uniforms[U].value=e.age),null!=a.uniforms[J]&&(a.uniforms[J].value=e.velocity))}})}}class we extends r{constructor(e){super(),this.transformRoot=e,this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}clearParticlesRecursive(){let e=this.childEmitters.length;for(;e--;){const t=this.childEmitters[e];t.stopEmit(),t.clearParticlesRecursive(),t.onExpired()}this.childEmitters.length=0;let t=this.particles.length;for(;t--;){const e=this.particles[t];this.system?.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),null!=this.system?this.system.pool.expire(e.reset()):e.reset()}this.particles.length=0}detachChildEmitterFromParticle(e,t){this.copyPositionToChildSpace(e,t.position),e.parentParticle=null,e.stopEmit()}update(e){if(!this.isEmitting&&0===this.particles.length&&0===this.childEmitters.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.isEmitting&&this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||0!==this.childEmitters.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle&&this.copyPositionToChildSpace(t,t.parentParticle.position),t.update(e)}copyPositionToChildSpace(e,t){const a=this._space??"world",r=e._space??"world";a!==r&&null!=this.transformRoot?(be.copy(t),"local"===a&&"world"===r?be.applyMatrix4(this.transformRoot.matrixWorld):"world"===a&&"local"===r&&(ve.copy(this.transformRoot.matrixWorld).invert(),be.applyMatrix4(ve)),e.position.copy(be)):e.position.copy(t)}clone(){const e=new we(this.transformRoot);return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}const be=new i.Vector3,ve=new i.Matrix4;export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
1
+ import e,{Behaviour as t,Body as a,Emitter as r,Rate as s}from"@hology/nebula";import*as i from"three";import{Object3D as n}from"three";import{AttributeVec3Node as o,AttributeVec4Node as l,NodeShaderMaterial as c,RgbNode as p,UniformFloatNode as u,UniformVec3Node as h,Vec3ExpressionNode as d,Vec4Node as m,attributeFloat as f,attributeVec3 as y,attributeVec4 as g,attributes as w,clamp as b,float as v,glslFunction as E,lambertMaterial as A,log as M,pow as x,rgb as P,rgba as S,smoothstep as I,standardMaterial as T,textureSampler2d as C,uniformFloat as R,uniforms as B,varying as k,varyingAttributes as j,varyingVec3 as D,varyingVec4 as G}from"three-shader-graph";import{prepareClassParameters as V,prepareShaderGraphParameters as F,prepareShapeParameters as z}from"../../scene/materializer.js";import{SerializedParamType as L}from"../../scene/model.js";import{ShapeLibrary as O}from"../../scene/objects/shapes.js";import{fragmentLinearEyeDepth as W,linearEyeDepth as Q}from"../../shader-nodes/depth.js";import{particleEnergyUniformName as H,particleTimeUniformName as U,particleUniforms as q,particleVelcoityUniformName as J}from"../../shader-nodes/particle.js";import{sampleFlipbook as N}from"../../shader-nodes/texture-sequence.js";import{DefaultInitializer as X}from"./initializsers.js";import{DelayRate as _,OnceRate as K}from"./rates.js";import{StretchedSprite as Y}from"./stretched-sprite.js";import{ThreeBlendingMode as Z}from"./vfx-asset.js";import{VfxBehaviourLibrary as $,VfxInitializserLibrary as ee}from"./vfx-defs.js";import{MultiRenderer as te}from"./vfx-renderers.js";import{WorldCollisionBehaviour as ae}from"./vfx-collision-behaviour.js";import{getSpritePosition as re,SpriteNodeShaderMaterial as se}from"../../shader/sprite-shader.js";import{DecalUnlitShader as ie}from"../../shader/builtin/decal-unlit-shader.js";import{DecalStandardShader as ne}from"../../shader/builtin/decal-standard-shader.js";import{createBoundBehaviour as oe,createBoundInitializer as le}from"./vfx-binding-runtime.js";import{buildShaderGraphMaterial as ce}from"../../shader/graph/index.js";export async function materializeVfx(t,a,r,s,o,l,c,p,u){let h=a;for(;null!=h.parent;)h=h.parent;const d=new n;d.name="particle system local",a.add(d);const m=new n;m.name="particle system world";const f=new te(m,d,i,s),y=new e;return(await Promise.all(t.vfx.emitters.slice().sort((e,t)=>(t.output.renderOrder??0)-(e.output.renderOrder??0)).map(async e=>{const t=await pe(e,r,c,p,y,o,l,u,a);return t.setParentRecursive(y),t.emit()}))).forEach(e=>y.addEmitter(e)),y.addRenderer(f).emit({onEnd:()=>{}}),{container:m,system:y,dispose:()=>{m.removeFromParent(),d.removeFromParent(),f.dispose()}}}async function pe(e,t,r,p,v,x,P,T,D){const V=function(e){let t;switch(e.rate.type){case"continuous":t=new _(e.rate.delay??0,e.rate.count,e.rate.time,e.rate.duration);break;case"once":t=new K(e.rate.delay??0,e.rate.count);break;default:console.warn(`Failed to configure rate for emitter: ${JSON.stringify(e)}`),t=new s(0,1/0)}return t}(e);let F;switch(e.output.type){case"decal":F=new a(await async function(e,t,a,r,s){if("shaderGraph"===me(e)){const t=await de(e,"decal",a,r,s);if(null!=t){const a=new i.Mesh(new i.BoxGeometry(1,1,1),t);return null!=e.renderOrder&&(a.renderOrder=e.renderOrder),a}}const n=!1!==e.unlit?new ie:new ne;n.color=new i.Color(e.color),n instanceof ie?n.intensity=e.intensity??1:n.emissiveIntensity=e.intensity??1;if(e.colorMap){const a=await t.getTexture(e.colorMap);n.colorMap=a}if(e.alphaMap){const a=await t.getTexture(e.alphaMap);n.alphaMap=a}const o=n.build();o.blending=Z[e.blendingMode]??i.NormalBlending,o.transparent=!0,o.side=i.BackSide,o.depthTest=!1,null!=o&&!0===e.bloom&&(o.userData.hasBloom=!0);o.defines.IS_PARTICLE="";const l=new i.BoxGeometry(1,1,1),c=new i.Mesh(l,o);null!=e.renderOrder&&(c.renderOrder=e.renderOrder);return c}(e.output,t,r,p,P));break;case"sprite":F=new a(await async function(e,t,a,r,s){let n=null;const o=me(e);"shaderGraph"===o&&(n=await de(e,"sprite",a,r,s));null==n&&"shader"===o&&null!=e.shader&&(n=await he(e,t,s));null==n&&(n=await async function(e,t){const a=null!=e.texture?await t.getTexture(e.texture):ue,r=C(a);let s=r.sample(j.uv);e.flipbook?.enabled&&(s=N(r,w.uv,e.flipbook.columns,e.flipbook.rows,q.time,e.flipbook.fps,e.flipbook.mode));const n=new u("rotation",0),o=new h("color").rgb,l=R("opacity",1),c=Q.subtract(W).divide(Q);let p=l;switch(e.opacityChannel??"red"){case"none":break;case"red":p=p.multiply(s.r);break;case"alpha":p=p.multiply(s.a)}if("number"==typeof e.softness&&e.softness>0){const t=b(c,0,1e3);p=p.multiply(I(0,.2*e.softness,t))}const d=re(n),m=S(o.multiply(s.rgb).multiplyScalar(e.intensity??1),p);var f=new se({color:m,emissive:m.rgb.multiplyScalar(p),transparent:!0,position:d,alphaTest:1e-4,uniforms:{color:{value:new i.Color(e.color)}}});f.alphaHash=!0,null!=f&&!0===e.bloom&&(f.userData.hasBloom=!0);return f.blending=Z[e.blendingMode]??i.NormalBlending,f}(e,t));fe(n,e);const l=new i.Mesh(new i.PlaneGeometry(1,1),n);return l.name="sprite",l}(e.output,t,r,p,P));break;case"stretchedSprite":F=new a(await async function(e,t){"shaderGraph"===me(e)&&console.warn("Shader graph materials are not supported for stretched sprite VFX outputs yet. Falling back to the default stretched sprite material.");const a=null!=e.texture?await t.getTexture(e.texture):ue,r=C(a).sample(j.uv),s=G(new l("color")),n=s.rgb.multiply(r.rgb);let o=s.w;switch(e.opacityChannel??"red"){case"none":break;case"red":o=o.multiply(r.r);break;case"alpha":o=o.multiply(r.a)}if("number"==typeof e.softness&&e.softness>0){const t=Q.subtract(W).divide(M(Q)),a=b(t,0,1e3);o=o.multiply(I(0,.2*e.softness,a))}const c=E(m,{position:w.position,offset:y("offset"),modelViewMatrix:B.modelViewMatrix,velocity:g("velocity"),size:y("size"),rotation:f("rotation")},"\n float lengthFactor = velocity.w;\n float avgSize = (size.x + size.y) * 0.5;\n\n vec4 mvPosition = modelViewMatrix * vec4( offset , 1.0 );\n vec3 viewVelocity = normalMatrix * velocity.xyz;\n float vlength = length(viewVelocity); \n mvPosition.xyz += position.y * normalize(cross(mvPosition.xyz, viewVelocity)) * avgSize; \n mvPosition.xyz -= (position.x + 0.5) * viewVelocity * (1.0 + lengthFactor / vlength) * avgSize;\n return projectionMatrix * mvPosition;\n ");var p=new se({color:S(n.multiplyScalar(e.intensity??1),o),alphaTest:.1,transparent:!0,position:c,uniforms:{color:{value:new i.Color(e.color)}}});null!=p&&!0===e.bloom&&(p.userData.hasBloom=!0);p.blending=Z[e.blendingMode]??i.NormalBlending;const u=new Y(new i.PlaneGeometry(1,1),p);return u.scaleFactor=e.scale,u}(e.output,t));break;case"shape":F=new a(await async function(e,t,a,r,s){if(null==e.shape)return console.log("Shape is null"),new n;const l=O[e.shape];if(null==l)return console.error(`No shape with type ${e.shape}`),new n;const p=z(e.params??{}),u=l.geometry(p);let h=null;const m=me(e);"shaderGraph"===m&&(h=await de(e,"surface",a,r,s));null==h&&"shader"===m&&null!=e.shader&&(h=await he(e,t,s));null==h&&(h="material"===m&&null!=e.material?ye(await t.getMaterial(e.material)):function(){const e=k(new d("instanceColor")).rgb,t=k(new o("particleData")).x;return new c({color:A({color:e}).rgb.rgba(t),opacity:t,transparent:!0})}());return fe(h,e),new i.Mesh(u,h)}(e.output,t,r,p,P));break;case"mesh":F=new a(await async function(e,t,a,r,s){if(null==e.assetId)return console.warn("Can't use mesh as particle without asset id"),new n;const o=await t.getMesh(e.assetId),l=await t.getAsset(e.assetId),c=me(e);if("shaderGraph"===c||"shader"===c||"material"===c){let n;"shaderGraph"===c?n=await de(e,"surface",a,r,s):"shader"===c&&null!=e.shader?n=await he(e,t,s):"material"===c&&null!=e.material&&(n=ye(await t.getMaterial(e.material))),fe(n,e),o.traverse(e=>{e instanceof i.Mesh&&null!=n&&(e.material=n)})}else{const e=[];if(null!=l.materialAssignments)for(const a of l.materialAssignments)o.traverse(r=>{r instanceof i.Mesh&&r.material instanceof i.Material&&r.material.color instanceof i.Color&&(r.material.name!=a.name&&null!=a.name||"#"+r.material.color.getHexString()!==a.color||e.push(t.getMaterial(a.materialId).then(e=>r.material=e)))});await Promise.all(e)}const p=[];if(o.traverse(e=>{e instanceof i.Mesh&&p.push(e)}),1===p.length){const e=p[0];return e.updateWorldMatrix(!0,!0),e.updateMatrixWorld(),e.matrix.copy(e.matrixWorld),e.matrixWorld.decompose(e.position,e.quaternion,e.scale),e.removeFromParent(),e}return o}(e.output,t,r,p,P));break;case"trail":{const s="shaderGraph"===me(e.output)?await de(e.output,"trail",r,p,P,{trailBillboard:e.output.billboard??!1}):null;F=new a({type:"trail",taper:e.output.taper,headGeometry:null,material:s instanceof i.ShaderMaterial?s:void 0,dragTexture:!1,texture:null!=e.output.texture?await t.getTexture(e.output.texture):null,opacityChannel:e.output.opacityChannel,color:e.output.color,colorEnd:e.output.colorEnd,intensity:e.output.intensity??1,intensityEnd:e.output.intensityEnd??1,length:e.output.length,opacityStart:e.output.opacityStart,opacityEnd:e.output.opacityEnd,bloom:e.output.bloom,scrollSpeed:e.output.scrollSpeed,width:e.output.width,billboard:e.output.billboard??!1});break}default:console.error("Failed to create particly system body: "+JSON.stringify(e))}const H=new we(D);H.parent=v,H.setRate(V),H._space=e.output.space;const U=await Promise.all(e.initializers.filter(e=>!1!==e.enabled).filter(e=>null!=ee[e.type]).map(async e=>{const t=ee[e.type],a=await z(e.params??{});return le(t,e.params??{},a,T)}));U.push(F,new X),H.addInitializers(U);const J=await Promise.all(e.behaviours.filter(e=>!1!==e.enabled).filter(e=>null!=$[e.type]).map(async e=>{const t=$[e.type];for(const[a,r]of Object.entries(e.params))t.parameters&&null!=t.parameters[a]&&"curve"===t.parameters[a].type&&r.type!==L.Curve&&(r.type=L.Curve);const a=await z(e.params??{},r,p);return oe(t,e.params??{},a,T)}).sort((e,t)=>e instanceof ae?1:0));J.push(new ge);for(const e of J)e instanceof ae&&(e.physics=x);H.addBehaviours(J);for(const a of e.children??[]){const e=await pe(a,t,r,p,v,x,P,T,D),s=new EmitterPool(()=>{const t=e.clone();return t.onExpired=()=>{const e=H.childEmitters.findIndex(e=>e.id===t.id);-1!=e&&H.childEmitters.splice(e,1),null!=t.parentParticle&&(n.delete(t.parentParticle.id),t.parentParticle=null),s.release(t)},t}),i=H.eventDispatcher,n=new Map;H.bindEmitterEvent=!0,i.addEventListener("PARTICLE_DEAD",e=>{const t=n.get(e.id);null!=t&&(H.detachChildEmitterFromParticle(t,e),n.delete(e.id))});let o="PARTICLE_CREATED";if("spawnEvent"in a)switch(a.spawnEvent){case"collision":o="PARTICLE_COLLISION";break;case"start":o="PARTICLE_CREATED"}i.addEventListener(o,e=>{const t=s.get();t.age=0,t.totalEmitTimes=-1,t.particles.length=0,t.currentEmitTime=0,t.cID=0,t.eventDispatcher.removeAllEventListeners(),H.childEmitters.push(t),n.set(e.id,t),t.parentParticle=e,t.system=H.system,t.emit()})}return H}const ue=(new i.TextureLoader).load("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJkSURBVHjaxJeJbusgEEW94S1L//83X18M2MSuLd2pbqc4wZGqRLrKBsyZhQHny7Jk73xVL8xpVhWrcmiB5lX+6GJ5YgQ2owbAm8oIwH1VgKZUmGcRqKGGPgtEQQAzGR8hQ59fAmhJHSAagigJ4E7GPWRXOYC6owAd1JM6wDQPADyMWUqZRMqmAojHp1Vn6EQQEgUNMJLnUjMyJsM49wygBkAPw9dVFwXRkncCIIW3GRgoTQUZn6HxCMAFEFd8TwEQ78X4rHbILoAUmeT+RFG4UhQ6MiIAE4W/UsYFjuVjAIa2nIY4q1R0GFtQWG3E84lqw2GO2QOoCKBVu0BAPgDSU0eUDjjQenNkV/AW/pWChhpMTelo1a64AOKM30vk18GzTHXCNtI/Knz3DFBgsUqBGIjTInXRY1yA9xkVoqW5tVq3pDR9A0hfF5BSARmVnh7RMDCaIdcNgbPBkgzn1Bu+SfIEFSpSBmkxyrMicb0fAEuCZrWnN89veA/4XcakrPcjBWzkTuLjlbfTQPOlBhz+HwkqqPXmPQDdrQItxE1moGof1S74j/8txk8EHhTQrAE8qlwfqS5yukm1x/rAJ9Jiaa6nyATqD78aUVBhFo8b1V4DdTXdCW+IxA1zB4JhiOhZMEWO1HqnvdoHZ4FAMIhV9REF8FiUm0jsYPEJx/Fm/N8OhH90HI9YRHesWbXXZwAShU8qThe7H8YAuJmw5yOd989uRINKRTJAhoF8jbqrHKfeCYdIISZfSq26bk/K+yO3YvfKrVgiwQBHnwt8ynPB25+M8hceTt/ybPhnryJ78+tLgAEAuCFyiQgQB30AAAAASUVORK5CYII=");async function he(e,t,a){const r=a.get(e.shader);if(null==r)return console.error("No shader exists with name "+e.shader),new i.Material;const s=new r.type,n=await V(e.shaderParams??{},r.type,t,{getTexture:e=>t.getTexture(e.id),getMaterial:e=>t.getMaterial(e.id),getMesh:e=>t.getMesh(e.id)},void 0,void 0,void 0,void 0,void 0,s);return Object.assign(s,n),s.build()}async function de(e,t,a,r,s,i={}){const n=e.shaderGraph;if("asset"!==n?.source||null==n.assetId)return console.warn(`Missing shader graph asset reference for ${e.type} VFX output`),null;const o=await a.getAsset(n.assetId),l=o?.shaderGraph;if(null==l)return console.warn(`Missing shader graph asset "${n.assetId}" for ${e.type} VFX output`),null;if(l.target!==t)return console.warn(`Shader graph "${o.name}" targets "${l.target}" but ${e.type} VFX output expects "${t}"`),null;try{const t=await F(e.shaderGraphParams??{},l,a,r,void 0,s.shaders),o=ce(l,{parameters:t,trailBillboard:i.trailBillboard});return o.userData.customShaderName=`shaderGraph:${n.assetId}`,fe(o,e),o}catch(e){return console.log("Shader graph VFX runtime error: "+e,e),null}}function me(e){return null!=e.materialSource?e.materialSource:"asset"===e.shaderGraph?.source?"shaderGraph":"shader"in e&&null!=e.shader?"shader":"mesh"!==e.type&&"shape"!==e.type||null==e.material?"default":"material"}function fe(e,t){null!=e&&("bloom"in t&&!0===t.bloom&&(e.userData.hasBloom=!0),"sprite"===t.type?(e.blending=Z[t.blendingMode]??i.NormalBlending,!0===t.lockY&&e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.LOCK_Y_AXIS="")):"decal"===t.type?(e.blending=Z[t.blendingMode]??i.NormalBlending,e.transparent=!0,e.side=i.BackSide,e.depthTest=!1,e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE="")):"shape"!==t.type&&"mesh"!==t.type||e instanceof i.ShaderMaterial&&(e.defines??(e.defines={}),e.defines.IS_PARTICLE=""))}function ye(e){const t=k(new d("instanceColor")).rgb;let a,r=k(new o("particleData")).x;if(e instanceof i.MeshStandardMaterial||e instanceof i.MeshLambertMaterial||e instanceof i.MeshBasicMaterial){let s=t.multiply(P(e.color));null!=e.map&&(s=s.multiply(C(e.map).sample(j.uv).rgb)),null!=e.alphaMap&&(r=r.multiply(C(e.alphaMap).sample(j.uv).r)),e instanceof i.MeshStandardMaterial?a=new c({color:T({color:s,emissive:P(e.emissive),emissiveIntensity:v(e.emissiveIntensity),roughness:e.roughness,metalness:e.metalness}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshLambertMaterial?a=new c({color:A({color:s}).rgb.rgba(r),emissive:P(e.emissive).multiplyScalar(e.emissiveIntensity),transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}):e instanceof i.MeshBasicMaterial&&(a=new c({color:s.rgb.rgba(r),emissive:s.rgb,transparent:e.transparent,opacity:r,alphaTest:e.alphaTest}))}else e instanceof c&&(a=e.clone(),a.defines.IS_PARTICLE="");return null!=a&&(!0===e.userData?.hasBloom&&null!=a&&(a.userData.hasBloom=!0),a.side=e.side,a.transparent=e.transparent),a??e}class ge extends t{initialize(e){e.body instanceof i.Object3D&&e.body.traverse(e=>{if(e instanceof i.Mesh){const t=e.material;t instanceof c&&(null!=t.uniforms[H]||null!=t.uniforms[U]||t.uniforms[J])}})}mutate(e,t,a){this.energize(e,t),e.target instanceof n&&e.target.traverse(t=>{if(t instanceof i.Mesh){const a=t.material;a instanceof c&&(null!=a.uniforms[H]&&(a.uniforms[H].value=this.energy),null!=a.uniforms[U]&&(a.uniforms[U].value=e.age),null!=a.uniforms[J]&&(a.uniforms[J].value=e.velocity))}})}}class we extends r{constructor(e){super(),this.transformRoot=e,this.childEmitters=[],this.bindEmitterEvent=!1,this.onExpired=()=>{}}clearParticlesRecursive(){let e=this.childEmitters.length;for(;e--;){const t=this.childEmitters[e];t.stopEmit(),t.clearParticlesRecursive(),t.onExpired()}this.childEmitters.length=0;let t=this.particles.length;for(;t--;){const e=this.particles[t];this.system?.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),null!=this.system?this.system.pool.expire(e.reset()):e.reset()}this.particles.length=0}detachChildEmitterFromParticle(e,t){this.copyPositionToChildSpace(e,t.position),e.parentParticle=null,e.stopEmit()}update(e){if(!this.isEmitting&&0===this.particles.length&&0===this.childEmitters.length)return;this.age+=e,(this.dead||this.age>=this.life)&&this.destroy(),this.isEmitting&&this.generate(e),this.integrate(e);let t=this.particles.length;for(;t--;){const e=this.particles[t];e.dead&&(this.system&&this.system.dispatch("PARTICLE_DEAD",e),this.bindEmitterEvent&&this.dispatch("PARTICLE_DEAD",e),this.system.pool.expire(e.reset()),this.particles.splice(t,1))}this.updateEmitterBehaviours(e),this.updateChildren(e),this.isEmitting||0!==this.particles.length||0!==this.childEmitters.length||this.onExpired()}updateChildren(e){for(const t of this.childEmitters)null!=t.parentParticle&&this.copyPositionToChildSpace(t,t.parentParticle.position),t.update(e)}copyPositionToChildSpace(e,t){const a=this._space??"world",r=e._space??"world";a!==r&&null!=this.transformRoot?(be.copy(t),"local"===a&&"world"===r?be.applyMatrix4(this.transformRoot.matrixWorld):"world"===a&&"local"===r&&(ve.copy(this.transformRoot.matrixWorld).invert(),be.applyMatrix4(ve)),e.position.copy(be)):e.position.copy(t)}clone(){const e=new we(this.transformRoot);return e.setRate(this.rate.clone()),e.behaviours=this.behaviours,e.initializers=this.initializers,e._space=this._space,e.body=this.body,e.parent=this.parent,e.system=this.system,e}setParentRecursive(e){this.system=e,this.childEmitters.forEach(t=>t.setParentRecursive(e))}}const be=new i.Vector3,ve=new i.Matrix4;export class EmitterPool{constructor(e){this.creator=e,this.instances=[]}get(){0==this.instances.length&&this.instances.push(this.creator());return this.instances.pop()}release(e){this.instances.push(e)}dispose(){this.instances.length=0}}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -56,6 +56,7 @@ export declare class CombinedRenderer extends MeshRenderer {
56
56
  target: THREE.Mesh | Object3D;
57
57
  }): void;
58
58
  onParticleUpdate(particle: any): void;
59
+ private applyUniforms;
59
60
  onParticleDead(particle: any): void;
60
61
  }
61
62
  export declare class StretchedSpriteInstancedRenderer extends MeshRenderer {