@hology/core 0.0.201 → 0.0.202

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 (37) hide show
  1. package/dist/effects/sequence/sequence-actor.d.ts +1 -1
  2. package/dist/effects/sequence/sequence-actor.js +1 -1
  3. package/dist/effects/sequence/sequence-data.d.ts +81 -8
  4. package/dist/effects/sequence/sequence-data.js +1 -1
  5. package/dist/effects/sequence/sequence-definitions.d.ts +3 -2
  6. package/dist/effects/sequence/sequence-definitions.js +1 -1
  7. package/dist/effects/sequence/sequence-ops.js +1 -1
  8. package/dist/effects/sequence/sequence-player.d.ts +39 -2
  9. package/dist/effects/sequence/sequence-player.js +1 -1
  10. package/dist/effects/vfx/initializsers.d.ts +14 -0
  11. package/dist/effects/vfx/initializsers.js +1 -1
  12. package/dist/effects/vfx/vfx-defs.d.ts +12 -1
  13. package/dist/effects/vfx/vfx-defs.js +1 -1
  14. package/dist/effects/vfx/zones.d.ts +3 -1
  15. package/dist/effects/vfx/zones.js +1 -1
  16. package/dist/gameplay/services/asset-loader.d.ts +3 -0
  17. package/dist/gameplay/services/asset-loader.js +1 -1
  18. package/dist/rendering/post-process-effect.d.ts +2 -1
  19. package/dist/rendering/post-process-effect.js +1 -1
  20. package/dist/scene/materializer.js +1 -1
  21. package/dist/shader/graph/compiler.d.ts +6 -1
  22. package/dist/shader/graph/compiler.js +1 -1
  23. package/dist/shader/graph/model.d.ts +3 -2
  24. package/dist/shader/graph/model.js +1 -1
  25. package/dist/shader/graph/registry.js +1 -1
  26. package/dist/shader/parameter.d.ts +1 -0
  27. package/dist/shader/parameter.js +1 -1
  28. package/dist/shader-nodes/curve-sample.d.ts +1 -0
  29. package/dist/shader-nodes/curve-sample.js +1 -1
  30. package/dist/test/sequence-asset-refresh.test.d.ts +2 -0
  31. package/dist/test/sequence-asset-refresh.test.js +4 -0
  32. package/dist/test/sequence-post-process.test.d.ts +2 -0
  33. package/dist/test/sequence-post-process.test.js +4 -0
  34. package/dist/test/sequence-property-parameters.test.js +1 -1
  35. package/dist/test/shader-graph.test.js +1 -1
  36. package/package.json +1 -1
  37. package/tsconfig.tsbuildinfo +1 -1
@@ -154,7 +154,7 @@ export declare class SequenceActor extends BaseActor implements SequenceAction {
154
154
  /**
155
155
  * Refresh a specific asset used in the sequence
156
156
  */
157
- refreshAsset(assetId: string): void;
157
+ refreshAsset(assetId: string): Promise<boolean>;
158
158
  /**
159
159
  * Update the sequence (called automatically from render loop)
160
160
  */
@@ -1,4 +1,4 @@
1
- import{__decorate as e,__metadata as t}from"tslib";import{Actor as s,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as a}from"../../gameplay/inject.js";import{ViewController as o}from"../../gameplay/services/render.js";import{AssetLoader as i}from"../../gameplay/services/asset-loader.js";import{World as l}from"../../gameplay/services/world.js";import{ActorFactory as n}from"../../gameplay/actors/factory.js";import{VfxService as p}from"../../effects/vfx/vfx-service.js";import{Parameter as c}from"../../shader/parameter.js";import{createSequenceData as h}from"./sequence-data.js";import{SequencePlayer as d,SequencePlaybackState as m}from"./sequence-player.js";import{Subject as y,takeUntil as u}from"rxjs";let b=class extends r{constructor(){super(...arguments),this.sequenceData=h(),this.sequenceAssetId=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.onComplete=new y,this.onLoop=new y,this.player=new d,this.viewController=a(o),this.assetLoader=a(i),this.world=a(l),this.actorFactory=a(n),this.vfxService=a(p),this.sourceAsset=null}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,this.player.cameraControlEnabled=e}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId=e,this.player.cameraControlTrackId=e}get timescale(){return this.player.timescale}set timescale(e){this.player.timescale=e}get loop(){return this.player.loop}set loop(e){this.player.loop=e}get state(){return this.player.state}get time(){return this.player.time}get duration(){return this.player.duration}get paused(){return this.player.state===m.Paused}get externalTimeControl(){return this.player.externalTimeControl}set externalTimeControl(e){this.player.externalTimeControl=e}get inEditor(){return this.player.inEditor}set inEditor(e){this.player.inEditor=e}async onInit(){this.player.setWorld(this.world),this.player.setViewController(this.viewController),this.player.setAudioListener(this.viewController.audioListener),this.player.setAssetLoader(this.assetLoader),this.player.setActorFactory(this.actorFactory),this.player.setVfxService(this.vfxService),this.viewController.onUpdate(this).pipe(u(this.disposed)).subscribe(e=>this.player.update(e)),this.player.onComplete.pipe(u(this.disposed)).subscribe(()=>this.onComplete.next()),this.player.onLoop.pipe(u(this.disposed)).subscribe(e=>this.onLoop.next(e)),this.sequenceAssetId?await this.loadFromAssetId(this.sequenceAssetId):this.sequenceData&&this.player.load(this.sequenceData)}async loadFromAsset(e){if("sequence"!==e.type)throw new Error(`Asset must be a sequence asset but is ${e.type}`);this.sourceAsset=e,this.sourceAsset.sequence&&(this.sequenceData=this.sourceAsset.sequence,this.player.load(this.sequenceData))}async loadFromAssetId(e){const t=await this.assetLoader.getAsset(e);t&&await this.loadFromAsset(t)}setSequenceData(e){this.sequenceData=e,this.player.load(e)}bindRole(e,t){this.player.bindRole(e,t)}bindObject(e,t){this.player.bindObject(e,t)}getLocator(e){return this.player.getLocator(e)}getLocators(e){return this.player.getLocators(e)}getActiveTrackObjects(e){return this.player.getActiveTrackObjects(e)}play(e){this.player.cameraControlEnabled=e?.cameraControlEnabled??this.cameraControlEnabled,this.player.play()}pause(){this.player.pause()}cancel(){this.player.cancel()}stop(){this.player.stop()}restart(){this.player.restart()}seek(e){this.player.seek(e)}refreshAsset(e){this.player.refreshAsset(e)}onUpdate(e){}onEndPlay(){this.player.dispose()}dispose(){this.world.removeActor(this)}};e([c({label:"Sequence Data"}),t("design:type",Object)],b.prototype,"sequenceData",void 0),e([c({label:"Camera Control Enabled"}),t("design:type",Boolean),t("design:paramtypes",[Boolean])],b.prototype,"cameraControlEnabled",null),b=e([s()],b);export{b as SequenceActor};/*
1
+ import{__decorate as e,__metadata as t}from"tslib";import{Actor as s,BaseActor as r}from"../../gameplay/actors/actor.js";import{inject as a}from"../../gameplay/inject.js";import{ViewController as o}from"../../gameplay/services/render.js";import{AssetLoader as i}from"../../gameplay/services/asset-loader.js";import{World as l}from"../../gameplay/services/world.js";import{ActorFactory as n}from"../../gameplay/actors/factory.js";import{VfxService as p}from"../../effects/vfx/vfx-service.js";import{Parameter as c}from"../../shader/parameter.js";import{createSequenceData as h}from"./sequence-data.js";import{SequencePlayer as d,SequencePlaybackState as m}from"./sequence-player.js";import{Subject as y,takeUntil as u}from"rxjs";let b=class extends r{constructor(){super(...arguments),this.sequenceData=h(),this.sequenceAssetId=null,this._cameraControlEnabled=!1,this._cameraControlTrackId=null,this.onComplete=new y,this.onLoop=new y,this.player=new d,this.viewController=a(o),this.assetLoader=a(i),this.world=a(l),this.actorFactory=a(n),this.vfxService=a(p),this.sourceAsset=null}get cameraControlEnabled(){return this._cameraControlEnabled}set cameraControlEnabled(e){this._cameraControlEnabled=e,this.player.cameraControlEnabled=e}get cameraControlTrackId(){return this._cameraControlTrackId}set cameraControlTrackId(e){this._cameraControlTrackId=e,this.player.cameraControlTrackId=e}get timescale(){return this.player.timescale}set timescale(e){this.player.timescale=e}get loop(){return this.player.loop}set loop(e){this.player.loop=e}get state(){return this.player.state}get time(){return this.player.time}get duration(){return this.player.duration}get paused(){return this.player.state===m.Paused}get externalTimeControl(){return this.player.externalTimeControl}set externalTimeControl(e){this.player.externalTimeControl=e}get inEditor(){return this.player.inEditor}set inEditor(e){this.player.inEditor=e}async onInit(){this.player.setWorld(this.world),this.player.setViewController(this.viewController),this.player.setAudioListener(this.viewController.audioListener),this.player.setAssetLoader(this.assetLoader),this.player.setActorFactory(this.actorFactory),this.player.setVfxService(this.vfxService),this.viewController.onUpdate(this).pipe(u(this.disposed)).subscribe(e=>this.player.update(e)),this.player.onComplete.pipe(u(this.disposed)).subscribe(()=>this.onComplete.next()),this.player.onLoop.pipe(u(this.disposed)).subscribe(e=>this.onLoop.next(e)),this.sequenceAssetId?await this.loadFromAssetId(this.sequenceAssetId):this.sequenceData&&this.player.load(this.sequenceData)}async loadFromAsset(e){if("sequence"!==e.type)throw new Error(`Asset must be a sequence asset but is ${e.type}`);this.sourceAsset=e,this.sourceAsset.sequence&&(this.sequenceData=this.sourceAsset.sequence,this.player.load(this.sequenceData))}async loadFromAssetId(e){const t=await this.assetLoader.getAsset(e);t&&await this.loadFromAsset(t)}setSequenceData(e){this.sequenceData=e,this.player.load(e)}bindRole(e,t){this.player.bindRole(e,t)}bindObject(e,t){this.player.bindObject(e,t)}getLocator(e){return this.player.getLocator(e)}getLocators(e){return this.player.getLocators(e)}getActiveTrackObjects(e){return this.player.getActiveTrackObjects(e)}play(e){this.player.cameraControlEnabled=e?.cameraControlEnabled??this.cameraControlEnabled,this.player.play()}pause(){this.player.pause()}cancel(){this.player.cancel()}stop(){this.player.stop()}restart(){this.player.restart()}seek(e){this.player.seek(e)}refreshAsset(e){return this.player.refreshAsset(e)}onUpdate(e){}onEndPlay(){this.player.dispose()}dispose(){this.world.removeActor(this)}};e([c({label:"Sequence Data"}),t("design:type",Object)],b.prototype,"sequenceData",void 0),e([c({label:"Camera Control Enabled"}),t("design:type",Boolean),t("design:paramtypes",[Boolean])],b.prototype,"cameraControlEnabled",null),b=e([s()],b);export{b as SequenceActor};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,6 +1,7 @@
1
1
  import { AssetId, CustomParamValue, SerializedParamType } from '../../scene/model.js';
2
2
  import { AudioParameterId } from './audio-parameters.js';
3
3
  import type { CameraShakeSettings } from '../../gameplay/services/camera-shake.js';
4
+ import type { PostProcessEffectStage } from '../../rendering/post-process-effect.js';
4
5
  export interface SequencePropertyOption {
5
6
  name: string;
6
7
  value: unknown;
@@ -19,6 +20,21 @@ export interface PropertySubTrackOptions {
19
20
  editorInput?: 'colorGrade';
20
21
  defaultValue?: CustomParamValue;
21
22
  }
23
+ export interface MaterialSubTrackOptions {
24
+ materialAssetId: AssetId;
25
+ parameterName: string;
26
+ uniformName: string;
27
+ uniformType: SerializedParamType;
28
+ valueType: SerializedParamType;
29
+ name?: string;
30
+ label?: string;
31
+ group?: string;
32
+ help?: string;
33
+ range?: [number, number];
34
+ precision?: number;
35
+ stepSize?: number;
36
+ defaultValue?: CustomParamValue;
37
+ }
22
38
  /**
23
39
  * The main sequence data structure containing all tracks and playback settings.
24
40
  * This is stored as a parameter on SequenceActor or as part of a SequenceAsset.
@@ -54,7 +70,7 @@ export declare enum SequenceRole {
54
70
  /** Secondary actor (e.g., companion, summoned entity) */
55
71
  Secondary = "secondary"
56
72
  }
57
- export type SequenceTrackType = 'object' | 'locator' | 'camera' | 'cameraShake' | 'audio' | 'vfx' | 'spawn' | 'group';
73
+ export type SequenceTrackType = 'object' | 'locator' | 'camera' | 'cameraShake' | 'postProcess' | 'audio' | 'vfx' | 'spawn' | 'group';
58
74
  /**
59
75
  * Base interface for all track types
60
76
  */
@@ -129,6 +145,18 @@ export interface CameraShakeTrack extends BaseTrack {
129
145
  /** Camera shake clips placed on the timeline */
130
146
  clips: CameraShakeClipInstance[];
131
147
  }
148
+ /**
149
+ * Post-process track - layers fullscreen shader graph effects onto the active local view.
150
+ */
151
+ export interface PostProcessTrack extends BaseTrack {
152
+ type: 'postProcess';
153
+ /** Post-process clips placed on the timeline */
154
+ clips: PostProcessClipInstance[];
155
+ /** Where the effects are inserted in the built-in post stack */
156
+ stage: PostProcessEffectStage;
157
+ /** Ordering relative to other post-process effects in the same stage */
158
+ priority: number;
159
+ }
132
160
  /**
133
161
  * Audio track - plays audio assets
134
162
  */
@@ -189,7 +217,7 @@ export interface GroupTrack extends BaseTrack {
189
217
  /** Child tracks within this group */
190
218
  childTracks: SequenceTrack[];
191
219
  }
192
- export type SequenceTrack = ObjectTrack | LocatorTrack | CameraTrack | CameraShakeTrack | AudioTrack | VfxTrack | SpawnTrack | GroupTrack;
220
+ export type SequenceTrack = ObjectTrack | LocatorTrack | CameraTrack | CameraShakeTrack | PostProcessTrack | AudioTrack | VfxTrack | SpawnTrack | GroupTrack;
193
221
  export type SubTrackType = 'transform' | 'animation' | 'property' | 'material' | 'visibility' | 'event' | 'audioParameter';
194
222
  /**
195
223
  * Base interface for sub-tracks
@@ -261,12 +289,30 @@ export interface PropertySubTrack extends BaseSubTrack {
261
289
  */
262
290
  export interface MaterialSubTrack extends BaseSubTrack {
263
291
  type: 'material';
264
- /** Material slot index or name */
265
- materialSlot: string | number;
266
- /** Uniform name to animate */
292
+ /** Material asset whose runtime material slots should be controlled */
293
+ materialAssetId: AssetId;
294
+ /** Source shader/shader graph parameter name */
295
+ parameterName: string;
296
+ /** Runtime uniform name to animate */
267
297
  uniformName: string;
268
- /** The type of uniform being animated */
298
+ /** The shader-authored parameter type, usually a Node type */
269
299
  uniformType: SerializedParamType;
300
+ /** The editable keyframe value type */
301
+ valueType: SerializedParamType;
302
+ /** Artist-facing parameter label */
303
+ label?: string;
304
+ /** Optional editor group for the parameter */
305
+ group?: string;
306
+ /** Help text shown in the editor */
307
+ help?: string;
308
+ /** Numeric range for scalar/vector editing */
309
+ range?: [number, number];
310
+ /** Numeric display precision */
311
+ precision?: number;
312
+ /** Drag/edit step size */
313
+ stepSize?: number;
314
+ /** Default keyframe value when adding new keys */
315
+ defaultValue?: CustomParamValue;
270
316
  /** Keyframes for uniform animation */
271
317
  keyframes: PropertyKeyframe[];
272
318
  }
@@ -299,7 +345,7 @@ export interface AudioParameterSubTrack extends BaseSubTrack {
299
345
  export type SubTrack = TransformSubTrack | AnimationSubTrack | PropertySubTrack | MaterialSubTrack | VisibilitySubTrack | EventSubTrack | AudioParameterSubTrack;
300
346
  export type SequenceValueSubTrack = PropertySubTrack | MaterialSubTrack | AudioParameterSubTrack;
301
347
  export type SequenceKeyframeSubTrack = TransformSubTrack | PropertySubTrack | MaterialSubTrack | VisibilitySubTrack | AudioParameterSubTrack;
302
- export type SequenceDirectClipTrack = CameraTrack | CameraShakeTrack | AudioTrack | VfxTrack | SpawnTrack;
348
+ export type SequenceDirectClipTrack = CameraTrack | CameraShakeTrack | PostProcessTrack | AudioTrack | VfxTrack | SpawnTrack;
303
349
  export type SequenceAnimationHostTrack = ObjectTrack | CameraTrack | SpawnTrack;
304
350
  export type AnimationClipRetimingMode = 'uniform' | 'impact' | 'advanced';
305
351
  export interface AnimationClipRetimingPoint {
@@ -392,6 +438,25 @@ export interface CameraShakeClipInstance extends CameraShakeSettings {
392
438
  /** Duration of this clip instance */
393
439
  duration: number;
394
440
  }
441
+ /**
442
+ * A post-process effect clip placed on the timeline.
443
+ */
444
+ export interface PostProcessClipInstance {
445
+ /** Unique identifier */
446
+ id: string;
447
+ /** Shader graph asset ID. The graph target must be postProcess. */
448
+ shaderGraphAssetId: AssetId | null;
449
+ /** Per-clip shader graph parameter overrides */
450
+ shaderGraphParams: Record<string, CustomParamValue>;
451
+ /** Start time of this clip on the timeline */
452
+ startTime: number;
453
+ /** Duration of this clip instance */
454
+ duration: number;
455
+ /** Fade in duration in seconds */
456
+ fadeInDuration: number;
457
+ /** Fade out duration in seconds */
458
+ fadeOutDuration: number;
459
+ }
395
460
  /**
396
461
  * An instance of an animation clip placed on the timeline
397
462
  */
@@ -514,6 +579,10 @@ export declare function createCameraTrack(name?: string): CameraTrack;
514
579
  * Creates a new camera shake track
515
580
  */
516
581
  export declare function createCameraShakeTrack(name?: string): CameraShakeTrack;
582
+ /**
583
+ * Creates a new post-process track
584
+ */
585
+ export declare function createPostProcessTrack(name?: string): PostProcessTrack;
517
586
  /**
518
587
  * Creates a new camera shot clip instance
519
588
  */
@@ -522,6 +591,10 @@ export declare function createCameraClipInstance(startTime: number, duration: nu
522
591
  * Creates a new camera shake clip instance
523
592
  */
524
593
  export declare function createCameraShakeClipInstance(startTime: number, duration: number): CameraShakeClipInstance;
594
+ /**
595
+ * Creates a new post-process clip instance
596
+ */
597
+ export declare function createPostProcessClipInstance(startTime: number, duration: number): PostProcessClipInstance;
525
598
  /**
526
599
  * Creates a new audio track
527
600
  */
@@ -561,7 +634,7 @@ export declare function createPropertySubTrack(options?: PropertySubTrackOptions
561
634
  /**
562
635
  * Creates a new material sub-track
563
636
  */
564
- export declare function createMaterialSubTrack(uniformName?: string, uniformType?: SerializedParamType, materialSlot?: string | number): MaterialSubTrack;
637
+ export declare function createMaterialSubTrack(options: MaterialSubTrackOptions): MaterialSubTrack;
565
638
  /**
566
639
  * Creates a new visibility sub-track
567
640
  */
@@ -1,4 +1,4 @@
1
- import{SerializedParamType as e}from"../../scene/model.js";import{randomString as t}from"../../utils/math.js";import{getAudioParameterDefinition as r}from"./audio-parameters.js";export class Sequence{constructor(e){this.data=e}}export var SequenceRole;!function(e){e.Self="self",e.Target="target",e.Target2="target2",e.Target3="target3",e.Secondary="secondary"}(SequenceRole||(SequenceRole={}));export function createSequenceData(){return{duration:5,loop:!1,playbackRate:1,tracks:[]}}export function createObjectTrack(e="Object Track"){return{id:t(),name:e,type:"object",muted:!1,locked:!1,targetId:null,role:null,subTracks:[]}}export function createCameraTrack(e="Camera Track"){return{id:t(),name:e,type:"camera",muted:!1,locked:!1,parentRole:null,clips:[],cameraSettings:{fov:60,near:.1,far:1e3},subTracks:[]}}export function createCameraShakeTrack(e="Camera Shake"){return{id:t(),name:e,type:"cameraShake",muted:!1,locked:!1,clips:[],subTracks:[]}}export function createCameraClipInstance(e,r){return{id:t(),startTime:e,duration:r,blendInDuration:.2,blendOutDuration:.2,blendInterpolation:"cubic"}}export function createCameraShakeClipInstance(e,r){return{id:t(),startTime:e,duration:r,attack:0,decay:Math.min(Math.max(.35*r,.05),Math.max(r,.05)),frequency:24,positionAmplitude:[0,0,.12],rotationAmplitude:[.015,.02,.01]}}export function createAudioTrack(e="Audio Track"){return{id:t(),name:e,type:"audio",muted:!1,locked:!1,clips:[],subTracks:[],volume:1,spatial:!1}}export function createVfxTrack(e="VFX Track"){return{id:t(),name:e,type:"vfx",muted:!1,locked:!1,clips:[],position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],subTracks:[]}}export function createSpawnTrack(e="Spawn Track"){return{id:t(),name:e,type:"spawn",muted:!1,locked:!1,spawnType:"mesh",role:null,clips:[],subTracks:[]}}export function createSpawnClipInstance(e,r){return{id:t(),startTime:e,duration:r}}export function createGroupTrack(e="Group"){return{id:t(),name:e,type:"group",muted:!1,locked:!1,collapsed:!1,childTracks:[],subTracks:[]}}export function createTransformSubTrack(){return{id:t(),name:"Transform",type:"transform",muted:!1,components:{position:!0,rotation:!0,scale:!0},keyframes:[]}}export function createAnimationSubTrack(e="Animation"){return{id:t(),name:e,type:"animation",muted:!1,clips:[]}}export function createAudioParameterSubTrack(e="volume"){const a=r(e);return{id:t(),name:a.displayName,type:"audioParameter",muted:!1,parameter:e,keyframes:[]}}export function createPropertySubTrack(r="",a=e.Number){const n="string"==typeof r?{propertyPath:r,propertyType:a}:r;return{id:t(),name:n.name??n.label??n.propertyPath??"Property",type:"property",muted:!1,propertyPath:n.propertyPath,propertyType:n.propertyType,label:n.label,group:n.group,help:n.help,range:n.range,precision:n.precision,stepSize:n.stepSize,options:n.options,editorInput:n.editorInput,defaultValue:n.defaultValue,keyframes:[]}}export function createMaterialSubTrack(r="",a=e.Number,n=0){return{id:t(),name:r||"Material",type:"material",muted:!1,materialSlot:n,uniformName:r,uniformType:a,keyframes:[]}}export function createVisibilitySubTrack(e="Visibility"){return{id:t(),name:e,type:"visibility",muted:!1,keyframes:[]}}export function createTransformKeyframe(e){return{id:t(),time:e,position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],interpolation:"cubic"}}export function createPropertyKeyframe(r,a={type:e.Number,value:0}){return{id:t(),time:r,value:a,interpolation:"linear"}}export function createAnimationClipInstance(e,r,a){return{id:t(),animationClipAssetId:e,startTime:r,duration:a,clipStartOffset:0,clipEndOffset:0,playbackRate:1,fadeInDuration:.2,retiming:void 0,rootMotion:!1}}export function createAnimationClipRetimingPoint(e=.35,r=.55){return{id:t(),clipProgress:e,sourceProgress:r}}export function createAnimationClipRetiming(e="impact",t=("uniform"===e?[]:[createAnimationClipRetimingPoint()])){return{mode:e,points:t}}export function createAudioClipInstance(e,r,a){return{id:t(),audioAssetId:e,startTime:r,duration:a,clipStartOffset:0,playbackRate:1,volume:1,fadeInDuration:0,fadeOutDuration:0,volumeRandomization:0,pitchRandomization:0}}export function createVfxClipInstance(e,r,a){return{id:t(),vfxAssetId:e,startTime:r,duration:a,endBehavior:"finish",expireWithinSeconds:.25}}export function createEventSubTrack(e="Events"){return{id:t(),name:e,type:"event",muted:!1,events:[]}}export function createSequenceEventData(e,r=""){return{id:t(),time:e,editorOnly:!1,functionName:r,arguments:[]}}export function createLocatorTrack(e="Locator"){return{id:t(),name:e,type:"locator",muted:!1,locked:!1,subTracks:[]}}/*
1
+ import{SerializedParamType as e}from"../../scene/model.js";import{randomString as t}from"../../utils/math.js";import{getAudioParameterDefinition as r}from"./audio-parameters.js";export class Sequence{constructor(e){this.data=e}}export var SequenceRole;!function(e){e.Self="self",e.Target="target",e.Target2="target2",e.Target3="target3",e.Secondary="secondary"}(SequenceRole||(SequenceRole={}));export function createSequenceData(){return{duration:5,loop:!1,playbackRate:1,tracks:[]}}export function createObjectTrack(e="Object Track"){return{id:t(),name:e,type:"object",muted:!1,locked:!1,targetId:null,role:null,subTracks:[]}}export function createCameraTrack(e="Camera Track"){return{id:t(),name:e,type:"camera",muted:!1,locked:!1,parentRole:null,clips:[],cameraSettings:{fov:60,near:.1,far:1e3},subTracks:[]}}export function createCameraShakeTrack(e="Camera Shake"){return{id:t(),name:e,type:"cameraShake",muted:!1,locked:!1,clips:[],subTracks:[]}}export function createPostProcessTrack(e="Post Process"){return{id:t(),name:e,type:"postProcess",muted:!1,locked:!1,clips:[],stage:"beforeOutput",priority:0,subTracks:[]}}export function createCameraClipInstance(e,r){return{id:t(),startTime:e,duration:r,blendInDuration:.2,blendOutDuration:.2,blendInterpolation:"cubic"}}export function createCameraShakeClipInstance(e,r){return{id:t(),startTime:e,duration:r,attack:0,decay:Math.min(Math.max(.35*r,.05),Math.max(r,.05)),frequency:24,positionAmplitude:[0,0,.12],rotationAmplitude:[.015,.02,.01]}}export function createPostProcessClipInstance(e,r){return{id:t(),shaderGraphAssetId:null,shaderGraphParams:{},startTime:e,duration:r,fadeInDuration:Math.min(.15,Math.max(.25*r,0)),fadeOutDuration:Math.min(.15,Math.max(.25*r,0))}}export function createAudioTrack(e="Audio Track"){return{id:t(),name:e,type:"audio",muted:!1,locked:!1,clips:[],subTracks:[],volume:1,spatial:!1}}export function createVfxTrack(e="VFX Track"){return{id:t(),name:e,type:"vfx",muted:!1,locked:!1,clips:[],position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],subTracks:[]}}export function createSpawnTrack(e="Spawn Track"){return{id:t(),name:e,type:"spawn",muted:!1,locked:!1,spawnType:"mesh",role:null,clips:[],subTracks:[]}}export function createSpawnClipInstance(e,r){return{id:t(),startTime:e,duration:r}}export function createGroupTrack(e="Group"){return{id:t(),name:e,type:"group",muted:!1,locked:!1,collapsed:!1,childTracks:[],subTracks:[]}}export function createTransformSubTrack(){return{id:t(),name:"Transform",type:"transform",muted:!1,components:{position:!0,rotation:!0,scale:!0},keyframes:[]}}export function createAnimationSubTrack(e="Animation"){return{id:t(),name:e,type:"animation",muted:!1,clips:[]}}export function createAudioParameterSubTrack(e="volume"){const a=r(e);return{id:t(),name:a.displayName,type:"audioParameter",muted:!1,parameter:e,keyframes:[]}}export function createPropertySubTrack(r="",a=e.Number){const n="string"==typeof r?{propertyPath:r,propertyType:a}:r;return{id:t(),name:n.name??n.label??n.propertyPath??"Property",type:"property",muted:!1,propertyPath:n.propertyPath,propertyType:n.propertyType,label:n.label,group:n.group,help:n.help,range:n.range,precision:n.precision,stepSize:n.stepSize,options:n.options,editorInput:n.editorInput,defaultValue:n.defaultValue,keyframes:[]}}export function createMaterialSubTrack(e){return{id:t(),name:e.name??e.label??e.parameterName??"Material",type:"material",muted:!1,materialAssetId:e.materialAssetId,parameterName:e.parameterName,uniformName:e.uniformName,uniformType:e.uniformType,valueType:e.valueType,label:e.label,group:e.group,help:e.help,range:e.range,precision:e.precision,stepSize:e.stepSize,defaultValue:e.defaultValue,keyframes:[]}}export function createVisibilitySubTrack(e="Visibility"){return{id:t(),name:e,type:"visibility",muted:!1,keyframes:[]}}export function createTransformKeyframe(e){return{id:t(),time:e,position:[0,0,0],rotation:[0,0,0],scale:[1,1,1],interpolation:"cubic"}}export function createPropertyKeyframe(r,a={type:e.Number,value:0}){return{id:t(),time:r,value:a,interpolation:"linear"}}export function createAnimationClipInstance(e,r,a){return{id:t(),animationClipAssetId:e,startTime:r,duration:a,clipStartOffset:0,clipEndOffset:0,playbackRate:1,fadeInDuration:.2,retiming:void 0,rootMotion:!1}}export function createAnimationClipRetimingPoint(e=.35,r=.55){return{id:t(),clipProgress:e,sourceProgress:r}}export function createAnimationClipRetiming(e="impact",t=("uniform"===e?[]:[createAnimationClipRetimingPoint()])){return{mode:e,points:t}}export function createAudioClipInstance(e,r,a){return{id:t(),audioAssetId:e,startTime:r,duration:a,clipStartOffset:0,playbackRate:1,volume:1,fadeInDuration:0,fadeOutDuration:0,volumeRandomization:0,pitchRandomization:0}}export function createVfxClipInstance(e,r,a){return{id:t(),vfxAssetId:e,startTime:r,duration:a,endBehavior:"finish",expireWithinSeconds:.25}}export function createEventSubTrack(e="Events"){return{id:t(),name:e,type:"event",muted:!1,events:[]}}export function createSequenceEventData(e,r=""){return{id:t(),time:e,editorOnly:!1,functionName:r,arguments:[]}}export function createLocatorTrack(e="Locator"){return{id:t(),name:e,type:"locator",muted:!1,locked:!1,subTracks:[]}}/*
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
- import { AnimationClipInstance, PropertySubTrackOptions, SequenceTrack, SequenceTrackType, SubTrack, SubTrackType } from './sequence-data.js';
1
+ import { AnimationClipInstance, PropertySubTrackOptions, MaterialSubTrackOptions, SequenceTrack, SequenceTrackType, SubTrack, SubTrackType } from './sequence-data.js';
2
2
  import { AudioParameterId } from './audio-parameters.js';
3
3
  import { SerializedParamType } from '../../scene/model.js';
4
- export type SequenceTrackRuntimeEvaluator = 'object' | 'locator' | 'camera' | 'cameraShake' | 'audio' | 'vfx' | 'spawn' | 'group';
4
+ export type SequenceTrackRuntimeEvaluator = 'object' | 'locator' | 'camera' | 'cameraShake' | 'postProcess' | 'audio' | 'vfx' | 'spawn' | 'group';
5
5
  export type SequenceSubTrackRuntimeEvaluator = 'transform' | 'animation' | 'visibility' | 'parameter' | 'event';
6
6
  export type SequenceSubTrackLaneKind = 'keyframes' | 'clips' | 'events';
7
7
  type DirectTrackClip = SequenceTrack extends infer TTrack ? TTrack extends {
@@ -38,6 +38,7 @@ export interface SequenceSubTrackCreateOptions {
38
38
  propertyPath?: string;
39
39
  propertyType?: SerializedParamType;
40
40
  property?: PropertySubTrackOptions;
41
+ material?: MaterialSubTrackOptions;
41
42
  }
42
43
  export interface AudioParameterSubTrackOption {
43
44
  parameter: AudioParameterId;
@@ -1,4 +1,4 @@
1
- import{createAnimationClipInstance as e,createAnimationSubTrack as r,createAudioClipInstance as a,createAudioParameterSubTrack as t,createAudioTrack as o,createCameraClipInstance as n,createCameraShakeClipInstance as i,createCameraShakeTrack as p,createCameraTrack as l,createEventSubTrack as c,createGroupTrack as u,createLocatorTrack as s,createMaterialSubTrack as m,createObjectTrack as d,createPropertySubTrack as T,createSpawnClipInstance as y,createSpawnTrack as b,createTransformSubTrack as k,createVfxClipInstance as f,createVfxTrack as v,createVisibilitySubTrack as E}from"./sequence-data.js";import{SerializedParamType as S}from"../../scene/model.js";const x=[{type:"object",label:"Object Track",icon:"mdil-hexagon",runtimeEvaluator:"object",createTrack:()=>d(),allowedSubTrackTypes:["transform","animation","property","material","visibility","event"],supportsParenting:!0,exposedInEditor:!1},{type:"locator",label:"Locator",icon:"mdil-map-marker-radius",runtimeEvaluator:"locator",createTrack:()=>s(),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"camera",label:"Camera Track",icon:"mdil-camcorder",runtimeEvaluator:"camera",createTrack:(e=0,r=2)=>{const a=l();return a.clips.push(n(e,r)),a.subTracks.push(k()),a},createDirectClip:(e=0,r=2)=>n(e,r),allowedSubTrackTypes:["transform","property"],exposedInEditor:!0},{type:"cameraShake",label:"Camera Shake",icon:"mdil-vibrate",runtimeEvaluator:"cameraShake",createTrack:(e=0,r=.35)=>{const a=p();return a.clips.push(i(e,r)),a},createDirectClip:(e=0,r=.35)=>i(e,r),allowedSubTrackTypes:[],exposedInEditor:!0},{type:"audio",label:"Audio Track",icon:"mdil-volume-high",runtimeEvaluator:"audio",createTrack:(e=0,r=2)=>{const t=o();return t.clips.push(a(null,e,r)),t},createDirectClip:(e=0,r=2)=>a(null,e,r),allowedSubTrackTypes:["audioParameter"],supportsParenting:!0,exposedInEditor:!0},{type:"vfx",label:"VFX Track",icon:"mdil-star",runtimeEvaluator:"vfx",createTrack:(e=0,r=2)=>{const a=v();return a.clips.push(f(null,e,r)),a},createDirectClip:(e=0,r=2)=>f(null,e,r),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"spawn",label:"Spawn Track",icon:"mdil-plus-box",runtimeEvaluator:"spawn",createTrack:(e=0,r=2)=>{const a=b();return a.clips.push(y(e,r)),a},createDirectClip:(e=0,r=2)=>y(e,r),allowedSubTrackTypes:["transform","animation","property","event"],supportsParenting:!0,exposedInEditor:!0},{type:"group",label:"Group",icon:"mdil-folder",runtimeEvaluator:"group",createTrack:()=>u(),allowedSubTrackTypes:[],exposedInEditor:!1}],w=[{type:"transform",label:"Transform",icon:"mdil-move-resize",laneKind:"keyframes",runtimeEvaluator:"transform",createSubTrack:()=>k(),supportedTrackTypes:["object","locator","camera","spawn","vfx"],exposedInEditor:!0},{type:"animation",label:"Animation",icon:"mdil-run",laneKind:"clips",runtimeEvaluator:"animation",createSubTrack:()=>r(),createClip:(r=0,a=2)=>e(null,r,a),supportedTrackTypes:["object","camera","spawn"],exposedInEditor:!0},{type:"property",label:"Property",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>T(e?.property??{propertyPath:e?.propertyPath??"",propertyType:e?.propertyType??S.Number}),supportedTrackTypes:["object","camera","spawn"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"customParam"}},{type:"material",label:"Material",icon:"mdil-palette",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:()=>m(),supportedTrackTypes:["object","spawn"],exposedInEditor:!1,valueLane:{kind:"customParam"}},{type:"visibility",label:"Visibility",icon:"mdil-eye",laneKind:"keyframes",runtimeEvaluator:"visibility",createSubTrack:()=>E(),supportedTrackTypes:["object","spawn","vfx"],exposedInEditor:!1},{type:"event",label:"Events",icon:"mdil-flash-outline",laneKind:"events",runtimeEvaluator:"event",createSubTrack:()=>c(),supportedTrackTypes:["object","spawn"],exposedInEditor:!0},{type:"audioParameter",label:"Audio Parameter",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>t(e?.parameter),supportedTrackTypes:["audio"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"number"}}];export const audioParameterSubTrackOptions=[{parameter:"volume",label:"Volume",icon:"mdil-tune"},{parameter:"detune",label:"Detune",icon:"mdil-music-note"},{parameter:"pan",label:"Pan",icon:"mdil-panorama-horizontal"},{parameter:"spatialBlend",label:"Spatial Blend",icon:"mdil-cube-outline"},{parameter:"lowpass",label:"Low Pass Filter",icon:"mdil-filter-variant"},{parameter:"highpass",label:"High Pass Filter",icon:"mdil-filter-variant"}];export const cameraPropertySubTrackOptions=[{name:"FOV",label:"FOV",propertyPath:"fov",propertyType:S.Number,group:"Camera",help:"Camera field of view in degrees.",range:[1,179],precision:1,stepSize:.1,defaultValue:{type:S.Number,value:60}}];const h=new Map(x.map(e=>[e.type,e])),P=new Map(w.map(e=>[e.type,e]));export function getSequenceTrackDefinitions(){return x}export function getSequenceSubTrackDefinitions(){return w}export function getSequenceTrackDefinition(e){return h.get(e)}export function getSequenceSubTrackDefinition(e){return P.get(e)}export function getEditorSequenceTrackDefinitions(){return x.filter(e=>!1!==e.exposedInEditor)}export function getEditorSequenceSubTrackDefinitions(e){return w.filter(r=>!1!==r.exposedInEditor&&r.supportedTrackTypes.some(r=>r===e.type))}export function canTrackAddSubTrack(e,r,a){if(e.locked)return!1;const t=getSequenceSubTrackDefinition(r);if(!t.supportedTrackTypes.some(r=>r===e.type))return!1;if("audioParameter"===r)return!!a?.parameter&&!e.subTracks.some(e=>"audioParameter"===e.type&&e.parameter===a.parameter);if("property"===r){const r=a?.property?.propertyPath??a?.propertyPath;return!!r&&!e.subTracks.some(e=>"property"===e.type&&e.propertyPath===r)}return!!t.allowMultiple||!e.subTracks.some(e=>e.type===r)}/*
1
+ import{createAnimationClipInstance as e,createAnimationSubTrack as r,createAudioClipInstance as a,createAudioParameterSubTrack as t,createAudioTrack as o,createCameraClipInstance as i,createCameraShakeClipInstance as n,createCameraShakeTrack as p,createCameraTrack as l,createEventSubTrack as c,createGroupTrack as s,createLocatorTrack as u,createMaterialSubTrack as m,createObjectTrack as d,createPostProcessClipInstance as T,createPostProcessTrack as y,createPropertySubTrack as b,createSpawnClipInstance as k,createSpawnTrack as f,createTransformSubTrack as v,createVfxClipInstance as E,createVfxTrack as S,createVisibilitySubTrack as x}from"./sequence-data.js";import{SerializedParamType as P}from"../../scene/model.js";const w=[{type:"object",label:"Object Track",icon:"mdil-hexagon",runtimeEvaluator:"object",createTrack:()=>d(),allowedSubTrackTypes:["transform","animation","property","material","visibility","event"],supportsParenting:!0,exposedInEditor:!1},{type:"locator",label:"Locator",icon:"mdil-map-marker",runtimeEvaluator:"locator",createTrack:()=>u(),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"camera",label:"Camera Track",icon:"mdil-camcorder",runtimeEvaluator:"camera",createTrack:(e=0,r=2)=>{const a=l();return a.clips.push(i(e,r)),a.subTracks.push(v()),a},createDirectClip:(e=0,r=2)=>i(e,r),allowedSubTrackTypes:["transform","property"],exposedInEditor:!0},{type:"cameraShake",label:"Camera Shake",icon:"mdil-camera",runtimeEvaluator:"cameraShake",createTrack:(e=0,r=.35)=>{const a=p();return a.clips.push(n(e,r)),a},createDirectClip:(e=0,r=.35)=>n(e,r),allowedSubTrackTypes:[],exposedInEditor:!0},{type:"postProcess",label:"Post Process",icon:"mdil-television",runtimeEvaluator:"postProcess",createTrack:(e=0,r=2)=>{const a=y();return a.clips.push(T(e,r)),a},createDirectClip:(e=0,r=2)=>T(e,r),allowedSubTrackTypes:[],exposedInEditor:!0},{type:"audio",label:"Audio Track",icon:"mdil-volume-high",runtimeEvaluator:"audio",createTrack:(e=0,r=2)=>{const t=o();return t.clips.push(a(null,e,r)),t},createDirectClip:(e=0,r=2)=>a(null,e,r),allowedSubTrackTypes:["audioParameter"],supportsParenting:!0,exposedInEditor:!0},{type:"vfx",label:"VFX Track",icon:"mdil-star",runtimeEvaluator:"vfx",createTrack:(e=0,r=2)=>{const a=S();return a.clips.push(E(null,e,r)),a},createDirectClip:(e=0,r=2)=>E(null,e,r),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"spawn",label:"Spawn Track",icon:"mdil-plus-box",runtimeEvaluator:"spawn",createTrack:(e=0,r=2)=>{const a=f();return a.clips.push(k(e,r)),a},createDirectClip:(e=0,r=2)=>k(e,r),allowedSubTrackTypes:["transform","animation","property","material","event"],supportsParenting:!0,exposedInEditor:!0},{type:"group",label:"Group",icon:"mdil-folder",runtimeEvaluator:"group",createTrack:()=>s(),allowedSubTrackTypes:[],exposedInEditor:!1}],h=[{type:"transform",label:"Transform",icon:"mdil-move-resize",laneKind:"keyframes",runtimeEvaluator:"transform",createSubTrack:()=>v(),supportedTrackTypes:["object","locator","camera","spawn","vfx"],exposedInEditor:!0},{type:"animation",label:"Animation",icon:"mdil-run",laneKind:"clips",runtimeEvaluator:"animation",createSubTrack:()=>r(),createClip:(r=0,a=2)=>e(null,r,a),supportedTrackTypes:["object","camera","spawn"],exposedInEditor:!0},{type:"property",label:"Property",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>b(e?.property??{propertyPath:e?.propertyPath??"",propertyType:e?.propertyType??P.Number}),supportedTrackTypes:["object","camera","spawn"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"customParam"}},{type:"material",label:"Material",icon:"mdil-palette",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>m(e.material),supportedTrackTypes:["object","spawn"],exposedInEditor:!1,valueLane:{kind:"customParam"}},{type:"visibility",label:"Visibility",icon:"mdil-eye",laneKind:"keyframes",runtimeEvaluator:"visibility",createSubTrack:()=>x(),supportedTrackTypes:["object","spawn","vfx"],exposedInEditor:!1},{type:"event",label:"Events",icon:"mdil-flash-outline",laneKind:"events",runtimeEvaluator:"event",createSubTrack:()=>c(),supportedTrackTypes:["object","spawn"],exposedInEditor:!0},{type:"audioParameter",label:"Audio Parameter",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:e=>t(e?.parameter),supportedTrackTypes:["audio"],allowMultiple:!0,exposedInEditor:!0,valueLane:{kind:"number"}}];export const audioParameterSubTrackOptions=[{parameter:"volume",label:"Volume",icon:"mdil-tune"},{parameter:"detune",label:"Detune",icon:"mdil-music-note"},{parameter:"pan",label:"Pan",icon:"mdil-panorama-horizontal"},{parameter:"spatialBlend",label:"Spatial Blend",icon:"mdil-cube-outline"},{parameter:"lowpass",label:"Low Pass Filter",icon:"mdil-filter-variant"},{parameter:"highpass",label:"High Pass Filter",icon:"mdil-filter-variant"}];export const cameraPropertySubTrackOptions=[{name:"FOV",label:"FOV",propertyPath:"fov",propertyType:P.Number,group:"Camera",help:"Camera field of view in degrees.",range:[1,179],precision:1,stepSize:.1,defaultValue:{type:P.Number,value:60}}];const g=new Map(w.map(e=>[e.type,e])),I=new Map(h.map(e=>[e.type,e]));export function getSequenceTrackDefinitions(){return w}export function getSequenceSubTrackDefinitions(){return h}export function getSequenceTrackDefinition(e){return g.get(e)}export function getSequenceSubTrackDefinition(e){return I.get(e)}export function getEditorSequenceTrackDefinitions(){return w.filter(e=>!1!==e.exposedInEditor)}export function getEditorSequenceSubTrackDefinitions(e){return h.filter(r=>!1!==r.exposedInEditor&&r.supportedTrackTypes.some(r=>r===e.type))}export function canTrackAddSubTrack(e,r,a){if(e.locked)return!1;const t=getSequenceSubTrackDefinition(r);if(!t.supportedTrackTypes.some(r=>r===e.type))return!1;if("audioParameter"===r)return!!a?.parameter&&!e.subTracks.some(e=>"audioParameter"===e.type&&e.parameter===a.parameter);if("property"===r){const r=a?.property?.propertyPath??a?.propertyPath;return!!r&&!e.subTracks.some(e=>"property"===e.type&&e.propertyPath===r)}if("material"===r){const r=a?.material;return!(!r?.materialAssetId||!r.parameterName)&&!e.subTracks.some(e=>"material"===e.type&&e.materialAssetId===r.materialAssetId&&e.parameterName===r.parameterName)}return!!t.allowMultiple||!e.subTracks.some(e=>e.type===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{randomString as r}from"../../utils/math.js";import{sortTimedSequenceItems as e}from"./sequence-value-lane.js";export function addTrack(r,e){return{...r,tracks:[...r.tracks,e]}}export function updateTrack(r,e,t){return{...r,tracks:r.tracks.map(r=>r.id===e?t(r):r)}}export function removeTrack(r,e){return{...r,tracks:r.tracks.filter(r=>r.id!==e)}}export function moveTrack(r,e,t){const a=r.tracks.findIndex(r=>r.id===e);if(a<0)return r;const n="up"===t?a-1:a+1;if(n<0||n>=r.tracks.length)return r;const i=[...r.tracks];return[i[a],i[n]]=[i[n],i[a]],{...r,tracks:i}}export function duplicateTrack(r,e){const t=r.tracks.findIndex(r=>r.id===e);if(t<0)return{data:r};const a=cloneTrackWithFreshIds(r.tracks[t]);a.name=`${r.tracks[t].name} (Copy)`;const n=[...r.tracks];return n.splice(t+1,0,a),{data:{...r,tracks:n},ref:{trackId:a.id}}}export function addSubTrack(r,e,t){return{data:updateTrack(r,e,r=>({...r,subTracks:[...r.subTracks,t]})),ref:{trackId:e,subTrackId:t.id}}}export function updateSubTrack(r,e,t,a){return updateTrack(r,e,r=>({...r,subTracks:r.subTracks.map(r=>r.id===t?a(r):r)}))}export function removeSubTrack(r,e,t){return updateTrack(r,e,r=>({...r,subTracks:r.subTracks.filter(r=>r.id!==t)}))}export function addTrackClip(r,e,t){return{data:updateTrack(r,e,r=>i(r)?{...r,clips:[...r.clips,t]}:r),ref:{trackId:e,clipId:t.id}}}export function updateTrackClip(r,e,t,a){return updateTrack(r,e,r=>i(r)?{...r,clips:r.clips.map(r=>r.id===t?a(r):r)}:r)}export function removeTrackClip(r,e,t){return updateTrack(r,e,r=>i(r)?{...r,clips:r.clips.filter(r=>r.id!==t)}:r)}export function addAnimationClip(r,e,t,a){return{data:n(r,e,t,r=>({...r,clips:[...r.clips,a]})),ref:{trackId:e,subTrackId:t,clipId:a.id}}}export function updateAnimationClip(r,e,t,a,i){return n(r,e,t,r=>({...r,clips:r.clips.map(r=>r.id===a?i(r):r)}))}export function removeAnimationClip(r,e,t,a){return n(r,e,t,r=>({...r,clips:r.clips.filter(r=>r.id!==a)}))}export function addSubTrackKeyframe(r,t,a,n){let i=-1,p="transform";return{data:updateSubTrack(r,t,a,r=>{if(p=r.type,u(r)&&d(n)){const t=e([...r.events,n]);return i=t.findIndex(r=>r.id===n.id),{...r,events:t}}if(c(r)&&!d(n)){const t=e([...r.keyframes,n]);return i=t.findIndex(r=>r.id===n.id),{...r,keyframes:t}}return r}),ref:-1===i?void 0:{trackId:t,subTrackId:a,keyframeId:n.id,keyframeIndex:i,subTrackType:p,time:n.time}}}export function updateSubTrackKeyframe(r,t,a,n,i){let d;return{data:updateSubTrack(r,t,a,r=>{if(u(r)){const c=e(r.events.map(r=>r.id===n?i(r):r)),u=c.findIndex(r=>r.id===n);return u>=0&&(d={trackId:t,subTrackId:a,keyframeId:n,keyframeIndex:u,subTrackType:r.type,time:c[u].time}),{...r,events:c}}if(c(r)){const c=e(r.keyframes.map(r=>r.id===n?i(r):r)),u=c.findIndex(r=>r.id===n);return u>=0&&(d={trackId:t,subTrackId:a,keyframeId:n,keyframeIndex:u,subTrackType:r.type,time:c[u].time}),{...r,keyframes:c}}return r}),ref:d}}export function removeSubTrackKeyframe(r,e,t,a){return updateSubTrack(r,e,t,r=>u(r)?{...r,events:r.events.filter(r=>r.id!==a)}:c(r)?{...r,keyframes:r.keyframes.filter(r=>r.id!==a)}:r)}export function cloneTrackWithFreshIds(r){return t(JSON.parse(JSON.stringify(r)))}function t(e){return e.id=r(),e.subTracks=e.subTracks.map(a),"group"===e.type&&(e.childTracks=e.childTracks.map(r=>t(r))),i(e)&&(e.clips=e.clips.map(e=>({...e,id:r()}))),e}function a(e){return e.id=r(),"animation"===e.type?(e.clips=e.clips.map(e=>({...e,id:r()})),e):"event"===e.type?(e.events=e.events.map(e=>({...e,id:r()})),e):(c(e)&&(e.keyframes=e.keyframes.map(e=>({...e,id:r()}))),e)}function n(r,e,t,a){return updateSubTrack(r,e,t,r=>"animation"===r.type?a(r):r)}function i(r){return"camera"===r.type||"cameraShake"===r.type||"audio"===r.type||"vfx"===r.type||"spawn"===r.type}function c(r){return"transform"===r.type||"property"===r.type||"audioParameter"===r.type||"material"===r.type||"visibility"===r.type}function u(r){return"event"===r.type}function d(r){return"arguments"in r}/*
1
+ import{randomString as r}from"../../utils/math.js";import{sortTimedSequenceItems as e}from"./sequence-value-lane.js";export function addTrack(r,e){return{...r,tracks:[...r.tracks,e]}}export function updateTrack(r,e,t){return{...r,tracks:r.tracks.map(r=>r.id===e?t(r):r)}}export function removeTrack(r,e){return{...r,tracks:r.tracks.filter(r=>r.id!==e)}}export function moveTrack(r,e,t){const a=r.tracks.findIndex(r=>r.id===e);if(a<0)return r;const n="up"===t?a-1:a+1;if(n<0||n>=r.tracks.length)return r;const i=[...r.tracks];return[i[a],i[n]]=[i[n],i[a]],{...r,tracks:i}}export function duplicateTrack(r,e){const t=r.tracks.findIndex(r=>r.id===e);if(t<0)return{data:r};const a=cloneTrackWithFreshIds(r.tracks[t]);a.name=`${r.tracks[t].name} (Copy)`;const n=[...r.tracks];return n.splice(t+1,0,a),{data:{...r,tracks:n},ref:{trackId:a.id}}}export function addSubTrack(r,e,t){return{data:updateTrack(r,e,r=>({...r,subTracks:[...r.subTracks,t]})),ref:{trackId:e,subTrackId:t.id}}}export function updateSubTrack(r,e,t,a){return updateTrack(r,e,r=>({...r,subTracks:r.subTracks.map(r=>r.id===t?a(r):r)}))}export function removeSubTrack(r,e,t){return updateTrack(r,e,r=>({...r,subTracks:r.subTracks.filter(r=>r.id!==t)}))}export function addTrackClip(r,e,t){return{data:updateTrack(r,e,r=>i(r)?{...r,clips:[...r.clips,t]}:r),ref:{trackId:e,clipId:t.id}}}export function updateTrackClip(r,e,t,a){return updateTrack(r,e,r=>i(r)?{...r,clips:r.clips.map(r=>r.id===t?a(r):r)}:r)}export function removeTrackClip(r,e,t){return updateTrack(r,e,r=>i(r)?{...r,clips:r.clips.filter(r=>r.id!==t)}:r)}export function addAnimationClip(r,e,t,a){return{data:n(r,e,t,r=>({...r,clips:[...r.clips,a]})),ref:{trackId:e,subTrackId:t,clipId:a.id}}}export function updateAnimationClip(r,e,t,a,i){return n(r,e,t,r=>({...r,clips:r.clips.map(r=>r.id===a?i(r):r)}))}export function removeAnimationClip(r,e,t,a){return n(r,e,t,r=>({...r,clips:r.clips.filter(r=>r.id!==a)}))}export function addSubTrackKeyframe(r,t,a,n){let i=-1,p="transform";return{data:updateSubTrack(r,t,a,r=>{if(p=r.type,u(r)&&d(n)){const t=e([...r.events,n]);return i=t.findIndex(r=>r.id===n.id),{...r,events:t}}if(c(r)&&!d(n)){const t=e([...r.keyframes,n]);return i=t.findIndex(r=>r.id===n.id),{...r,keyframes:t}}return r}),ref:-1===i?void 0:{trackId:t,subTrackId:a,keyframeId:n.id,keyframeIndex:i,subTrackType:p,time:n.time}}}export function updateSubTrackKeyframe(r,t,a,n,i){let d;return{data:updateSubTrack(r,t,a,r=>{if(u(r)){const c=e(r.events.map(r=>r.id===n?i(r):r)),u=c.findIndex(r=>r.id===n);return u>=0&&(d={trackId:t,subTrackId:a,keyframeId:n,keyframeIndex:u,subTrackType:r.type,time:c[u].time}),{...r,events:c}}if(c(r)){const c=e(r.keyframes.map(r=>r.id===n?i(r):r)),u=c.findIndex(r=>r.id===n);return u>=0&&(d={trackId:t,subTrackId:a,keyframeId:n,keyframeIndex:u,subTrackType:r.type,time:c[u].time}),{...r,keyframes:c}}return r}),ref:d}}export function removeSubTrackKeyframe(r,e,t,a){return updateSubTrack(r,e,t,r=>u(r)?{...r,events:r.events.filter(r=>r.id!==a)}:c(r)?{...r,keyframes:r.keyframes.filter(r=>r.id!==a)}:r)}export function cloneTrackWithFreshIds(r){return t(JSON.parse(JSON.stringify(r)))}function t(e){return e.id=r(),e.subTracks=e.subTracks.map(a),"group"===e.type&&(e.childTracks=e.childTracks.map(r=>t(r))),i(e)&&(e.clips=e.clips.map(e=>({...e,id:r()}))),e}function a(e){return e.id=r(),"animation"===e.type?(e.clips=e.clips.map(e=>({...e,id:r()})),e):"event"===e.type?(e.events=e.events.map(e=>({...e,id:r()})),e):(c(e)&&(e.keyframes=e.keyframes.map(e=>({...e,id:r()}))),e)}function n(r,e,t,a){return updateSubTrack(r,e,t,r=>"animation"===r.type?a(r):r)}function i(r){return"camera"===r.type||"cameraShake"===r.type||"postProcess"===r.type||"audio"===r.type||"vfx"===r.type||"spawn"===r.type}function c(r){return"transform"===r.type||"property"===r.type||"audioParameter"===r.type||"material"===r.type||"visibility"===r.type}function u(r){return"event"===r.type}function d(r){return"arguments"in r}/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -5,7 +5,7 @@ import { VfxService } from '../../effects/vfx/vfx-service.js';
5
5
  import { BaseActor } from '../../gameplay/actors/actor.js';
6
6
  import { ActorFactory } from '../../gameplay/actors/factory.js';
7
7
  import { AssetLoader } from '../../gameplay/services/asset-loader.js';
8
- import { World } from '../../gameplay/services/world.js';
8
+ import type { World } from '../../gameplay/services/world.js';
9
9
  import { PrefabInstance } from '../../scene/objects/prefab.js';
10
10
  import { SequenceData, SequenceRole, SequenceTrack } from './sequence-data.js';
11
11
  import { SequenceLocatorReader, SequenceLocatorSnapshot } from './sequence-locator.js';
@@ -110,6 +110,8 @@ export declare class SequencePlayer implements SequenceLocatorReader {
110
110
  private cameraBlendOutClipKey;
111
111
  private activeCameraShakeClipKeys;
112
112
  private nextCameraShakeClipKeys;
113
+ private activePostProcessClips;
114
+ private nextPostProcessClipKeys;
113
115
  private audioListener;
114
116
  private audioBuffers;
115
117
  private loadingAudioBuffers;
@@ -136,6 +138,8 @@ export declare class SequencePlayer implements SequenceLocatorReader {
136
138
  private propertyPathSegments;
137
139
  private propertyResolutionCache;
138
140
  private propertySnapshots;
141
+ private materialResolutionCache;
142
+ private materialSnapshots;
139
143
  private audioFilters;
140
144
  private audioPannerNodes;
141
145
  private firedEvents;
@@ -294,6 +298,17 @@ export declare class SequencePlayer implements SequenceLocatorReader {
294
298
  private evaluateEventSubTrack;
295
299
  private evaluateCameraTrack;
296
300
  private evaluateCameraShakeTrack;
301
+ private evaluatePostProcessTrack;
302
+ private isPostProcessClipActive;
303
+ private getPostProcessClipKey;
304
+ private ensurePostProcessClipEffect;
305
+ private loadPostProcessClipEffect;
306
+ private isPostProcessClipEntryCurrent;
307
+ private applyPostProcessClipWeight;
308
+ private getPostProcessClipWeight;
309
+ private syncPostProcessEffects;
310
+ private clearPostProcessEffects;
311
+ private releasePostProcessClipEffect;
297
312
  private getCameraPlayable;
298
313
  private ensureSequenceCamera;
299
314
  private clearSequenceCameras;
@@ -397,7 +412,12 @@ export declare class SequencePlayer implements SequenceLocatorReader {
397
412
  private restorePropertySnapshotsForInstance;
398
413
  private restorePropertySnapshotsForTarget;
399
414
  private restoreAllPropertySnapshots;
415
+ private restoreMaterialSnapshotsForInstance;
416
+ private restoreMaterialSnapshotsForTarget;
417
+ private restoreAllMaterialSnapshots;
400
418
  private applyResolvedMaterialValue;
419
+ private getMaterialSlotResolutions;
420
+ private ensureSequenceControlledMaterial;
401
421
  private ensureAnimationClip;
402
422
  private prepareAnimationPlayback;
403
423
  private getPlayableAnimationClip;
@@ -421,7 +441,24 @@ export declare class SequencePlayer implements SequenceLocatorReader {
421
441
  private restoreOriginalParents;
422
442
  private evaluateAudioSubTracks;
423
443
  private stringToRandom;
424
- refreshAsset(assetId: string): void;
444
+ refreshAsset(assetId: string): Promise<boolean>;
445
+ private refreshVfxActorsForAssetIds;
446
+ private vfxClipKeyUsesAnyAsset;
447
+ private refreshSpawnedInstancesForClipKeys;
448
+ private getSpawnClipKeysForAsset;
449
+ private refreshShaderGraphDependentAssets;
450
+ private findSequenceVfxAssetIdsUsingShaderGraph;
451
+ private findSpawnClipKeysUsingShaderGraph;
452
+ private spawnTrackUsesShaderGraph;
453
+ private assetUsesShaderGraph;
454
+ private assetUsesShaderGraphUncached;
455
+ private materialAssetUsesShaderGraph;
456
+ private materialAssignmentsUseShaderGraph;
457
+ private sceneObjectsUseShaderGraph;
458
+ private vfxAssetUsesShaderGraph;
459
+ private emitterUsesShaderGraph;
460
+ private emitterOutputUsesShaderGraph;
461
+ private getAssetOrNull;
425
462
  private invokeSequenceEvent;
426
463
  private resolveSequenceEventActorReference;
427
464
  private resolveSequenceEventSequence;