@needle-tools/engine 5.1.0-canary.c111c4f → 5.1.0-canary.cce79c8

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 (294) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/components.needle.json +1 -1
  3. package/dist/needle-engine.bundle-B1w7P037.min.js +1733 -0
  4. package/dist/needle-engine.bundle-C4w-9vec.umd.cjs +1733 -0
  5. package/dist/{needle-engine.bundle-BuaGvme0.js → needle-engine.bundle-CPbnC8NP.js} +15153 -14701
  6. package/dist/needle-engine.d.ts +898 -271
  7. package/dist/needle-engine.js +584 -582
  8. package/dist/needle-engine.min.js +1 -1
  9. package/dist/needle-engine.umd.cjs +1 -1
  10. package/dist/three-examples.js +3778 -4289
  11. package/dist/three-examples.min.js +14 -301
  12. package/dist/three-examples.umd.cjs +14 -301
  13. package/lib/engine/api.d.ts +5 -0
  14. package/lib/engine/api.js +4 -0
  15. package/lib/engine/api.js.map +1 -1
  16. package/lib/engine/codegen/register_types.js +2 -10
  17. package/lib/engine/codegen/register_types.js.map +1 -1
  18. package/lib/engine/debug/debug_spatial_console.d.ts +2 -0
  19. package/lib/engine/debug/debug_spatial_console.js +10 -7
  20. package/lib/engine/debug/debug_spatial_console.js.map +1 -1
  21. package/lib/engine/engine_addressables.d.ts +2 -0
  22. package/lib/engine/engine_addressables.js +6 -3
  23. package/lib/engine/engine_addressables.js.map +1 -1
  24. package/lib/engine/engine_audio.d.ts +68 -0
  25. package/lib/engine/engine_audio.js +172 -0
  26. package/lib/engine/engine_audio.js.map +1 -1
  27. package/lib/engine/engine_components.js +1 -1
  28. package/lib/engine/engine_components.js.map +1 -1
  29. package/lib/engine/engine_context.d.ts +17 -20
  30. package/lib/engine/engine_context.js +15 -17
  31. package/lib/engine/engine_context.js.map +1 -1
  32. package/lib/engine/engine_disposable.d.ts +172 -0
  33. package/lib/engine/engine_disposable.js +136 -0
  34. package/lib/engine/engine_disposable.js.map +1 -0
  35. package/lib/engine/engine_gameobject.d.ts +1 -10
  36. package/lib/engine/engine_gameobject.js +22 -120
  37. package/lib/engine/engine_gameobject.js.map +1 -1
  38. package/lib/engine/engine_gltf_builtin_components.js +7 -69
  39. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  40. package/lib/engine/engine_init.js +13 -3
  41. package/lib/engine/engine_init.js.map +1 -1
  42. package/lib/engine/engine_input.d.ts +1 -1
  43. package/lib/engine/engine_input.js +1 -1
  44. package/lib/engine/engine_input.js.map +1 -1
  45. package/lib/engine/engine_instantiate_resolve.d.ts +42 -0
  46. package/lib/engine/engine_instantiate_resolve.js +372 -0
  47. package/lib/engine/engine_instantiate_resolve.js.map +1 -0
  48. package/lib/engine/engine_license.js +1 -1
  49. package/lib/engine/engine_license.js.map +1 -1
  50. package/lib/engine/engine_mainloop_utils.js +7 -4
  51. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  52. package/lib/engine/engine_networking.d.ts +51 -37
  53. package/lib/engine/engine_networking.js +132 -82
  54. package/lib/engine/engine_networking.js.map +1 -1
  55. package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
  56. package/lib/engine/engine_networking.transport.websocket.js +38 -0
  57. package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
  58. package/lib/engine/engine_networking_blob.js +1 -1
  59. package/lib/engine/engine_networking_blob.js.map +1 -1
  60. package/lib/engine/engine_networking_instantiate.js +2 -2
  61. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  62. package/lib/engine/engine_networking_types.d.ts +39 -1
  63. package/lib/engine/engine_networking_types.js +7 -0
  64. package/lib/engine/engine_networking_types.js.map +1 -1
  65. package/lib/engine/engine_physics_rapier.d.ts +11 -3
  66. package/lib/engine/engine_physics_rapier.js +88 -25
  67. package/lib/engine/engine_physics_rapier.js.map +1 -1
  68. package/lib/engine/engine_scenedata.d.ts +5 -7
  69. package/lib/engine/engine_scenedata.js +16 -13
  70. package/lib/engine/engine_scenedata.js.map +1 -1
  71. package/lib/engine/engine_serialization_builtin_serializer.d.ts +10 -16
  72. package/lib/engine/engine_serialization_builtin_serializer.js +56 -46
  73. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  74. package/lib/engine/engine_serialization_core.d.ts +1 -0
  75. package/lib/engine/engine_serialization_core.js +7 -0
  76. package/lib/engine/engine_serialization_core.js.map +1 -1
  77. package/lib/engine/engine_types.d.ts +19 -11
  78. package/lib/engine/engine_types.js +1 -1
  79. package/lib/engine/engine_types.js.map +1 -1
  80. package/lib/engine/engine_util_decorator.js +7 -2
  81. package/lib/engine/engine_util_decorator.js.map +1 -1
  82. package/lib/engine/engine_utils.d.ts +1 -1
  83. package/lib/engine/engine_utils.js +19 -5
  84. package/lib/engine/engine_utils.js.map +1 -1
  85. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  86. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
  87. package/lib/engine/webcomponents/jsx.d.ts +51 -0
  88. package/lib/engine/webcomponents/logo-element.js.map +1 -1
  89. package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +3 -4
  90. package/lib/engine/webcomponents/needle menu/needle-menu.js +1 -1
  91. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  92. package/lib/engine/webcomponents/needle-button.js.map +1 -1
  93. package/lib/engine/webcomponents/needle-engine.d.ts +10 -4
  94. package/lib/engine/webcomponents/needle-engine.js +1 -1
  95. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  96. package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
  97. package/lib/engine/xr/NeedleXRSession.js +50 -14
  98. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  99. package/lib/engine/xr/events.d.ts +1 -1
  100. package/lib/engine/xr/events.js.map +1 -1
  101. package/lib/engine-components/Animation.js +17 -16
  102. package/lib/engine-components/Animation.js.map +1 -1
  103. package/lib/engine-components/Animator.d.ts +6 -0
  104. package/lib/engine-components/Animator.js +17 -12
  105. package/lib/engine-components/Animator.js.map +1 -1
  106. package/lib/engine-components/AnimatorController.builder.d.ts +113 -0
  107. package/lib/engine-components/AnimatorController.builder.js +195 -0
  108. package/lib/engine-components/AnimatorController.builder.js.map +1 -0
  109. package/lib/engine-components/AnimatorController.d.ts +4 -119
  110. package/lib/engine-components/AnimatorController.js +35 -233
  111. package/lib/engine-components/AnimatorController.js.map +1 -1
  112. package/lib/engine-components/AudioSource.d.ts +19 -3
  113. package/lib/engine-components/AudioSource.js +121 -68
  114. package/lib/engine-components/AudioSource.js.map +1 -1
  115. package/lib/engine-components/Collider.d.ts +18 -9
  116. package/lib/engine-components/Collider.js +61 -14
  117. package/lib/engine-components/Collider.js.map +1 -1
  118. package/lib/engine-components/Component.d.ts +72 -9
  119. package/lib/engine-components/Component.js +114 -10
  120. package/lib/engine-components/Component.js.map +1 -1
  121. package/lib/engine-components/DragControls.d.ts +7 -0
  122. package/lib/engine-components/DragControls.js +19 -7
  123. package/lib/engine-components/DragControls.js.map +1 -1
  124. package/lib/engine-components/EventList.d.ts +31 -9
  125. package/lib/engine-components/EventList.js +37 -76
  126. package/lib/engine-components/EventList.js.map +1 -1
  127. package/lib/engine-components/Joints.d.ts +4 -2
  128. package/lib/engine-components/Joints.js +19 -3
  129. package/lib/engine-components/Joints.js.map +1 -1
  130. package/lib/engine-components/Light.d.ts +0 -19
  131. package/lib/engine-components/Light.js +13 -97
  132. package/lib/engine-components/Light.js.map +1 -1
  133. package/lib/engine-components/Networking.d.ts +1 -1
  134. package/lib/engine-components/Networking.js +1 -1
  135. package/lib/engine-components/OrbitControls.js +16 -11
  136. package/lib/engine-components/OrbitControls.js.map +1 -1
  137. package/lib/engine-components/ReflectionProbe.js +2 -0
  138. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  139. package/lib/engine-components/RigidBody.d.ts +12 -4
  140. package/lib/engine-components/RigidBody.js +18 -4
  141. package/lib/engine-components/RigidBody.js.map +1 -1
  142. package/lib/engine-components/SeeThrough.js +2 -2
  143. package/lib/engine-components/SeeThrough.js.map +1 -1
  144. package/lib/engine-components/api.d.ts +1 -1
  145. package/lib/engine-components/api.js +1 -1
  146. package/lib/engine-components/api.js.map +1 -1
  147. package/lib/engine-components/codegen/components.d.ts +3 -9
  148. package/lib/engine-components/codegen/components.js +3 -9
  149. package/lib/engine-components/codegen/components.js.map +1 -1
  150. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
  151. package/lib/engine-components/postprocessing/VolumeParameter.d.ts +2 -0
  152. package/lib/engine-components/postprocessing/VolumeParameter.js +4 -1
  153. package/lib/engine-components/postprocessing/VolumeParameter.js.map +1 -1
  154. package/lib/engine-components/timeline/PlayableDirector.d.ts +16 -6
  155. package/lib/engine-components/timeline/PlayableDirector.js +63 -61
  156. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  157. package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
  158. package/lib/engine-components/timeline/SignalAsset.js +1 -0
  159. package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
  160. package/lib/engine-components/timeline/TimelineBuilder.d.ts +247 -0
  161. package/lib/engine-components/timeline/TimelineBuilder.js +400 -0
  162. package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
  163. package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
  164. package/lib/engine-components/timeline/TimelineModels.js +3 -0
  165. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  166. package/lib/engine-components/timeline/TimelineTracks.d.ts +23 -0
  167. package/lib/engine-components/timeline/TimelineTracks.js +71 -13
  168. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  169. package/lib/engine-components/timeline/index.d.ts +2 -1
  170. package/lib/engine-components/timeline/index.js +2 -0
  171. package/lib/engine-components/timeline/index.js.map +1 -1
  172. package/lib/engine-components/ui/Canvas.d.ts +1 -1
  173. package/lib/engine-components/ui/Canvas.js +2 -8
  174. package/lib/engine-components/ui/Canvas.js.map +1 -1
  175. package/lib/engine-components/ui/Text.d.ts +1 -0
  176. package/lib/engine-components/ui/Text.js +10 -7
  177. package/lib/engine-components/ui/Text.js.map +1 -1
  178. package/lib/engine-components/web/CursorFollow.js +21 -12
  179. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  180. package/lib/engine-components/webxr/WebXRImageTracking.js +4 -0
  181. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  182. package/lib/needle-engine.d.ts +2 -0
  183. package/lib/needle-engine.js +1 -0
  184. package/lib/needle-engine.js.map +1 -1
  185. package/package.json +2 -83
  186. package/plugins/common/license.js +5 -2
  187. package/plugins/common/worker.js +9 -4
  188. package/plugins/dts-generator/dts.codegen.js +12 -6
  189. package/plugins/dts-generator/dts.writer.js +1 -1
  190. package/plugins/dts-generator/glb.extractor.js +12 -1
  191. package/plugins/dts-generator/glb.reader.js +42 -33
  192. package/plugins/types/userconfig.d.ts +12 -0
  193. package/plugins/vite/asap.js +17 -8
  194. package/plugins/vite/dependencies.js +29 -10
  195. package/plugins/vite/dependency-watcher.js +2 -2
  196. package/plugins/vite/dts-generator.d.ts +2 -2
  197. package/plugins/vite/dts-generator.js +6 -1
  198. package/plugins/vite/editor-connection.js +3 -3
  199. package/plugins/vite/local-files-core.js +3 -3
  200. package/plugins/vite/local-files-utils.d.ts +3 -1
  201. package/plugins/vite/local-files-utils.js +29 -5
  202. package/plugins/vite/reload.js +19 -18
  203. package/plugins/vite/server.js +2 -1
  204. package/src/engine/api.ts +7 -0
  205. package/src/engine/codegen/register_types.ts +2 -10
  206. package/src/engine/debug/debug_spatial_console.ts +10 -7
  207. package/src/engine/engine_addressables.ts +6 -3
  208. package/src/engine/engine_audio.ts +184 -0
  209. package/src/engine/engine_components.ts +1 -1
  210. package/src/engine/engine_context.ts +22 -23
  211. package/src/engine/engine_disposable.ts +214 -0
  212. package/src/engine/engine_gameobject.ts +54 -159
  213. package/src/engine/engine_gltf_builtin_components.ts +7 -76
  214. package/src/engine/engine_init.ts +13 -3
  215. package/src/engine/engine_input.ts +1 -1
  216. package/src/engine/engine_instantiate_resolve.ts +407 -0
  217. package/src/engine/engine_license.ts +1 -1
  218. package/src/engine/engine_mainloop_utils.ts +7 -4
  219. package/src/engine/engine_networking.transport.websocket.ts +45 -0
  220. package/src/engine/engine_networking.ts +161 -137
  221. package/src/engine/engine_networking_blob.ts +1 -1
  222. package/src/engine/engine_networking_instantiate.ts +2 -2
  223. package/src/engine/engine_networking_types.ts +41 -1
  224. package/src/engine/engine_physics_rapier.ts +82 -27
  225. package/src/engine/engine_scenedata.ts +16 -13
  226. package/src/engine/engine_serialization_builtin_serializer.ts +64 -52
  227. package/src/engine/engine_serialization_core.ts +9 -0
  228. package/src/engine/engine_types.ts +24 -15
  229. package/src/engine/engine_util_decorator.ts +7 -2
  230. package/src/engine/engine_utils.ts +16 -5
  231. package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  232. package/src/engine/webcomponents/jsx.d.ts +51 -0
  233. package/src/engine/webcomponents/logo-element.ts +1 -0
  234. package/src/engine/webcomponents/needle menu/needle-menu.ts +3 -2
  235. package/src/engine/webcomponents/needle-button.ts +1 -0
  236. package/src/engine/webcomponents/needle-engine.ts +11 -4
  237. package/src/engine/xr/NeedleXRSession.ts +48 -13
  238. package/src/engine/xr/events.ts +1 -1
  239. package/src/engine-components/Animation.ts +19 -16
  240. package/src/engine-components/Animator.ts +18 -11
  241. package/src/engine-components/AnimatorController.builder.ts +261 -0
  242. package/src/engine-components/AnimatorController.ts +23 -292
  243. package/src/engine-components/AudioSource.ts +130 -79
  244. package/src/engine-components/Collider.ts +66 -18
  245. package/src/engine-components/Component.ts +118 -20
  246. package/src/engine-components/DragControls.ts +18 -11
  247. package/src/engine-components/EventList.ts +45 -83
  248. package/src/engine-components/Joints.ts +20 -4
  249. package/src/engine-components/Light.ts +13 -96
  250. package/src/engine-components/Networking.ts +1 -1
  251. package/src/engine-components/OrbitControls.ts +18 -9
  252. package/src/engine-components/ReflectionProbe.ts +2 -0
  253. package/src/engine-components/RigidBody.ts +18 -4
  254. package/src/engine-components/SeeThrough.ts +2 -2
  255. package/src/engine-components/api.ts +1 -1
  256. package/src/engine-components/codegen/components.ts +3 -9
  257. package/src/engine-components/postprocessing/VolumeParameter.ts +4 -1
  258. package/src/engine-components/timeline/PlayableDirector.ts +61 -64
  259. package/src/engine-components/timeline/SignalAsset.ts +4 -1
  260. package/src/engine-components/timeline/TimelineBuilder.ts +565 -0
  261. package/src/engine-components/timeline/TimelineModels.ts +5 -1
  262. package/src/engine-components/timeline/TimelineTracks.ts +74 -13
  263. package/src/engine-components/timeline/index.ts +2 -1
  264. package/src/engine-components/ui/Canvas.ts +2 -8
  265. package/src/engine-components/ui/Text.ts +12 -8
  266. package/src/engine-components/web/CursorFollow.ts +21 -13
  267. package/src/engine-components/webxr/WebXRImageTracking.ts +2 -0
  268. package/src/needle-engine.ts +1 -0
  269. package/dist/needle-engine.bundle-CayCdkzK.min.js +0 -1732
  270. package/dist/needle-engine.bundle-DVhVGqQR.umd.cjs +0 -1732
  271. package/lib/engine-components/AvatarLoader.d.ts +0 -80
  272. package/lib/engine-components/AvatarLoader.js +0 -232
  273. package/lib/engine-components/AvatarLoader.js.map +0 -1
  274. package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
  275. package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
  276. package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
  277. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
  278. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
  279. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
  280. package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
  281. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
  282. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
  283. package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
  284. package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
  285. package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
  286. package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
  287. package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
  288. package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
  289. package/src/engine-components/AvatarLoader.ts +0 -264
  290. package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
  291. package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
  292. package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
  293. package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
  294. package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
@@ -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;
@@ -26,6 +26,9 @@ export var ClipExtrapolation;
26
26
  ClipExtrapolation[ClipExtrapolation["Continue"] = 4] = "Continue";
27
27
  })(ClipExtrapolation || (ClipExtrapolation = {}));
28
28
  ;
29
+ export function isTrackModel(obj) {
30
+ return typeof obj === "object" && obj !== null && "name" in obj && "type" in obj && "outputs" in obj && "muted" in obj;
31
+ }
29
32
  export var MarkerType;
30
33
  (function (MarkerType) {
31
34
  MarkerType["Signal"] = "SignalEmitter";
@@ -1 +1 @@
1
- {"version":3,"file":"TimelineModels.js","sourceRoot":"","sources":["../../../src/engine-components/timeline/TimelineModels.ts"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,MAAM,CAAN,IAAY,SAOX;AAPD,WAAY,SAAS;IACjB,2CAA8B,CAAA;IAC9B,yCAA4B,CAAA;IAC5B,iCAAoB,CAAA;IACpB,qCAAwB,CAAA;IACxB,mCAAsB,CAAA;IACtB,mCAAsB,CAAA;AAC1B,CAAC,EAPW,SAAS,KAAT,SAAS,QAOpB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,iBAMX;AAND,WAAY,iBAAiB;IACzB,yDAAQ,CAAA;IACR,yDAAQ,CAAA;IACR,yDAAQ,CAAA;IACR,iEAAY,CAAA;IACZ,iEAAY,CAAA;AAChB,CAAC,EANW,iBAAiB,KAAjB,iBAAiB,QAM5B;AAAA,CAAC;AAgFF,MAAM,CAAN,IAAY,UAEX;AAFD,WAAY,UAAU;IAClB,sCAAwB,CAAA;AAC5B,CAAC,EAFW,UAAU,KAAV,UAAU,QAErB"}
1
+ {"version":3,"file":"TimelineModels.js","sourceRoot":"","sources":["../../../src/engine-components/timeline/TimelineModels.ts"],"names":[],"mappings":"AAaA;;;;GAIG;AACH,MAAM,CAAN,IAAY,SAOX;AAPD,WAAY,SAAS;IACjB,2CAA8B,CAAA;IAC9B,yCAA4B,CAAA;IAC5B,iCAAoB,CAAA;IACpB,qCAAwB,CAAA;IACxB,mCAAsB,CAAA;IACtB,mCAAsB,CAAA;AAC1B,CAAC,EAPW,SAAS,KAAT,SAAS,QAOpB;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,iBAMX;AAND,WAAY,iBAAiB;IACzB,yDAAQ,CAAA;IACR,yDAAQ,CAAA;IACR,yDAAQ,CAAA;IACR,iEAAY,CAAA;IACZ,iEAAY,CAAA;AAChB,CAAC,EANW,iBAAiB,KAAjB,iBAAiB,QAM5B;AAAA,CAAC;AAiBF,MAAM,UAAU,YAAY,CAAC,GAAW;IACpC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC;AAC3H,CAAC;AAiED,MAAM,CAAN,IAAY,UAEX;AAFD,WAAY,UAAU;IAClB,sCAAwB,CAAA;AAC5B,CAAC,EAFW,UAAU,KAAV,UAAU,QAErB"}
@@ -69,6 +69,20 @@ export declare class AnimationTrackHandler extends TrackHandler {
69
69
  declare type AudioClipModel = Models.ClipModel & {
70
70
  _didTriggerPlay: boolean;
71
71
  };
72
+ /**
73
+ * Handles audio playback for a timeline audio track.
74
+ *
75
+ * **Runtime mutation:** The track model is read fresh every frame during `evaluate()`.
76
+ * You can mutate `track.volume`, `clip.start`, `clip.end`, `clip.asset.volume` etc.
77
+ * at any time — changes take effect on the next frame without rebuilding the timeline.
78
+ *
79
+ * **Audio stopping:** Audio clips are automatically stopped when:
80
+ * - Timeline time moves outside a clip's `[start, end]` range (e.g. jumping or normal playback advancing past a clip)
81
+ * - The track is muted (via `muted = true`)
82
+ * - The director is stopped (`director.stop()`)
83
+ * - The director is paused (`director.pause()`)
84
+ * - The director is disabled or destroyed
85
+ */
72
86
  export declare class AudioTrackHandler extends TrackHandler {
73
87
  models: Array<AudioClipModel>;
74
88
  listener: AudioListener;
@@ -76,6 +90,9 @@ export declare class AudioTrackHandler extends TrackHandler {
76
90
  audioContextTimeOffset: Array<number>;
77
91
  lastTime: number;
78
92
  audioSource?: AudioSource;
93
+ /** Track-level volume multiplier (0–1). Applied on top of per-clip volume each frame. */
94
+ get volume(): number;
95
+ set volume(val: number);
79
96
  private _audioLoader;
80
97
  private getAudioFilePath;
81
98
  onAllowAudioChanged(allow: boolean): void;
@@ -106,6 +123,12 @@ export declare class SignalTrackHandler extends TrackHandler {
106
123
  models: Models.SignalMarkerModel[];
107
124
  didTrigger: boolean[];
108
125
  receivers: Array<SignalReceiver | null>;
126
+ private _lastTime;
127
+ onEnable(): void;
128
+ onMuteChanged(): void;
129
+ evaluate(time: number): void;
130
+ }
131
+ export declare class ActivationTrackHandler extends TrackHandler {
109
132
  evaluate(time: number): void;
110
133
  }
111
134
  export declare class ControlTrackHandler extends TrackHandler {
@@ -525,6 +525,20 @@ export class AnimationTrackHandler extends TrackHandler {
525
525
  }
526
526
  }
527
527
  const muteAudioTracks = getParam("mutetimeline");
528
+ /**
529
+ * Handles audio playback for a timeline audio track.
530
+ *
531
+ * **Runtime mutation:** The track model is read fresh every frame during `evaluate()`.
532
+ * You can mutate `track.volume`, `clip.start`, `clip.end`, `clip.asset.volume` etc.
533
+ * at any time — changes take effect on the next frame without rebuilding the timeline.
534
+ *
535
+ * **Audio stopping:** Audio clips are automatically stopped when:
536
+ * - Timeline time moves outside a clip's `[start, end]` range (e.g. jumping or normal playback advancing past a clip)
537
+ * - The track is muted (via `muted = true`)
538
+ * - The director is stopped (`director.stop()`)
539
+ * - The director is paused (`director.pause()`)
540
+ * - The director is disabled or destroyed
541
+ */
528
542
  export class AudioTrackHandler extends TrackHandler {
529
543
  models = [];
530
544
  listener;
@@ -532,6 +546,9 @@ export class AudioTrackHandler extends TrackHandler {
532
546
  audioContextTimeOffset = [];
533
547
  lastTime = 0;
534
548
  audioSource;
549
+ /** Track-level volume multiplier (0–1). Applied on top of per-clip volume each frame. */
550
+ get volume() { return this.track.volume ?? 1; }
551
+ set volume(val) { this.track.volume = val; }
535
552
  _audioLoader = null;
536
553
  getAudioFilePath(path) {
537
554
  // TODO: this should be the timeline asset location probably which MIGHT be different
@@ -781,19 +798,27 @@ export class SignalTrackHandler extends TrackHandler {
781
798
  models = [];
782
799
  didTrigger = [];
783
800
  receivers = [];
784
- // TODO: test when timeline signals are being reset in Unity
785
- // onEnable() {
786
- // for (let i = 0; i < this.didTrigger?.length; i++) {
787
- // this.didTrigger[i] = false;
788
- // }
789
- // }
790
- // private _lastTime: number = -1;
801
+ _lastTime = -1;
802
+ onEnable() {
803
+ // Reset state so signals fire fresh on replay
804
+ this._lastTime = -1;
805
+ for (let i = 0; i < this.didTrigger.length; i++) {
806
+ this.didTrigger[i] = false;
807
+ }
808
+ }
809
+ onMuteChanged() {
810
+ // When unmuted, sync _lastTime to avoid stale comparisons
811
+ if (!this.track.muted) {
812
+ this._lastTime = -1;
813
+ }
814
+ }
791
815
  evaluate(time) {
792
816
  if (this.track.muted)
793
817
  return;
794
- // let lastTime = this._lastTime;
795
- // if (lastTime === -1) lastTime = time;
796
- // this._lastTime = time;
818
+ let lastTime = this._lastTime;
819
+ if (lastTime === -1)
820
+ lastTime = time;
821
+ this._lastTime = time;
797
822
  const estimatedFrameLengthWithPadding = this.director.context.time.deltaTime * 1.5;
798
823
  for (let i = 0; i < this.models.length; i++) {
799
824
  const model = this.models[i];
@@ -813,7 +838,6 @@ export class SignalTrackHandler extends TrackHandler {
813
838
  isActive = true;
814
839
  }
815
840
  }
816
- // console.log(time, td, isActive);
817
841
  if (isActive) {
818
842
  if (!wasTriggered) {
819
843
  if (debug)
@@ -832,9 +856,43 @@ export class SignalTrackHandler extends TrackHandler {
832
856
  }
833
857
  }
834
858
  }
835
- else {
836
- if (!model.emitOnce)
859
+ else if (!model.emitOnce) {
860
+ // Only reset didTrigger when time has moved backward past the signal
861
+ // (e.g. timeline looped or was scrubbed back). Don't reset just because
862
+ // the deltaTime-based activation window shrank on a fast frame.
863
+ if (time < model.time && lastTime >= model.time) {
837
864
  this.didTrigger[i] = false;
865
+ }
866
+ }
867
+ }
868
+ }
869
+ }
870
+ export class ActivationTrackHandler extends TrackHandler {
871
+ evaluate(time) {
872
+ if (this.track.muted)
873
+ return;
874
+ // NE-3241 / NE-3737: Don't evaluate when stopped (preserves "Leave as is" post-playback).
875
+ // But DO evaluate if the user explicitly called director.evaluate().
876
+ if (!this.director.isPlaying && !this.director._isUserEvaluation)
877
+ return;
878
+ for (let i = 0; i < this.track.outputs.length; i++) {
879
+ const binding = this.track.outputs[i];
880
+ if (typeof binding !== "object" || binding === null)
881
+ continue;
882
+ let isActive = false;
883
+ if (this.track.clips) {
884
+ for (const clip of this.track.clips) {
885
+ if (clip.start <= time && time <= clip.end) {
886
+ isActive = true;
887
+ break;
888
+ }
889
+ }
890
+ }
891
+ const obj = binding;
892
+ if (obj.visible !== undefined && obj.visible !== isActive) {
893
+ obj.visible = isActive;
894
+ if (debug)
895
+ console.warn(this.director.name, "ActivationTrack-" + i, obj.name, isActive, time);
838
896
  }
839
897
  }
840
898
  }