@needle-tools/engine 5.1.0-canary.fbdfce3 → 5.1.0-experimental.03e8105

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 (311) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/SKILL.md +4 -1
  3. package/components.needle.json +1 -1
  4. package/dist/{needle-engine.bundle-BFSj2Fz8.js → needle-engine.bundle-BNqUjnSQ.js} +19180 -18386
  5. package/dist/needle-engine.bundle-Bt8ULD7E.umd.cjs +1733 -0
  6. package/dist/needle-engine.bundle-DF6ovbwD.min.js +1733 -0
  7. package/dist/needle-engine.d.ts +1487 -356
  8. package/dist/needle-engine.js +544 -542
  9. package/dist/needle-engine.min.js +1 -1
  10. package/dist/needle-engine.umd.cjs +1 -1
  11. package/dist/three.js +1 -0
  12. package/dist/three.min.js +21 -21
  13. package/dist/three.umd.cjs +16 -16
  14. package/lib/engine/api.d.ts +8 -1
  15. package/lib/engine/api.js +7 -1
  16. package/lib/engine/api.js.map +1 -1
  17. package/lib/engine/codegen/register_types.js +10 -18
  18. package/lib/engine/codegen/register_types.js.map +1 -1
  19. package/lib/engine/engine_audio.d.ts +68 -0
  20. package/lib/engine/engine_audio.js +172 -0
  21. package/lib/engine/engine_audio.js.map +1 -1
  22. package/lib/engine/engine_camera.fit.js +16 -4
  23. package/lib/engine/engine_camera.fit.js.map +1 -1
  24. package/lib/engine/engine_components.js +1 -1
  25. package/lib/engine/engine_components.js.map +1 -1
  26. package/lib/engine/engine_context.d.ts +21 -8
  27. package/lib/engine/engine_context.js +32 -16
  28. package/lib/engine/engine_context.js.map +1 -1
  29. package/lib/engine/engine_context_eventbus.d.ts +47 -0
  30. package/lib/engine/engine_context_eventbus.js +47 -0
  31. package/lib/engine/engine_context_eventbus.js.map +1 -0
  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 +7 -7
  41. package/lib/engine/engine_init.js.map +1 -1
  42. package/lib/engine/engine_input.d.ts +24 -5
  43. package/lib/engine/engine_input.js +3 -2
  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.d.ts +7 -7
  49. package/lib/engine/engine_license.js +183 -57
  50. package/lib/engine/engine_license.js.map +1 -1
  51. package/lib/engine/engine_mainloop_utils.js +7 -4
  52. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  53. package/lib/engine/engine_networking.d.ts +51 -37
  54. package/lib/engine/engine_networking.js +132 -82
  55. package/lib/engine/engine_networking.js.map +1 -1
  56. package/lib/engine/engine_networking.transport.websocket.d.ts +15 -0
  57. package/lib/engine/engine_networking.transport.websocket.js +38 -0
  58. package/lib/engine/engine_networking.transport.websocket.js.map +1 -0
  59. package/lib/engine/engine_networking_blob.js +4 -4
  60. package/lib/engine/engine_networking_blob.js.map +1 -1
  61. package/lib/engine/engine_networking_instantiate.js +2 -2
  62. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  63. package/lib/engine/engine_networking_types.d.ts +39 -1
  64. package/lib/engine/engine_networking_types.js +7 -0
  65. package/lib/engine/engine_networking_types.js.map +1 -1
  66. package/lib/engine/engine_physics_rapier.d.ts +21 -3
  67. package/lib/engine/engine_physics_rapier.js +94 -25
  68. package/lib/engine/engine_physics_rapier.js.map +1 -1
  69. package/lib/engine/engine_scenedata.js +2 -2
  70. package/lib/engine/engine_scenedata.js.map +1 -1
  71. package/lib/engine/engine_serialization_builtin_serializer.js +28 -5
  72. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  73. package/lib/engine/engine_serialization_core.d.ts +1 -0
  74. package/lib/engine/engine_serialization_core.js +7 -0
  75. package/lib/engine/engine_serialization_core.js.map +1 -1
  76. package/lib/engine/engine_types.d.ts +29 -11
  77. package/lib/engine/engine_types.js +1 -1
  78. package/lib/engine/engine_types.js.map +1 -1
  79. package/lib/engine/engine_util_decorator.js +7 -2
  80. package/lib/engine/engine_util_decorator.js.map +1 -1
  81. package/lib/engine/engine_utils.d.ts +1 -1
  82. package/lib/engine/engine_utils.js +19 -5
  83. package/lib/engine/engine_utils.js.map +1 -1
  84. package/lib/engine/engine_utils_qrcode.js +2 -2
  85. package/lib/engine/engine_utils_qrcode.js.map +1 -1
  86. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  87. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
  88. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
  89. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  90. package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +1 -1
  91. package/lib/engine/webcomponents/needle menu/needle-menu.js +6 -6
  92. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  93. package/lib/engine/webcomponents/needle-engine.d.ts +10 -4
  94. package/lib/engine/webcomponents/needle-engine.js +3 -3
  95. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  96. package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
  97. package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
  98. package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
  99. package/lib/engine/xr/NeedleXRSession.js +50 -14
  100. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  101. package/lib/engine/xr/TempXRContext.js +2 -2
  102. package/lib/engine/xr/TempXRContext.js.map +1 -1
  103. package/lib/engine/xr/events.d.ts +1 -1
  104. package/lib/engine/xr/events.js.map +1 -1
  105. package/lib/engine-components/Animation.js +17 -16
  106. package/lib/engine-components/Animation.js.map +1 -1
  107. package/lib/engine-components/AnimationBuilder.d.ts +158 -0
  108. package/lib/engine-components/AnimationBuilder.js +305 -0
  109. package/lib/engine-components/AnimationBuilder.js.map +1 -0
  110. package/lib/engine-components/Animator.d.ts +6 -0
  111. package/lib/engine-components/Animator.js +23 -13
  112. package/lib/engine-components/Animator.js.map +1 -1
  113. package/lib/engine-components/AnimatorController.builder.d.ts +191 -0
  114. package/lib/engine-components/AnimatorController.builder.js +263 -0
  115. package/lib/engine-components/AnimatorController.builder.js.map +1 -0
  116. package/lib/engine-components/AnimatorController.d.ts +2 -119
  117. package/lib/engine-components/AnimatorController.js +33 -232
  118. package/lib/engine-components/AnimatorController.js.map +1 -1
  119. package/lib/engine-components/AudioSource.d.ts +19 -3
  120. package/lib/engine-components/AudioSource.js +121 -68
  121. package/lib/engine-components/AudioSource.js.map +1 -1
  122. package/lib/engine-components/Collider.d.ts +18 -9
  123. package/lib/engine-components/Collider.js +61 -14
  124. package/lib/engine-components/Collider.js.map +1 -1
  125. package/lib/engine-components/Component.d.ts +72 -9
  126. package/lib/engine-components/Component.js +114 -10
  127. package/lib/engine-components/Component.js.map +1 -1
  128. package/lib/engine-components/ContactShadows.d.ts +1 -0
  129. package/lib/engine-components/ContactShadows.js +14 -1
  130. package/lib/engine-components/ContactShadows.js.map +1 -1
  131. package/lib/engine-components/DragControls.d.ts +7 -0
  132. package/lib/engine-components/DragControls.js +19 -7
  133. package/lib/engine-components/DragControls.js.map +1 -1
  134. package/lib/engine-components/DropListener.js +3 -0
  135. package/lib/engine-components/DropListener.js.map +1 -1
  136. package/lib/engine-components/EventList.d.ts +31 -9
  137. package/lib/engine-components/EventList.js +37 -76
  138. package/lib/engine-components/EventList.js.map +1 -1
  139. package/lib/engine-components/Joints.d.ts +4 -2
  140. package/lib/engine-components/Joints.js +19 -3
  141. package/lib/engine-components/Joints.js.map +1 -1
  142. package/lib/engine-components/Light.js +9 -1
  143. package/lib/engine-components/Light.js.map +1 -1
  144. package/lib/engine-components/Networking.d.ts +1 -1
  145. package/lib/engine-components/Networking.js +1 -1
  146. package/lib/engine-components/OrbitControls.d.ts +0 -2
  147. package/lib/engine-components/OrbitControls.js +30 -12
  148. package/lib/engine-components/OrbitControls.js.map +1 -1
  149. package/lib/engine-components/RigidBody.d.ts +12 -4
  150. package/lib/engine-components/RigidBody.js +18 -4
  151. package/lib/engine-components/RigidBody.js.map +1 -1
  152. package/lib/engine-components/SceneSwitcher.js +3 -0
  153. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  154. package/lib/engine-components/SeeThrough.js +2 -2
  155. package/lib/engine-components/SeeThrough.js.map +1 -1
  156. package/lib/engine-components/api.d.ts +2 -1
  157. package/lib/engine-components/api.js +2 -1
  158. package/lib/engine-components/api.js.map +1 -1
  159. package/lib/engine-components/codegen/components.d.ts +7 -13
  160. package/lib/engine-components/codegen/components.js +7 -13
  161. package/lib/engine-components/codegen/components.js.map +1 -1
  162. package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
  163. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  164. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
  165. package/lib/engine-components/timeline/PlayableDirector.d.ts +21 -11
  166. package/lib/engine-components/timeline/PlayableDirector.js +75 -67
  167. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  168. package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
  169. package/lib/engine-components/timeline/SignalAsset.js +1 -0
  170. package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
  171. package/lib/engine-components/timeline/TimelineBuilder.d.ts +413 -0
  172. package/lib/engine-components/timeline/TimelineBuilder.js +506 -0
  173. package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
  174. package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
  175. package/lib/engine-components/timeline/TimelineModels.js +3 -0
  176. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  177. package/lib/engine-components/timeline/TimelineTracks.d.ts +37 -6
  178. package/lib/engine-components/timeline/TimelineTracks.js +92 -26
  179. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  180. package/lib/engine-components/timeline/index.d.ts +2 -1
  181. package/lib/engine-components/timeline/index.js +2 -0
  182. package/lib/engine-components/timeline/index.js.map +1 -1
  183. package/lib/engine-components/ui/Canvas.d.ts +1 -1
  184. package/lib/engine-components/ui/Canvas.js +2 -8
  185. package/lib/engine-components/ui/Canvas.js.map +1 -1
  186. package/lib/engine-components/ui/Text.d.ts +1 -0
  187. package/lib/engine-components/ui/Text.js +10 -7
  188. package/lib/engine-components/ui/Text.js.map +1 -1
  189. package/lib/engine-components/web/CursorFollow.d.ts +0 -1
  190. package/lib/engine-components/web/CursorFollow.js +21 -13
  191. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  192. package/lib/engine-components/webxr/WebXRImageTracking.js +4 -0
  193. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  194. package/package.json +2 -83
  195. package/plugins/common/cloud.js +6 -1
  196. package/plugins/common/license.js +31 -10
  197. package/plugins/common/worker.js +9 -4
  198. package/plugins/vite/asap.js +17 -8
  199. package/plugins/vite/dependencies.js +29 -10
  200. package/plugins/vite/dependency-watcher.js +2 -2
  201. package/plugins/vite/editor-connection.js +3 -3
  202. package/plugins/vite/license.js +46 -7
  203. package/plugins/vite/local-files-core.js +3 -3
  204. package/plugins/vite/local-files-utils.d.ts +3 -1
  205. package/plugins/vite/local-files-utils.js +29 -5
  206. package/plugins/vite/reload.js +1 -1
  207. package/plugins/vite/server.js +2 -1
  208. package/src/engine/api.ts +11 -1
  209. package/src/engine/codegen/register_types.ts +10 -18
  210. package/src/engine/engine_audio.ts +184 -0
  211. package/src/engine/engine_camera.fit.ts +15 -4
  212. package/src/engine/engine_components.ts +1 -1
  213. package/src/engine/engine_context.ts +34 -18
  214. package/src/engine/engine_context_eventbus.ts +73 -0
  215. package/src/engine/engine_disposable.ts +214 -0
  216. package/src/engine/engine_gameobject.ts +54 -159
  217. package/src/engine/engine_gltf_builtin_components.ts +7 -76
  218. package/src/engine/engine_init.ts +7 -7
  219. package/src/engine/engine_input.ts +28 -7
  220. package/src/engine/engine_instantiate_resolve.ts +407 -0
  221. package/src/engine/engine_license.ts +197 -55
  222. package/src/engine/engine_mainloop_utils.ts +7 -4
  223. package/src/engine/engine_networking.transport.websocket.ts +45 -0
  224. package/src/engine/engine_networking.ts +161 -137
  225. package/src/engine/engine_networking_blob.ts +4 -4
  226. package/src/engine/engine_networking_instantiate.ts +2 -2
  227. package/src/engine/engine_networking_types.ts +41 -1
  228. package/src/engine/engine_physics_rapier.ts +102 -33
  229. package/src/engine/engine_scenedata.ts +3 -3
  230. package/src/engine/engine_serialization_builtin_serializer.ts +32 -9
  231. package/src/engine/engine_serialization_core.ts +9 -0
  232. package/src/engine/engine_types.ts +46 -27
  233. package/src/engine/engine_util_decorator.ts +7 -2
  234. package/src/engine/engine_utils.ts +16 -5
  235. package/src/engine/engine_utils_qrcode.ts +2 -2
  236. package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  237. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
  238. package/src/engine/webcomponents/needle menu/needle-menu.ts +6 -6
  239. package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
  240. package/src/engine/webcomponents/needle-engine.ts +12 -6
  241. package/src/engine/xr/NeedleXRSession.ts +48 -13
  242. package/src/engine/xr/TempXRContext.ts +2 -2
  243. package/src/engine/xr/events.ts +1 -1
  244. package/src/engine-components/Animation.ts +19 -16
  245. package/src/engine-components/AnimationBuilder.ts +472 -0
  246. package/src/engine-components/Animator.ts +24 -12
  247. package/src/engine-components/AnimatorController.builder.ts +387 -0
  248. package/src/engine-components/AnimatorController.ts +20 -291
  249. package/src/engine-components/AudioSource.ts +130 -79
  250. package/src/engine-components/Collider.ts +66 -18
  251. package/src/engine-components/Component.ts +118 -20
  252. package/src/engine-components/ContactShadows.ts +15 -1
  253. package/src/engine-components/DragControls.ts +18 -11
  254. package/src/engine-components/DropListener.ts +3 -0
  255. package/src/engine-components/EventList.ts +45 -83
  256. package/src/engine-components/Joints.ts +20 -4
  257. package/src/engine-components/Light.ts +10 -2
  258. package/src/engine-components/Networking.ts +1 -1
  259. package/src/engine-components/OrbitControls.ts +34 -14
  260. package/src/engine-components/RigidBody.ts +18 -4
  261. package/src/engine-components/SceneSwitcher.ts +3 -0
  262. package/src/engine-components/SeeThrough.ts +2 -2
  263. package/src/engine-components/api.ts +2 -1
  264. package/src/engine-components/codegen/components.ts +7 -13
  265. package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
  266. package/src/engine-components/timeline/PlayableDirector.ts +83 -81
  267. package/src/engine-components/timeline/SignalAsset.ts +4 -1
  268. package/src/engine-components/timeline/TimelineBuilder.ts +824 -0
  269. package/src/engine-components/timeline/TimelineModels.ts +5 -1
  270. package/src/engine-components/timeline/TimelineTracks.ts +96 -27
  271. package/src/engine-components/timeline/index.ts +2 -1
  272. package/src/engine-components/ui/Canvas.ts +2 -8
  273. package/src/engine-components/ui/Text.ts +12 -8
  274. package/src/engine-components/web/CursorFollow.ts +21 -14
  275. package/src/engine-components/webxr/WebXRImageTracking.ts +2 -0
  276. package/dist/needle-engine.bundle-CmxIO5uH.min.js +0 -1732
  277. package/dist/needle-engine.bundle-tJIZukCz.umd.cjs +0 -1732
  278. package/lib/engine-components/AvatarLoader.d.ts +0 -80
  279. package/lib/engine-components/AvatarLoader.js +0 -232
  280. package/lib/engine-components/AvatarLoader.js.map +0 -1
  281. package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
  282. package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
  283. package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
  284. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
  285. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
  286. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
  287. package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
  288. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
  289. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
  290. package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
  291. package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
  292. package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
  293. package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
  294. package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
  295. package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
  296. package/plugins/dts-generator/dts.codegen.js +0 -334
  297. package/plugins/dts-generator/dts.scan.js +0 -99
  298. package/plugins/dts-generator/dts.writer.js +0 -59
  299. package/plugins/dts-generator/glb.discovery.js +0 -279
  300. package/plugins/dts-generator/glb.extractor.js +0 -215
  301. package/plugins/dts-generator/glb.reader.js +0 -167
  302. package/plugins/dts-generator/index.js +0 -36
  303. package/plugins/dts-generator/manifest.types.js +0 -174
  304. package/plugins/gltf-packer.mjs +0 -1
  305. package/src/engine-components/AvatarLoader.ts +0 -264
  306. package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
  307. package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
  308. package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
  309. package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
  310. package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
  311. package/src/vite-env.d.ts +0 -16
@@ -40,11 +40,13 @@ import { GLTFLoader } from '../../../node_modules/@types/three/examples/jsm/load
40
40
  import { GLTFLoaderPlugin } from '../../../node_modules/@types/three/examples/jsm/loaders/GLTFLoader.js';
41
41
  import { GLTFParser } from '../../../node_modules/@types/three/examples/jsm/loaders/GLTFLoader.js';
42
42
  import { Group } from 'three';
43
+ import { ImpulseJoint } from '@dimforge/rapier3d-compat';
43
44
  import { InstancedMesh } from 'three';
44
45
  import { Intersection } from 'three';
45
46
  import { IParticleSystem as IParticleSystem_2 } from 'three.quarks';
46
47
  import { KeyframeTrack } from 'three';
47
48
  import { Layers } from 'three';
49
+ import { Light as Light_2 } from 'three';
48
50
  import { LightProbe } from 'three';
49
51
  import { Line2 } from '../../../../node_modules/@types/three/examples/jsm/lines/Line2.js';
50
52
  import { Loader } from 'three';
@@ -122,6 +124,8 @@ export declare class __Ignore {
122
124
 
123
125
  export declare function __internalNotifyObjectDestroyed(obj: Object3D): void;
124
126
 
127
+ /* Excluded from this release type: __tFkl */
128
+
125
129
  /** Data describing the accessible semantics for a 3D object or component. */
126
130
  declare type AccessibilityData = {
127
131
  /** ARIA role (e.g. `"button"`, `"img"`, `"region"`). */
@@ -254,6 +258,31 @@ export declare class ActionModel implements IBehaviorElement {
254
258
  writeTo(document: USDDocument, writer: USDWriter): void;
255
259
  }
256
260
 
261
+ /**
262
+ * Options for an activation clip in the timeline builder
263
+ */
264
+ export declare type ActivationClipOptions = {
265
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
266
+ start?: number;
267
+ /** Duration of the clip in seconds (required) */
268
+ duration: number;
269
+ /** Ease-in duration in seconds (default: 0) */
270
+ easeIn?: number;
271
+ /** Ease-out duration in seconds (default: 0) */
272
+ easeOut?: number;
273
+ };
274
+
275
+ /**
276
+ * Builder for activation tracks. Provides `.clip()` for defining activation windows.
277
+ * @category Animation and Sequencing
278
+ */
279
+ export declare interface ActivationTrackBuilder extends TimelineBuilderBase {
280
+ /** Adds an activation clip that shows/hides the bound object */
281
+ clip(options: ActivationClipOptions): ActivationTrackBuilder;
282
+ /** Mutes this track so it is skipped during playback */
283
+ muted(muted?: boolean): ActivationTrackBuilder;
284
+ }
285
+
257
286
  export declare const activeInHierarchyFieldName = "needle_isActiveInHierarchy";
258
287
 
259
288
  /**
@@ -487,6 +516,62 @@ declare class Animation_2 extends Component implements IAnimationComponent {
487
516
  }
488
517
  export { Animation_2 as Animation }
489
518
 
519
+ /**
520
+ * A fluent builder for creating `AnimationClip` instances from code.
521
+ *
522
+ * Use {@link AnimationBuilder.create} to start a new builder, chain `.track()` calls
523
+ * to add animation tracks, and call `.build()` to produce the clip.
524
+ *
525
+ * @example Single track
526
+ * ```ts
527
+ * const clip = AnimationBuilder.create()
528
+ * .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 })
529
+ * .build();
530
+ * ```
531
+ *
532
+ * @example Multiple tracks
533
+ * ```ts
534
+ * const clip = AnimationBuilder.create("DoorOpen")
535
+ * .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 })
536
+ * .track(light, "intensity", { from: 0, to: 5, duration: 1 })
537
+ * .build(room);
538
+ * ```
539
+ *
540
+ * @category Animation and Sequencing
541
+ * @group Utilities
542
+ */
543
+ export declare class AnimationBuilder {
544
+ private _name?;
545
+ private _tracks;
546
+ /** Creates a new AnimationBuilder instance */
547
+ static create(name?: string): AnimationBuilder;
548
+ constructor(name?: string);
549
+ /** Adds an animation track for an Object3D's position or scale */
550
+ track(target: Object3D, property: "position" | "scale", keyframes: KF_2<Vec3Value>, options?: TrackOptions): this;
551
+ /** Adds an animation track for an Object3D's quaternion */
552
+ track(target: Object3D, property: "quaternion", keyframes: KF_2<QuatValue>, options?: TrackOptions): this;
553
+ /** Adds an animation track for an Object3D's rotation (Euler, converted to quaternion) */
554
+ track(target: Object3D, property: "rotation", keyframes: KF_2<EulerValue>, options?: TrackOptions): this;
555
+ /** Adds an animation track for an Object3D's visibility */
556
+ track(target: Object3D, property: "visible", keyframes: KF_2<boolean>, options?: TrackOptions): this;
557
+ /** Adds an animation track for a material's numeric property */
558
+ track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF_2<number>, options?: TrackOptions): this;
559
+ /** Adds an animation track for a material's color property */
560
+ track(target: Material, property: "color" | "emissive", keyframes: KF_2<ColorValue>, options?: TrackOptions): this;
561
+ /** Adds an animation track for a light's numeric property */
562
+ track(target: Light_2, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF_2<number>, options?: TrackOptions): this;
563
+ /** Adds an animation track for a light's color */
564
+ track(target: Light_2, property: "color", keyframes: KF_2<ColorValue>, options?: TrackOptions): this;
565
+ /** Adds an animation track for a camera's numeric property */
566
+ track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF_2<number>, options?: TrackOptions): this;
567
+ /**
568
+ * Builds and returns the `AnimationClip`.
569
+ * @param root - Optional root Object3D for resolving track paths.
570
+ * When provided, tracks targeting a different object use `target.name` for named resolution.
571
+ */
572
+ build(root?: Object3D): AnimationClip;
573
+ }
574
+
490
575
  /**
491
576
  * @category Animation and Sequencing
492
577
  * @see {@link PlayableDirector} for the main component to control timelines in Needle Engine.
@@ -500,6 +585,34 @@ export declare type AnimationClipModel = {
500
585
  rotation?: Quat | Quaternion;
501
586
  };
502
587
 
588
+ /**
589
+ * Options for an animation clip in the timeline builder
590
+ */
591
+ export declare type AnimationClipOptions = {
592
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
593
+ start?: number;
594
+ /** Duration of the clip in seconds. Defaults to the animation clip duration. */
595
+ duration?: number;
596
+ /** Playback speed multiplier (default: 1) */
597
+ speed?: number;
598
+ /** Whether the animation should loop within the clip (default: false) */
599
+ loop?: boolean;
600
+ /** Ease-in duration in seconds (default: 0) */
601
+ easeIn?: number;
602
+ /** Ease-out duration in seconds (default: 0) */
603
+ easeOut?: number;
604
+ /** Offset into the source animation clip in seconds (default: 0) */
605
+ clipIn?: number;
606
+ /** Whether to remove the start offset of the animation (default: false) */
607
+ removeStartOffset?: boolean;
608
+ /** Pre-extrapolation mode (default: None) */
609
+ preExtrapolation?: ClipExtrapolation;
610
+ /** Post-extrapolation mode (default: None) */
611
+ postExtrapolation?: ClipExtrapolation;
612
+ /** Play the clip in reverse */
613
+ reversed?: boolean;
614
+ };
615
+
503
616
  /**
504
617
  * AnimationCurve is a representation of a curve that can be used to animate values over time.
505
618
  *
@@ -577,6 +690,19 @@ export declare class AnimationExtension implements IUSDExporterExtension {
577
690
 
578
691
  declare type AnimationIdentifier = AnimationClip | number | string | undefined;
579
692
 
693
+ /** User-friendly interpolation mode names */
694
+ export declare type AnimationInterpolation = "linear" | "smooth" | "step";
695
+
696
+ /** A single keyframe: a time and a value */
697
+ export declare type AnimationKeyframe<V> = {
698
+ /** Time in seconds */
699
+ time: number;
700
+ /** The value at this time */
701
+ value: V;
702
+ /** Interpolation mode for this track (default: `"linear"`). Note: Three.js applies one mode per track; the first keyframe's mode is used. */
703
+ interpolation?: AnimationInterpolation;
704
+ };
705
+
580
706
  /**
581
707
  * Registry for animation related data. Use {@link registerAnimationMixer} to register an animation mixer instance.
582
708
  * Can be accessed from {@link Context.animations} and is used internally e.g. when exporting GLTF files.
@@ -597,43 +723,39 @@ declare class AnimationsRegistry {
597
723
  unregisterAnimationMixer(mixer: AnimationMixer | null | undefined): void;
598
724
  }
599
725
 
600
- export declare class AnimationTrackHandler extends TrackHandler {
601
- /* Excluded from this release type: models */
602
- /* Excluded from this release type: trackOffset */
603
- /** The object that is being animated. */
604
- target?: Object3D;
605
- /** The AnimationMixer, should be shared with the animator if an animator is bound */
606
- mixer?: AnimationMixer;
607
- clips: Array<AnimationClip>;
608
- actions: Array<AnimationAction>;
609
- /**
610
- * You can use the weight to blend the timeline animation tracks with multiple animation tracks on the same object.
611
- * @default 1
612
- */
613
- weight: number;
614
- /** holds data/info about clips differences */
615
- private _actionOffsets;
616
- private _didBind;
617
- private _animator;
618
- onDisable(): void;
619
- onDestroy(): void;
620
- onStateChanged(): void;
621
- createHooks(clipModel: Models.AnimationClipModel, clip: any): void;
622
- bind(): void;
623
- private ensureTrackOffsets;
624
- private _useclipOffsets;
625
- private _totalOffsetPosition;
626
- private _totalOffsetRotation;
627
- private _totalOffsetPosition2;
628
- private _totalOffsetRotation2;
629
- private _summedPos;
630
- private _tempPos;
631
- private _summedRot;
632
- private _tempRot;
633
- private _clipRotQuat;
634
- evaluate(time: number): void;
635
- private createRotationInterpolant;
636
- private createPositionInterpolant;
726
+ /**
727
+ * Builder for animation tracks.
728
+ * Provides `.clip()` for pre-built AnimationClips and `.track()` for inline animation definition.
729
+ *
730
+ * @category Animation and Sequencing
731
+ */
732
+ export declare interface AnimationTrackBuilder extends TimelineBuilderBase {
733
+ /** Adds a pre-built AnimationClip */
734
+ clip(asset: AnimationClip, options?: AnimationClipOptions): AnimationTrackBuilder;
735
+ /** Adds a clip from a single {@link TrackDescriptor} */
736
+ clip(descriptor: TrackDescriptor, options?: AnimationClipOptions): AnimationTrackBuilder;
737
+ /** Adds a clip from multiple {@link TrackDescriptor}s */
738
+ clip(descriptors: TrackDescriptor[], options?: AnimationClipOptions): AnimationTrackBuilder;
739
+ /** Adds an animation track for an Object3D's position or scale */
740
+ track(target: Object3D, property: "position" | "scale", keyframes: KF_3<Vec3Value>, options?: TrackOptions): AnimationTrackBuilder;
741
+ /** Adds an animation track for an Object3D's quaternion */
742
+ track(target: Object3D, property: "quaternion", keyframes: KF_3<QuatValue>, options?: TrackOptions): AnimationTrackBuilder;
743
+ /** Adds an animation track for an Object3D's rotation (Euler, converted to quaternion) */
744
+ track(target: Object3D, property: "rotation", keyframes: KF_3<EulerValue>, options?: TrackOptions): AnimationTrackBuilder;
745
+ /** Adds an animation track for an Object3D's visibility */
746
+ track(target: Object3D, property: "visible", keyframes: KF_3<boolean>, options?: TrackOptions): AnimationTrackBuilder;
747
+ /** Adds an animation track for a material's numeric property */
748
+ track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF_3<number>, options?: TrackOptions): AnimationTrackBuilder;
749
+ /** Adds an animation track for a material's color property */
750
+ track(target: Material, property: "color" | "emissive", keyframes: KF_3<ColorValue>, options?: TrackOptions): AnimationTrackBuilder;
751
+ /** Adds an animation track for a light's numeric property */
752
+ track(target: Light_2, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF_3<number>, options?: TrackOptions): AnimationTrackBuilder;
753
+ /** Adds an animation track for a light's color */
754
+ track(target: Light_2, property: "color", keyframes: KF_3<ColorValue>, options?: TrackOptions): AnimationTrackBuilder;
755
+ /** Adds an animation track for a camera's numeric property */
756
+ track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF_3<number>, options?: TrackOptions): AnimationTrackBuilder;
757
+ /** Mutes this track so it is skipped during playback */
758
+ muted(muted?: boolean): AnimationTrackBuilder;
637
759
  }
638
760
 
639
761
  declare class AnimationTriggers {
@@ -726,6 +848,12 @@ export declare class Animator extends Component implements IAnimationComponent {
726
848
  * Identifies this component as an animation component in the engine
727
849
  */
728
850
  get isAnimationComponent(): boolean;
851
+ /**
852
+ * The current animator mixer, used for low-level control of animations. Owned by the AnimatorController
853
+ * @returns The current AnimationMixer, or null if no controller is assigned
854
+ * @see AnimatorController.mixer
855
+ */
856
+ get mixer(): AnimationMixer | null;
729
857
  /**
730
858
  * When enabled, animation will affect the root transform position and rotation
731
859
  */
@@ -1102,13 +1230,6 @@ export declare class AnimatorController {
1102
1230
  * @param animator - The animator to bind this controller to
1103
1231
  */
1104
1232
  bind(animator: Animator): void;
1105
- /**
1106
- * Creates a deep copy of this controller.
1107
- * Clones the model data but does not copy runtime state.
1108
- *
1109
- * @returns A new AnimatorController instance with the same configuration
1110
- */
1111
- clone(): AnimatorController | null;
1112
1233
  /**
1113
1234
  * Updates the controller's state machine and animations.
1114
1235
  * Called each frame by the animator component.
@@ -1151,11 +1272,15 @@ export declare class AnimatorController {
1151
1272
  /**
1152
1273
  * A fluent builder for creating {@link AnimatorController} instances from code.
1153
1274
  *
1154
- * Use {@link AnimatorController.build} to create a new builder.
1275
+ * Use {@link AnimatorControllerBuilder.create} or {@link AnimatorController.build} to create a new builder.
1155
1276
  *
1156
- * @example
1277
+ * The builder tracks state names and parameter types through the fluent chain,
1278
+ * providing autocomplete for state names in `.transition()` and type-aware
1279
+ * `.condition()` calls (e.g., trigger parameters don't require a mode argument).
1280
+ *
1281
+ * @example With pre-built AnimationClips
1157
1282
  * ```ts
1158
- * const controller = AnimatorController.build("CharacterController")
1283
+ * const controller = AnimatorControllerBuilder.create("CharacterController")
1159
1284
  * .floatParameter("Speed", 0)
1160
1285
  * .triggerParameter("Jump")
1161
1286
  * .state("Idle", { clip: idleClip, loop: true })
@@ -1166,36 +1291,70 @@ export declare class AnimatorController {
1166
1291
  * .transition("Walk", "Idle", { duration: 0.25 })
1167
1292
  * .condition("Speed", "less", 0.1)
1168
1293
  * .transition("*", "Jump", { duration: 0.1 })
1169
- * .condition("Jump", "if")
1294
+ * .condition("Jump")
1170
1295
  * .transition("Jump", "Idle", { hasExitTime: true, exitTime: 0.9, duration: 0.25 })
1171
1296
  * .build();
1172
1297
  * ```
1173
1298
  *
1299
+ * @example With inline tracks (no pre-built clips needed)
1300
+ * ```ts
1301
+ * const controller = AnimatorControllerBuilder.create("Door")
1302
+ * .boolParameter("Open", false)
1303
+ * .state("Closed", { loop: true })
1304
+ * .track(door, "position", { from: [0, 0, 0], to: [0, 0, 0], duration: 1 })
1305
+ * .state("Open", { loop: true })
1306
+ * .track(door, "position", { from: [0, 0, 0], to: [2, 0, 0], duration: 1 })
1307
+ * .track(light, "intensity", { from: 0, to: 5, duration: 1 })
1308
+ * .transition("Closed", "Open", { duration: 0.25 })
1309
+ * .condition("Open", "if")
1310
+ * .transition("Open", "Closed", { duration: 0.25 })
1311
+ * .condition("Open", "ifNot")
1312
+ * .build(room);
1313
+ * ```
1314
+ *
1315
+ * @typeParam TStates - Union of state names added via `.state()`. Used for autocomplete and validation in `.transition()` and `.defaultState()`.
1316
+ * @typeParam TParams - Record mapping parameter names to their types (`"trigger"`, `"bool"`, `"float"`, `"int"`). Used for type-aware `.condition()` overloads.
1317
+ *
1174
1318
  * @category Animation and Sequencing
1175
1319
  * @group Utilities
1176
1320
  */
1177
- export declare class AnimatorControllerBuilder {
1321
+ export declare class AnimatorControllerBuilder<TStates extends string = never, TParams extends Record<string, "trigger" | "bool" | "float" | "int"> = {}> {
1178
1322
  private _name;
1179
1323
  private _parameters;
1180
1324
  private _states;
1181
1325
  private _anyStateTransitions;
1182
1326
  private _defaultStateName;
1183
1327
  private _lastTransition;
1328
+ private _lastState;
1329
+ /**
1330
+ * Creates a new AnimatorControllerBuilder instance.
1331
+ * @param name - Optional name for the controller
1332
+ */
1333
+ static create(name?: string): AnimatorControllerBuilder;
1184
1334
  constructor(name?: string);
1185
1335
  /** Adds a float parameter */
1186
- floatParameter(name: string, defaultValue?: number): this;
1336
+ floatParameter<N extends string>(name: N, defaultValue?: number): AnimatorControllerBuilder<TStates, TParams & Record<N, "float">>;
1187
1337
  /** Adds an integer parameter */
1188
- intParameter(name: string, defaultValue?: number): this;
1338
+ intParameter<N extends string>(name: N, defaultValue?: number): AnimatorControllerBuilder<TStates, TParams & Record<N, "int">>;
1189
1339
  /** Adds a boolean parameter */
1190
- boolParameter(name: string, defaultValue?: boolean): this;
1340
+ boolParameter<N extends string>(name: N, defaultValue?: boolean): AnimatorControllerBuilder<TStates, TParams & Record<N, "bool">>;
1191
1341
  /** Adds a trigger parameter */
1192
- triggerParameter(name: string): this;
1342
+ triggerParameter<N extends string>(name: N): AnimatorControllerBuilder<TStates, TParams & Record<N, "trigger">>;
1193
1343
  /**
1194
1344
  * Adds a state to the controller. The first state added becomes the default state.
1345
+ *
1346
+ * When `options.clip` is provided, the state uses that clip directly.
1347
+ * When omitted, chain `.track()` calls to define animation tracks inline:
1348
+ * ```ts
1349
+ * .state("Open", { loop: true })
1350
+ * .track(door, "position", { from: [0,0,0], to: [2,0,0], duration: 1 })
1351
+ * .track(light, "intensity", { from: 0, to: 5, duration: 1 })
1352
+ * ```
1353
+ *
1195
1354
  * @param name - Unique name for the state
1196
- * @param options - State configuration including clip, loop, speed
1355
+ * @param options - State configuration including clip, loop, speed. When omitted, use `.track()` to add animation data.
1197
1356
  */
1198
- state(name: string, options: StateOptions): this;
1357
+ state<N extends string>(name: N, options?: StateOptions): AnimatorControllerBuilder<TStates | N, TParams>;
1199
1358
  /**
1200
1359
  * Adds a transition between two states.
1201
1360
  * Use `"*"` as the source to create a transition from any state.
@@ -1204,26 +1363,52 @@ export declare class AnimatorControllerBuilder {
1204
1363
  * @param to - Destination state name
1205
1364
  * @param options - Transition configuration
1206
1365
  */
1207
- transition(from: string, to: string, options?: TransitionOptions): this;
1366
+ transition(from: TStates | "*", to: TStates, options?: TransitionOptions): AnimatorControllerBuilder<TStates, TParams>;
1208
1367
  /**
1209
1368
  * Adds a condition to the most recently added transition.
1210
1369
  * Multiple conditions on the same transition are AND-ed together.
1370
+ *
1371
+ * The required arguments depend on the parameter type:
1372
+ * - **Trigger**: `.condition("Jump")` — mode defaults to `"if"`, no threshold needed
1373
+ * - **Bool**: `.condition("Open", "if")` or `.condition("Open", "ifNot")`
1374
+ * - **Float/Int**: `.condition("Speed", "greater", 0.1)`
1375
+ *
1211
1376
  * @param parameter - Name of the parameter to evaluate
1212
- * @param mode - Condition mode: `"if"`, `"ifNot"`, `"greater"`, `"less"`, `"equals"`, `"notEqual"`
1213
- * @param threshold - Comparison threshold for numeric conditions (default: 0)
1214
1377
  */
1215
- condition(parameter: string, mode: ConditionMode, threshold?: number): this;
1378
+ condition(parameter: ParamNamesOfType<TParams, "trigger">, mode?: "if" | "ifNot"): AnimatorControllerBuilder<TStates, TParams>;
1379
+ condition(parameter: ParamNamesOfType<TParams, "bool">, mode: "if" | "ifNot"): AnimatorControllerBuilder<TStates, TParams>;
1380
+ condition(parameter: ParamNamesOfType<TParams, "float" | "int">, mode: "greater" | "less" | "equals" | "notEqual", threshold?: number): AnimatorControllerBuilder<TStates, TParams>;
1381
+ /** Adds an animation track for an Object3D's position or scale to the current state */
1382
+ track(target: Object3D, property: "position" | "scale", keyframes: KF<Vec3Value>, options?: TrackOptions): this;
1383
+ /** Adds an animation track for an Object3D's quaternion to the current state */
1384
+ track(target: Object3D, property: "quaternion", keyframes: KF<QuatValue>, options?: TrackOptions): this;
1385
+ /** Adds an animation track for an Object3D's rotation (Euler, converted to quaternion) to the current state */
1386
+ track(target: Object3D, property: "rotation", keyframes: KF<EulerValue>, options?: TrackOptions): this;
1387
+ /** Adds an animation track for an Object3D's visibility to the current state */
1388
+ track(target: Object3D, property: "visible", keyframes: KF<boolean>, options?: TrackOptions): this;
1389
+ /** Adds an animation track for a material's numeric property to the current state */
1390
+ track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF<number>, options?: TrackOptions): this;
1391
+ /** Adds an animation track for a material's color property to the current state */
1392
+ track(target: Material, property: "color" | "emissive", keyframes: KF<ColorValue>, options?: TrackOptions): this;
1393
+ /** Adds an animation track for a light's numeric property to the current state */
1394
+ track(target: Light_2, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF<number>, options?: TrackOptions): this;
1395
+ /** Adds an animation track for a light's color to the current state */
1396
+ track(target: Light_2, property: "color", keyframes: KF<ColorValue>, options?: TrackOptions): this;
1397
+ /** Adds an animation track for a camera's numeric property to the current state */
1398
+ track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF<number>, options?: TrackOptions): this;
1216
1399
  /**
1217
1400
  * Sets which state is the default/entry state.
1218
1401
  * If not called, the first added state is used.
1219
1402
  * @param name - Name of the state
1220
1403
  */
1221
- defaultState(name: string): this;
1404
+ defaultState(name: TStates): AnimatorControllerBuilder<TStates, TParams>;
1222
1405
  /**
1223
1406
  * Builds and returns the {@link AnimatorController}.
1224
1407
  * Resolves all state name references to indices.
1408
+ * @param root - Optional root Object3D for resolving {@link TrackDescriptor} track paths.
1409
+ * When provided, tracks targeting a different object use `target.name` for named resolution.
1225
1410
  */
1226
- build(): AnimatorController;
1411
+ build(root?: Object3D): AnimatorController;
1227
1412
  }
1228
1413
 
1229
1414
  export declare type AnimatorControllerModel = {
@@ -1472,6 +1657,75 @@ export declare class Attractor extends Component {
1472
1657
 
1473
1658
  declare type AttributeChangeCallback = (value: string | null) => void;
1474
1659
 
1660
+ /**
1661
+ * Represents an audio clip that can be loaded and played independently.
1662
+ * The AudioClip class encapsulates the URL of the audio resource and provides
1663
+ * methods for playback control (play, pause, stop) and querying duration.
1664
+ */
1665
+ export declare class AudioClip {
1666
+ readonly url: string;
1667
+ /**
1668
+ * Creates a new AudioClip instance with the specified URL.
1669
+ * @param url The URL of the audio resource to load. This can be a path to an audio file or a MediaStream URL.
1670
+ */
1671
+ constructor(url: string);
1672
+ /** Whether the clip is currently playing.
1673
+ * @returns `true` if the clip is actively playing audio.
1674
+ */
1675
+ get isPlaying(): boolean;
1676
+ /**
1677
+ * The total duration of the audio clip in seconds.
1678
+ * Loads the audio metadata if not already available.
1679
+ * @returns A promise that resolves with the duration in seconds.
1680
+ */
1681
+ getDuration(): Promise<number>;
1682
+ /**
1683
+ * Plays the audio clip from the current position.
1684
+ * @returns A promise that resolves when playback finishes, or rejects on error.
1685
+ * If the clip is looping, the promise will never resolve on its own – call {@link stop} or {@link pause} to end playback.
1686
+ */
1687
+ play(): Promise<void>;
1688
+ /**
1689
+ * Pauses playback at the current position.
1690
+ * Call {@link play} to resume.
1691
+ */
1692
+ pause(): void;
1693
+ /**
1694
+ * Stops playback and resets the position to the beginning.
1695
+ */
1696
+ stop(): void;
1697
+ /** Whether the clip should loop when reaching the end. */
1698
+ get loop(): boolean;
1699
+ set loop(value: boolean);
1700
+ /** Playback volume from 0 (silent) to 1 (full). */
1701
+ get volume(): number;
1702
+ set volume(value: number);
1703
+ /** Current playback position in seconds. */
1704
+ get currentTime(): number;
1705
+ set currentTime(value: number);
1706
+ /** Normalized playback progress from 0 to 1.
1707
+ * @returns The current playback position as a value between 0 and 1, or 0 if the duration is unknown.
1708
+ */
1709
+ get progress(): number;
1710
+ /**
1711
+ * Seeks to a normalized position (0–1) in the clip.
1712
+ * @param position A value between 0 (start) and 1 (end).
1713
+ */
1714
+ seek(position: number): void;
1715
+ /** The underlying HTMLAudioElement, or `undefined` if not yet created.
1716
+ * Use this to connect the element to the Web Audio API via `createMediaElementSource()`.
1717
+ * @returns The HTMLAudioElement if the clip has been loaded or played, otherwise `undefined`.
1718
+ */
1719
+ get audioElement(): HTMLAudioElement | undefined;
1720
+ private _audioElement?;
1721
+ private _duration?;
1722
+ private _loadPromise?;
1723
+ private _loop;
1724
+ private _volume;
1725
+ /** Lazily creates and loads the shared HTMLAudioElement. */
1726
+ private ensureAudioElement;
1727
+ }
1728
+
1475
1729
  /**
1476
1730
  * @category Animation and Sequencing
1477
1731
  * @see {@link PlayableDirector} for the main component to control timelines in Needle Engine.
@@ -1486,6 +1740,26 @@ declare type AudioClipModel_2 = Models.ClipModel & {
1486
1740
  _didTriggerPlay: boolean;
1487
1741
  };
1488
1742
 
1743
+ /**
1744
+ * Options for an audio clip in the timeline builder
1745
+ */
1746
+ export declare type AudioClipOptions = {
1747
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
1748
+ start?: number;
1749
+ /** Duration of the clip in seconds (required for audio since we can't infer it) */
1750
+ duration: number;
1751
+ /** Playback speed multiplier (default: 1) */
1752
+ speed?: number;
1753
+ /** Volume multiplier for this clip (default: 1) */
1754
+ volume?: number;
1755
+ /** Whether the audio should loop within the clip (default: false) */
1756
+ loop?: boolean;
1757
+ /** Ease-in duration in seconds (default: 0) */
1758
+ easeIn?: number;
1759
+ /** Ease-out duration in seconds (default: 0) */
1760
+ easeOut?: number;
1761
+ };
1762
+
1489
1763
  export declare class AudioExtension implements IUSDExporterExtension {
1490
1764
  static getName(clip: string): string;
1491
1765
  get extensionName(): string;
@@ -1627,9 +1901,10 @@ export declare class AudioSource extends Component {
1627
1901
  */
1628
1902
  get isPlaying(): boolean;
1629
1903
  /**
1630
- * The total duration of the current audio clip in seconds.
1904
+ * The total duration of the currently loaded audio clip in seconds.
1631
1905
  *
1632
1906
  * @returns Duration in seconds or undefined if no clip is loaded
1907
+ * @remarks For MediaStream clips, duration is not directly available and will return undefined. If the audio clip has not started loading or is still loading, duration may also be undefined until the audio buffer is ready.
1633
1908
  */
1634
1909
  get duration(): number | undefined;
1635
1910
  /**
@@ -1654,7 +1929,8 @@ export declare class AudioSource extends Component {
1654
1929
  /**
1655
1930
  * Controls how the audio is positioned in space.
1656
1931
  * Values range from 0 (2D, non-positional) to 1 (fully 3D positioned).
1657
- * Note: 2D playback is not fully supported in the current implementation.
1932
+ * Internally uses a dual-path audio graph to crossfade between a spatialized (PannerNode)
1933
+ * and a non-spatialized (direct) signal path.
1658
1934
  */
1659
1935
  get spatialBlend(): number;
1660
1936
  set spatialBlend(val: number);
@@ -1702,7 +1978,11 @@ export declare class AudioSource extends Component {
1702
1978
  private audioLoader;
1703
1979
  private shouldPlay;
1704
1980
  private _lastClipStartedLoading;
1981
+ private _loadedClip;
1705
1982
  private _audioElement;
1983
+ private _entryNode;
1984
+ private _spatialGain;
1985
+ private _bypassGain;
1706
1986
  /**
1707
1987
  * Returns the underlying {@link PositionalAudio} object, creating it if necessary.
1708
1988
  * The audio source needs a user interaction to be initialized due to browser autoplay policies.
@@ -1730,6 +2010,15 @@ export declare class AudioSource extends Component {
1730
2010
  private onApplicationMuteChanged;
1731
2011
  private createAudio;
1732
2012
  private __onAllowAudioCallback;
2013
+ /**
2014
+ * Sets up the dual-path audio graph for spatial blend crossfading.
2015
+ * Creates two parallel signal paths from source to output:
2016
+ * - 3D path: entry → panner → spatialGain → gain (spatialized)
2017
+ * - 2D path: entry → bypassGain → gain (non-spatialized)
2018
+ */
2019
+ private setupSpatialBlendNodes;
2020
+ /** Updates the spatial/bypass gain values based on the current spatialBlend. */
2021
+ private updateSpatialBlendGains;
1733
2022
  private applySpatialDistanceSettings;
1734
2023
  private onNewClip;
1735
2024
  /**
@@ -1737,8 +2026,9 @@ export declare class AudioSource extends Component {
1737
2026
  * If no argument is provided, plays the currently assigned clip.
1738
2027
  *
1739
2028
  * @param clip - Optional audio clip or {@link MediaStream} to play
2029
+ * @returns A promise that resolves when playback starts successfully, or rejects on error
1740
2030
  */
1741
- play(clip?: string | MediaStream | undefined): void;
2031
+ play(clip?: string | MediaStream | undefined): Promise<boolean>;
1742
2032
  /**
1743
2033
  * Pauses audio playback while maintaining the current position.
1744
2034
  * Use play() to resume from the paused position.
@@ -1755,30 +2045,15 @@ export declare class AudioSource extends Component {
1755
2045
  /* Excluded from this release type: update */
1756
2046
  }
1757
2047
 
1758
- export declare class AudioTrackHandler extends TrackHandler {
1759
- models: Array<AudioClipModel_2>;
1760
- listener: AudioListener_3;
1761
- audio: Array<Audio_2>;
1762
- audioContextTimeOffset: Array<number>;
1763
- lastTime: number;
1764
- audioSource?: AudioSource;
1765
- private _audioLoader;
1766
- private getAudioFilePath;
1767
- onAllowAudioChanged(allow: boolean): void;
1768
- addModel(model: Models.ClipModel): void;
1769
- onDisable(): void;
1770
- onDestroy(): void;
1771
- onMuteChanged(): void;
1772
- stop(): void;
1773
- private _playableDirectorResumed;
1774
- onPauseChanged(): void;
1775
- evaluate(time: number): void;
1776
- /** Call to load audio buffer for a specific time in the track. Can be used to preload the timeline audio */
1777
- loadAudio(time: number, lookAhead?: number, lookBehind?: number): Promise<(AudioBuffer | null)[]> | null;
1778
- private isInTimeRange;
1779
- private static _audioBuffers;
1780
- static dispose(): void;
1781
- private handleAudioLoading;
2048
+ /**
2049
+ * Builder for audio tracks. Provides `.clip()` for adding audio clips by URL.
2050
+ * @category Animation and Sequencing
2051
+ */
2052
+ export declare interface AudioTrackBuilder extends TimelineBuilderBase {
2053
+ /** Adds an audio clip by URL */
2054
+ clip(url: string, options: AudioClipOptions): AudioTrackBuilder;
2055
+ /** Mutes this track so it is skipped during playback */
2056
+ muted(muted?: boolean): AudioTrackBuilder;
1782
2057
  }
1783
2058
 
1784
2059
  /* Excluded from this release type: AuralMode */
@@ -1811,69 +2086,6 @@ export declare class Avatar extends Component {
1811
2086
  private loadAvatarObjects;
1812
2087
  }
1813
2088
 
1814
- /* Excluded from this release type: Avatar_Brain_LookAt */
1815
-
1816
- /* Excluded from this release type: Avatar_MouthShapes */
1817
-
1818
- /* Excluded from this release type: Avatar_MustacheShake */
1819
-
1820
- /* Excluded from this release type: Avatar_POI */
1821
-
1822
- /* Excluded from this release type: AvatarBlink_Simple */
1823
-
1824
- /* Excluded from this release type: AvatarEyeLook_Rotation */
1825
-
1826
- /**
1827
- * Handles loading and instantiating avatar models from various sources.
1828
- * Provides functionality to find and extract important parts of an avatar (head, hands).
1829
- *
1830
- * Debug mode can be enabled with the URL parameter `?debugavatar`,
1831
- * which will log detailed information about avatar loading and configuration.
1832
- */
1833
- export declare class AvatarLoader {
1834
- private readonly avatarRegistryUrl;
1835
- /**
1836
- * Retrieves or creates a new avatar instance from an ID or existing Object3D.
1837
- * @param context The application context
1838
- * @param avatarId Either a string ID to load an avatar or an existing Object3D to use as avatar
1839
- * @returns Promise resolving to an AvatarModel if successful, or null if failed
1840
- */
1841
- getOrCreateNewAvatarInstance(context: Context, avatarId: string | Object3D): Promise<AvatarModel | null>;
1842
- /**
1843
- * Loads an avatar model from a file or registry using the provided ID.
1844
- * @param context The engine context
1845
- * @param avatarId The ID of the avatar to load
1846
- * @returns Promise resolving to the loaded avatar's Object3D, or null if failed
1847
- */
1848
- private loadAvatar;
1849
- /**
1850
- * Caches an avatar model for reuse.
1851
- * @param _id The ID to associate with the model
1852
- * @param _model The avatar model to cache
1853
- */
1854
- private cacheModel;
1855
- /**
1856
- * Analyzes an Object3D to find avatar parts (head, hands) based on naming conventions.
1857
- * @param obj The Object3D to search for avatar parts
1858
- * @returns A structured AvatarModel with references to found parts
1859
- */
1860
- private findAvatar;
1861
- /**
1862
- * Recursively searches for an avatar part by name within an Object3D hierarchy.
1863
- * @param obj The Object3D to search within
1864
- * @param searchString Array of strings that should all be present in the object name
1865
- * @returns The found Object3D part or null if not found
1866
- */
1867
- private findAvatarPart;
1868
- /**
1869
- * Handles HTTP response errors from avatar loading operations.
1870
- * @param response The fetch API response to check
1871
- * @returns The response if it was ok
1872
- * @throws Error with status text if response was not ok
1873
- */
1874
- private handleCustomAvatarErrors;
1875
- }
1876
-
1877
2089
  /**
1878
2090
  * Marks a GameObject as being controlled or owned by a player in networked XR sessions.
1879
2091
  * This is used internally by the networking system to identify player-controlled objects.
@@ -1934,35 +2146,6 @@ declare type AvatarMarkerEventArgs = {
1934
2146
  gameObject: Object3D;
1935
2147
  };
1936
2148
 
1937
- /**
1938
- * Represents an avatar model with head and hands references.
1939
- * Used for representing characters in 3D space.
1940
- */
1941
- export declare class AvatarModel {
1942
- /** The root object of the avatar model */
1943
- root: Object3D;
1944
- /** The head object of the avatar model */
1945
- head: Object3D;
1946
- /** The left hand object of the avatar model, if available */
1947
- leftHand: Object3D | null;
1948
- /** The right hand object of the avatar model, if available */
1949
- rigthHand: Object3D | null;
1950
- /**
1951
- * Checks if the avatar model has a valid configuration.
1952
- * An avatar is considered valid if it has a head.
1953
- * @returns Whether the avatar has a valid setup
1954
- */
1955
- get isValid(): boolean;
1956
- /**
1957
- * Creates a new avatar model.
1958
- * @param root The root object of the avatar
1959
- * @param head The head object of the avatar
1960
- * @param leftHand The left hand object of the avatar
1961
- * @param rigthHand The right hand object of the avatar
1962
- */
1963
- constructor(root: Object3D, head: Object3D, leftHand: Object3D | null, rigthHand: Object3D | null);
1964
- }
1965
-
1966
2149
  export declare enum Axes {
1967
2150
  None = 0,
1968
2151
  X = 2,
@@ -2176,6 +2359,8 @@ export declare class BehaviorModel {
2176
2359
  writeTo(_ext: BehaviorExtension, document: USDDocument, writer: USDWriter): void;
2177
2360
  }
2178
2361
 
2362
+ /* Excluded from this release type: _BGpnKD */
2363
+
2179
2364
  export declare type BinaryCallback = {
2180
2365
  (data: any | flatbuffers.ByteBuffer): void;
2181
2366
  };
@@ -2326,7 +2511,6 @@ export declare class BoxCollider extends Collider implements IBoxCollider {
2326
2511
  center: Vector3;
2327
2512
  /* Excluded from this release type: onEnable */
2328
2513
  /* Excluded from this release type: onDisable */
2329
- /* Excluded from this release type: onValidate */
2330
2514
  /**
2331
2515
  * Automatically fits the collider to the geometry of the object.
2332
2516
  * Sets the size and center based on the object's bounding box.
@@ -2600,6 +2784,7 @@ declare class CallHandle extends EventDispatcher<any> {
2600
2784
  * CallInfo represents a single callback method that can be invoked by the {@link EventList}.
2601
2785
  */
2602
2786
  export declare class CallInfo {
2787
+ $serializedTypes: Record<string, any>;
2603
2788
  /**
2604
2789
  * When the CallInfo is enabled it will be invoked when the EventList is invoked
2605
2790
  */
@@ -2946,7 +3131,7 @@ export declare class Canvas extends UIRootComponent implements ICanvas {
2946
3131
  private _receivers;
2947
3132
  registerEventReceiver(receiver: ICanvasEventReceiver): void;
2948
3133
  unregisterEventReceiver(receiver: ICanvasEventReceiver): void;
2949
- onEnterXR(args: NeedleXREventArgs): Promise<void>;
3134
+ onEnterXR(args: NeedleXREventArgs): void;
2950
3135
  onLeaveXR(args: NeedleXREventArgs): void;
2951
3136
  onBeforeRenderRoutine: () => void;
2952
3137
  onAfterRenderRoutine: () => void;
@@ -3522,6 +3707,22 @@ export declare abstract class Collider extends Component implements ICollider {
3522
3707
  * The layers that this collider will interact with. Used for filtering collision detection.
3523
3708
  */
3524
3709
  filter?: number[];
3710
+ /**
3711
+ * The density of the collider, used for automatic mass calculation when the attached {@link Rigidbody} has `autoMass` enabled.
3712
+ * Rapier computes mass from density using the real-world formula: `mass = density × volume`.
3713
+ * The volume is derived from the collider shape (sphere, box, capsule, or convex hull).
3714
+ *
3715
+ * Reference values (relative to water = 1.0):
3716
+ * - Wood: 0.5–0.9
3717
+ * - Water: 1.0 (engine default)
3718
+ * - Rubber: 1.2
3719
+ * - Steel: 7.8
3720
+ *
3721
+ * @default undefined — uses the physics engine default of 1.0
3722
+ */
3723
+ density?: number;
3724
+ /* Excluded from this release type: _propertiesDirty */
3725
+ /* Excluded from this release type: onValidate */
3525
3726
  /* Excluded from this release type: awake */
3526
3727
  /* Excluded from this release type: start */
3527
3728
  /* Excluded from this release type: onEnable */
@@ -3625,6 +3826,9 @@ declare class ColorSerializer extends TypeSerializer {
3625
3826
 
3626
3827
  export declare let colorSerializer: ColorSerializer;
3627
3828
 
3829
+ /** A Color value, either as a Three.js Color or as an `[r, g, b]` tuple (0–1) */
3830
+ declare type ColorValue = Color | [number, number, number];
3831
+
3628
3832
  /**
3629
3833
  * Utility method to check if two materials were created from the same glTF material
3630
3834
  */
@@ -3644,7 +3848,7 @@ export declare function compareAssociation<T extends Material>(obj1: T, obj2: T)
3644
3848
  * **Input event methods:**
3645
3849
  * {@link onPointerDown}, {@link onPointerUp}, {@link onPointerEnter}, {@link onPointerExit} and {@link onPointerMove}.
3646
3850
  *
3647
- * @example
3851
+ * @example Basic component
3648
3852
  * ```typescript
3649
3853
  * import { Behaviour } from "@needle-tools/engine";
3650
3854
  * export class MyComponent extends Behaviour {
@@ -3657,6 +3861,25 @@ export declare function compareAssociation<T extends Material>(obj1: T, obj2: T)
3657
3861
  * }
3658
3862
  * ```
3659
3863
  *
3864
+ * @example Automatic cleanup with autoCleanup
3865
+ * ```typescript
3866
+ * import { Behaviour, serializable, EventList } from "@needle-tools/engine";
3867
+ * export class ScoreTracker extends Behaviour {
3868
+ * @serializable(EventList)
3869
+ * onScoreChanged?: EventList<number>;
3870
+ *
3871
+ * start() {
3872
+ * // Registered during start → survives enable/disable, cleaned up on destroy
3873
+ * this.autoCleanup(this.onScoreChanged?.on(score => console.log("Score:", score)));
3874
+ * }
3875
+ *
3876
+ * onEnable() {
3877
+ * // Registered during onEnable → cleaned up on disable
3878
+ * this.autoCleanup(() => this.cleanupResources());
3879
+ * }
3880
+ * }
3881
+ * ```
3882
+ *
3660
3883
  * @group Components
3661
3884
  */
3662
3885
  declare abstract class Component implements IComponent, EventTarget, Partial<INeedleXRSessionEventReceiver>, Partial<IPointerEventHandler> {
@@ -3707,6 +3930,50 @@ declare abstract class Component implements IComponent, EventTarget, Partial<INe
3707
3930
  * @returns True if the component is enabled and all parent GameObjects are active
3708
3931
  */
3709
3932
  get activeAndEnabled(): boolean;
3933
+ private __disableCleanups?;
3934
+ private __destroyCleanups?;
3935
+ /**
3936
+ * @experimental
3937
+ * Register a resource for automatic cleanup tied to this component's lifecycle.
3938
+ * Accepts {@link IDisposable} objects, cleanup functions, or event unsubscribe functions.
3939
+ * `null` and `undefined` are safe no-ops (convenient for conditional subscriptions).
3940
+ *
3941
+ * **Lifecycle-aware:** The cleanup store is chosen automatically based on when `autoCleanup` is called:
3942
+ * - Called during {@link onEnable} → cleaned up on {@link onDisable} (and re-registered on re-enable)
3943
+ * - Called during {@link awake} or {@link start} → cleaned up on {@link onDestroy} (survives enable/disable cycles)
3944
+ * - Called at any other time (e.g. from update) → cleaned up on {@link onDisable}
3945
+ *
3946
+ * @param disposable An {@link IDisposable}, a cleanup/unsubscribe function, or `null`/`undefined`
3947
+ *
3948
+ * @example EventList subscriptions
3949
+ * ```ts
3950
+ * import { Behaviour, serializable, EventList } from "@needle-tools/engine";
3951
+ *
3952
+ * export class MyComponent extends Behaviour {
3953
+ * @serializable(EventList)
3954
+ * onScoreChanged?: EventList<number>;
3955
+ *
3956
+ * onEnable() {
3957
+ * this.autoCleanup(this.onScoreChanged?.on(score => {
3958
+ * console.log("Score:", score);
3959
+ * }));
3960
+ * }
3961
+ * }
3962
+ * ```
3963
+ *
3964
+ * @example Lifetime subscriptions in awake
3965
+ * ```ts
3966
+ * import { Behaviour } from "@needle-tools/engine";
3967
+ *
3968
+ * export class Persistent extends Behaviour {
3969
+ * awake() {
3970
+ * // Registered during awake → survives enable/disable, cleaned up on destroy
3971
+ * this.autoCleanup(() => this.save());
3972
+ * }
3973
+ * }
3974
+ * ```
3975
+ */
3976
+ protected autoCleanup(disposable: IDisposable | DisposeFn | Function | null | undefined): void;
3710
3977
  private get __isActive();
3711
3978
  private get __isActiveInHierarchy();
3712
3979
  private set __isActiveInHierarchy(value);
@@ -3725,11 +3992,6 @@ declare abstract class Component implements IComponent, EventTarget, Partial<INe
3725
3992
  * For example, URL to the glTF file this component was loaded from
3726
3993
  */
3727
3994
  sourceId?: SourceIdentifier;
3728
- /**
3729
- * Called when this component needs to remap guids after an instantiate operation.
3730
- * @param guidsMap Mapping from old guids to newly generated guids
3731
- */
3732
- resolveGuids?(guidsMap: GuidsMap): void;
3733
3995
  /**
3734
3996
  * Called once when the component becomes active for the first time.
3735
3997
  * This is the first lifecycle callback to be invoked
@@ -3942,6 +4204,10 @@ declare abstract class Component implements IComponent, EventTarget, Partial<INe
3942
4204
  destroy(): void;
3943
4205
  /* Excluded from this release type: __didAwake */
3944
4206
  /* Excluded from this release type: __didStart */
4207
+ /** True while start() has finished executing (used by autoCleanup to distinguish start from update) */
4208
+ private __didCompleteStart;
4209
+ /** True while onEnable() is executing (used by autoCleanup to route to disable store) */
4210
+ private __inEnableOrDisableCallback;
3945
4211
  /* Excluded from this release type: __didEnable */
3946
4212
  /* Excluded from this release type: __isEnabled */
3947
4213
  /* Excluded from this release type: __destroyed */
@@ -4231,6 +4497,7 @@ export declare class ContactShadows extends Component {
4231
4497
  set needsUpdate(val: boolean);
4232
4498
  get needsUpdate(): boolean;
4233
4499
  private _needsUpdate;
4500
+ private _needsFit;
4234
4501
  /** All shadow objects are parented to this object.
4235
4502
  * The gameObject itself should not be transformed because we want the ContactShadows object e.g. also have a GroundProjectedEnv component
4236
4503
  * in which case ContactShadows scale would affect the projection
@@ -4484,19 +4751,31 @@ export declare class Context implements IContext {
4484
4751
  private _mainCamera;
4485
4752
  private _fallbackCamera;
4486
4753
  /** access application state (e.g. if all audio should be muted) */
4487
- application: Application;
4754
+ get application(): Application;
4755
+ private _application;
4488
4756
  /** access animation mixer used by components in the scene */
4489
- animations: AnimationsRegistry;
4757
+ get animations(): AnimationsRegistry;
4758
+ private _animations;
4490
4759
  /** access timings (current frame number, deltaTime, timeScale, ...) */
4491
- time: Time;
4760
+ get time(): Time;
4761
+ private _time;
4492
4762
  /** access input data (e.g. click or touch events) */
4493
- input: Input;
4763
+ get input(): Input;
4764
+ private _input;
4494
4765
  /** access physics related methods (e.g. raycasting). To access the phyiscs engine use `context.physics.engine` */
4495
- physics: Physics;
4766
+ get physics(): Physics;
4767
+ private _physics;
4496
4768
  /** access postprocessing effects stack. Add/remove effects and configure adaptive performance settings */
4497
- postprocessing: PostProcessing;
4769
+ get postprocessing(): PostProcessing;
4770
+ private _postprocessing;
4498
4771
  /** access networking methods (use it to send or listen to messages or join a networking backend) */
4499
- connection: NetworkConnection;
4772
+ get connection(): NetworkConnection;
4773
+ private _connection;
4774
+ /** context-level event bus for decoupled component communication
4775
+ * @see {@link ContextEventMap} for known event types
4776
+ */
4777
+ get events(): EventBus;
4778
+ private _events;
4500
4779
  /** @deprecated AssetDatabase is deprecated */
4501
4780
  assets: AssetDatabase;
4502
4781
  /** All registered lights in the scene, maintained by the Light component.
@@ -4755,6 +5034,18 @@ export declare type ContextEventArgs = {
4755
5034
  files?: LoadedModel[];
4756
5035
  };
4757
5036
 
5037
+ /** Typed event map for {@link Context.events}.
5038
+ * Known events get full autocomplete; custom events can be typed at the call site via generic parameter.
5039
+ */
5040
+ export declare interface ContextEventMap {
5041
+ "scene-content-changed": {
5042
+ /** The component that triggered the change (e.g. SceneSwitcher, DropListener) */
5043
+ readonly source: IComponent;
5044
+ /** The root object that was added/loaded */
5045
+ readonly object: Object3D;
5046
+ };
5047
+ }
5048
+
4758
5049
  /** Use to register to various Needle Engine context events and to get access to all current instances
4759
5050
  * e.g. when being created in the DOM
4760
5051
  * @example
@@ -4806,6 +5097,20 @@ export declare type ControlClipModel = {
4806
5097
  updateDirector: boolean;
4807
5098
  };
4808
5099
 
5100
+ /**
5101
+ * Options for a control clip in the timeline builder
5102
+ */
5103
+ export declare type ControlClipOptions = {
5104
+ /** Start time of the clip in seconds. If omitted, placed after the previous clip on this track. */
5105
+ start?: number;
5106
+ /** Duration of the clip in seconds (required) */
5107
+ duration: number;
5108
+ /** Whether to control the activation of the source object (default: true) */
5109
+ controlActivation?: boolean;
5110
+ /** Whether to update a nested PlayableDirector on the source object (default: true) */
5111
+ updateDirector?: boolean;
5112
+ };
5113
+
4809
5114
  /** true when selectstart was ever received.
4810
5115
  * On VisionOS 1.1 we always have select events (as per the spec), so this is always true
4811
5116
  */
@@ -4816,12 +5121,15 @@ declare type ControllerAxes = "xr-standard-thumbstick" | "xr-standard-touchpad";
4816
5121
  */
4817
5122
  export declare type ControllerChangedEvt = (args: NeedleXRControllerEventArgs) => void;
4818
5123
 
4819
- export declare class ControlTrackHandler extends TrackHandler {
4820
- models: Array<Models.ClipModel>;
4821
- timelines: Array<PlayableDirector | null>;
4822
- resolveSourceObjects(_context: Context): void;
4823
- private _previousActiveModel;
4824
- evaluate(time: number): void;
5124
+ /**
5125
+ * Builder for control tracks. Provides `.clip()` for controlling nested objects/timelines.
5126
+ * @category Animation and Sequencing
5127
+ */
5128
+ export declare interface ControlTrackBuilder extends TimelineBuilderBase {
5129
+ /** Adds a control clip for a source object */
5130
+ clip(sourceObject: Object3D, options: ControlClipOptions): ControlTrackBuilder;
5131
+ /** Mutes this track so it is skipped during playback */
5132
+ muted(muted?: boolean): ControlTrackBuilder;
4825
5133
  }
4826
5134
 
4827
5135
  /**@obsolete use Graphics.copyTexture */
@@ -5009,7 +5317,6 @@ export declare class CursorFollow extends Component {
5009
5317
  * - Cursor that follows terrain or mesh surfaces
5010
5318
  *
5011
5319
  * **Important notes:**
5012
- * - Requires objects in the scene to have colliders for raycasting to work
5013
5320
  * - Works best with {@link keepDistance} set to `false` to allow depth changes
5014
5321
  * - Can be combined with {@link damping} for smooth surface following
5015
5322
  * - The raycast uses the physics system's raycast functionality
@@ -5136,7 +5443,7 @@ export declare function decompressGpuTexture(texture: any, maxTextureSize?: numb
5136
5443
  * return true;
5137
5444
  * });
5138
5445
  * */
5139
- export declare function deepClone(obj: any, predicate?: deepClonePredicate): any;
5446
+ export declare function deepClone(obj: any, predicate?: deepClonePredicate, _visited?: WeakSet<object>): any;
5140
5447
 
5141
5448
  declare type deepClonePredicate = (owner: any, propertyName: string, current: any) => boolean;
5142
5449
 
@@ -5364,7 +5671,7 @@ export declare namespace DeviceUtilities {
5364
5671
  * Controls how the {@link PlayableDirector} behaves when playback reaches the end.
5365
5672
  * @see {@link PlayableDirector.extrapolationMode}
5366
5673
  */
5367
- declare enum DirectorWrapMode {
5674
+ export declare enum DirectorWrapMode {
5368
5675
  /** Hold the last frame when playback reaches the end of the timeline. */
5369
5676
  Hold = 0,
5370
5677
  /** Loop back to the start and continue playing indefinitely. */
@@ -5373,6 +5680,101 @@ declare enum DirectorWrapMode {
5373
5680
  None = 2
5374
5681
  }
5375
5682
 
5683
+ /**
5684
+ * A store for managing disposable resources (event subscriptions, listeners, callbacks)
5685
+ * that should be cleaned up together.
5686
+ *
5687
+ * DisposableStore collects disposables and disposes them all at once when
5688
+ * {@link dispose} is called. After disposal, the store can be reused — new items
5689
+ * can be added and a subsequent {@link dispose} call will clean those up.
5690
+ *
5691
+ * This is the same pattern used internally by VSCode for lifecycle-bound resource management.
5692
+ *
5693
+ * @example Basic usage
5694
+ * ```ts
5695
+ * import { DisposableStore, on } from "@needle-tools/engine";
5696
+ *
5697
+ * const store = new DisposableStore();
5698
+ *
5699
+ * // Register a DOM event listener (typed!)
5700
+ * store.add(on(window, "resize", (ev) => console.log(ev)));
5701
+ *
5702
+ * // Register the return value of EventList.on()
5703
+ * store.add(myEventList.on(data => console.log(data)));
5704
+ *
5705
+ * // Register a raw cleanup function
5706
+ * store.add(() => someSDK.off("event", handler));
5707
+ *
5708
+ * // Later: dispose everything at once
5709
+ * store.dispose();
5710
+ * ```
5711
+ *
5712
+ * @example Use with Needle Engine components
5713
+ * ```ts
5714
+ * import { Behaviour, serializable, EventList, on } from "@needle-tools/engine";
5715
+ *
5716
+ * export class MyComponent extends Behaviour {
5717
+ * @serializable(EventList)
5718
+ * onClick?: EventList;
5719
+ *
5720
+ * onEnable() {
5721
+ * // DOM events — fully typed
5722
+ * this.autoCleanup(on(window, "resize", (ev) => this.onResize(ev)));
5723
+ *
5724
+ * // EventList — .on() returns a function, autoCleanup accepts it
5725
+ * this.autoCleanup(this.onClick?.on(() => console.log("clicked!")));
5726
+ * }
5727
+ * // No onDisable needed — cleaned up automatically!
5728
+ * }
5729
+ * ```
5730
+ *
5731
+ * @category Utilities
5732
+ * @group Lifecycle
5733
+ */
5734
+ export declare class DisposableStore implements IDisposable {
5735
+ private _disposables;
5736
+ /** The number of registered disposables */
5737
+ get size(): number;
5738
+ /**
5739
+ * Register a disposable resource. Accepts:
5740
+ * - An {@link IDisposable} object (has a `dispose()` method) — e.g. from {@link on}
5741
+ * - A cleanup function (e.g. return value of `EventList.on()`)
5742
+ * - `null` or `undefined` (safe no-op for conditional subscriptions)
5743
+ *
5744
+ * When {@link dispose} is called, all registered resources are cleaned up.
5745
+ *
5746
+ * @param disposable The resource to register for disposal
5747
+ *
5748
+ * @example
5749
+ * ```ts
5750
+ * const store = new DisposableStore();
5751
+ *
5752
+ * // IDisposable object from on()
5753
+ * store.add(on(window, "resize", handler));
5754
+ *
5755
+ * // Function returned by EventList.on()
5756
+ * store.add(myEvent.on(handler));
5757
+ *
5758
+ * // Raw cleanup function
5759
+ * store.add(() => connection.close());
5760
+ *
5761
+ * // Conditional — safe with undefined
5762
+ * store.add(this.maybeEvent?.on(handler));
5763
+ * ```
5764
+ */
5765
+ add(disposable: IDisposable | DisposeFn | Function | null | undefined): void;
5766
+ /**
5767
+ * Dispose all registered resources. Each registered disposable is cleaned up,
5768
+ * then the internal list is cleared. The store can be reused after disposal.
5769
+ *
5770
+ * Called automatically by the engine when a component's `onDisable` lifecycle fires.
5771
+ */
5772
+ dispose(): void;
5773
+ }
5774
+
5775
+ /** A function that performs cleanup when called */
5776
+ export declare type DisposeFn = () => void;
5777
+
5376
5778
  /** Recursive disposes all referenced resources by this object. Does not traverse children */
5377
5779
  export declare function disposeObjectResources(obj: object | null | undefined): void;
5378
5780
 
@@ -5480,6 +5882,12 @@ export declare class DragControls extends Component implements IPointerEventHand
5480
5882
  * providing visual feedback about the object's position relative to surfaces below it.
5481
5883
  */
5482
5884
  showGizmo: boolean;
5885
+ /** Invoked once when a drag begins (after the minimum drag distance threshold is met). */
5886
+ dragStarted: EventList;
5887
+ /** Invoked every frame while the object is being dragged. */
5888
+ dragUpdated: EventList;
5889
+ /** Invoked once when the last pointer is released and the drag ends. */
5890
+ dragEnded: EventList;
5483
5891
  /**
5484
5892
  * Returns the object currently being dragged by this DragControls component, if any.
5485
5893
  * @returns The object being dragged or null if no object is currently dragged
@@ -5920,6 +6328,45 @@ export declare class EnvironmentScene extends Scene {
5920
6328
  createAreaLightMaterial(intensity: number): MeshBasicMaterial;
5921
6329
  }
5922
6330
 
6331
+ /** An Euler value, either as a Three.js Euler or as a `[x, y, z]` tuple (radians) */
6332
+ declare type EulerValue = Euler | [number, number, number];
6333
+
6334
+ /** Typed event bus. Known {@link ContextEventMap} events get full autocomplete.
6335
+ * Custom events can be typed at the call site via generic parameter.
6336
+ * @example Known events
6337
+ * ```ts
6338
+ * context.events.on("scene-content-changed", e => e.object);
6339
+ * ```
6340
+ * @example Custom events — type at call site
6341
+ * ```ts
6342
+ * context.events.emit<{ pts: number }>("scored", { pts: 10 });
6343
+ * context.events.on<{ pts: number }>("scored", e => e.pts);
6344
+ * ```
6345
+ * @example Once
6346
+ * ```ts
6347
+ * context.events.on("scene-content-changed", e => { ... }, { once: true });
6348
+ * ```
6349
+ */
6350
+ export declare class EventBus {
6351
+ private _listeners;
6352
+ /** Emit a known {@link ContextEventMap} event */
6353
+ emit<K extends keyof ContextEventMap & string>(type: K, detail?: ContextEventMap[K]): void;
6354
+ /** Emit a custom event with user-provided type */
6355
+ emit<T>(type: string, detail?: T): void;
6356
+ /** Subscribe to a known {@link ContextEventMap} event. Returns an unsubscribe function. */
6357
+ on<K extends keyof ContextEventMap & string>(type: K, callback: (args: ContextEventMap[K]) => void, options?: EventBusListenerOptions): () => void;
6358
+ /** Subscribe to a custom event with user-provided type. Returns an unsubscribe function. */
6359
+ on<T>(type: string, callback: (args: T) => void, options?: EventBusListenerOptions): () => void;
6360
+ /** Remove all listeners. Called when the context is cleared or destroyed. */
6361
+ clear(): void;
6362
+ }
6363
+
6364
+ /** Options for {@link EventBus.on}. */
6365
+ export declare interface EventBusListenerOptions {
6366
+ /** If true the listener is automatically removed after the first invocation. */
6367
+ once?: boolean;
6368
+ }
6369
+
5923
6370
  /**
5924
6371
  * EventList manages a list of callbacks that can be invoked together.
5925
6372
  * Used for Unity-style events that can be configured in the editor (Unity or Blender).
@@ -5966,13 +6413,9 @@ export declare class EnvironmentScene extends Scene {
5966
6413
  * @see {@link Button} for UI button events
5967
6414
  */
5968
6415
  export declare class EventList<TArgs extends any = any> implements IEventList {
6416
+ $serializedTypes: Record<string, any>;
5969
6417
  /** checked during instantiate to create a new instance */
5970
6418
  readonly isEventList = true;
5971
- /* Excluded from this release type: __internalOnInstantiate */
5972
- private target?;
5973
- private key?;
5974
- /** set an event target to try invoke the EventTarget dispatchEvent when this EventList is invoked */
5975
- setEventTarget(key: string, target: object): void;
5976
6419
  /** How many callback methods are subscribed to this event */
5977
6420
  get listenerCount(): number;
5978
6421
  /** If the event is currently being invoked */
@@ -6005,13 +6448,41 @@ export declare class EventList<TArgs extends any = any> implements IEventList {
6005
6448
  invoke(...args: Array<TArgs>): boolean;
6006
6449
  /** Add a new event listener to this event
6007
6450
  * @returns a function to remove the event listener
6451
+ * @see {@link removeEventListener} for more details and return value information
6452
+ * @see {@link off} for an alias with better readability when unsubscribing from events
6453
+ * @example
6454
+ * ```ts
6455
+ * const off = myEvent.addEventListener(args => console.log("Clicked!", args));
6456
+ * // later
6457
+ * off();
6458
+ * ```
6008
6459
  */
6009
6460
  addEventListener(callback: (args: TArgs) => void): Function;
6461
+ /**
6462
+ * Alias for addEventListener for better readability when subscribing to events. You can use it like this:
6463
+ * ```ts
6464
+ * myEvent.on(args => console.log("Clicked!", args));
6465
+ * ```
6466
+ * @returns a function to remove the event listener
6467
+ * @see {@link addEventListener} for more details and return value information
6468
+ */
6469
+ on(callback: (args: TArgs) => void): Function;
6010
6470
  /**
6011
6471
  * Remove an event listener from this event.
6012
6472
  * @returns true if the event listener was found and removed, false otherwise
6013
6473
  */
6014
6474
  removeEventListener(fn: Function | null | undefined): boolean;
6475
+ /**
6476
+ * Alias for removeEventListener for better readability when unsubscribing from events. You can use it like this:
6477
+ * ```ts
6478
+ * const off = myEvent.on(args => console.log("Clicked!", args));
6479
+ * // later
6480
+ * off();
6481
+ * ```
6482
+ *
6483
+ * @see {@link removeEventListener} for more details and return value information
6484
+ */
6485
+ off(callback: Function | null | undefined): boolean;
6015
6486
  /**
6016
6487
  * Remove all event listeners from this event. Use with caution! This will remove all listeners!
6017
6488
  */
@@ -6042,6 +6513,7 @@ declare type EventListenerOptions_2 = {
6042
6513
  signal?: AbortSignal;
6043
6514
  };
6044
6515
 
6516
+ /** @deprecated No longer automatically dispatched. Use `eventList.on()` directly instead. */
6045
6517
  export declare class EventListEvent<TArgs extends any> extends Event {
6046
6518
  args?: TArgs;
6047
6519
  }
@@ -6495,7 +6967,7 @@ declare type FitParameters = {
6495
6967
  * @see {@link HingeJoint} for rotating connections
6496
6968
  */
6497
6969
  export declare class FixedJoint extends Joint {
6498
- protected createJoint(self: Rigidbody, other: Rigidbody): void;
6970
+ protected createJoint(self: Rigidbody, other: Rigidbody): any;
6499
6971
  }
6500
6972
 
6501
6973
  declare type FocusRect = DOMRect | Element | {
@@ -7679,14 +8151,8 @@ export declare type GuidsMap = {
7679
8151
  [key: string]: string;
7680
8152
  };
7681
8153
 
7682
- /* Excluded from this release type: hasCommercialLicense */
7683
-
7684
- /* Excluded from this release type: hasIndieLicense */
7685
-
7686
8154
  /* Excluded from this release type: hasPointerEventComponent */
7687
8155
 
7688
- /* Excluded from this release type: hasProLicense */
7689
-
7690
8156
  export declare function hideDebugConsole(): void;
7691
8157
 
7692
8158
  export declare enum HideFlags {
@@ -7746,7 +8212,7 @@ export declare class HingeJoint extends Joint {
7746
8212
  anchor?: Vector3;
7747
8213
  /** Axis of rotation for the hinge (e.g., Vector3(0,1,0) for vertical axis) */
7748
8214
  axis?: Vector3;
7749
- protected createJoint(self: Rigidbody, other: Rigidbody): void;
8215
+ protected createJoint(self: Rigidbody, other: Rigidbody): any;
7750
8216
  }
7751
8217
 
7752
8218
  declare type HitPointObject = Object3D & {
@@ -7969,7 +8435,7 @@ declare const HTMLElementBase: typeof HTMLElement;
7969
8435
 
7970
8436
  export declare type IAnimationComponent = Pick<IComponent, "gameObject"> & {
7971
8437
  isAnimationComponent: boolean;
7972
- addClip?(clip: AnimationClip): any;
8438
+ addClip?(clip: AnimationClip): void;
7973
8439
  };
7974
8440
 
7975
8441
  /* Excluded from this release type: IApplyPrototypeExtension */
@@ -8043,6 +8509,12 @@ export declare interface ICollider extends IComponent {
8043
8509
  * Default: undefined
8044
8510
  */
8045
8511
  filter?: number[];
8512
+ /** The density of the collider used for automatic mass calculation.
8513
+ * When the attached Rigidbody has `autoMass` enabled, the mass is computed as `density × volume`.
8514
+ * Note: Make sure to call updateProperties after having changed this property
8515
+ * Default: undefined (uses physics engine default of 1.0)
8516
+ */
8517
+ density?: number;
8046
8518
  }
8047
8519
 
8048
8520
  export declare type ICollisionContext = {
@@ -8069,7 +8541,6 @@ export declare interface IComponent extends IHasGuid {
8069
8541
  /* Excluded from this release type: __internalEnable */
8070
8542
  /* Excluded from this release type: __internalDisable */
8071
8543
  /* Excluded from this release type: __internalDestroy */
8072
- /* Excluded from this release type: resolveGuids */
8073
8544
  /** experimental, called when the script is registered for the first time, this is called even if the component is not enabled. */
8074
8545
  registering?(): any;
8075
8546
  awake(): any;
@@ -8106,6 +8577,24 @@ export declare interface IConnectionData {
8106
8577
 
8107
8578
  export declare type IContext = Context;
8108
8579
 
8580
+ /**
8581
+ * Interface for objects that hold resources and can be disposed.
8582
+ * Implement this interface on any object that needs deterministic cleanup.
8583
+ *
8584
+ * @example
8585
+ * ```ts
8586
+ * class MyResource implements IDisposable {
8587
+ * dispose() { /* release resources *\/ }
8588
+ * }
8589
+ * ```
8590
+ *
8591
+ * @category Utilities
8592
+ * @group Lifecycle
8593
+ */
8594
+ export declare interface IDisposable {
8595
+ dispose(): void;
8596
+ }
8597
+
8109
8598
  /** Implement to receive callbacks from {@type @needle-tools/editor-sync} package */
8110
8599
  declare interface IEditorModification {
8111
8600
  /**
@@ -8125,7 +8614,6 @@ export declare interface IEffectProvider {
8125
8614
 
8126
8615
  export declare interface IEventList {
8127
8616
  readonly isEventList: true;
8128
- __internalOnInstantiate(map: InstantiateContext): IEventList;
8129
8617
  }
8130
8618
 
8131
8619
  export declare interface IGameObject extends Object3D {
@@ -8418,13 +8906,45 @@ export declare interface INeedleXRSessionEventReceiver extends Pick<IComponent,
8418
8906
  export declare interface INetworkConnection {
8419
8907
  get isConnected(): boolean;
8420
8908
  get isInRoom(): boolean;
8421
- send(key: string, data: IModel | object | boolean | null | string | number, queue: SendQueue): unknown;
8909
+ send(key: string, data?: IModel | object | boolean | string | number, queue?: SendQueue): unknown;
8422
8910
  }
8423
8911
 
8424
8912
  export declare interface INetworkingWebsocketUrlProvider {
8425
8913
  getWebsocketUrl(): string | null;
8426
8914
  }
8427
8915
 
8916
+ /**
8917
+ * @experimental
8918
+ * Interface for a network transport layer used by {@link NetworkConnection}.
8919
+ * The default implementation wraps a websocket via `websocket-ts`.
8920
+ * Custom implementations can be injected into {@link NetworkConnection.connect}
8921
+ * for testing or alternative transports.
8922
+ *
8923
+ * **Lifecycle:** After creating a transport and passing it to `connect()`,
8924
+ * `NetworkConnection` sets the four event callbacks (`onOpen`, `onClose`,
8925
+ * `onError`, `onMessage`) and then calls {@link start}. The transport
8926
+ * should call `onOpen` when the connection is ready.
8927
+ */
8928
+ export declare interface INetworkTransport {
8929
+ /** Start the connection. Called by NetworkConnection after event callbacks are set.
8930
+ * May return a promise if setup is async (e.g. dynamic imports). */
8931
+ start(): void | Promise<void>;
8932
+ /** Send data (string for JSON messages, Uint8Array for binary) */
8933
+ send(data: string | Uint8Array): void;
8934
+ /** Close the transport */
8935
+ close(): void | Promise<void>;
8936
+ /** The URL this transport is connected to, if applicable */
8937
+ readonly url: string | undefined;
8938
+ /** Called when the transport connection opens */
8939
+ onOpen: (() => void) | null;
8940
+ /** Called when the transport connection closes */
8941
+ onClose: (() => void) | null;
8942
+ /** Called when an error occurs */
8943
+ onError: ((err: any) => void) | null;
8944
+ /** Called when a message is received. Data is either a string (JSON) or Blob (binary). */
8945
+ onMessage: ((data: string | Blob) => void) | null;
8946
+ }
8947
+
8428
8948
  export declare class InheritVelocityModule {
8429
8949
  enabled: boolean;
8430
8950
  curve: MinMaxCurve;
@@ -8511,14 +9031,33 @@ export declare class Input implements IInput {
8511
9031
  */
8512
9032
  private readonly _eventListeners;
8513
9033
  /** Adds an event listener for the specified event type. The callback will be called when the event is triggered.
9034
+ *
9035
+ * Returns an unsubscribe function — call it to remove the listener.
9036
+ * Pass it to {@link Behaviour.autoCleanup} for automatic lifecycle management.
9037
+ *
8514
9038
  * @param type The event type to listen for
8515
9039
  * @param callback The callback to call when the event is triggered
8516
9040
  * @param options The options for adding the event listener.
8517
- * @example Basic usage
9041
+ * @returns A function that removes the event listener when called.
9042
+ *
9043
+ * @example With autoCleanup (recommended)
8518
9044
  * ```ts
8519
- * input.addEventListener("pointerdown", (evt) => {
9045
+ * export class MyComponent extends Behaviour {
9046
+ * onEnable() {
9047
+ * this.autoCleanup(this.context.input.addEventListener("pointerdown", (evt) => {
9048
+ * console.log("Pointer down", evt.pointerId, evt.pointerType);
9049
+ * }));
9050
+ * }
9051
+ * // Listener is automatically removed on disable — no manual cleanup needed!
9052
+ * }
9053
+ * ```
9054
+ * @example Manual unsubscribe
9055
+ * ```ts
9056
+ * const off = input.addEventListener("pointerdown", (evt) => {
8520
9057
  * console.log("Pointer down", evt.pointerId, evt.pointerType);
8521
9058
  * });
9059
+ * // later
9060
+ * off();
8522
9061
  * ```
8523
9062
  * @example Adding a listener that is called after all other listeners
8524
9063
  * By using a higher value for the queue the listener will be called after other listeners (default queue is 0).
@@ -8534,8 +9073,8 @@ export declare class Input implements IInput {
8534
9073
  * }, { once: true });
8535
9074
  * ```
8536
9075
  */
8537
- addEventListener(type: PointerEventNames, callback: PointerEventListener, options?: EventListenerOptions_2): any;
8538
- addEventListener(type: KeyboardEventNames, callback: KeyboardEventListener, options?: EventListenerOptions_2): any;
9076
+ addEventListener(type: PointerEventNames, callback: PointerEventListener, options?: EventListenerOptions_2): () => void;
9077
+ addEventListener(type: KeyboardEventNames, callback: KeyboardEventListener, options?: EventListenerOptions_2): () => void;
8539
9078
  /** Removes the event listener from the specified event type. If no queue is specified the listener will be removed from all queues.
8540
9079
  * @param type The event type to remove the listener from
8541
9080
  * @param callback The callback to remove
@@ -8981,7 +9520,7 @@ export declare function instantiate(instance: AssetReference, opts?: IInstantiat
8981
9520
  export declare function instantiate(instance: IGameObject | Object3D, opts?: IInstantiateOptions | null): IGameObject;
8982
9521
 
8983
9522
  /**
8984
- * Provides access to the instantiated object and its clone
9523
+ * Provides access to the instantiated object map (used by EventList etc.)
8985
9524
  */
8986
9525
  export declare type InstantiateContext = Readonly<InstantiateReferenceMap>;
8987
9526
 
@@ -9021,7 +9560,8 @@ export declare class InstantiateOptions implements IInstantiateOptions {
9021
9560
  cloneAssign(other: InstantiateOptions | IInstantiateOptions): void;
9022
9561
  }
9023
9562
 
9024
- declare type InstantiateReferenceMap = Record<string, ObjectCloneReference>;
9563
+ /** Maps uuid/guid { original, clone } for Object3D and Component instances */
9564
+ export declare type InstantiateReferenceMap = Record<string, ObjectCloneReference>;
9025
9565
 
9026
9566
  /**
9027
9567
  * An empty component that can be used to mark an object as interactable.
@@ -9092,8 +9632,10 @@ export declare interface IPhysicsEngine {
9092
9632
  postStep(): any;
9093
9633
  /** Indicates whether the physics engine is currently updating */
9094
9634
  get isUpdating(): boolean;
9095
- /** Clears all cached data (e.g., mesh data when creating scaled mesh colliders) */
9096
- clearCaches(): any;
9635
+ /** Tears down the physics world and frees all resources. The world will be re-created on next use. */
9636
+ dispose(): void;
9637
+ /** @deprecated Use {@link dispose} instead. */
9638
+ clearCaches(): void;
9097
9639
  /** Enables or disables the physics engine */
9098
9640
  enabled: boolean;
9099
9641
  /** Returns the underlying physics world object */
@@ -9140,6 +9682,11 @@ export declare interface IPhysicsEngine {
9140
9682
  * @returns False to ignore this collider, true to include it
9141
9683
  */
9142
9684
  filterPredicate?: (collider: ICollider) => boolean;
9685
+ /** When true, trigger/sensor colliders will be included in the raycast results.
9686
+ * By default trigger colliders are skipped.
9687
+ * @default false
9688
+ */
9689
+ includeTriggers?: boolean;
9143
9690
  }): RaycastResult;
9144
9691
  /**
9145
9692
  * Performs a raycast that also returns the normal vector at the hit point
@@ -9167,6 +9714,11 @@ export declare interface IPhysicsEngine {
9167
9714
  * @returns False to ignore this collider, true to include it
9168
9715
  */
9169
9716
  filterPredicate?: (collider: ICollider) => boolean;
9717
+ /** When true, trigger/sensor colliders will be included in the raycast results.
9718
+ * By default trigger colliders are skipped.
9719
+ * @default false
9720
+ */
9721
+ includeTriggers?: boolean;
9170
9722
  }): RaycastResult;
9171
9723
  /**
9172
9724
  * Finds all colliders within a sphere
@@ -9323,8 +9875,9 @@ export declare interface IPhysicsEngine {
9323
9875
  * @returns The underlying physics body or null if not found
9324
9876
  */
9325
9877
  getBody(obj: ICollider | IRigidbody): null | any;
9326
- addFixedJoint(body1: IRigidbody, body2: IRigidbody): any;
9327
- addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3): any;
9878
+ addFixedJoint(body1: IRigidbody, body2: IRigidbody): Promise<any> | any;
9879
+ addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: Vec3, axis: Vec3): Promise<any> | any;
9880
+ removeJoint(joint: any): void;
9328
9881
  /** Enable to render collider shapes */
9329
9882
  debugRenderColliders: boolean;
9330
9883
  /** Enable to visualize raycasts in the scene with gizmos */
@@ -9545,6 +10098,18 @@ export declare function isDestroyed(go: Object3D): boolean;
9545
10098
  /** True when the application runs on a local url */
9546
10099
  export declare function isDevEnvironment(): boolean;
9547
10100
 
10101
+ /**
10102
+ * Type guard to check if an object implements {@link IDisposable}.
10103
+ *
10104
+ * @example
10105
+ * ```ts
10106
+ * if (isDisposable(obj)) {
10107
+ * obj.dispose(); // safe to call
10108
+ * }
10109
+ * ```
10110
+ */
10111
+ export declare function isDisposable(value: unknown): value is IDisposable;
10112
+
9548
10113
  export declare function isDisposed(obj: object): boolean;
9549
10114
 
9550
10115
  export declare interface ISerializable {
@@ -9579,6 +10144,10 @@ export declare function isHotReloadEnabled(): boolean;
9579
10144
  /**@returns true if the element is an needle engine icon element */
9580
10145
  export declare function isIconElement(element: Node): boolean;
9581
10146
 
10147
+ export declare interface ISignalReceiver {
10148
+ readonly isSignalReceiver: true;
10149
+ }
10150
+
9582
10151
  /** @deprecated use {@link DeviceUtilities.isiOS} instead */
9583
10152
  export declare function isiOS(): boolean;
9584
10153
 
@@ -9613,6 +10182,8 @@ export declare function isResourceTrackingEnabled(): boolean;
9613
10182
  /** @deprecated use {@link DeviceUtilities.isSafari} instead */
9614
10183
  export declare function isSafari(): boolean;
9615
10184
 
10185
+ export declare function isTrackModel(obj: unknown): obj is TrackModel;
10186
+
9616
10187
  export declare function isUsingInstancing(instance: Object3D): boolean;
9617
10188
 
9618
10189
  export declare interface ITime {
@@ -9737,7 +10308,9 @@ declare abstract class Joint extends Component {
9737
10308
  connectedBody?: Rigidbody;
9738
10309
  get rigidBody(): Rigidbody | null;
9739
10310
  private _rigidBody;
10311
+ private _jointHandle;
9740
10312
  onEnable(): void;
10313
+ onDisable(): void;
9741
10314
  private create;
9742
10315
  protected abstract createJoint(self: Rigidbody, other: Rigidbody): any;
9743
10316
  }
@@ -9779,6 +10352,15 @@ declare class Keyframe_2 {
9779
10352
  }
9780
10353
  export { Keyframe_2 as Keyframe }
9781
10354
 
10355
+ /** Keyframe array or tween shorthand */
10356
+ declare type KF<V> = AnimationKeyframe<V>[] | Tween<V>;
10357
+
10358
+ /** Keyframe array or tween shorthand */
10359
+ declare type KF_2<V> = AnimationKeyframe<V>[] | Tween<V>;
10360
+
10361
+ /** Keyframe array or tween shorthand */
10362
+ declare type KF_3<V> = AnimationKeyframe<V>[] | Tween<V>;
10363
+
9782
10364
  declare type LabelHandle = {
9783
10365
  setText(str: string): any;
9784
10366
  };
@@ -10447,13 +11029,15 @@ export declare function markAsInstancedRendered(go: Object3D, instanced: boolean
10447
11029
  time: number;
10448
11030
  }
10449
11031
 
10450
- export declare class MarkerTrackHandler extends TrackHandler {
10451
- models: Array<Models.MarkerModel & Record<string, any>>;
10452
- needsSorting: boolean;
10453
- foreachMarker<T>(type?: string | null): Generator<T, void, unknown>;
10454
- onEnable(): void;
10455
- evaluate(_time: number): void;
10456
- private sort;
11032
+ /**
11033
+ * Builder for marker tracks. Provides `.marker()` for adding markers.
11034
+ * @category Animation and Sequencing
11035
+ */
11036
+ export declare interface MarkerTrackBuilder extends TimelineBuilderBase {
11037
+ /** Adds a marker referencing a signal asset by guid */
11038
+ marker(time: number, asset: string, options?: SignalMarkerOptions): MarkerTrackBuilder;
11039
+ /** Mutes this track so it is skipped during playback */
11040
+ muted(muted?: boolean): MarkerTrackBuilder;
10457
11041
  }
10458
11042
 
10459
11043
  export declare enum MarkerType {
@@ -10999,6 +11583,7 @@ export declare type Model = (GLTF | FBX | OBJ | CustomModel);
10999
11583
 
11000
11584
  declare namespace Models {
11001
11585
  export {
11586
+ isTrackModel,
11002
11587
  TimelineAssetModel,
11003
11588
  TrackType,
11004
11589
  ClipExtrapolation,
@@ -11206,11 +11791,17 @@ export declare interface NeedleEngineAttributes {
11206
11791
  'hash': string;
11207
11792
  /** Set to automatically add OrbitControls to the loaded scene. */
11208
11793
  'camera-controls': string;
11209
- /** Override the default draco decoder path location. */
11794
+ /** Override the default Draco decoder/decompressor path. Can be a URL or a local path to a directory containing the Draco decoder files.
11795
+ * @default "https://www.gstatic.com/draco/versioned/decoders/1.5.7/"
11796
+ * @example <needle-engine dracoDecoderPath="./decoders/draco/"></needle-engine>
11797
+ */
11210
11798
  'dracoDecoderPath': string;
11211
- /** Override the default draco library type. */
11799
+ /** Override the default Draco decoder type. */
11212
11800
  'dracoDecoderType': 'wasm' | 'js';
11213
- /** Override the default KTX2 transcoder/decoder path. */
11801
+ /** Override the default KTX2 transcoder/decoder path. Can be a URL or a local path to a directory containing the KTX2 transcoder files.
11802
+ * @default "https://cdn.needle.tools/static/three/0.179.1/basis2/"
11803
+ * @example <needle-engine ktx2DecoderPath="./decoders/ktx2/"></needle-engine>
11804
+ */
11214
11805
  'ktx2DecoderPath': string;
11215
11806
  /** Prevent context from being disposed when element is removed from DOM. */
11216
11807
  'keep-alive': 'true' | 'false';
@@ -12164,8 +12755,7 @@ export declare class NeedleXRSession implements INeedleXRSession {
12164
12755
  get referenceSpace(): XRSpace | null;
12165
12756
  /** @returns the XRFrame `viewerpose` using the xr `referenceSpace` */
12166
12757
  get viewerPose(): XRViewerPose | undefined;
12167
- /** @returns `true` if any image is currently being tracked */
12168
- /** returns true if images are currently being tracked */
12758
+ /** @returns `true` if any image is currently being tracked or emulated */
12169
12759
  get isTrackingImages(): boolean;
12170
12760
  /** The currently active XR rig */
12171
12761
  get rig(): IXRRig | null;
@@ -12211,6 +12801,8 @@ export declare class NeedleXRSession implements INeedleXRSession {
12211
12801
  private readonly _xr_update_scripts;
12212
12802
  /** scripts that are in the scene but inactive (e.g. disabled parent gameObject) */
12213
12803
  private readonly _inactive_scripts;
12804
+ /** tracks scripts that have received onEnterXR — prevents spurious onLeaveXR calls */
12805
+ private readonly _scripts_in_xr;
12214
12806
  private readonly _controllerAdded;
12215
12807
  private readonly _controllerRemoved;
12216
12808
  private readonly _originalCameraWorldPosition?;
@@ -12598,7 +13190,7 @@ export declare class NetworkConnection implements INetworkConnection {
12598
13190
  /** Use to leave a room that you are currently connected to (use `leaveRoom()` to disconnect from the currently active room but you can also specify a room name) */
12599
13191
  leaveRoom(room?: string | null): boolean;
12600
13192
  /** Send a message to the networking backend - it will be broadcasted to all connected users (except yourself) in the same room by default */
12601
- send<K extends NetworkEventKey>(key: K, data?: (K extends keyof NetworkEventMap ? NetworkEventData<K> : WebsocketSendType) | null, queue?: SendQueue): void;
13193
+ send<K extends NetworkEventKey>(key: K, data?: (K extends keyof NetworkEventMap ? NetworkEventData<K> : WebsocketSendType), queue?: SendQueue): void;
12602
13194
  /**
12603
13195
  * Deletes the network state for a specific object on the server.
12604
13196
  * This removes the object's state from the room, preventing it from being sent to newly joining users.
@@ -12620,61 +13212,69 @@ export declare class NetworkConnection implements INetworkConnection {
12620
13212
  private _defaultMessagesBufferArray;
12621
13213
  sendBufferedMessagesNow(): void;
12622
13214
  /** Use to start listening to networking events.
12623
- * To unsubscribe from events use the `{@link stopListen}` method.
13215
+ * Returns an unsubscribe function that removes the listener when called.
13216
+ * The returned function can also be passed to {@link stopListen} or {@link Component.autoCleanup} for automatic lifecycle management.
12624
13217
  *
12625
- * @example Custom event example
13218
+ * @example With autoCleanup (recommended)
12626
13219
  * ```ts
12627
- * // Listen to a custom event sent by the server
12628
- * this.context.connection.beginListen<MyDataType>("my-custom-event", (data) => {
12629
- * console.log("Received custom event:", data);
12630
- * });
13220
+ * export class MyComponent extends Behaviour {
13221
+ * onEnable() {
13222
+ * this.autoCleanup(this.context.connection.beginListen("joined-room", () => {
13223
+ * console.log("I joined a networked room");
13224
+ * }));
13225
+ * }
13226
+ * // Automatically unsubscribed on disable — no manual cleanup needed!
13227
+ * }
13228
+ * ```
13229
+ *
13230
+ * @example Manual unsubscribe
13231
+ * ```ts
13232
+ * const unsub = this.context.connection.beginListen("joined-room", () => { });
13233
+ * // Later:
13234
+ * unsub(); // removes the listener
12631
13235
  * ```
12632
13236
  *
12633
- * @example Listening to room events
13237
+ * @example With stopListen (legacy pattern, still supported)
12634
13238
  * ```ts
12635
- * // Make sure to unsubscribe from events when the component is disabled
12636
13239
  * export class MyComponent extends Behaviour {
12637
13240
  * onEnable() {
12638
- * this.connection.beginListen("joined-room", this.onJoinedRoom)
13241
+ * this.context.connection.beginListen("joined-room", this.onJoinedRoom);
12639
13242
  * }
12640
13243
  * onDisable() {
12641
- * this.connection.stopListen("joined-room", this.onJoinedRoom)
13244
+ * this.context.connection.stopListen("joined-room", this.onJoinedRoom);
12642
13245
  * }
12643
13246
  * onJoinedRoom = () => {
12644
- * console.log("I joined a networked room")
13247
+ * console.log("I joined a networked room");
12645
13248
  * }
12646
13249
  * }
12647
13250
  * ```
12648
13251
  * @link https://engine.needle.tools/docs/networking.html
12649
13252
  *
12650
13253
  */
12651
- beginListen<K extends NetworkEventKey>(key: K, callback: K extends keyof NetworkEventMap ? NetworkEventMap[K] : (...args: any[]) => void): K extends keyof NetworkEventMap ? NetworkEventMap[K] : (...args: any[]) => void;
13254
+ beginListen<K extends NetworkEventKey>(key: K, callback: K extends keyof NetworkEventMap ? NetworkEventMap[K] : (...args: any[]) => void): DisposeFn;
12652
13255
  /**@deprecated please use stopListen instead (2.65.2-pre) */
12653
13256
  stopListening<K extends NetworkEventKey>(key: K, callback: (K extends keyof NetworkEventMap ? NetworkEventMap[K] : (...args: any[]) => void) | null): void;
12654
- /** Use to stop listening to networking events
13257
+ /** Use to stop listening to networking events.
13258
+ * Accepts either the original callback or the unsubscribe function returned by {@link beginListen}.
12655
13259
  * To subscribe to events use the `{@link beginListen}` method.
12656
- * See the example below for typical usage:
12657
13260
  *
12658
- * ### Component Example
12659
- * ```ts
12660
- * // Make sure to unsubscribe from events when the component is disabled
12661
- * export class MyComponent extends Behaviour {
12662
- * onEnable() {
12663
- * this.connection.beginListen("joined-room", this.onJoinedRoom)
12664
- * }
12665
- * onDisable() {
12666
- * this.connection.stopListen("joined-room", this.onJoinedRoom)
12667
- * }
12668
- * onJoinedRoom = () => {
12669
- * console.log("I joined a networked room")
12670
- * }
12671
- * }
13261
+ * @example
13262
+ * ```ts
13263
+ * // Both patterns work:
13264
+ * this.context.connection.stopListen("joined-room", this.onJoinedRoom); // original callback
13265
+ * this.context.connection.stopListen("joined-room", unsub); // unsubscribe fn from beginListen
12672
13266
  * ```
12673
13267
  */
12674
- stopListen<K extends NetworkEventKey>(key: K, callback: (K extends keyof NetworkEventMap ? NetworkEventMap[K] : (...args: any[]) => void) | null): void;
12675
- /** Use to start listening to networking binary events */
12676
- beginListenBinary(identifier: string, callback: BinaryCallback): BinaryCallback;
12677
- /** Use to stop listening to networking binary events */
13268
+ private static _didLogStopListenHint;
13269
+ stopListen<K extends NetworkEventKey>(key: K, callback: (K extends keyof NetworkEventMap ? NetworkEventMap[K] : (...args: any[]) => void) | Function | null): void;
13270
+ /** Use to start listening to networking binary events.
13271
+ * Returns an unsubscribe function that removes the listener when called.
13272
+ * The returned function can also be passed to {@link stopListenBinary} or {@link Component.autoCleanup}.
13273
+ */
13274
+ beginListenBinary(identifier: string, callback: BinaryCallback): DisposeFn;
13275
+ /** Use to stop listening to networking binary events.
13276
+ * Accepts either the original callback or the unsubscribe function returned by {@link beginListenBinary}.
13277
+ */
12678
13278
  stopListenBinary(identifier: string, callback: any): void;
12679
13279
  private netWebSocketUrlProvider?;
12680
13280
  /** Use to override the networking server backend url.
@@ -12683,16 +13283,19 @@ export declare class NetworkConnection implements INetworkConnection {
12683
13283
  registerProvider(prov: INetworkingWebsocketUrlProvider): void;
12684
13284
  /** Used to connect to the networking server
12685
13285
  * @param url Optional url to connect to. If not provided, it will use the url from the registered `INetworkingWebsocketUrlProvider` or the default backend networking url. If you want to change the url after connecting, you need to disconnect first and then connect again with the new url.
13286
+ * @param transport Optional custom transport to use instead of the default websocket. Useful for testing or alternative transports.
12686
13287
  */
12687
- connect(url?: string): Promise<boolean>;
13288
+ connect(url?: string, transport?: INetworkTransport): Promise<boolean>;
12688
13289
  /** Disconnect from the networking backend + reset internal state */
12689
13290
  disconnect(): void;
13291
+ /** Full teardown: disconnect, clear all listeners, and release all resources.
13292
+ * Called when the owning Context is destroyed. After dispose(), this instance should not be reused. */
13293
+ dispose(): void;
12690
13294
  private _listeners;
12691
13295
  private _listenersBinary;
12692
13296
  private connected;
12693
- private channelId;
12694
13297
  private _connectionId;
12695
- private _ws;
13298
+ private _transport;
12696
13299
  private _waitingForSocket;
12697
13300
  private _isInRoom;
12698
13301
  private _currentRoomName;
@@ -12702,6 +13305,8 @@ export declare class NetworkConnection implements INetworkConnection {
12702
13305
  private _state;
12703
13306
  private _currentDelay;
12704
13307
  private _connectingToWebsocketPromise;
13308
+ /** Wire up a transport's event callbacks and start it */
13309
+ private connectTransport;
12705
13310
  private connectWebsocket;
12706
13311
  private onMessage;
12707
13312
  private handleIncomingBinaryMessage;
@@ -12830,7 +13435,7 @@ export declare interface NetworkEventMap {
12830
13435
  * @see {@link RoomEvents} for room lifecycle events
12831
13436
  * @see {@link isLocalNetwork} for local network detection
12832
13437
  * @link https://engine.needle.tools/docs/how-to-guides/networking/
12833
- * @summary Networking configuration
13438
+ * @summary Configures the websocket server URL for multiplayer networking
12834
13439
  * @category Networking
12835
13440
  * @group Components
12836
13441
  */
@@ -12967,7 +13572,7 @@ export declare type OBJ = {
12967
13572
  scenes: Object3D[];
12968
13573
  };
12969
13574
 
12970
- declare type ObjectCloneReference = {
13575
+ export declare type ObjectCloneReference = {
12971
13576
  readonly original: object;
12972
13577
  readonly clone: object;
12973
13578
  };
@@ -13174,6 +13779,61 @@ export declare function offXRSessionEnd(fn: (evt: XRSessionEventArgs) => void):
13174
13779
  */
13175
13780
  export declare function offXRSessionStart(fn: (evt: XRSessionEventArgs) => void): void;
13176
13781
 
13782
+ /**
13783
+ * @experimental
13784
+ * Subscribe to a DOM event on any {@link EventTarget} (window, document, HTML elements, etc.)
13785
+ * and return an {@link IDisposable} that removes the listener when disposed.
13786
+ *
13787
+ * Provides full TypeScript event type inference — the callback parameter
13788
+ * is automatically typed based on the event name (e.g. `"resize"` → `UIEvent`,
13789
+ * `"click"` → `MouseEvent`).
13790
+ *
13791
+ * Use with {@link DisposableStore.add} for automatic lifecycle cleanup in components.
13792
+ *
13793
+ * @param target The EventTarget to listen on (window, document, an element, etc.)
13794
+ * @param type The event name (e.g. `"resize"`, `"click"`, `"keydown"`)
13795
+ * @param listener The event handler callback
13796
+ * @param options Optional addEventListener options (passive, capture, once, signal)
13797
+ * @returns An {@link IDisposable} that removes the event listener when disposed
13798
+ *
13799
+ * @example Standalone usage
13800
+ * ```ts
13801
+ * import { on } from "@needle-tools/engine";
13802
+ *
13803
+ * const sub = on(window, "resize", (ev) => {
13804
+ * // ev is typed as UIEvent
13805
+ * console.log("resized", ev.target);
13806
+ * });
13807
+ *
13808
+ * // Later: clean up
13809
+ * sub.dispose();
13810
+ * ```
13811
+ *
13812
+ * @example With autoCleanup in a component
13813
+ * ```ts
13814
+ * import { Behaviour, on } from "@needle-tools/engine";
13815
+ *
13816
+ * export class MyComponent extends Behaviour {
13817
+ * onEnable() {
13818
+ * this.autoCleanup(on(window, "resize", (ev) => { /* UIEvent *\/ }));
13819
+ * this.autoCleanup(on(document, "keydown", (ev) => { /* KeyboardEvent *\/ }));
13820
+ * this.autoCleanup(on(this.context.domElement, "click", (ev) => { /* MouseEvent *\/ }));
13821
+ * }
13822
+ * // All listeners removed automatically on disable!
13823
+ * }
13824
+ * ```
13825
+ *
13826
+ * @category Utilities
13827
+ * @group Lifecycle
13828
+ */
13829
+ export declare function on<K extends keyof WindowEventMap>(target: Window, type: K, listener: (ev: WindowEventMap[K]) => void, options?: boolean | AddEventListenerOptions): IDisposable;
13830
+
13831
+ export declare function on<K extends keyof DocumentEventMap>(target: Document, type: K, listener: (ev: DocumentEventMap[K]) => void, options?: boolean | AddEventListenerOptions): IDisposable;
13832
+
13833
+ export declare function on<K extends keyof HTMLElementEventMap>(target: HTMLElement, type: K, listener: (ev: HTMLElementEventMap[K]) => void, options?: boolean | AddEventListenerOptions): IDisposable;
13834
+
13835
+ export declare function on(target: EventTarget, type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): IDisposable;
13836
+
13177
13837
  /**
13178
13838
  * Register a callback in the engine onAfterRender event
13179
13839
  * This is called every frame after the main camera has rendered
@@ -13814,8 +14474,6 @@ export declare class OrbitControls extends Component implements ICameraControlle
13814
14474
  * @param options The options for fitting the camera. Use to provide objects to fit to, fit direction and size and other settings.
13815
14475
  */
13816
14476
  fitCamera(options?: OrbitFitCameraOptions): any;
13817
- /** @deprecated Use fitCamera(options) */
13818
- fitCamera(objects?: Object3D | Array<Object3D>, options?: Omit<OrbitFitCameraOptions, "objects">): any;
13819
14477
  private _haveAttachedKeyboardEvents;
13820
14478
  }
13821
14479
 
@@ -14016,6 +14674,11 @@ export declare class OrbitControls extends Component implements ICameraControlle
14016
14674
  value: number | boolean | string;
14017
14675
  };
14018
14676
 
14677
+ /** Extracts parameter names of a given type from the builder's tracked parameter map */
14678
+ declare type ParamNamesOfType<TParams, PType extends string> = {
14679
+ [K in keyof TParams & string]: TParams[K] extends PType ? K : never;
14680
+ }[keyof TParams & string];
14681
+
14019
14682
  declare type ParseNumber<T> = T extends `${infer U extends number}` ? U : never;
14020
14683
 
14021
14684
  /** Load a gltf file from a url. This is the core method used by Needle Engine to load gltf files. All known extensions are registered here.
@@ -14647,13 +15310,15 @@ export declare class OrbitControls extends Component implements ICameraControlle
14647
15310
  * The timeline asset containing tracks, clips, and markers that this director will play.
14648
15311
  * Assign a timeline asset exported from Unity or Blender to enable playback.
14649
15312
  */
14650
- playableAsset?: Models.TimelineAssetModel;
15313
+ get playableAsset(): Models.TimelineAssetModel | undefined;
15314
+ set playableAsset(value: Models.TimelineAssetModel | undefined);
15315
+ private _playableAsset?;
14651
15316
  /**
14652
15317
  * When true, the timeline starts playing automatically when the component awakens.
14653
15318
  * Set to false to control playback manually via `play()`.
14654
15319
  * @default false
14655
15320
  */
14656
- playOnAwake?: boolean;
15321
+ playOnAwake: boolean;
14657
15322
  /**
14658
15323
  * Determines how the timeline behaves when it reaches the end of its duration.
14659
15324
  * @default DirectorWrapMode.Loop
@@ -14731,15 +15396,15 @@ export declare class OrbitControls extends Component implements ICameraControlle
14731
15396
  /** Iterates over all tracks of the timeline
14732
15397
  * @returns all tracks of the timeline
14733
15398
  */
14734
- forEachTrack(): Generator<Tracks.TrackHandler, void, unknown>;
15399
+ forEachTrack(): Generator<Tracks.TimelineTrackHandler, void, unknown>;
14735
15400
  /**
14736
15401
  * @returns all animation tracks of the timeline
14737
15402
  */
14738
- get animationTracks(): Tracks.AnimationTrackHandler[];
15403
+ get animationTracks(): Tracks.TimelineAnimationTrack[];
14739
15404
  /**
14740
15405
  * @returns all audio tracks of the timeline
14741
15406
  */
14742
- get audioTracks(): Tracks.AudioTrackHandler[];
15407
+ get audioTracks(): Tracks.TimelineAudioTrack[];
14743
15408
  /**
14744
15409
  * @returns all signal tracks of the timeline
14745
15410
  */
@@ -14747,7 +15412,15 @@ export declare class OrbitControls extends Component implements ICameraControlle
14747
15412
  /**
14748
15413
  * @returns all marker tracks of the timeline
14749
15414
  */
14750
- get markerTracks(): Tracks.MarkerTrackHandler[];
15415
+ get markerTracks(): Tracks.TimelineMarkerTrack[];
15416
+ /**
15417
+ * @returns all activation tracks of the timeline
15418
+ */
15419
+ get activationTracks(): Tracks.TimelineActivationTrack[];
15420
+ /**
15421
+ * @returns all tracks of the timeline
15422
+ */
15423
+ get tracks(): ReadonlyArray<Tracks.TimelineTrackHandler>;
14751
15424
  /**
14752
15425
  * Iterates over all markers of the timeline, optionally filtering by type
14753
15426
  *
@@ -14761,13 +15434,13 @@ export declare class OrbitControls extends Component implements ICameraControlle
14761
15434
  *
14762
15435
  */
14763
15436
  foreachMarker<T extends Record<string, any>>(type?: string | null): Generator<(T & Models.MarkerModel)>;
14764
- private _guidsMap?;
14765
- /* Excluded from this release type: resolveGuids */
15437
+ private _needsGraphRebuild;
14766
15438
  private _isPlaying;
14767
15439
  private _internalUpdateRoutine;
14768
15440
  private _isPaused;
14769
15441
  /** internal, true during the time stop() is being processed */
14770
15442
  private _isStopping;
15443
+ /* Excluded from this release type: _isUserEvaluation */
14771
15444
  private _time;
14772
15445
  private _duration;
14773
15446
  private _weight;
@@ -14776,6 +15449,7 @@ export declare class OrbitControls extends Component implements ICameraControlle
14776
15449
  private readonly _signalTracks;
14777
15450
  private readonly _markerTracks;
14778
15451
  private readonly _controlTracks;
15452
+ private readonly _activationTracks;
14779
15453
  private readonly _customTracks;
14780
15454
  private readonly _tracksArray;
14781
15455
  private get _allTracks();
@@ -15767,6 +16441,9 @@ export declare class OrbitControls extends Component implements ICameraControlle
15767
16441
  w: number;
15768
16442
  };
15769
16443
 
16444
+ /** A Quaternion value, either as a Three.js Quaternion or as a `[x, y, z, w]` tuple */
16445
+ declare type QuatValue = Quaternion | [number, number, number, number];
16446
+
15770
16447
  /** Generates a random number
15771
16448
  * @deprecated use Mathf.random(min, max)
15772
16449
  */
@@ -15892,6 +16569,11 @@ export declare class OrbitControls extends Component implements ICameraControlle
15892
16569
  * @default undefined
15893
16570
  */
15894
16571
  useIgnoreRaycastLayer?: boolean;
16572
+ /** When true, trigger/sensor colliders will be included in the raycast results.
16573
+ * By default trigger colliders are skipped.
16574
+ * @default false
16575
+ */
16576
+ includeTriggers?: boolean;
15895
16577
  }): null | {
15896
16578
  point: Vector3;
15897
16579
  collider: ICollider;
@@ -15909,6 +16591,11 @@ export declare class OrbitControls extends Component implements ICameraControlle
15909
16591
  * @default undefined
15910
16592
  */
15911
16593
  useIgnoreRaycastLayer?: boolean;
16594
+ /** When true, trigger/sensor colliders will be included in the raycast results.
16595
+ * By default trigger colliders are skipped.
16596
+ * @default false
16597
+ */
16598
+ includeTriggers?: boolean;
15912
16599
  }): null | {
15913
16600
  point: Vector3;
15914
16601
  normal: Vector3;
@@ -15954,6 +16641,10 @@ export declare class OrbitControls extends Component implements ICameraControlle
15954
16641
  private _gravity;
15955
16642
  get gravity(): Vec3;
15956
16643
  set gravity(value: Vec3);
16644
+ /** Tears down the physics world and frees all WASM resources.
16645
+ * After calling this, the world will be re-created on next use. */
16646
+ dispose(): void;
16647
+ /** @deprecated Use {@link dispose} instead. */
15957
16648
  clearCaches(): void;
15958
16649
  addBoxCollider(collider: ICollider, size: Vector3): Promise<void>;
15959
16650
  addSphereCollider(collider: ICollider): Promise<void>;
@@ -16000,7 +16691,8 @@ export declare class OrbitControls extends Component implements ICameraControlle
16000
16691
  private getRigidbodyRelativeMatrix;
16001
16692
  private static centerConnectionPos;
16002
16693
  private static centerConnectionRot;
16003
- addFixedJoint(body1: IRigidbody, body2: IRigidbody): void;
16694
+ private _jointTempMatrix;
16695
+ addFixedJoint(body1: IRigidbody, body2: IRigidbody): Promise<ImpulseJoint | null>;
16004
16696
  /** The joint prevents any relative movement between two rigid-bodies, except for relative rotations along one axis. This is typically used to simulate wheels, fans, etc. They are characterized by one local anchor as well as one local axis on each rigid-body. */
16005
16697
  addHingeJoint(body1: IRigidbody, body2: IRigidbody, anchor: {
16006
16698
  x: number;
@@ -16010,8 +16702,11 @@ export declare class OrbitControls extends Component implements ICameraControlle
16010
16702
  x: number;
16011
16703
  y: number;
16012
16704
  z: number;
16013
- }): void;
16705
+ }): Promise<ImpulseJoint | null>;
16706
+ removeJoint(joint: ImpulseJoint): void;
16707
+ /** Compute the relative transform from body1's local space to body2's local space (W2⁻¹ * W1), ignoring scale. */
16014
16708
  private calculateJointRelativeMatrices;
16709
+ private normalizeMatrixColumns;
16015
16710
  }
16016
16711
 
16017
16712
  /**
@@ -16814,10 +17509,17 @@ export declare class OrbitControls extends Component implements ICameraControlle
16814
17509
  */
16815
17510
  export declare class Rigidbody extends Component implements IRigidbody {
16816
17511
  get isRigidbody(): boolean;
16817
- /** When true the mass will be automatically calculated by the attached colliders */
17512
+ /** When true the mass is automatically computed from the attached colliders using `mass = density × volume`.
17513
+ * Each collider's {@link Collider.density} determines how heavy it contributes to the total mass.
17514
+ * Disable to set mass explicitly via the `mass` property.
17515
+ */
16818
17516
  autoMass: boolean;
16819
- /** By default the mass will be automatically calculated (see `autoMass`) by the physics engine using the collider sizes
16820
- * To set the mass manually you can either set the `mass` value or set `autoMass` to `false`
17517
+ /** The mass of the rigidbody in kg (when `autoMass` is disabled).
17518
+ * When `autoMass` is enabled, reading this returns the computed mass from `density × volume` of all attached colliders.
17519
+ * Setting this property automatically disables `autoMass`.
17520
+ *
17521
+ * **Prefer using {@link Collider.density}** with `autoMass` enabled instead — density scales
17522
+ * naturally with collider size, while explicit mass stays fixed regardless of shape changes.
16821
17523
  */
16822
17524
  set mass(value: number);
16823
17525
  get mass(): number;
@@ -16900,7 +17602,8 @@ export declare class OrbitControls extends Component implements ICameraControlle
16900
17602
  onEnable(): void;
16901
17603
  onDisable(): void;
16902
17604
  onDestroy(): void;
16903
- onValidate(): void;
17605
+ onValidate(property?: string): void;
17606
+ private static _didWarnAutoMass;
16904
17607
  beforePhysics(): Generator<undefined, void, unknown>;
16905
17608
  /** Teleport the rigidbody to a new position in the world.
16906
17609
  * Will reset forces before setting the object world position
@@ -18120,10 +18823,17 @@ export declare class OrbitControls extends Component implements ICameraControlle
18120
18823
 
18121
18824
  export declare function sendDestroyed(guid: string, con: INetworkConnection, opts?: SyncDestroyOptions): void;
18122
18825
 
18826
+ /** Controls when a network message is actually sent to the server.
18827
+ * @see {@link NetworkConnection.send}
18828
+ */
18123
18829
  export declare enum SendQueue {
18830
+ /** Hold the message until the transport connection opens, then send it. Use for messages that must arrive as soon as the socket is ready (e.g. join-room). */
18124
18831
  OnConnection = 0,
18832
+ /** Hold the message until the client has joined a room, then send it. Use for messages that require room context. */
18125
18833
  OnRoomJoin = 1,
18834
+ /** Buffer the message and send it on the next `sendBufferedMessagesNow()` call (typically once per frame). This is the default for `send()`. */
18126
18835
  Queued = 2,
18836
+ /** Send the message to the server immediately without buffering. */
18127
18837
  Immediate = 3
18128
18838
  }
18129
18839
 
@@ -18556,6 +19266,16 @@ export declare class OrbitControls extends Component implements ICameraControlle
18556
19266
  asset: string;
18557
19267
  }
18558
19268
 
19269
+ /**
19270
+ * Options for a signal marker in the timeline builder
19271
+ */
19272
+ export declare type SignalMarkerOptions = {
19273
+ /** Whether the signal should fire if the playback starts past its time (default: false) */
19274
+ retroActive?: boolean;
19275
+ /** Whether the signal should only fire once (default: false) */
19276
+ emitOnce?: boolean;
19277
+ };
19278
+
18559
19279
  /** SignalReceiver is a component that listens for signals and invokes a reaction when a signal is received.
18560
19280
  * Signals can be added to a signal track on a {@link PlayableDirector}
18561
19281
  *
@@ -18563,7 +19283,8 @@ export declare class OrbitControls extends Component implements ICameraControlle
18563
19283
  * @category Animation and Sequencing
18564
19284
  * @group Components
18565
19285
  */
18566
- export declare class SignalReceiver extends Component {
19286
+ export declare class SignalReceiver extends Component implements ISignalReceiver {
19287
+ readonly isSignalReceiver = true;
18567
19288
  private static receivers;
18568
19289
  static invoke(guid: string): void;
18569
19290
  events?: SignalReceiverEvent[];
@@ -18582,10 +19303,26 @@ export declare class OrbitControls extends Component implements ICameraControlle
18582
19303
  reaction: EventList<void>;
18583
19304
  }
18584
19305
 
18585
- export declare class SignalTrackHandler extends TrackHandler {
19306
+ /**
19307
+ * Builder for signal tracks. Provides `.signal()` for callback-based signals and `.marker()` for asset-based markers.
19308
+ * @category Animation and Sequencing
19309
+ */
19310
+ export declare interface SignalTrackBuilder extends TimelineBuilderBase {
19311
+ /** Adds a signal with a callback that fires at the given time */
19312
+ signal(time: number, callback: Function, options?: SignalMarkerOptions): SignalTrackBuilder;
19313
+ /** Adds a signal marker referencing a signal asset by guid */
19314
+ marker(time: number, asset: string, options?: SignalMarkerOptions): SignalTrackBuilder;
19315
+ /** Mutes this track so it is skipped during playback */
19316
+ muted(muted?: boolean): SignalTrackBuilder;
19317
+ }
19318
+
19319
+ export declare class SignalTrackHandler extends TimelineTrackHandler {
18586
19320
  models: Models.SignalMarkerModel[];
18587
19321
  didTrigger: boolean[];
18588
19322
  receivers: Array<SignalReceiver | null>;
19323
+ private _lastTime;
19324
+ onEnable(): void;
19325
+ onMuteChanged(): void;
18589
19326
  evaluate(time: number): void;
18590
19327
  }
18591
19328
 
@@ -19085,10 +19822,6 @@ export declare class OrbitControls extends Component implements ICameraControlle
19085
19822
  * Removes scale change monitoring when the collider is disabled.
19086
19823
  */
19087
19824
  onDisable(): void;
19088
- /**
19089
- * Updates collider properties when validated in the editor or inspector.
19090
- */
19091
- onValidate(): void;
19092
19825
  }
19093
19826
 
19094
19827
  export declare class SphereIntersection implements Intersection {
@@ -19841,8 +20574,15 @@ export declare class OrbitControls extends Component implements ICameraControlle
19841
20574
  * Configuration for an animation state in the builder
19842
20575
  */
19843
20576
  export declare type StateOptions = {
19844
- /** The animation clip for this state */
19845
- clip: AnimationClip;
20577
+ /**
20578
+ * The animation clip for this state. Accepts:
20579
+ * - A pre-built `AnimationClip`
20580
+ * - A single {@link TrackDescriptor} from {@link track}
20581
+ * - An array of {@link TrackDescriptor}s (multiple tracks combined into one clip)
20582
+ *
20583
+ * When omitted, use {@link AnimatorControllerBuilder.track .track()} to define animation tracks inline.
20584
+ */
20585
+ clip?: AnimationClip | TrackDescriptor | TrackDescriptor[];
19846
20586
  /** Whether the animation should loop (default: false) */
19847
20587
  loop?: boolean;
19848
20588
  /** Base speed multiplier (default: 1) */
@@ -20408,6 +21148,7 @@ export declare class OrbitControls extends Component implements ICameraControlle
20408
21148
  set font(val: string | null);
20409
21149
  get font(): string | null;
20410
21150
  private _font;
21151
+ private _assignedAtRuntime;
20411
21152
  /**
20412
21153
  * Whether to support basic rich text tags in the `text` property. Supported tags include `<b>`, `<i>`, and `<color=hex>`. For example: `Hello <b>World</b>` or `Score: <color=#ff0000>100</color>`
20413
21154
  * @default false
@@ -20663,6 +21404,57 @@ export declare class OrbitControls extends Component implements ICameraControlle
20663
21404
  /* Excluded from this release type: update */
20664
21405
  }
20665
21406
 
21407
+ /**
21408
+ * Handles activation (visibility) of bound objects for a timeline activation track.
21409
+ *
21410
+ * Each clip on the track defines a time range during which the bound objects should be active (visible).
21411
+ * @see TimelineTrackHandler for details on how tracks and clips work in general, and how to mutate them at runtime.
21412
+ * @see PlayableDirector for how to control timeline playback and time.
21413
+ * @see TimelineBuilder for how to create and configure timelines and tracks in the editor.
21414
+ */
21415
+ export declare class TimelineActivationTrack extends TimelineTrackHandler {
21416
+ evaluate(time: number): void;
21417
+ }
21418
+
21419
+ export declare class TimelineAnimationTrack extends TimelineTrackHandler {
21420
+ /* Excluded from this release type: models */
21421
+ /* Excluded from this release type: trackOffset */
21422
+ /** The object that is being animated. */
21423
+ target?: Object3D;
21424
+ /** The AnimationMixer, should be shared with the animator if an animator is bound */
21425
+ mixer?: AnimationMixer;
21426
+ clips: Array<AnimationClip>;
21427
+ actions: Array<AnimationAction>;
21428
+ /**
21429
+ * You can use the weight to blend the timeline animation tracks with multiple animation tracks on the same object.
21430
+ * @default 1
21431
+ */
21432
+ weight: number;
21433
+ /** holds data/info about clips differences */
21434
+ private _actionOffsets;
21435
+ private _didBind;
21436
+ private _animator;
21437
+ onDisable(): void;
21438
+ onDestroy(): void;
21439
+ onStateChanged(): void;
21440
+ createHooks(clipModel: Models.AnimationClipModel, clip: any): void;
21441
+ bind(): void;
21442
+ private ensureTrackOffsets;
21443
+ private _useclipOffsets;
21444
+ private _totalOffsetPosition;
21445
+ private _totalOffsetRotation;
21446
+ private _totalOffsetPosition2;
21447
+ private _totalOffsetRotation2;
21448
+ private _summedPos;
21449
+ private _tempPos;
21450
+ private _summedRot;
21451
+ private _tempRot;
21452
+ private _clipRotQuat;
21453
+ evaluate(time: number): void;
21454
+ private createRotationInterpolant;
21455
+ private createPositionInterpolant;
21456
+ }
21457
+
20666
21458
  /**
20667
21459
  * @category Animation and Sequencing
20668
21460
  * @see {@link PlayableDirector} for the main component to control timelines in Needle Engine.
@@ -20672,6 +21464,325 @@ export declare class OrbitControls extends Component implements ICameraControlle
20672
21464
  tracks: TrackModel[];
20673
21465
  };
20674
21466
 
21467
+ /**
21468
+ * Handles audio playback for a timeline audio track.
21469
+ *
21470
+ * **Runtime mutation:** The track model is read fresh every frame during `evaluate()`.
21471
+ * You can mutate `track.volume`, `clip.start`, `clip.end`, `clip.asset.volume` etc.
21472
+ * at any time — changes take effect on the next frame without rebuilding the timeline.
21473
+ *
21474
+ * **Audio stopping:** Audio clips are automatically stopped when:
21475
+ * - Timeline time moves outside a clip's `[start, end]` range (e.g. jumping or normal playback advancing past a clip)
21476
+ * - The track is muted (via `muted = true`)
21477
+ * - The director is stopped (`director.stop()`)
21478
+ * - The director is paused (`director.pause()`)
21479
+ * - The director is disabled or destroyed
21480
+ */
21481
+ export declare class TimelineAudioTrack extends TimelineTrackHandler {
21482
+ models: Array<AudioClipModel_2>;
21483
+ listener: AudioListener_3;
21484
+ audio: Array<Audio_2>;
21485
+ audioContextTimeOffset: Array<number>;
21486
+ lastTime: number;
21487
+ audioSource?: AudioSource;
21488
+ /** Track-level volume multiplier (0–1). Applied on top of per-clip volume each frame. */
21489
+ get volume(): number;
21490
+ set volume(val: number);
21491
+ private _audioLoader;
21492
+ private getAudioFilePath;
21493
+ onAllowAudioChanged(allow: boolean): void;
21494
+ addModel(model: Models.ClipModel): void;
21495
+ onDisable(): void;
21496
+ onDestroy(): void;
21497
+ onMuteChanged(): void;
21498
+ stop(): void;
21499
+ private _playableDirectorResumed;
21500
+ onPauseChanged(): void;
21501
+ evaluate(time: number): void;
21502
+ /** Call to load audio buffer for a specific time in the track. Can be used to preload the timeline audio */
21503
+ loadAudio(time: number, lookAhead?: number, lookBehind?: number): Promise<(AudioBuffer | null)[]> | null;
21504
+ private isInTimeRange;
21505
+ private static _audioBuffers;
21506
+ static dispose(): void;
21507
+ private handleAudioLoading;
21508
+ }
21509
+
21510
+ /**
21511
+ * A fluent builder for creating timeline assets ({@link TimelineAssetModel}) from code.
21512
+ *
21513
+ * Use {@link TimelineBuilder.create} to start building a timeline.
21514
+ *
21515
+ * @example Using build() for timelines without signal callbacks
21516
+ * ```ts
21517
+ * const timeline = TimelineBuilder.create("MySequence")
21518
+ * .animationTrack("Character", animator)
21519
+ * .clip(walkClip, { duration: 2, easeIn: 0.3 })
21520
+ * .clip(runClip, { duration: 3, easeIn: 0.5, easeOut: 0.5 })
21521
+ * .activationTrack("FX", particleObject)
21522
+ * .clip({ start: 1, duration: 2 })
21523
+ * .audioTrack("Music", audioSource)
21524
+ * .clip("music.mp3", { start: 0, duration: 5, volume: 0.8 })
21525
+ * .build();
21526
+ *
21527
+ * director.playableAsset = timeline;
21528
+ * director.play();
21529
+ * ```
21530
+ *
21531
+ * @example With inline tracks (no pre-built clips needed)
21532
+ * ```ts
21533
+ * TimelineBuilder.create("DoorSequence")
21534
+ * .animationTrack("Door", door)
21535
+ * .track(door, "position", { from: [0, 0, 0], to: [2, 0, 0], duration: 1 })
21536
+ * .track(light, "intensity", { from: 0, to: 5, duration: 1 })
21537
+ * .signalTrack("Events")
21538
+ * .signal(0.5, () => playSound("creak"))
21539
+ * .install(director);
21540
+ *
21541
+ * director.play();
21542
+ * ```
21543
+ *
21544
+ * @example Using install() with signal callbacks
21545
+ * ```ts
21546
+ * TimelineBuilder.create("WithSignals")
21547
+ * .animationTrack("Character", animator)
21548
+ * .clip(walkClip, { duration: 2 })
21549
+ * .signalTrack("Events")
21550
+ * .signal(1.0, () => console.log("1 second!"))
21551
+ * .signal(2.0, () => spawnParticles())
21552
+ * .install(director);
21553
+ *
21554
+ * director.play();
21555
+ * ```
21556
+ *
21557
+ * @category Animation and Sequencing
21558
+ * @group Utilities
21559
+ */
21560
+ export declare class TimelineBuilder {
21561
+ private _name;
21562
+ private _tracks;
21563
+ private _currentTrack;
21564
+ private _pendingSignals;
21565
+ private _idProvider;
21566
+ private constructor();
21567
+ /**
21568
+ * Creates a new TimelineBuilder instance.
21569
+ * @param name - Name for the timeline asset
21570
+ * @param seed - Optional numeric seed for deterministic guid generation. Defaults to `Date.now()`.
21571
+ */
21572
+ static create(name?: string, seed?: number): TimelineBuilderBase;
21573
+ /**
21574
+ * Adds an animation track. Chain `.clip()` calls to add pre-built clips,
21575
+ * or chain `.track()` calls to define animation data inline:
21576
+ *
21577
+ * @example With pre-built AnimationClip
21578
+ * ```ts
21579
+ * .animationTrack("Character", animator)
21580
+ * .clip(walkClip, { duration: 2, easeIn: 0.3 })
21581
+ * .clip(runClip, { duration: 3 })
21582
+ * ```
21583
+ *
21584
+ * @example With inline tracks
21585
+ * ```ts
21586
+ * .animationTrack("Door", door)
21587
+ * .track(door, "position", { from: [0, 0, 0], to: [2, 0, 0], duration: 1 })
21588
+ * .track(light, "intensity", { from: 0, to: 5, duration: 1 })
21589
+ * ```
21590
+ *
21591
+ * @param name - Display name for the track
21592
+ * @param binding - The Animator or Object3D to animate
21593
+ */
21594
+ animationTrack(name: string, binding?: Animator | Object3D | null): AnimationTrackBuilder;
21595
+ /**
21596
+ * Adds an audio track. Subsequent `.clip()` calls add audio clips to this track.
21597
+ * @param name - Display name for the track
21598
+ * @param binding - The AudioSource to play audio on (optional)
21599
+ * @param volume - Track volume multiplier (default: 1)
21600
+ */
21601
+ audioTrack(name: string, binding?: AudioSource | Object3D | null, volume?: number): AudioTrackBuilder;
21602
+ /**
21603
+ * Adds an activation track. Subsequent `.clip()` calls define when the bound object is active.
21604
+ * @param name - Display name for the track
21605
+ * @param binding - The Object3D to show/hide
21606
+ */
21607
+ activationTrack(name: string, binding?: Object3D | null): ActivationTrackBuilder;
21608
+ /**
21609
+ * Adds a control track. Subsequent `.clip()` calls control nested timelines or objects.
21610
+ * @param name - Display name for the track
21611
+ */
21612
+ controlTrack(name: string): ControlTrackBuilder;
21613
+ /**
21614
+ * Adds a signal track. Use `.signal()` or `.marker()` to add signal markers.
21615
+ * @param name - Display name for the track
21616
+ * @param binding - The SignalReceiver component (optional — if using `.signal()` with callbacks, one is created automatically by {@link install})
21617
+ */
21618
+ signalTrack(name: string, binding?: SignalReceiver | Object3D | null): SignalTrackBuilder;
21619
+ /**
21620
+ * Adds a marker track. Use `.marker()` to add markers.
21621
+ * @param name - Display name for the track
21622
+ */
21623
+ markerTrack(name: string): MarkerTrackBuilder;
21624
+ /**
21625
+ * Adds a clip to the current track. The clip type must match the track type.
21626
+ *
21627
+ * - On an **animation track**: pass an `AnimationClip`, a {@link TrackDescriptor}, or a `TrackDescriptor[]` — and optional {@link AnimationClipOptions}
21628
+ * - On an **audio track**: pass a clip URL (string) and {@link AudioClipOptions}
21629
+ * - On an **activation track**: pass {@link ActivationClipOptions}
21630
+ * - On a **control track**: pass an Object3D and {@link ControlClipOptions}
21631
+ */
21632
+ clip(asset: AnimationClip, options?: AnimationClipOptions): this;
21633
+ clip(descriptor: TrackDescriptor, options?: AnimationClipOptions): this;
21634
+ clip(descriptors: TrackDescriptor[], options?: AnimationClipOptions): this;
21635
+ clip(url: string, options: AudioClipOptions): this;
21636
+ clip(options: ActivationClipOptions): this;
21637
+ clip(sourceObject: Object3D, options: ControlClipOptions): this;
21638
+ /**
21639
+ * Adds a signal marker to the current signal or marker track.
21640
+ * @param time - Time in seconds when the signal fires
21641
+ * @param asset - The signal asset identifier (guid string)
21642
+ * @param options - Optional marker configuration
21643
+ */
21644
+ marker(time: number, asset: string, options?: SignalMarkerOptions): this;
21645
+ /**
21646
+ * Adds a signal with a callback to the current signal track.
21647
+ * This is a convenience method that automatically generates a signal asset guid,
21648
+ * adds the marker, and registers the callback so that {@link install} can wire up
21649
+ * the `SignalReceiver` on the director's GameObject.
21650
+ *
21651
+ * @param time - Time in seconds when the signal fires
21652
+ * @param callback - The function to invoke when the signal fires
21653
+ * @param options - Optional marker configuration
21654
+ *
21655
+ * @example
21656
+ * ```ts
21657
+ * const timeline = TimelineBuilder.create("Sequence")
21658
+ * .signalTrack("Events")
21659
+ * .signal(1.0, () => console.log("1 second reached!"))
21660
+ * .signal(3.5, () => console.log("halfway!"), { emitOnce: true })
21661
+ * .install(director);
21662
+ * ```
21663
+ */
21664
+ signal(time: number, callback: Function, options?: SignalMarkerOptions): this;
21665
+ /**
21666
+ * Mutes the current track so it is skipped during playback.
21667
+ */
21668
+ muted(muted?: boolean): this;
21669
+ /** Adds an animation track descriptor for an Object3D's position or scale to the current animation track */
21670
+ track(target: Object3D, property: "position" | "scale", keyframes: KF_3<Vec3Value>, options?: TrackOptions): this;
21671
+ /** Adds an animation track descriptor for an Object3D's quaternion to the current animation track */
21672
+ track(target: Object3D, property: "quaternion", keyframes: KF_3<QuatValue>, options?: TrackOptions): this;
21673
+ /** Adds an animation track descriptor for an Object3D's rotation (Euler, converted to quaternion) to the current animation track */
21674
+ track(target: Object3D, property: "rotation", keyframes: KF_3<EulerValue>, options?: TrackOptions): this;
21675
+ /** Adds an animation track descriptor for an Object3D's visibility to the current animation track */
21676
+ track(target: Object3D, property: "visible", keyframes: KF_3<boolean>, options?: TrackOptions): this;
21677
+ /** Adds an animation track descriptor for a material's numeric property to the current animation track */
21678
+ track(target: Material, property: "opacity" | "roughness" | "metalness" | "alphaTest" | "emissiveIntensity" | "envMapIntensity" | "bumpScale" | "displacementScale" | "displacementBias", keyframes: KF_3<number>, options?: TrackOptions): this;
21679
+ /** Adds an animation track descriptor for a material's color property to the current animation track */
21680
+ track(target: Material, property: "color" | "emissive", keyframes: KF_3<ColorValue>, options?: TrackOptions): this;
21681
+ /** Adds an animation track descriptor for a light's numeric property to the current animation track */
21682
+ track(target: Light_2, property: "intensity" | "distance" | "angle" | "penumbra" | "decay", keyframes: KF_3<number>, options?: TrackOptions): this;
21683
+ /** Adds an animation track descriptor for a light's color to the current animation track */
21684
+ track(target: Light_2, property: "color", keyframes: KF_3<ColorValue>, options?: TrackOptions): this;
21685
+ /** Adds an animation track descriptor for a camera's numeric property to the current animation track */
21686
+ track(target: PerspectiveCamera, property: "fov" | "near" | "far" | "zoom", keyframes: KF_3<number>, options?: TrackOptions): this;
21687
+ /**
21688
+ * Builds and returns the {@link TimelineAssetModel}.
21689
+ * Assign the result to `PlayableDirector.playableAsset` to play it.
21690
+ *
21691
+ * If you used `.signal()` with callbacks, use {@link install} instead — it calls `build()`
21692
+ * internally and also wires up the SignalReceiver on the director's GameObject.
21693
+ */
21694
+ build(): TimelineAssetModel;
21695
+ /**
21696
+ * Builds the timeline asset, assigns it to the director, and wires up any
21697
+ * `.signal()` callbacks by creating/configuring a {@link SignalReceiver} on the
21698
+ * director's GameObject.
21699
+ *
21700
+ * @param director - The PlayableDirector to install the timeline on
21701
+ * @returns The built TimelineAssetModel (also assigned to `director.playableAsset`)
21702
+ *
21703
+ * @example
21704
+ * ```ts
21705
+ * TimelineBuilder.create("MyTimeline")
21706
+ * .animationTrack("Anim", animator)
21707
+ * .clip(walkClip, { duration: 2 })
21708
+ * .signalTrack("Events")
21709
+ * .signal(1.0, () => console.log("signal fired!"))
21710
+ * .install(director);
21711
+ *
21712
+ * director.play();
21713
+ * ```
21714
+ */
21715
+ install(director: PlayableDirector): TimelineAssetModel;
21716
+ private pushTrack;
21717
+ /** Commits any pending `.track()` descriptors on the current animation track into a clip */
21718
+ private commitInlineTracks;
21719
+ }
21720
+
21721
+ /**
21722
+ * Shared methods available on all track builders and the TimelineBuilder entry point.
21723
+ * Provides track creation, build, and install methods.
21724
+ *
21725
+ * @category Animation and Sequencing
21726
+ */
21727
+ export declare interface TimelineBuilderBase {
21728
+ /** Adds an animation track. Chain `.clip()` or `.track()` to add content. */
21729
+ animationTrack(name: string, binding?: Animator | Object3D | null): AnimationTrackBuilder;
21730
+ /** Adds an audio track. Chain `.clip()` to add audio clips. */
21731
+ audioTrack(name: string, binding?: AudioSource | Object3D | null, volume?: number): AudioTrackBuilder;
21732
+ /** Adds an activation track. Chain `.clip()` to define activation windows. */
21733
+ activationTrack(name: string, binding?: Object3D | null): ActivationTrackBuilder;
21734
+ /** Adds a control track. Chain `.clip()` to control nested objects/timelines. */
21735
+ controlTrack(name: string): ControlTrackBuilder;
21736
+ /** Adds a signal track. Chain `.signal()` or `.marker()` to add events. */
21737
+ signalTrack(name: string, binding?: SignalReceiver | Object3D | null): SignalTrackBuilder;
21738
+ /** Adds a marker track. Chain `.marker()` to add markers. */
21739
+ markerTrack(name: string): MarkerTrackBuilder;
21740
+ /** Builds and returns the {@link TimelineAssetModel}. */
21741
+ build(): TimelineAssetModel;
21742
+ /** Builds the timeline, assigns it to the director, and wires up signal callbacks. */
21743
+ install(director: PlayableDirector): TimelineAssetModel;
21744
+ }
21745
+
21746
+ export declare class TimelineControlTrack extends TimelineTrackHandler {
21747
+ models: Array<Models.ClipModel>;
21748
+ timelines: Array<PlayableDirector | null>;
21749
+ resolveSourceObjects(_context: Context): void;
21750
+ private _previousActiveModel;
21751
+ evaluate(time: number): void;
21752
+ }
21753
+
21754
+ export declare class TimelineMarkerTrack extends TimelineTrackHandler {
21755
+ models: Array<Models.MarkerModel & Record<string, any>>;
21756
+ needsSorting: boolean;
21757
+ foreachMarker<T>(type?: string | null): Generator<T, void, unknown>;
21758
+ onEnable(): void;
21759
+ evaluate(_time: number): void;
21760
+ private sort;
21761
+ }
21762
+
21763
+ /**
21764
+ * A TrackHandler is responsible for evaluating a specific type of timeline track.
21765
+ * A timeline track can be an animation track, audio track, signal track, control track etc and is controlled by a {@link PlayableDirector}.
21766
+ */
21767
+ export declare abstract class TimelineTrackHandler {
21768
+ director: PlayableDirector;
21769
+ track: Models.TrackModel;
21770
+ get muted(): boolean;
21771
+ set muted(val: boolean);
21772
+ forEachClip(backwards?: boolean): IterableIterator<Models.ClipModel>;
21773
+ onEnable?(): any;
21774
+ onDisable?(): any;
21775
+ onDestroy?(): any;
21776
+ abstract evaluate(time: number): any;
21777
+ onMuteChanged?(): any;
21778
+ onPauseChanged?(): any;
21779
+ /** invoked when PlayableDirectory playmode state changes (paused, playing, stopped) */
21780
+ onStateChanged?(isPlaying: boolean): any;
21781
+ getClipTime(time: number, model: Models.ClipModel): number;
21782
+ getClipTimeNormalized(time: number, model: Models.ClipModel): number;
21783
+ evaluateWeight(time: number, index: number, models: Array<Models.ClipModel>, isActive?: boolean): number;
21784
+ }
21785
+
20675
21786
  declare type TonemappingAttributeOptions = "none" | "linear" | "neutral" | "agx";
20676
21787
 
20677
21788
  /**
@@ -20700,27 +21811,20 @@ export declare class OrbitControls extends Component implements ICameraControlle
20700
21811
  export declare function toSourceId(src: string | null): SourceIdentifier | undefined;
20701
21812
 
20702
21813
  /**
20703
- * A TrackHandler is responsible for evaluating a specific type of timeline track.
20704
- * A timeline track can be an animation track, audio track, signal track, control track etc and is controlled by a {@link PlayableDirector}.
21814
+ * An opaque descriptor for a single animation track.
21815
+ * Created by {@link track} and resolved into a Three.js KeyframeTrack
21816
+ * when passed to {@link createAnimation}, or inline to
21817
+ * {@link AnimatorControllerBuilder.state} / {@link TimelineBuilder.clip}.
21818
+ *
21819
+ * @category Animation and Sequencing
20705
21820
  */
20706
- export declare abstract class TrackHandler {
20707
- director: PlayableDirector;
20708
- track: Models.TrackModel;
20709
- get muted(): boolean;
20710
- set muted(val: boolean);
20711
- forEachClip(backwards?: boolean): IterableIterator<Models.ClipModel>;
20712
- onEnable?(): any;
20713
- onDisable?(): any;
20714
- onDestroy?(): any;
20715
- abstract evaluate(time: number): any;
20716
- onMuteChanged?(): any;
20717
- onPauseChanged?(): any;
20718
- /** invoked when PlayableDirectory playmode state changes (paused, playing, stopped) */
20719
- onStateChanged?(isPlaying: boolean): any;
20720
- getClipTime(time: number, model: Models.ClipModel): number;
20721
- getClipTimeNormalized(time: number, model: Models.ClipModel): number;
20722
- evaluateWeight(time: number, index: number, models: Array<Models.ClipModel>, isActive?: boolean): number;
20723
- }
21821
+ declare type TrackDescriptor = {
21822
+ readonly __isTrackDescriptor: true;
21823
+ /* Excluded from this release type: _target */
21824
+ /* Excluded from this release type: _property */
21825
+ /* Excluded from this release type: _keyframes */
21826
+ /* Excluded from this release type: _root */
21827
+ };
20724
21828
 
20725
21829
  /**
20726
21830
  * @category Animation and Sequencing
@@ -20746,14 +21850,26 @@ export declare class OrbitControls extends Component implements ICameraControlle
20746
21850
  rotation: Quat | Quaternion;
20747
21851
  };
20748
21852
 
21853
+ /** Options for a single track */
21854
+ declare type TrackOptions = {
21855
+ /**
21856
+ * Root object for resolving the track path.
21857
+ * - If `root === target` → self-targeting (`.property`)
21858
+ * - If `root !== target` → named targeting (`"targetName.property"` using `target.name`)
21859
+ * - If omitted → self-targeting by default
21860
+ */
21861
+ root?: Object3D;
21862
+ };
21863
+
20749
21864
  declare namespace Tracks {
20750
21865
  export {
20751
- TrackHandler,
20752
- AnimationTrackHandler,
20753
- AudioTrackHandler,
20754
- MarkerTrackHandler,
21866
+ TimelineTrackHandler,
21867
+ TimelineAnimationTrack,
21868
+ TimelineAudioTrack,
21869
+ TimelineMarkerTrack,
20755
21870
  SignalTrackHandler,
20756
- ControlTrackHandler
21871
+ TimelineActivationTrack,
21872
+ TimelineControlTrack
20757
21873
  }
20758
21874
  }
20759
21875
 
@@ -20959,10 +22075,8 @@ export declare class OrbitControls extends Component implements ICameraControlle
20959
22075
  export declare type TransitionOptions = {
20960
22076
  /** Duration of the crossfade in seconds (default: 0) */
20961
22077
  duration?: number;
20962
- /** Normalized exit time 0-1 (default: 1). Only used when hasExitTime is true */
22078
+ /** Normalized exit time 0-1. When set, the transition waits until the source animation reaches this point before transitioning. */
20963
22079
  exitTime?: number;
20964
- /** Whether the transition waits for exitTime before transitioning (default: false) */
20965
- hasExitTime?: boolean;
20966
22080
  /** Normalized offset into the destination state's animation (default: 0) */
20967
22081
  offset?: number;
20968
22082
  /** Whether duration is in seconds (true) or normalized (false) (default: false) */
@@ -21032,6 +22146,18 @@ export declare class OrbitControls extends Component implements ICameraControlle
21032
22146
 
21033
22147
  export declare function tryGetGuid(obj: any): string | undefined | null;
21034
22148
 
22149
+ /** Shorthand for a simple two-keyframe animation (start → end) */
22150
+ export declare type Tween<V> = {
22151
+ /** Start value (at time 0) */
22152
+ from: V;
22153
+ /** End value (at time = duration) */
22154
+ to: V;
22155
+ /** Duration in seconds (default: 1) */
22156
+ duration?: number;
22157
+ /** Interpolation mode (default: `"linear"`) */
22158
+ interpolation?: AnimationInterpolation;
22159
+ };
22160
+
21035
22161
  declare type Type = new (...args: any[]) => any;
21036
22162
 
21037
22163
  declare type TypeResolver<T> = (data: any) => Constructor<T> | null;
@@ -21083,6 +22209,8 @@ export declare class OrbitControls extends Component implements ICameraControlle
21083
22209
  getKey(type: Type): string | null;
21084
22210
  }
21085
22211
 
22212
+ /* Excluded from this release type: UFadk */
22213
+
21086
22214
  export declare interface UIDProvider {
21087
22215
  seed: number;
21088
22216
  generateUUID(): string;
@@ -21555,6 +22683,9 @@ export declare class OrbitControls extends Component implements ICameraControlle
21555
22683
  z: number;
21556
22684
  };
21557
22685
 
22686
+ /** A Vector3 value, either as a Three.js Vector3 or as a `[x, y, z]` tuple */
22687
+ declare type Vec3Value = Vector3 | [number, number, number];
22688
+
21558
22689
  export declare type Vec4 = {
21559
22690
  x: number;
21560
22691
  y: number;
@@ -22476,7 +23607,7 @@ export declare class OrbitControls extends Component implements ICameraControlle
22476
23607
  private onApplyPose;
22477
23608
  }
22478
23609
 
22479
- declare type WebsocketSendType = IModel | object | boolean | null | string | number;
23610
+ declare type WebsocketSendType = IModel | object | boolean | string | number;
22480
23611
 
22481
23612
  /**
22482
23613
  * Use the [WebXR](https://engine.needle.tools/docs/api/WebXR) component to enable VR and AR on **iOS and Android** in your scene. VisionOS support is also provided via QuickLook USDZ export.
@@ -23519,6 +24650,28 @@ export declare class OrbitControls extends Component implements ICameraControlle
23519
24650
  export { }
23520
24651
 
23521
24652
 
24653
+ declare module 'three' {
24654
+ interface SkinnedMesh {
24655
+ staticGenerator?: StaticGeometryGenerator;
24656
+ staticGeometry?: BufferGeometry;
24657
+ staticGeometryLastUpdate?: number;
24658
+ }
24659
+ interface Mesh {
24660
+ acceleratedRaycast?: any;
24661
+ }
24662
+ interface SkinnedMesh {
24663
+ /** @deprecated use autoUpdateMeshBvhInterval */
24664
+ autoUpdateMeshBVH?: boolean;
24665
+ /**
24666
+ * Interval in milliseconds to automatically update the mesh BVH. When set to >= 0 the BVH will be updated every x milliseconds.
24667
+ * @default undefined (disabled)
24668
+ */
24669
+ autoUpdateMeshBvhInterval?: number;
24670
+ bvhNeedsUpdate?: boolean;
24671
+ }
24672
+ }
24673
+
24674
+
23522
24675
  declare module 'three' {
23523
24676
  interface Object3D {
23524
24677
  get guid(): string | undefined;
@@ -23664,25 +24817,3 @@ declare module 'three' {
23664
24817
  slerp(end: Vector3, t: number): Vector3;
23665
24818
  }
23666
24819
  }
23667
-
23668
-
23669
- declare module 'three' {
23670
- interface SkinnedMesh {
23671
- staticGenerator?: StaticGeometryGenerator;
23672
- staticGeometry?: BufferGeometry;
23673
- staticGeometryLastUpdate?: number;
23674
- }
23675
- interface Mesh {
23676
- acceleratedRaycast?: any;
23677
- }
23678
- interface SkinnedMesh {
23679
- /** @deprecated use autoUpdateMeshBvhInterval */
23680
- autoUpdateMeshBVH?: boolean;
23681
- /**
23682
- * Interval in milliseconds to automatically update the mesh BVH. When set to >= 0 the BVH will be updated every x milliseconds.
23683
- * @default undefined (disabled)
23684
- */
23685
- autoUpdateMeshBvhInterval?: number;
23686
- bvhNeedsUpdate?: boolean;
23687
- }
23688
- }