@needle-tools/engine 5.1.0-alpha.3 → 5.1.0-alpha.4

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 (178) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/SKILL.md +4 -1
  3. package/components.needle.json +1 -1
  4. package/dist/needle-engine.bundle-AjVIot3d.min.js +1733 -0
  5. package/dist/{needle-engine.bundle-DF01sSGQ.js → needle-engine.bundle-B7cqsI4c.js} +9149 -8867
  6. package/dist/{needle-engine.bundle-C-ixARur.umd.cjs → needle-engine.bundle-DQCuBTVp.umd.cjs} +154 -154
  7. package/dist/needle-engine.d.ts +754 -199
  8. package/dist/needle-engine.js +583 -584
  9. package/dist/needle-engine.min.js +1 -1
  10. package/dist/needle-engine.umd.cjs +1 -1
  11. package/lib/engine/api.d.ts +3 -0
  12. package/lib/engine/api.js +2 -0
  13. package/lib/engine/api.js.map +1 -1
  14. package/lib/engine/codegen/register_types.js +2 -10
  15. package/lib/engine/codegen/register_types.js.map +1 -1
  16. package/lib/engine/engine_context.js +2 -1
  17. package/lib/engine/engine_context.js.map +1 -1
  18. package/lib/engine/engine_disposable.d.ts +172 -0
  19. package/lib/engine/engine_disposable.js +136 -0
  20. package/lib/engine/engine_disposable.js.map +1 -0
  21. package/lib/engine/engine_gameobject.d.ts +1 -10
  22. package/lib/engine/engine_gameobject.js +20 -118
  23. package/lib/engine/engine_gameobject.js.map +1 -1
  24. package/lib/engine/engine_gltf_builtin_components.js +7 -69
  25. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  26. package/lib/engine/engine_instantiate_resolve.d.ts +42 -0
  27. package/lib/engine/engine_instantiate_resolve.js +372 -0
  28. package/lib/engine/engine_instantiate_resolve.js.map +1 -0
  29. package/lib/engine/engine_mainloop_utils.js +2 -2
  30. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  31. package/lib/engine/engine_networking.d.ts +51 -37
  32. package/lib/engine/engine_networking.js +132 -82
  33. package/lib/engine/engine_networking.js.map +1 -1
  34. package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
  35. package/lib/engine/engine_networking.transport.websocket.js +38 -0
  36. package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
  37. package/lib/engine/engine_networking_instantiate.js +2 -2
  38. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  39. package/lib/engine/engine_networking_types.d.ts +39 -1
  40. package/lib/engine/engine_networking_types.js +7 -0
  41. package/lib/engine/engine_networking_types.js.map +1 -1
  42. package/lib/engine/engine_physics_rapier.d.ts +11 -3
  43. package/lib/engine/engine_physics_rapier.js +88 -25
  44. package/lib/engine/engine_physics_rapier.js.map +1 -1
  45. package/lib/engine/engine_serialization_builtin_serializer.js +1 -5
  46. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  47. package/lib/engine/engine_serialization_core.d.ts +1 -0
  48. package/lib/engine/engine_serialization_core.js +7 -0
  49. package/lib/engine/engine_serialization_core.js.map +1 -1
  50. package/lib/engine/engine_types.d.ts +19 -11
  51. package/lib/engine/engine_types.js +1 -1
  52. package/lib/engine/engine_types.js.map +1 -1
  53. package/lib/engine/engine_util_decorator.js +7 -2
  54. package/lib/engine/engine_util_decorator.js.map +1 -1
  55. package/lib/engine/engine_utils.d.ts +1 -1
  56. package/lib/engine/engine_utils.js +19 -5
  57. package/lib/engine/engine_utils.js.map +1 -1
  58. package/lib/engine-components/Animator.d.ts +6 -0
  59. package/lib/engine-components/Animator.js +17 -12
  60. package/lib/engine-components/Animator.js.map +1 -1
  61. package/lib/engine-components/AnimatorController.builder.d.ts +113 -0
  62. package/lib/engine-components/AnimatorController.builder.js +195 -0
  63. package/lib/engine-components/AnimatorController.builder.js.map +1 -0
  64. package/lib/engine-components/AnimatorController.d.ts +2 -119
  65. package/lib/engine-components/AnimatorController.js +31 -232
  66. package/lib/engine-components/AnimatorController.js.map +1 -1
  67. package/lib/engine-components/Collider.d.ts +18 -9
  68. package/lib/engine-components/Collider.js +61 -14
  69. package/lib/engine-components/Collider.js.map +1 -1
  70. package/lib/engine-components/Component.d.ts +72 -9
  71. package/lib/engine-components/Component.js +114 -10
  72. package/lib/engine-components/Component.js.map +1 -1
  73. package/lib/engine-components/DragControls.js +0 -7
  74. package/lib/engine-components/DragControls.js.map +1 -1
  75. package/lib/engine-components/EventList.d.ts +31 -9
  76. package/lib/engine-components/EventList.js +37 -76
  77. package/lib/engine-components/EventList.js.map +1 -1
  78. package/lib/engine-components/Joints.d.ts +4 -2
  79. package/lib/engine-components/Joints.js +19 -3
  80. package/lib/engine-components/Joints.js.map +1 -1
  81. package/lib/engine-components/Light.js +9 -1
  82. package/lib/engine-components/Light.js.map +1 -1
  83. package/lib/engine-components/RigidBody.d.ts +12 -4
  84. package/lib/engine-components/RigidBody.js +18 -4
  85. package/lib/engine-components/RigidBody.js.map +1 -1
  86. package/lib/engine-components/api.d.ts +1 -1
  87. package/lib/engine-components/api.js +1 -1
  88. package/lib/engine-components/api.js.map +1 -1
  89. package/lib/engine-components/codegen/components.d.ts +3 -9
  90. package/lib/engine-components/codegen/components.js +3 -9
  91. package/lib/engine-components/codegen/components.js.map +1 -1
  92. package/lib/engine-components/timeline/PlayableDirector.d.ts +16 -6
  93. package/lib/engine-components/timeline/PlayableDirector.js +70 -62
  94. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  95. package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
  96. package/lib/engine-components/timeline/SignalAsset.js +1 -0
  97. package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
  98. package/lib/engine-components/timeline/TimelineBuilder.d.ts +247 -0
  99. package/lib/engine-components/timeline/TimelineBuilder.js +400 -0
  100. package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
  101. package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
  102. package/lib/engine-components/timeline/TimelineModels.js +3 -0
  103. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  104. package/lib/engine-components/timeline/TimelineTracks.d.ts +23 -0
  105. package/lib/engine-components/timeline/TimelineTracks.js +71 -13
  106. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  107. package/lib/engine-components/timeline/index.d.ts +2 -1
  108. package/lib/engine-components/timeline/index.js +2 -0
  109. package/lib/engine-components/timeline/index.js.map +1 -1
  110. package/package.json +2 -83
  111. package/plugins/common/license.js +5 -2
  112. package/plugins/common/worker.js +9 -4
  113. package/plugins/vite/dependencies.js +1 -11
  114. package/plugins/vite/dependency-watcher.js +2 -2
  115. package/plugins/vite/editor-connection.js +3 -3
  116. package/plugins/vite/reload.js +1 -1
  117. package/plugins/vite/server.js +2 -1
  118. package/src/engine/api.ts +4 -0
  119. package/src/engine/codegen/register_types.ts +2 -10
  120. package/src/engine/engine_context.ts +2 -1
  121. package/src/engine/engine_disposable.ts +214 -0
  122. package/src/engine/engine_gameobject.ts +52 -157
  123. package/src/engine/engine_gltf_builtin_components.ts +7 -76
  124. package/src/engine/engine_instantiate_resolve.ts +407 -0
  125. package/src/engine/engine_mainloop_utils.ts +2 -2
  126. package/src/engine/engine_networking.transport.websocket.ts +45 -0
  127. package/src/engine/engine_networking.ts +161 -137
  128. package/src/engine/engine_networking_instantiate.ts +2 -2
  129. package/src/engine/engine_networking_types.ts +41 -1
  130. package/src/engine/engine_physics_rapier.ts +82 -27
  131. package/src/engine/engine_serialization_builtin_serializer.ts +1 -6
  132. package/src/engine/engine_serialization_core.ts +9 -0
  133. package/src/engine/engine_types.ts +24 -15
  134. package/src/engine/engine_util_decorator.ts +7 -2
  135. package/src/engine/engine_utils.ts +16 -5
  136. package/src/engine-components/Animator.ts +18 -11
  137. package/src/engine-components/AnimatorController.builder.ts +261 -0
  138. package/src/engine-components/AnimatorController.ts +19 -291
  139. package/src/engine-components/Collider.ts +66 -18
  140. package/src/engine-components/Component.ts +118 -20
  141. package/src/engine-components/DragControls.ts +0 -9
  142. package/src/engine-components/EventList.ts +45 -83
  143. package/src/engine-components/Joints.ts +20 -4
  144. package/src/engine-components/Light.ts +10 -2
  145. package/src/engine-components/RigidBody.ts +18 -4
  146. package/src/engine-components/api.ts +1 -1
  147. package/src/engine-components/codegen/components.ts +3 -9
  148. package/src/engine-components/timeline/PlayableDirector.ts +67 -65
  149. package/src/engine-components/timeline/SignalAsset.ts +4 -1
  150. package/src/engine-components/timeline/TimelineBuilder.ts +564 -0
  151. package/src/engine-components/timeline/TimelineModels.ts +5 -1
  152. package/src/engine-components/timeline/TimelineTracks.ts +74 -13
  153. package/src/engine-components/timeline/index.ts +2 -1
  154. package/dist/needle-engine.bundle-CHmXdnE1.min.js +0 -1733
  155. package/lib/engine-components/AvatarLoader.d.ts +0 -80
  156. package/lib/engine-components/AvatarLoader.js +0 -232
  157. package/lib/engine-components/AvatarLoader.js.map +0 -1
  158. package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
  159. package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
  160. package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
  161. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
  162. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
  163. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
  164. package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
  165. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
  166. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
  167. package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
  168. package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
  169. package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
  170. package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
  171. package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
  172. package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
  173. package/src/engine-components/AvatarLoader.ts +0 -264
  174. package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
  175. package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
  176. package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
  177. package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
  178. package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
@@ -0,0 +1,247 @@
1
+ import { AnimationClip, Object3D } from "three";
2
+ import type { Animator } from "../Animator.js";
3
+ import type { AudioSource } from "../AudioSource.js";
4
+ import { SignalReceiver } from "./SignalAsset.js";
5
+ import type { PlayableDirector } from "./PlayableDirector.js";
6
+ import { ClipExtrapolation } from "./TimelineModels.js";
7
+ import type { TimelineAssetModel } from "./TimelineModels.js";
8
+ /**
9
+ * Options for an animation clip in the timeline builder
10
+ */
11
+ export declare type AnimationClipOptions = {
12
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
13
+ start?: number;
14
+ /** Duration of the clip in seconds. Defaults to the animation clip duration. */
15
+ duration?: number;
16
+ /** Playback speed multiplier (default: 1) */
17
+ speed?: number;
18
+ /** Whether the animation should loop within the clip (default: false) */
19
+ loop?: boolean;
20
+ /** Ease-in duration in seconds (default: 0) */
21
+ easeIn?: number;
22
+ /** Ease-out duration in seconds (default: 0) */
23
+ easeOut?: number;
24
+ /** Offset into the source animation clip in seconds (default: 0) */
25
+ clipIn?: number;
26
+ /** Whether to remove the start offset of the animation (default: false) */
27
+ removeStartOffset?: boolean;
28
+ /** Pre-extrapolation mode (default: None) */
29
+ preExtrapolation?: ClipExtrapolation;
30
+ /** Post-extrapolation mode (default: None) */
31
+ postExtrapolation?: ClipExtrapolation;
32
+ /** Play the clip in reverse */
33
+ reversed?: boolean;
34
+ };
35
+ /**
36
+ * Options for an audio clip in the timeline builder
37
+ */
38
+ export declare type AudioClipOptions = {
39
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
40
+ start?: number;
41
+ /** Duration of the clip in seconds (required for audio since we can't infer it) */
42
+ duration: number;
43
+ /** Playback speed multiplier (default: 1) */
44
+ speed?: number;
45
+ /** Volume multiplier for this clip (default: 1) */
46
+ volume?: number;
47
+ /** Whether the audio should loop within the clip (default: false) */
48
+ loop?: boolean;
49
+ /** Ease-in duration in seconds (default: 0) */
50
+ easeIn?: number;
51
+ /** Ease-out duration in seconds (default: 0) */
52
+ easeOut?: number;
53
+ };
54
+ /**
55
+ * Options for an activation clip in the timeline builder
56
+ */
57
+ export declare type ActivationClipOptions = {
58
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
59
+ start?: number;
60
+ /** Duration of the clip in seconds (required) */
61
+ duration: number;
62
+ /** Ease-in duration in seconds (default: 0) */
63
+ easeIn?: number;
64
+ /** Ease-out duration in seconds (default: 0) */
65
+ easeOut?: number;
66
+ };
67
+ /**
68
+ * Options for a control clip in the timeline builder
69
+ */
70
+ export declare type ControlClipOptions = {
71
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
72
+ start?: number;
73
+ /** Duration of the clip in seconds (required) */
74
+ duration: number;
75
+ /** Whether to control the activation of the source object (default: true) */
76
+ controlActivation?: boolean;
77
+ /** Whether to update a nested PlayableDirector on the source object (default: true) */
78
+ updateDirector?: boolean;
79
+ };
80
+ /**
81
+ * Options for a signal marker in the timeline builder
82
+ */
83
+ export declare type SignalMarkerOptions = {
84
+ /** Whether the signal should fire if the playback starts past its time (default: false) */
85
+ retroActive?: boolean;
86
+ /** Whether the signal should only fire once (default: false) */
87
+ emitOnce?: boolean;
88
+ };
89
+ /**
90
+ * A fluent builder for creating timeline assets ({@link TimelineAssetModel}) from code.
91
+ *
92
+ * Use {@link TimelineBuilder.create} to start building a timeline.
93
+ *
94
+ * @example Using build() for timelines without signal callbacks
95
+ * ```ts
96
+ * const timeline = TimelineBuilder.create("MySequence")
97
+ * .animationTrack("Character", animator)
98
+ * .clip(walkClip, { duration: 2, easeIn: 0.3 })
99
+ * .clip(runClip, { duration: 3, easeIn: 0.5, easeOut: 0.5 })
100
+ * .activationTrack("FX", particleObject)
101
+ * .clip({ start: 1, duration: 2 })
102
+ * .audioTrack("Music", audioSource)
103
+ * .clip("music.mp3", { start: 0, duration: 5, volume: 0.8 })
104
+ * .build();
105
+ *
106
+ * director.playableAsset = timeline;
107
+ * director.play();
108
+ * ```
109
+ *
110
+ * @example Using install() with signal callbacks
111
+ * ```ts
112
+ * TimelineBuilder.create("WithSignals")
113
+ * .animationTrack("Character", animator)
114
+ * .clip(walkClip, { duration: 2 })
115
+ * .signalTrack("Events")
116
+ * .signal(1.0, () => console.log("1 second!"))
117
+ * .signal(2.0, () => spawnParticles())
118
+ * .install(director);
119
+ *
120
+ * director.play();
121
+ * ```
122
+ *
123
+ * @category Animation and Sequencing
124
+ * @group Utilities
125
+ */
126
+ export declare class TimelineBuilder {
127
+ private _name;
128
+ private _tracks;
129
+ private _currentTrack;
130
+ private _pendingSignals;
131
+ private _idProvider;
132
+ private constructor();
133
+ /**
134
+ * Creates a new TimelineBuilder instance.
135
+ * @param name - Name for the timeline asset
136
+ * @param seed - Optional numeric seed for deterministic guid generation. Defaults to `Date.now()`.
137
+ */
138
+ static create(name?: string, seed?: number): TimelineBuilder;
139
+ /**
140
+ * Adds an animation track. Subsequent `.clip()` calls add animation clips to this track.
141
+ * @param name - Display name for the track
142
+ * @param binding - The Animator or Object3D to animate
143
+ */
144
+ animationTrack(name: string, binding?: Animator | Object3D | null): this;
145
+ /**
146
+ * Adds an audio track. Subsequent `.clip()` calls add audio clips to this track.
147
+ * @param name - Display name for the track
148
+ * @param binding - The AudioSource to play audio on (optional)
149
+ * @param volume - Track volume multiplier (default: 1)
150
+ */
151
+ audioTrack(name: string, binding?: AudioSource | Object3D | null, volume?: number): this;
152
+ /**
153
+ * Adds an activation track. Subsequent `.clip()` calls define when the bound object is active.
154
+ * @param name - Display name for the track
155
+ * @param binding - The Object3D to show/hide
156
+ */
157
+ activationTrack(name: string, binding?: Object3D | null): this;
158
+ /**
159
+ * Adds a control track. Subsequent `.clip()` calls control nested timelines or objects.
160
+ * @param name - Display name for the track
161
+ */
162
+ controlTrack(name: string): this;
163
+ /**
164
+ * Adds a signal track. Use `.signal()` or `.marker()` to add signal markers.
165
+ * @param name - Display name for the track
166
+ * @param binding - The SignalReceiver component (optional — if using `.signal()` with callbacks, one is created automatically by {@link install})
167
+ */
168
+ signalTrack(name: string, binding?: SignalReceiver | Object3D | null): this;
169
+ /**
170
+ * Adds a marker track. Use `.marker()` to add markers.
171
+ * @param name - Display name for the track
172
+ */
173
+ markerTrack(name: string): this;
174
+ /**
175
+ * Adds a clip to the current track. The clip type must match the track type.
176
+ *
177
+ * - On an **animation track**: pass an `AnimationClip` and optional {@link AnimationClipOptions}
178
+ * - On an **audio track**: pass a clip URL (string) and {@link AudioClipOptions}
179
+ * - On an **activation track**: pass {@link ActivationClipOptions}
180
+ * - On a **control track**: pass an Object3D and {@link ControlClipOptions}
181
+ */
182
+ clip(asset: AnimationClip, options?: AnimationClipOptions): this;
183
+ clip(url: string, options: AudioClipOptions): this;
184
+ clip(options: ActivationClipOptions): this;
185
+ clip(sourceObject: Object3D, options: ControlClipOptions): this;
186
+ /**
187
+ * Adds a signal marker to the current signal or marker track.
188
+ * @param time - Time in seconds when the signal fires
189
+ * @param asset - The signal asset identifier (guid string)
190
+ * @param options - Optional marker configuration
191
+ */
192
+ marker(time: number, asset: string, options?: SignalMarkerOptions): this;
193
+ /**
194
+ * Adds a signal with a callback to the current signal track.
195
+ * This is a convenience method that automatically generates a signal asset guid,
196
+ * adds the marker, and registers the callback so that {@link install} can wire up
197
+ * the `SignalReceiver` on the director's GameObject.
198
+ *
199
+ * @param time - Time in seconds when the signal fires
200
+ * @param callback - The function to invoke when the signal fires
201
+ * @param options - Optional marker configuration
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * const timeline = TimelineBuilder.create("Sequence")
206
+ * .signalTrack("Events")
207
+ * .signal(1.0, () => console.log("1 second reached!"))
208
+ * .signal(3.5, () => console.log("halfway!"), { emitOnce: true })
209
+ * .install(director);
210
+ * ```
211
+ */
212
+ signal(time: number, callback: Function, options?: SignalMarkerOptions): this;
213
+ /**
214
+ * Mutes the current track so it is skipped during playback.
215
+ */
216
+ muted(muted?: boolean): this;
217
+ /**
218
+ * Builds and returns the {@link TimelineAssetModel}.
219
+ * Assign the result to `PlayableDirector.playableAsset` to play it.
220
+ *
221
+ * If you used `.signal()` with callbacks, use {@link install} instead — it calls `build()`
222
+ * internally and also wires up the SignalReceiver on the director's GameObject.
223
+ */
224
+ build(): TimelineAssetModel;
225
+ /**
226
+ * Builds the timeline asset, assigns it to the director, and wires up any
227
+ * `.signal()` callbacks by creating/configuring a {@link SignalReceiver} on the
228
+ * director's GameObject.
229
+ *
230
+ * @param director - The PlayableDirector to install the timeline on
231
+ * @returns The built TimelineAssetModel (also assigned to `director.playableAsset`)
232
+ *
233
+ * @example
234
+ * ```ts
235
+ * TimelineBuilder.create("MyTimeline")
236
+ * .animationTrack("Anim", animator)
237
+ * .clip(walkClip, { duration: 2 })
238
+ * .signalTrack("Events")
239
+ * .signal(1.0, () => console.log("signal fired!"))
240
+ * .install(director);
241
+ *
242
+ * director.play();
243
+ * ```
244
+ */
245
+ install(director: PlayableDirector): TimelineAssetModel;
246
+ private pushTrack;
247
+ }
@@ -0,0 +1,400 @@
1
+ import { GameObject } from "../Component.js";
2
+ import { InstantiateIdProvider } from "../../engine/engine_networking_instantiate.js";
3
+ import { EventList } from "../EventList.js";
4
+ import { SignalAsset, SignalReceiver, SignalReceiverEvent } from "./SignalAsset.js";
5
+ import { ClipExtrapolation, TrackType } from "./TimelineModels.js";
6
+ import { MarkerType } from "./TimelineModels.js";
7
+ /**
8
+ * A fluent builder for creating timeline assets ({@link TimelineAssetModel}) from code.
9
+ *
10
+ * Use {@link TimelineBuilder.create} to start building a timeline.
11
+ *
12
+ * @example Using build() for timelines without signal callbacks
13
+ * ```ts
14
+ * const timeline = TimelineBuilder.create("MySequence")
15
+ * .animationTrack("Character", animator)
16
+ * .clip(walkClip, { duration: 2, easeIn: 0.3 })
17
+ * .clip(runClip, { duration: 3, easeIn: 0.5, easeOut: 0.5 })
18
+ * .activationTrack("FX", particleObject)
19
+ * .clip({ start: 1, duration: 2 })
20
+ * .audioTrack("Music", audioSource)
21
+ * .clip("music.mp3", { start: 0, duration: 5, volume: 0.8 })
22
+ * .build();
23
+ *
24
+ * director.playableAsset = timeline;
25
+ * director.play();
26
+ * ```
27
+ *
28
+ * @example Using install() with signal callbacks
29
+ * ```ts
30
+ * TimelineBuilder.create("WithSignals")
31
+ * .animationTrack("Character", animator)
32
+ * .clip(walkClip, { duration: 2 })
33
+ * .signalTrack("Events")
34
+ * .signal(1.0, () => console.log("1 second!"))
35
+ * .signal(2.0, () => spawnParticles())
36
+ * .install(director);
37
+ *
38
+ * director.play();
39
+ * ```
40
+ *
41
+ * @category Animation and Sequencing
42
+ * @group Utilities
43
+ */
44
+ export class TimelineBuilder {
45
+ _name;
46
+ _tracks = [];
47
+ _currentTrack = null;
48
+ _pendingSignals = [];
49
+ _idProvider;
50
+ constructor(name, seed) {
51
+ this._name = name;
52
+ this._idProvider = new InstantiateIdProvider(seed ?? Date.now());
53
+ }
54
+ /**
55
+ * Creates a new TimelineBuilder instance.
56
+ * @param name - Name for the timeline asset
57
+ * @param seed - Optional numeric seed for deterministic guid generation. Defaults to `Date.now()`.
58
+ */
59
+ static create(name, seed) {
60
+ return new TimelineBuilder(name ?? "Timeline", seed);
61
+ }
62
+ // #region Track creation
63
+ /**
64
+ * Adds an animation track. Subsequent `.clip()` calls add animation clips to this track.
65
+ * @param name - Display name for the track
66
+ * @param binding - The Animator or Object3D to animate
67
+ */
68
+ animationTrack(name, binding) {
69
+ this._currentTrack = this.pushTrack(name, TrackType.Animation, binding ?? null);
70
+ return this;
71
+ }
72
+ /**
73
+ * Adds an audio track. Subsequent `.clip()` calls add audio clips to this track.
74
+ * @param name - Display name for the track
75
+ * @param binding - The AudioSource to play audio on (optional)
76
+ * @param volume - Track volume multiplier (default: 1)
77
+ */
78
+ audioTrack(name, binding, volume) {
79
+ this._currentTrack = this.pushTrack(name, TrackType.Audio, binding ?? null);
80
+ this._currentTrack.volume = volume;
81
+ return this;
82
+ }
83
+ /**
84
+ * Adds an activation track. Subsequent `.clip()` calls define when the bound object is active.
85
+ * @param name - Display name for the track
86
+ * @param binding - The Object3D to show/hide
87
+ */
88
+ activationTrack(name, binding) {
89
+ this._currentTrack = this.pushTrack(name, TrackType.Activation, binding ?? null);
90
+ return this;
91
+ }
92
+ /**
93
+ * Adds a control track. Subsequent `.clip()` calls control nested timelines or objects.
94
+ * @param name - Display name for the track
95
+ */
96
+ controlTrack(name) {
97
+ this._currentTrack = this.pushTrack(name, TrackType.Control, null);
98
+ return this;
99
+ }
100
+ /**
101
+ * Adds a signal track. Use `.signal()` or `.marker()` to add signal markers.
102
+ * @param name - Display name for the track
103
+ * @param binding - The SignalReceiver component (optional — if using `.signal()` with callbacks, one is created automatically by {@link install})
104
+ */
105
+ signalTrack(name, binding) {
106
+ this._currentTrack = this.pushTrack(name, TrackType.Signal, binding ?? null);
107
+ return this;
108
+ }
109
+ /**
110
+ * Adds a marker track. Use `.marker()` to add markers.
111
+ * @param name - Display name for the track
112
+ */
113
+ markerTrack(name) {
114
+ this._currentTrack = this.pushTrack(name, TrackType.Marker, null);
115
+ return this;
116
+ }
117
+ clip(assetOrOptions, options) {
118
+ if (!this._currentTrack)
119
+ throw new Error("TimelineBuilder: .clip() must be called after a track method (e.g. .animationTrack())");
120
+ const track = this._currentTrack;
121
+ switch (track.type) {
122
+ case TrackType.Animation: {
123
+ const animClip = assetOrOptions;
124
+ const opts = (options ?? {});
125
+ const duration = opts.duration ?? animClip.duration;
126
+ const start = opts.start ?? track.cursor;
127
+ const end = start + duration;
128
+ const clipModel = {
129
+ start,
130
+ end,
131
+ duration,
132
+ timeScale: opts.speed ?? 1,
133
+ clipIn: opts.clipIn ?? 0,
134
+ easeInDuration: opts.easeIn ?? 0,
135
+ easeOutDuration: opts.easeOut ?? 0,
136
+ preExtrapolationMode: opts.preExtrapolation ?? ClipExtrapolation.None,
137
+ postExtrapolationMode: opts.postExtrapolation ?? ClipExtrapolation.None,
138
+ reversed: opts.reversed,
139
+ asset: {
140
+ clip: animClip,
141
+ loop: opts.loop ?? false,
142
+ duration: animClip.duration,
143
+ removeStartOffset: opts.removeStartOffset ?? false,
144
+ },
145
+ };
146
+ track.clips.push(clipModel);
147
+ track.cursor = end;
148
+ break;
149
+ }
150
+ case TrackType.Audio: {
151
+ const url = assetOrOptions;
152
+ const opts = (options ?? {});
153
+ const duration = opts.duration;
154
+ const start = opts.start ?? track.cursor;
155
+ const end = start + duration;
156
+ const clipModel = {
157
+ start,
158
+ end,
159
+ duration,
160
+ timeScale: opts.speed ?? 1,
161
+ clipIn: 0,
162
+ easeInDuration: opts.easeIn ?? 0,
163
+ easeOutDuration: opts.easeOut ?? 0,
164
+ preExtrapolationMode: ClipExtrapolation.None,
165
+ postExtrapolationMode: ClipExtrapolation.None,
166
+ asset: {
167
+ clip: url,
168
+ loop: opts.loop ?? false,
169
+ volume: opts.volume ?? 1,
170
+ },
171
+ };
172
+ track.clips.push(clipModel);
173
+ track.cursor = end;
174
+ break;
175
+ }
176
+ case TrackType.Activation: {
177
+ const opts = assetOrOptions;
178
+ const start = opts.start ?? track.cursor;
179
+ const end = start + opts.duration;
180
+ const clipModel = {
181
+ start,
182
+ end,
183
+ duration: opts.duration,
184
+ timeScale: 1,
185
+ clipIn: 0,
186
+ easeInDuration: opts.easeIn ?? 0,
187
+ easeOutDuration: opts.easeOut ?? 0,
188
+ preExtrapolationMode: ClipExtrapolation.None,
189
+ postExtrapolationMode: ClipExtrapolation.None,
190
+ asset: {},
191
+ };
192
+ track.clips.push(clipModel);
193
+ track.cursor = end;
194
+ break;
195
+ }
196
+ case TrackType.Control: {
197
+ const sourceObject = assetOrOptions;
198
+ const opts = (options ?? {});
199
+ const start = opts.start ?? track.cursor;
200
+ const duration = opts.duration;
201
+ const end = start + duration;
202
+ const clipModel = {
203
+ start,
204
+ end,
205
+ duration,
206
+ timeScale: 1,
207
+ clipIn: 0,
208
+ easeInDuration: 0,
209
+ easeOutDuration: 0,
210
+ preExtrapolationMode: ClipExtrapolation.None,
211
+ postExtrapolationMode: ClipExtrapolation.None,
212
+ asset: {
213
+ sourceObject,
214
+ controlActivation: opts.controlActivation ?? true,
215
+ updateDirector: opts.updateDirector ?? true,
216
+ },
217
+ };
218
+ track.clips.push(clipModel);
219
+ track.cursor = end;
220
+ break;
221
+ }
222
+ default:
223
+ throw new Error(`TimelineBuilder: .clip() is not supported on track type "${track.type}"`);
224
+ }
225
+ return this;
226
+ }
227
+ /**
228
+ * Adds a signal marker to the current signal or marker track.
229
+ * @param time - Time in seconds when the signal fires
230
+ * @param asset - The signal asset identifier (guid string)
231
+ * @param options - Optional marker configuration
232
+ */
233
+ marker(time, asset, options) {
234
+ if (!this._currentTrack)
235
+ throw new Error("TimelineBuilder: .marker() must be called after a track method");
236
+ if (this._currentTrack.type !== TrackType.Signal && this._currentTrack.type !== TrackType.Marker) {
237
+ throw new Error(`TimelineBuilder: .marker() is only supported on signal and marker tracks, not "${this._currentTrack.type}"`);
238
+ }
239
+ const marker = {
240
+ type: MarkerType.Signal,
241
+ time,
242
+ retroActive: options?.retroActive ?? false,
243
+ emitOnce: options?.emitOnce ?? false,
244
+ asset,
245
+ };
246
+ this._currentTrack.markers.push(marker);
247
+ // Update cursor past the marker
248
+ if (time > this._currentTrack.cursor) {
249
+ this._currentTrack.cursor = time;
250
+ }
251
+ return this;
252
+ }
253
+ /**
254
+ * Adds a signal with a callback to the current signal track.
255
+ * This is a convenience method that automatically generates a signal asset guid,
256
+ * adds the marker, and registers the callback so that {@link install} can wire up
257
+ * the `SignalReceiver` on the director's GameObject.
258
+ *
259
+ * @param time - Time in seconds when the signal fires
260
+ * @param callback - The function to invoke when the signal fires
261
+ * @param options - Optional marker configuration
262
+ *
263
+ * @example
264
+ * ```ts
265
+ * const timeline = TimelineBuilder.create("Sequence")
266
+ * .signalTrack("Events")
267
+ * .signal(1.0, () => console.log("1 second reached!"))
268
+ * .signal(3.5, () => console.log("halfway!"), { emitOnce: true })
269
+ * .install(director);
270
+ * ```
271
+ */
272
+ signal(time, callback, options) {
273
+ if (!this._currentTrack)
274
+ throw new Error("TimelineBuilder: .signal() must be called after a track method");
275
+ if (this._currentTrack.type !== TrackType.Signal && this._currentTrack.type !== TrackType.Marker) {
276
+ throw new Error(`TimelineBuilder: .signal() is only supported on signal and marker tracks, not "${this._currentTrack.type}"`);
277
+ }
278
+ const guid = this._idProvider.generateUUID();
279
+ const trackIndex = this._tracks.indexOf(this._currentTrack);
280
+ // Add the marker with the generated guid
281
+ const marker = {
282
+ type: MarkerType.Signal,
283
+ time,
284
+ retroActive: options?.retroActive ?? false,
285
+ emitOnce: options?.emitOnce ?? false,
286
+ asset: guid,
287
+ };
288
+ this._currentTrack.markers.push(marker);
289
+ // Store the pending signal for wiring during install()
290
+ this._pendingSignals.push({ trackIndex, guid, callback });
291
+ if (time > this._currentTrack.cursor) {
292
+ this._currentTrack.cursor = time;
293
+ }
294
+ return this;
295
+ }
296
+ /**
297
+ * Mutes the current track so it is skipped during playback.
298
+ */
299
+ muted(muted = true) {
300
+ if (!this._currentTrack)
301
+ throw new Error("TimelineBuilder: .muted() must be called after a track method");
302
+ this._currentTrack.muted = muted;
303
+ return this;
304
+ }
305
+ // #endregion
306
+ /**
307
+ * Builds and returns the {@link TimelineAssetModel}.
308
+ * Assign the result to `PlayableDirector.playableAsset` to play it.
309
+ *
310
+ * If you used `.signal()` with callbacks, use {@link install} instead — it calls `build()`
311
+ * internally and also wires up the SignalReceiver on the director's GameObject.
312
+ */
313
+ build() {
314
+ const tracks = this._tracks.map(t => {
315
+ const track = {
316
+ name: t.name,
317
+ type: t.type,
318
+ muted: t.muted,
319
+ outputs: t.outputs,
320
+ };
321
+ if (t.clips.length > 0)
322
+ track.clips = t.clips;
323
+ if (t.markers.length > 0)
324
+ track.markers = t.markers;
325
+ if (t.volume !== undefined)
326
+ track.volume = t.volume;
327
+ if (t.trackOffset !== undefined)
328
+ track.trackOffset = t.trackOffset;
329
+ return track;
330
+ });
331
+ return {
332
+ name: this._name,
333
+ tracks,
334
+ };
335
+ }
336
+ /**
337
+ * Builds the timeline asset, assigns it to the director, and wires up any
338
+ * `.signal()` callbacks by creating/configuring a {@link SignalReceiver} on the
339
+ * director's GameObject.
340
+ *
341
+ * @param director - The PlayableDirector to install the timeline on
342
+ * @returns The built TimelineAssetModel (also assigned to `director.playableAsset`)
343
+ *
344
+ * @example
345
+ * ```ts
346
+ * TimelineBuilder.create("MyTimeline")
347
+ * .animationTrack("Anim", animator)
348
+ * .clip(walkClip, { duration: 2 })
349
+ * .signalTrack("Events")
350
+ * .signal(1.0, () => console.log("signal fired!"))
351
+ * .install(director);
352
+ *
353
+ * director.play();
354
+ * ```
355
+ */
356
+ install(director) {
357
+ const asset = this.build();
358
+ // Wire up signal callbacks
359
+ if (this._pendingSignals.length > 0) {
360
+ const obj = director.gameObject;
361
+ let receiver = GameObject.getComponent(obj, SignalReceiver);
362
+ if (!receiver) {
363
+ receiver = GameObject.addComponent(obj, SignalReceiver);
364
+ }
365
+ if (!receiver.events) {
366
+ receiver.events = [];
367
+ }
368
+ for (const pending of this._pendingSignals) {
369
+ const signalAsset = new SignalAsset();
370
+ signalAsset.guid = pending.guid;
371
+ const evt = new SignalReceiverEvent();
372
+ evt.signal = signalAsset;
373
+ evt.reaction = new EventList([pending.callback]);
374
+ receiver.events.push(evt);
375
+ // Wire the receiver as the output binding for the signal track
376
+ const track = asset.tracks[pending.trackIndex];
377
+ if (track && !track.outputs.includes(receiver)) {
378
+ track.outputs.push(receiver);
379
+ }
380
+ }
381
+ }
382
+ director.playableAsset = asset;
383
+ return asset;
384
+ }
385
+ // #region Private helpers
386
+ pushTrack(name, type, binding) {
387
+ const track = {
388
+ name,
389
+ type,
390
+ muted: false,
391
+ outputs: binding ? [binding] : [],
392
+ clips: [],
393
+ markers: [],
394
+ cursor: 0,
395
+ };
396
+ this._tracks.push(track);
397
+ return track;
398
+ }
399
+ }
400
+ //# sourceMappingURL=TimelineBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TimelineBuilder.js","sourceRoot":"","sources":["../../../src/engine-components/timeline/TimelineBuilder.ts"],"names":[],"mappings":"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"}
@@ -36,7 +36,7 @@ export declare enum ClipExtrapolation {
36
36
  * @category Animation and Sequencing
37
37
  * @see {@link PlayableDirector} for the main component to control timelines in Needle Engine.
38
38
  */
39
- export declare type TrackModel = {
39
+ export type TrackModel = {
40
40
  name: string;
41
41
  type: TrackType;
42
42
  muted: boolean;
@@ -46,6 +46,7 @@ export declare type TrackModel = {
46
46
  trackOffset?: TrackOffset;
47
47
  volume?: number;
48
48
  };
49
+ export declare function isTrackModel(obj: unknown): obj is TrackModel;
49
50
  declare type Vec3 = {
50
51
  x: number;
51
52
  y: number;