@hology/core 0.0.196 → 0.0.198

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 (67) hide show
  1. package/dist/effects/sequence/sequence-action.d.ts +8 -1
  2. package/dist/effects/sequence/sequence-actor.d.ts +14 -2
  3. package/dist/effects/sequence/sequence-actor.js +1 -1
  4. package/dist/effects/sequence/sequence-data.d.ts +98 -4
  5. package/dist/effects/sequence/sequence-data.js +1 -1
  6. package/dist/effects/sequence/sequence-definitions.d.ts +12 -8
  7. package/dist/effects/sequence/sequence-definitions.js +1 -1
  8. package/dist/effects/sequence/sequence-ops.js +1 -1
  9. package/dist/effects/sequence/sequence-player.d.ts +66 -2
  10. package/dist/effects/sequence/sequence-player.js +1 -1
  11. package/dist/effects/sequence/sequence-value-lane.d.ts +1 -0
  12. package/dist/effects/sequence/sequence-value-lane.js +1 -1
  13. package/dist/gameplay/actors/builtin/components/character/character-animation.d.ts +2 -0
  14. package/dist/gameplay/actors/builtin/components/character/character-animation.js +1 -1
  15. package/dist/gameplay/actors/builtin/navmesh-actor.js +1 -1
  16. package/dist/gameplay/actors/builtin/post-process-volume-actor.js +1 -1
  17. package/dist/gameplay/index.d.ts +1 -0
  18. package/dist/gameplay/index.js +1 -1
  19. package/dist/gameplay/initiate.d.ts +1 -0
  20. package/dist/gameplay/initiate.js +1 -1
  21. package/dist/gameplay/services/camera-shake.d.ts +28 -0
  22. package/dist/gameplay/services/camera-shake.js +4 -0
  23. package/dist/gameplay/services/physics/physics-system.js +1 -1
  24. package/dist/gameplay/services/render.d.ts +47 -2
  25. package/dist/gameplay/services/render.js +1 -1
  26. package/dist/rendering/post-process-effect.d.ts +63 -0
  27. package/dist/rendering/post-process-effect.js +4 -0
  28. package/dist/rendering.d.ts +15 -1
  29. package/dist/rendering.js +1 -1
  30. package/dist/scene/asset-resource-loader.d.ts +3 -1
  31. package/dist/scene/asset-resource-loader.js +1 -1
  32. package/dist/scene/collision/collision-shape-import.js +1 -1
  33. package/dist/scene/collision/collision-shape.js +1 -1
  34. package/dist/scene/materializer.d.ts +20 -2
  35. package/dist/scene/materializer.js +1 -1
  36. package/dist/scene/scatter/surface-scatter-manager.d.ts +44 -0
  37. package/dist/scene/scatter/surface-scatter-manager.js +4 -0
  38. package/dist/scene/storage/storage.d.ts +2 -0
  39. package/dist/scene/storage/storage.js +1 -1
  40. package/dist/shader/builtin/landscape-composite-shader.js +1 -1
  41. package/dist/shader/builtin/standard-shader.d.ts +2 -0
  42. package/dist/shader/builtin/standard-shader.js +1 -1
  43. package/dist/shader/builtin/unlit-shader.d.ts +2 -1
  44. package/dist/shader/builtin/unlit-shader.js +1 -1
  45. package/dist/shader/index.d.ts +1 -0
  46. package/dist/shader/index.js +1 -1
  47. package/dist/shader/post-process-shader.d.ts +14 -0
  48. package/dist/shader/post-process-shader.js +4 -0
  49. package/dist/shader/uv-nodes.d.ts +4 -0
  50. package/dist/shader/uv-nodes.js +4 -0
  51. package/dist/shader-nodes/index.d.ts +1 -1
  52. package/dist/shader-nodes/index.js +1 -1
  53. package/dist/test/authored-collision-rescale.test.d.ts +2 -0
  54. package/dist/test/authored-collision-rescale.test.js +4 -0
  55. package/dist/test/camera-shake.test.d.ts +2 -0
  56. package/dist/test/camera-shake.test.js +4 -0
  57. package/dist/test/collision-shape-import.test.js +1 -1
  58. package/dist/test/post-process-effect.test.d.ts +2 -0
  59. package/dist/test/post-process-effect.test.js +4 -0
  60. package/dist/test/sequence-camera-control.test.d.ts +2 -0
  61. package/dist/test/sequence-camera-control.test.js +4 -0
  62. package/dist/test/sequence-property-parameters.test.d.ts +2 -0
  63. package/dist/test/sequence-property-parameters.test.js +4 -0
  64. package/dist/test/storage-case-collision.test.d.ts +2 -0
  65. package/dist/test/storage-case-collision.test.js +4 -0
  66. package/package.json +2 -2
  67. package/tsconfig.tsbuildinfo +1 -1
@@ -8,11 +8,18 @@ import { SequenceLocatorReader } from './sequence-locator.js';
8
8
  export interface SequenceAction extends SequenceLocatorReader {
9
9
  /** Bind a role to a runtime target for dynamic actor binding */
10
10
  bindRole(role: SequenceRole, target: BaseActor | Object3D): void;
11
- play(): void;
11
+ play(options?: SequencePlayOptions): void;
12
12
  pause(): void;
13
13
  stop(): void;
14
14
  restart(): void;
15
15
  seek(time: number): void;
16
16
  dispose(): void;
17
17
  }
18
+ export interface SequencePlayOptions {
19
+ /**
20
+ * When true, camera clips are allowed to take control of the local render camera
21
+ * for this playback.
22
+ */
23
+ cameraControlEnabled?: boolean;
24
+ }
18
25
  //# sourceMappingURL=sequence-action.d.ts.map
@@ -4,7 +4,7 @@ import { SequencePlaybackState } from './sequence-player.js';
4
4
  import { Asset } from '../../scene/model.js';
5
5
  import { Subject } from 'rxjs';
6
6
  import { Object3D } from 'three';
7
- import { SequenceAction } from './sequence-action.js';
7
+ import { SequenceAction, SequencePlayOptions } from './sequence-action.js';
8
8
  import { SequenceLocatorSnapshot } from './sequence-locator.js';
9
9
  /**
10
10
  * SequenceActor is an actor that plays a sequence in the world.
@@ -38,6 +38,17 @@ export declare class SequenceActor extends BaseActor implements SequenceAction {
38
38
  * If set, this takes precedence over inline sequenceData.
39
39
  */
40
40
  sequenceAssetId: string | null;
41
+ /**
42
+ * When true, camera clips in this sequence are allowed to take control of
43
+ * the local rendered camera. Keep this disabled for remote/simulated ability
44
+ * playback and enable only on the locally controlled client.
45
+ */
46
+ private _cameraControlEnabled;
47
+ get cameraControlEnabled(): boolean;
48
+ set cameraControlEnabled(value: boolean);
49
+ private _cameraControlTrackId;
50
+ get cameraControlTrackId(): string | null;
51
+ set cameraControlTrackId(value: string | null);
41
52
  /**
42
53
  * Playback rate multiplier
43
54
  */
@@ -114,10 +125,11 @@ export declare class SequenceActor extends BaseActor implements SequenceAction {
114
125
  bindObject(objectId: string, target: Object3D | BaseActor): void;
115
126
  getLocator(bindingId: string): SequenceLocatorSnapshot | null;
116
127
  getLocators(bindingId: string): SequenceLocatorSnapshot[];
128
+ getActiveTrackObjects(trackId: string): Object3D[];
117
129
  /**
118
130
  * Start or resume playback
119
131
  */
120
- play(): void;
132
+ play(options?: SequencePlayOptions): void;
121
133
  /**
122
134
  * Pause playback
123
135
  */
@@ -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 i}from"../../gameplay/inject.js";import{ViewController as a}from"../../gameplay/services/render.js";import{AssetLoader as o}from"../../gameplay/services/asset-loader.js";import{World as l}from"../../gameplay/services/world.js";import{ActorFactory as p}from"../../gameplay/actors/factory.js";import{VfxService as n}from"../../effects/vfx/vfx-service.js";import{Parameter as h}from"../../shader/parameter.js";import{createSequenceData as c}from"./sequence-data.js";import{SequencePlayer as y,SequencePlaybackState as d}from"./sequence-player.js";import{Subject as m,takeUntil as u}from"rxjs";let f=class extends r{constructor(){super(...arguments),this.sequenceData=c(),this.sequenceAssetId=null,this.onComplete=new m,this.onLoop=new m,this.player=new y,this.viewController=i(a),this.assetLoader=i(o),this.world=i(l),this.actorFactory=i(p),this.vfxService=i(n),this.sourceAsset=null}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===d.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.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)}play(){this.player.play()}pause(){this.player.pause()}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([h({label:"Sequence Data"}),t("design:type",Object)],f.prototype,"sequenceData",void 0),f=e([s()],f);export{f 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()}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};/*
2
2
  * Copyright (©) 2026 Hology Interactive AB. All rights reserved.
3
3
  * See the LICENSE.md file for details.
4
4
  */
@@ -1,5 +1,24 @@
1
1
  import { AssetId, CustomParamValue, SerializedParamType } from '../../scene/model.js';
2
2
  import { AudioParameterId } from './audio-parameters.js';
3
+ import type { CameraShakeSettings } from '../../gameplay/services/camera-shake.js';
4
+ export interface SequencePropertyOption {
5
+ name: string;
6
+ value: unknown;
7
+ }
8
+ export interface PropertySubTrackOptions {
9
+ propertyPath: string;
10
+ propertyType: SerializedParamType;
11
+ name?: string;
12
+ label?: string;
13
+ group?: string;
14
+ help?: string;
15
+ range?: [number, number];
16
+ precision?: number;
17
+ stepSize?: number;
18
+ options?: SequencePropertyOption[];
19
+ editorInput?: 'colorGrade';
20
+ defaultValue?: CustomParamValue;
21
+ }
3
22
  /**
4
23
  * The main sequence data structure containing all tracks and playback settings.
5
24
  * This is stored as a parameter on SequenceActor or as part of a SequenceAsset.
@@ -35,7 +54,7 @@ export declare enum SequenceRole {
35
54
  /** Secondary actor (e.g., companion, summoned entity) */
36
55
  Secondary = "secondary"
37
56
  }
38
- export type SequenceTrackType = 'object' | 'locator' | 'camera' | 'audio' | 'vfx' | 'spawn' | 'group';
57
+ export type SequenceTrackType = 'object' | 'locator' | 'camera' | 'cameraShake' | 'audio' | 'vfx' | 'spawn' | 'group';
39
58
  /**
40
59
  * Base interface for all track types
41
60
  */
@@ -89,6 +108,12 @@ export interface LocatorTrack extends BaseTrack {
89
108
  */
90
109
  export interface CameraTrack extends BaseTrack {
91
110
  type: 'camera';
111
+ /** Runtime role used as the camera's parent/anchor when set. */
112
+ parentRole?: SequenceRole | null;
113
+ /** Optional socket/bone name on parentRole. */
114
+ parentRoleSocketName?: string;
115
+ /** Camera shot clips placed on the timeline */
116
+ clips: CameraClipInstance[];
92
117
  /** Camera settings */
93
118
  cameraSettings: {
94
119
  fov: number;
@@ -96,6 +121,14 @@ export interface CameraTrack extends BaseTrack {
96
121
  far: number;
97
122
  };
98
123
  }
124
+ /**
125
+ * Camera shake track - layers deterministic shake onto the active local view.
126
+ */
127
+ export interface CameraShakeTrack extends BaseTrack {
128
+ type: 'cameraShake';
129
+ /** Camera shake clips placed on the timeline */
130
+ clips: CameraShakeClipInstance[];
131
+ }
99
132
  /**
100
133
  * Audio track - plays audio assets
101
134
  */
@@ -156,7 +189,7 @@ export interface GroupTrack extends BaseTrack {
156
189
  /** Child tracks within this group */
157
190
  childTracks: SequenceTrack[];
158
191
  }
159
- export type SequenceTrack = ObjectTrack | LocatorTrack | CameraTrack | AudioTrack | VfxTrack | SpawnTrack | GroupTrack;
192
+ export type SequenceTrack = ObjectTrack | LocatorTrack | CameraTrack | CameraShakeTrack | AudioTrack | VfxTrack | SpawnTrack | GroupTrack;
160
193
  export type SubTrackType = 'transform' | 'animation' | 'property' | 'material' | 'visibility' | 'event' | 'audioParameter';
161
194
  /**
162
195
  * Base interface for sub-tracks
@@ -202,6 +235,24 @@ export interface PropertySubTrack extends BaseSubTrack {
202
235
  propertyPath: string;
203
236
  /** The type of property being animated */
204
237
  propertyType: SerializedParamType;
238
+ /** Artist-facing parameter label */
239
+ label?: string;
240
+ /** Optional editor group for the parameter */
241
+ group?: string;
242
+ /** Help text shown in the editor */
243
+ help?: string;
244
+ /** Numeric range for scalar/vector editing */
245
+ range?: [number, number];
246
+ /** Numeric display precision */
247
+ precision?: number;
248
+ /** Drag/edit step size */
249
+ stepSize?: number;
250
+ /** Discrete options for enum-like values */
251
+ options?: SequencePropertyOption[];
252
+ /** Specialized editor input hint */
253
+ editorInput?: 'colorGrade';
254
+ /** Default keyframe value when adding new keys */
255
+ defaultValue?: CustomParamValue;
205
256
  /** Keyframes for property animation */
206
257
  keyframes: PropertyKeyframe[];
207
258
  }
@@ -248,7 +299,7 @@ export interface AudioParameterSubTrack extends BaseSubTrack {
248
299
  export type SubTrack = TransformSubTrack | AnimationSubTrack | PropertySubTrack | MaterialSubTrack | VisibilitySubTrack | EventSubTrack | AudioParameterSubTrack;
249
300
  export type SequenceValueSubTrack = PropertySubTrack | MaterialSubTrack | AudioParameterSubTrack;
250
301
  export type SequenceKeyframeSubTrack = TransformSubTrack | PropertySubTrack | MaterialSubTrack | VisibilitySubTrack | AudioParameterSubTrack;
251
- export type SequenceDirectClipTrack = AudioTrack | VfxTrack | SpawnTrack;
302
+ export type SequenceDirectClipTrack = CameraTrack | CameraShakeTrack | AudioTrack | VfxTrack | SpawnTrack;
252
303
  export type SequenceAnimationHostTrack = ObjectTrack | CameraTrack | SpawnTrack;
253
304
  export type AnimationClipRetimingMode = 'uniform' | 'impact' | 'advanced';
254
305
  export interface AnimationClipRetimingPoint {
@@ -310,6 +361,37 @@ export interface VisibilityKeyframe {
310
361
  /** Whether the object is visible */
311
362
  visible: boolean;
312
363
  }
364
+ /**
365
+ * A camera shot clip placed on the timeline.
366
+ * While active, the camera track can take over the rendered view if the
367
+ * SequenceActor has camera control enabled.
368
+ */
369
+ export interface CameraClipInstance {
370
+ /** Unique identifier */
371
+ id: string;
372
+ /** Start time of this clip on the timeline */
373
+ startTime: number;
374
+ /** Duration of this clip instance */
375
+ duration: number;
376
+ /** Blend from the current gameplay camera into this shot. */
377
+ blendInDuration: number;
378
+ /** Blend from this shot back to the current gameplay camera. */
379
+ blendOutDuration: number;
380
+ /** Interpolation curve for blend in/out. */
381
+ blendInterpolation: InterpolationMode;
382
+ }
383
+ /**
384
+ * A camera shake clip placed on the timeline.
385
+ * While active, it layers shake onto the current local rendered view.
386
+ */
387
+ export interface CameraShakeClipInstance extends CameraShakeSettings {
388
+ /** Unique identifier */
389
+ id: string;
390
+ /** Start time of this clip on the timeline */
391
+ startTime: number;
392
+ /** Duration of this clip instance */
393
+ duration: number;
394
+ }
313
395
  /**
314
396
  * An instance of an animation clip placed on the timeline
315
397
  */
@@ -428,6 +510,18 @@ export declare function createObjectTrack(name?: string): ObjectTrack;
428
510
  * Creates a new camera track
429
511
  */
430
512
  export declare function createCameraTrack(name?: string): CameraTrack;
513
+ /**
514
+ * Creates a new camera shake track
515
+ */
516
+ export declare function createCameraShakeTrack(name?: string): CameraShakeTrack;
517
+ /**
518
+ * Creates a new camera shot clip instance
519
+ */
520
+ export declare function createCameraClipInstance(startTime: number, duration: number): CameraClipInstance;
521
+ /**
522
+ * Creates a new camera shake clip instance
523
+ */
524
+ export declare function createCameraShakeClipInstance(startTime: number, duration: number): CameraShakeClipInstance;
431
525
  /**
432
526
  * Creates a new audio track
433
527
  */
@@ -463,7 +557,7 @@ export declare function createAudioParameterSubTrack(parameter?: AudioParameterI
463
557
  /**
464
558
  * Creates a new property sub-track
465
559
  */
466
- export declare function createPropertySubTrack(propertyPath?: string, propertyType?: SerializedParamType): PropertySubTrack;
560
+ export declare function createPropertySubTrack(options?: PropertySubTrackOptions | string, propertyType?: SerializedParamType): PropertySubTrack;
467
561
  /**
468
562
  * Creates a new material sub-track
469
563
  */
@@ -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,cameraSettings:{fov:60,near:.1,far:1e3},subTracks:[]}}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){return{id:t(),name:r||"Property",type:"property",muted:!1,propertyPath:r,propertyType:a,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 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:[]}}/*
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
- import { AnimationClipInstance, SequenceTrack, SequenceTrackType, SubTrack, SubTrackType } from './sequence-data.js';
1
+ import { AnimationClipInstance, PropertySubTrackOptions, SequenceTrack, SequenceTrackType, SubTrack, SubTrackType } from './sequence-data.js';
2
2
  import { AudioParameterId } from './audio-parameters.js';
3
- export type SequenceTrackRuntimeEvaluator = 'object' | 'locator' | 'camera' | 'audio' | 'vfx' | 'spawn' | 'group';
3
+ import { SerializedParamType } from '../../scene/model.js';
4
+ export type SequenceTrackRuntimeEvaluator = 'object' | 'locator' | 'camera' | 'cameraShake' | 'audio' | 'vfx' | 'spawn' | 'group';
4
5
  export type SequenceSubTrackRuntimeEvaluator = 'transform' | 'animation' | 'visibility' | 'parameter' | 'event';
5
6
  export type SequenceSubTrackLaneKind = 'keyframes' | 'clips' | 'events';
6
7
  type DirectTrackClip = SequenceTrack extends infer TTrack ? TTrack extends {
@@ -23,9 +24,7 @@ export interface SequenceSubTrackDefinition<TSubTrack extends SubTrack = SubTrac
23
24
  icon: string;
24
25
  laneKind: SequenceSubTrackLaneKind;
25
26
  runtimeEvaluator: SequenceSubTrackRuntimeEvaluator;
26
- createSubTrack: (options?: {
27
- parameter?: AudioParameterId;
28
- }) => TSubTrack;
27
+ createSubTrack: (options?: SequenceSubTrackCreateOptions) => TSubTrack;
29
28
  createClip?: (startTime?: number, defaultDuration?: number) => AnimationClipInstance;
30
29
  supportedTrackTypes: readonly SequenceTrackType[];
31
30
  allowMultiple?: boolean;
@@ -34,20 +33,25 @@ export interface SequenceSubTrackDefinition<TSubTrack extends SubTrack = SubTrac
34
33
  kind: 'number' | 'customParam';
35
34
  };
36
35
  }
36
+ export interface SequenceSubTrackCreateOptions {
37
+ parameter?: AudioParameterId;
38
+ propertyPath?: string;
39
+ propertyType?: SerializedParamType;
40
+ property?: PropertySubTrackOptions;
41
+ }
37
42
  export interface AudioParameterSubTrackOption {
38
43
  parameter: AudioParameterId;
39
44
  label: string;
40
45
  icon: string;
41
46
  }
42
47
  export declare const audioParameterSubTrackOptions: AudioParameterSubTrackOption[];
48
+ export declare const cameraPropertySubTrackOptions: PropertySubTrackOptions[];
43
49
  export declare function getSequenceTrackDefinitions(): SequenceTrackDefinition[];
44
50
  export declare function getSequenceSubTrackDefinitions(): SequenceSubTrackDefinition[];
45
51
  export declare function getSequenceTrackDefinition(type: SequenceTrackType): SequenceTrackDefinition;
46
52
  export declare function getSequenceSubTrackDefinition(type: SubTrackType): SequenceSubTrackDefinition;
47
53
  export declare function getEditorSequenceTrackDefinitions(): SequenceTrackDefinition[];
48
54
  export declare function getEditorSequenceSubTrackDefinitions(track: SequenceTrack): SequenceSubTrackDefinition[];
49
- export declare function canTrackAddSubTrack(track: SequenceTrack, type: SubTrackType, options?: {
50
- parameter?: AudioParameterId;
51
- }): boolean;
55
+ export declare function canTrackAddSubTrack(track: SequenceTrack, type: SubTrackType, options?: SequenceSubTrackCreateOptions): boolean;
52
56
  export {};
53
57
  //# sourceMappingURL=sequence-definitions.d.ts.map
@@ -1,4 +1,4 @@
1
- import{createAnimationClipInstance as e,createAnimationSubTrack as a,createAudioClipInstance as r,createAudioParameterSubTrack as t,createAudioTrack as n,createCameraTrack as o,createEventSubTrack as i,createGroupTrack as l,createLocatorTrack as p,createMaterialSubTrack as c,createObjectTrack as u,createPropertySubTrack as s,createSpawnClipInstance as m,createSpawnTrack as d,createTransformSubTrack as T,createVfxClipInstance as b,createVfxTrack as k,createVisibilitySubTrack as y}from"./sequence-data.js";const f=[{type:"object",label:"Object Track",icon:"mdil-hexagon",runtimeEvaluator:"object",createTrack:()=>u(),allowedSubTrackTypes:["transform","animation","property","material","visibility","event"],supportsParenting:!0,exposedInEditor:!1},{type:"locator",label:"Locator",icon:"mdil-map-marker-radius",runtimeEvaluator:"locator",createTrack:()=>p(),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"camera",label:"Camera Track",icon:"mdil-camcorder",runtimeEvaluator:"camera",createTrack:(r=0,t=2)=>{const n=o(),i=a();return i.clips.push(e(null,r,t)),n.subTracks.push(i),n},allowedSubTrackTypes:["transform","animation","property","event"],exposedInEditor:!0},{type:"audio",label:"Audio Track",icon:"mdil-volume-high",runtimeEvaluator:"audio",createTrack:(e=0,a=2)=>{const t=n();return t.clips.push(r(null,e,a)),t},createDirectClip:(e=0,a=2)=>r(null,e,a),allowedSubTrackTypes:["audioParameter"],supportsParenting:!0,exposedInEditor:!0},{type:"vfx",label:"VFX Track",icon:"mdil-star",runtimeEvaluator:"vfx",createTrack:(e=0,a=2)=>{const r=k();return r.clips.push(b(null,e,a)),r},createDirectClip:(e=0,a=2)=>b(null,e,a),allowedSubTrackTypes:["transform"],supportsParenting:!0,exposedInEditor:!0},{type:"spawn",label:"Spawn Track",icon:"mdil-plus-box",runtimeEvaluator:"spawn",createTrack:(e=0,a=2)=>{const r=d();return r.clips.push(m(e,a)),r},createDirectClip:(e=0,a=2)=>m(e,a),allowedSubTrackTypes:["transform","animation","property","event"],supportsParenting:!0,exposedInEditor:!0},{type:"group",label:"Group",icon:"mdil-folder",runtimeEvaluator:"group",createTrack:()=>l(),allowedSubTrackTypes:[],exposedInEditor:!1}],v=[{type:"transform",label:"Transform",icon:"mdil-move-resize",laneKind:"keyframes",runtimeEvaluator:"transform",createSubTrack:()=>T(),supportedTrackTypes:["object","locator","camera","spawn","vfx"],exposedInEditor:!0},{type:"animation",label:"Animation",icon:"mdil-run",laneKind:"clips",runtimeEvaluator:"animation",createSubTrack:()=>a(),createClip:(a=0,r=2)=>e(null,a,r),supportedTrackTypes:["object","camera","spawn"],exposedInEditor:!0},{type:"property",label:"Property",icon:"mdil-tune",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:()=>s(),supportedTrackTypes:["object","camera","spawn"],exposedInEditor:!1,valueLane:{kind:"customParam"}},{type:"material",label:"Material",icon:"mdil-palette",laneKind:"keyframes",runtimeEvaluator:"parameter",createSubTrack:()=>c(),supportedTrackTypes:["object","spawn"],exposedInEditor:!1,valueLane:{kind:"customParam"}},{type:"visibility",label:"Visibility",icon:"mdil-eye",laneKind:"keyframes",runtimeEvaluator:"visibility",createSubTrack:()=>y(),supportedTrackTypes:["object","spawn","vfx"],exposedInEditor:!1},{type:"event",label:"Events",icon:"mdil-flash-outline",laneKind:"events",runtimeEvaluator:"event",createSubTrack:()=>i(),supportedTrackTypes:["object","spawn","camera"],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"}];const E=new Map(f.map(e=>[e.type,e])),x=new Map(v.map(e=>[e.type,e]));export function getSequenceTrackDefinitions(){return f}export function getSequenceSubTrackDefinitions(){return v}export function getSequenceTrackDefinition(e){return E.get(e)}export function getSequenceSubTrackDefinition(e){return x.get(e)}export function getEditorSequenceTrackDefinitions(){return f.filter(e=>!1!==e.exposedInEditor)}export function getEditorSequenceSubTrackDefinitions(e){return v.filter(a=>!1!==a.exposedInEditor&&a.supportedTrackTypes.some(a=>a===e.type))}export function canTrackAddSubTrack(e,a,r){if(e.locked)return!1;const t=getSequenceSubTrackDefinition(a);return!!t.supportedTrackTypes.some(a=>a===e.type)&&("audioParameter"===a?!!r?.parameter&&!e.subTracks.some(e=>"audioParameter"===e.type&&e.parameter===r.parameter):!!t.allowMultiple||!e.subTracks.some(e=>e.type===a))}/*
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)}/*
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"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||"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
  */
@@ -10,6 +10,7 @@ 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';
12
12
  import { CharacterAnimationComponent } from '../../gameplay/actors/index.js';
13
+ import type { ViewController } from '../../gameplay/services/render.js';
13
14
  /**
14
15
  * Playback state of the sequence
15
16
  */
@@ -96,8 +97,19 @@ export declare class SequencePlayer implements SequenceLocatorReader {
96
97
  readonly onTimeUpdate: import("rxjs").Observable<number>;
97
98
  readonly onStateChange: import("rxjs").Observable<SequencePlaybackState>;
98
99
  private loopCount;
99
- private sequenceCamera;
100
- private originalCamera;
100
+ private viewController;
101
+ private _cameraControlEnabled;
102
+ private _cameraControlTrackId;
103
+ private sequenceCameras;
104
+ private cameraPlayables;
105
+ private cameraBlendCamera;
106
+ private cameraBlendSource;
107
+ private cameraBlendOutSource;
108
+ private cameraOverrideHandle;
109
+ private activeCameraClipKey;
110
+ private cameraBlendOutClipKey;
111
+ private activeCameraShakeClipKeys;
112
+ private nextCameraShakeClipKeys;
101
113
  private audioListener;
102
114
  private audioBuffers;
103
115
  private loadingAudioBuffers;
@@ -121,6 +133,9 @@ export declare class SequencePlayer implements SequenceLocatorReader {
121
133
  private activeVfxClips;
122
134
  private locatorMarkers;
123
135
  private clearCounter;
136
+ private propertyPathSegments;
137
+ private propertyResolutionCache;
138
+ private propertySnapshots;
124
139
  private audioFilters;
125
140
  private audioPannerNodes;
126
141
  private firedEvents;
@@ -164,6 +179,20 @@ export declare class SequencePlayer implements SequenceLocatorReader {
164
179
  */
165
180
  get inEditor(): boolean;
166
181
  set inEditor(value: boolean);
182
+ /**
183
+ * When true, active camera clips are allowed to control the local rendered view.
184
+ * Gameplay should enable this only for the locally controlled actor/client.
185
+ */
186
+ get cameraControlEnabled(): boolean;
187
+ set cameraControlEnabled(value: boolean);
188
+ /**
189
+ * Optional editor/runtime pilot filter. When set, camera control only considers
190
+ * clips from this camera track; null preserves the normal sequence-wide camera
191
+ * priority behavior.
192
+ */
193
+ get cameraControlTrackId(): string | null;
194
+ set cameraControlTrackId(value: string | null);
195
+ setViewController(viewController: ViewController): void;
167
196
  /**
168
197
  * Set world dependency
169
198
  */
@@ -249,6 +278,7 @@ export declare class SequencePlayer implements SequenceLocatorReader {
249
278
  private evaluateTrack;
250
279
  private evaluateObjectTrack;
251
280
  private evaluateLocatorTrack;
281
+ getActiveTrackObjects(trackId: string): Object3D[];
252
282
  private evaluateSubTracks;
253
283
  private evaluateTransformSubTrack;
254
284
  private evaluateAnimationSubTrack;
@@ -257,6 +287,33 @@ export declare class SequencePlayer implements SequenceLocatorReader {
257
287
  private evaluateParameterSubTrack;
258
288
  private evaluateEventSubTrack;
259
289
  private evaluateCameraTrack;
290
+ private evaluateCameraShakeTrack;
291
+ private getCameraPlayable;
292
+ private ensureSequenceCamera;
293
+ private clearSequenceCameras;
294
+ private applyCameraTrackSettings;
295
+ private getCurrentCameraAspect;
296
+ private updateCameraControl;
297
+ private findActiveCameraShot;
298
+ private findBlendOutCameraShot;
299
+ private isCameraControlTrackEligible;
300
+ private updateActiveCameraShot;
301
+ private updateCameraBlendOut;
302
+ private ensureCameraBlendCamera;
303
+ private ensureCameraBlendSource;
304
+ private ensureCameraBlendOutSource;
305
+ private ensureCameraOverride;
306
+ private releaseCameraOverride;
307
+ private isCameraClipActive;
308
+ private getCameraClipEnd;
309
+ private isCameraShakeClipActive;
310
+ private getCameraShakeClipEnd;
311
+ private getCameraClipKey;
312
+ private evaluateCameraBlendAlpha;
313
+ private syncCameraShakeContributions;
314
+ private clearCameraShakeContributions;
315
+ private copyCameraState;
316
+ private blendCameraState;
260
317
  private evaluateAudioTrack;
261
318
  private tryStartAudioClip;
262
319
  private applyAudioParameters;
@@ -327,6 +384,13 @@ export declare class SequencePlayer implements SequenceLocatorReader {
327
384
  private spawnForClip;
328
385
  private getPlayableObject;
329
386
  private applyResolvedPropertyValue;
387
+ private getPropertyResolution;
388
+ private getPropertyPathSegments;
389
+ private getPropertySnapshotKey;
390
+ private capturePropertySnapshot;
391
+ private restorePropertySnapshotsForInstance;
392
+ private restorePropertySnapshotsForTarget;
393
+ private restoreAllPropertySnapshots;
330
394
  private applyResolvedMaterialValue;
331
395
  private ensureAnimationClip;
332
396
  private prepareAnimationPlayback;