@needle-tools/engine 5.1.0-canary.deec6e4 → 5.1.0-canary.e6680fa

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 (326) hide show
  1. package/CHANGELOG.md +99 -1
  2. package/SKILL.md +4 -1
  3. package/components.needle.json +1 -1
  4. package/dist/needle-engine.bundle-Bl_hyH5G.umd.cjs +1734 -0
  5. package/dist/needle-engine.bundle-Cduc1gj6.min.js +1734 -0
  6. package/dist/{needle-engine.bundle-CvtELXh0.js → needle-engine.bundle-DNcqT8nJ.js} +19415 -18452
  7. package/dist/needle-engine.d.ts +1588 -374
  8. package/dist/needle-engine.js +572 -569
  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 +46 -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 +186 -58
  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_pmrem.js +51 -3
  70. package/lib/engine/engine_pmrem.js.map +1 -1
  71. package/lib/engine/engine_scenedata.js +2 -2
  72. package/lib/engine/engine_scenedata.js.map +1 -1
  73. package/lib/engine/engine_serialization_builtin_serializer.js +28 -5
  74. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  75. package/lib/engine/engine_serialization_core.d.ts +1 -0
  76. package/lib/engine/engine_serialization_core.js +7 -0
  77. package/lib/engine/engine_serialization_core.js.map +1 -1
  78. package/lib/engine/engine_types.d.ts +29 -11
  79. package/lib/engine/engine_types.js +1 -1
  80. package/lib/engine/engine_types.js.map +1 -1
  81. package/lib/engine/engine_util_decorator.js +7 -2
  82. package/lib/engine/engine_util_decorator.js.map +1 -1
  83. package/lib/engine/engine_utils.d.ts +1 -1
  84. package/lib/engine/engine_utils.js +19 -5
  85. package/lib/engine/engine_utils.js.map +1 -1
  86. package/lib/engine/engine_utils_format.js +20 -14
  87. package/lib/engine/engine_utils_format.js.map +1 -1
  88. package/lib/engine/engine_utils_qrcode.js +2 -2
  89. package/lib/engine/engine_utils_qrcode.js.map +1 -1
  90. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  91. package/lib/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js.map +1 -1
  92. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
  93. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  94. package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +1 -1
  95. package/lib/engine/webcomponents/needle menu/needle-menu.js +6 -6
  96. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  97. package/lib/engine/webcomponents/needle-engine.d.ts +10 -4
  98. package/lib/engine/webcomponents/needle-engine.js +3 -3
  99. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  100. package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
  101. package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
  102. package/lib/engine/xr/NeedleXRSession.d.ts +3 -2
  103. package/lib/engine/xr/NeedleXRSession.js +50 -14
  104. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  105. package/lib/engine/xr/TempXRContext.js +2 -2
  106. package/lib/engine/xr/TempXRContext.js.map +1 -1
  107. package/lib/engine/xr/events.d.ts +1 -1
  108. package/lib/engine/xr/events.js.map +1 -1
  109. package/lib/engine-components/Animation.js +17 -16
  110. package/lib/engine-components/Animation.js.map +1 -1
  111. package/lib/engine-components/AnimationBuilder.d.ts +158 -0
  112. package/lib/engine-components/AnimationBuilder.js +305 -0
  113. package/lib/engine-components/AnimationBuilder.js.map +1 -0
  114. package/lib/engine-components/Animator.d.ts +6 -0
  115. package/lib/engine-components/Animator.js +23 -13
  116. package/lib/engine-components/Animator.js.map +1 -1
  117. package/lib/engine-components/AnimatorController.builder.d.ts +191 -0
  118. package/lib/engine-components/AnimatorController.builder.js +263 -0
  119. package/lib/engine-components/AnimatorController.builder.js.map +1 -0
  120. package/lib/engine-components/AnimatorController.d.ts +2 -119
  121. package/lib/engine-components/AnimatorController.js +33 -232
  122. package/lib/engine-components/AnimatorController.js.map +1 -1
  123. package/lib/engine-components/AudioSource.d.ts +19 -3
  124. package/lib/engine-components/AudioSource.js +121 -68
  125. package/lib/engine-components/AudioSource.js.map +1 -1
  126. package/lib/engine-components/Camera.d.ts +6 -1
  127. package/lib/engine-components/Camera.js +16 -3
  128. package/lib/engine-components/Camera.js.map +1 -1
  129. package/lib/engine-components/CameraUtils.js +14 -6
  130. package/lib/engine-components/CameraUtils.js.map +1 -1
  131. package/lib/engine-components/Collider.d.ts +18 -9
  132. package/lib/engine-components/Collider.js +61 -14
  133. package/lib/engine-components/Collider.js.map +1 -1
  134. package/lib/engine-components/Component.d.ts +72 -9
  135. package/lib/engine-components/Component.js +114 -10
  136. package/lib/engine-components/Component.js.map +1 -1
  137. package/lib/engine-components/ContactShadows.d.ts +1 -0
  138. package/lib/engine-components/ContactShadows.js +14 -1
  139. package/lib/engine-components/ContactShadows.js.map +1 -1
  140. package/lib/engine-components/DragControls.d.ts +7 -0
  141. package/lib/engine-components/DragControls.js +19 -7
  142. package/lib/engine-components/DragControls.js.map +1 -1
  143. package/lib/engine-components/DropListener.js +4 -0
  144. package/lib/engine-components/DropListener.js.map +1 -1
  145. package/lib/engine-components/EventList.d.ts +31 -9
  146. package/lib/engine-components/EventList.js +37 -76
  147. package/lib/engine-components/EventList.js.map +1 -1
  148. package/lib/engine-components/Joints.d.ts +4 -2
  149. package/lib/engine-components/Joints.js +19 -3
  150. package/lib/engine-components/Joints.js.map +1 -1
  151. package/lib/engine-components/Light.js +9 -1
  152. package/lib/engine-components/Light.js.map +1 -1
  153. package/lib/engine-components/Networking.d.ts +1 -1
  154. package/lib/engine-components/Networking.js +1 -1
  155. package/lib/engine-components/OrbitControls.d.ts +1 -2
  156. package/lib/engine-components/OrbitControls.js +37 -14
  157. package/lib/engine-components/OrbitControls.js.map +1 -1
  158. package/lib/engine-components/RigidBody.d.ts +12 -4
  159. package/lib/engine-components/RigidBody.js +18 -4
  160. package/lib/engine-components/RigidBody.js.map +1 -1
  161. package/lib/engine-components/SceneSwitcher.js +3 -0
  162. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  163. package/lib/engine-components/SeeThrough.js +2 -2
  164. package/lib/engine-components/SeeThrough.js.map +1 -1
  165. package/lib/engine-components/VideoPlayer.d.ts +8 -2
  166. package/lib/engine-components/VideoPlayer.js +42 -19
  167. package/lib/engine-components/VideoPlayer.js.map +1 -1
  168. package/lib/engine-components/Voip.d.ts +16 -7
  169. package/lib/engine-components/Voip.js +90 -53
  170. package/lib/engine-components/Voip.js.map +1 -1
  171. package/lib/engine-components/api.d.ts +3 -1
  172. package/lib/engine-components/api.js +3 -1
  173. package/lib/engine-components/api.js.map +1 -1
  174. package/lib/engine-components/codegen/components.d.ts +7 -13
  175. package/lib/engine-components/codegen/components.js +7 -13
  176. package/lib/engine-components/codegen/components.js.map +1 -1
  177. package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
  178. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  179. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
  180. package/lib/engine-components/timeline/PlayableDirector.d.ts +21 -11
  181. package/lib/engine-components/timeline/PlayableDirector.js +75 -67
  182. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  183. package/lib/engine-components/timeline/SignalAsset.d.ts +3 -1
  184. package/lib/engine-components/timeline/SignalAsset.js +1 -0
  185. package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
  186. package/lib/engine-components/timeline/TimelineBuilder.d.ts +413 -0
  187. package/lib/engine-components/timeline/TimelineBuilder.js +506 -0
  188. package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -0
  189. package/lib/engine-components/timeline/TimelineModels.d.ts +2 -1
  190. package/lib/engine-components/timeline/TimelineModels.js +3 -0
  191. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  192. package/lib/engine-components/timeline/TimelineTracks.d.ts +37 -6
  193. package/lib/engine-components/timeline/TimelineTracks.js +92 -26
  194. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  195. package/lib/engine-components/timeline/index.d.ts +2 -1
  196. package/lib/engine-components/timeline/index.js +2 -0
  197. package/lib/engine-components/timeline/index.js.map +1 -1
  198. package/lib/engine-components/ui/Canvas.d.ts +1 -1
  199. package/lib/engine-components/ui/Canvas.js +2 -8
  200. package/lib/engine-components/ui/Canvas.js.map +1 -1
  201. package/lib/engine-components/ui/Text.d.ts +1 -0
  202. package/lib/engine-components/ui/Text.js +10 -7
  203. package/lib/engine-components/ui/Text.js.map +1 -1
  204. package/lib/engine-components/web/CursorFollow.d.ts +0 -1
  205. package/lib/engine-components/web/CursorFollow.js +21 -13
  206. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  207. package/lib/engine-components/webxr/WebXRImageTracking.d.ts +62 -1
  208. package/lib/engine-components/webxr/WebXRImageTracking.js +59 -2
  209. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  210. package/package.json +2 -83
  211. package/plugins/common/cloud.js +6 -1
  212. package/plugins/common/license.js +55 -12
  213. package/plugins/common/worker.js +9 -4
  214. package/plugins/types/userconfig.d.ts +4 -1
  215. package/plugins/vite/asap.js +17 -8
  216. package/plugins/vite/build-pipeline.js +57 -20
  217. package/plugins/vite/dependencies.js +29 -10
  218. package/plugins/vite/dependency-watcher.js +2 -2
  219. package/plugins/vite/editor-connection.js +3 -3
  220. package/plugins/vite/license.js +42 -7
  221. package/plugins/vite/local-files-core.js +3 -3
  222. package/plugins/vite/local-files-utils.d.ts +3 -1
  223. package/plugins/vite/local-files-utils.js +29 -5
  224. package/plugins/vite/reload.js +1 -1
  225. package/plugins/vite/server.js +2 -1
  226. package/src/engine/api.ts +11 -1
  227. package/src/engine/codegen/register_types.ts +10 -18
  228. package/src/engine/engine_audio.ts +184 -0
  229. package/src/engine/engine_camera.fit.ts +15 -4
  230. package/src/engine/engine_components.ts +1 -1
  231. package/src/engine/engine_context.ts +52 -19
  232. package/src/engine/engine_context_eventbus.ts +73 -0
  233. package/src/engine/engine_disposable.ts +214 -0
  234. package/src/engine/engine_gameobject.ts +54 -159
  235. package/src/engine/engine_gltf_builtin_components.ts +7 -76
  236. package/src/engine/engine_init.ts +7 -7
  237. package/src/engine/engine_input.ts +28 -7
  238. package/src/engine/engine_instantiate_resolve.ts +407 -0
  239. package/src/engine/engine_license.ts +202 -56
  240. package/src/engine/engine_mainloop_utils.ts +7 -4
  241. package/src/engine/engine_networking.transport.websocket.ts +45 -0
  242. package/src/engine/engine_networking.ts +161 -137
  243. package/src/engine/engine_networking_blob.ts +4 -4
  244. package/src/engine/engine_networking_instantiate.ts +2 -2
  245. package/src/engine/engine_networking_types.ts +41 -1
  246. package/src/engine/engine_physics_rapier.ts +102 -33
  247. package/src/engine/engine_pmrem.ts +53 -3
  248. package/src/engine/engine_scenedata.ts +3 -3
  249. package/src/engine/engine_serialization_builtin_serializer.ts +32 -9
  250. package/src/engine/engine_serialization_core.ts +9 -0
  251. package/src/engine/engine_types.ts +46 -27
  252. package/src/engine/engine_util_decorator.ts +7 -2
  253. package/src/engine/engine_utils.ts +16 -5
  254. package/src/engine/engine_utils_format.ts +20 -14
  255. package/src/engine/engine_utils_qrcode.ts +2 -2
  256. package/src/engine/physics/workers/mesh-bvh/GenerateMeshBVHWorker.js +1 -1
  257. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
  258. package/src/engine/webcomponents/needle menu/needle-menu.ts +6 -6
  259. package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
  260. package/src/engine/webcomponents/needle-engine.ts +12 -6
  261. package/src/engine/xr/NeedleXRSession.ts +48 -13
  262. package/src/engine/xr/TempXRContext.ts +2 -2
  263. package/src/engine/xr/events.ts +1 -1
  264. package/src/engine-components/Animation.ts +19 -16
  265. package/src/engine-components/AnimationBuilder.ts +472 -0
  266. package/src/engine-components/Animator.ts +24 -12
  267. package/src/engine-components/AnimatorController.builder.ts +387 -0
  268. package/src/engine-components/AnimatorController.ts +20 -291
  269. package/src/engine-components/AudioSource.ts +130 -79
  270. package/src/engine-components/Camera.ts +16 -3
  271. package/src/engine-components/CameraUtils.ts +12 -5
  272. package/src/engine-components/Collider.ts +66 -18
  273. package/src/engine-components/Component.ts +118 -20
  274. package/src/engine-components/ContactShadows.ts +15 -1
  275. package/src/engine-components/DragControls.ts +18 -11
  276. package/src/engine-components/DropListener.ts +4 -0
  277. package/src/engine-components/EventList.ts +45 -83
  278. package/src/engine-components/Joints.ts +20 -4
  279. package/src/engine-components/Light.ts +10 -2
  280. package/src/engine-components/Networking.ts +1 -1
  281. package/src/engine-components/OrbitControls.ts +42 -16
  282. package/src/engine-components/RigidBody.ts +18 -4
  283. package/src/engine-components/SceneSwitcher.ts +3 -0
  284. package/src/engine-components/SeeThrough.ts +2 -2
  285. package/src/engine-components/VideoPlayer.ts +40 -17
  286. package/src/engine-components/Voip.ts +88 -53
  287. package/src/engine-components/api.ts +3 -1
  288. package/src/engine-components/codegen/components.ts +7 -13
  289. package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
  290. package/src/engine-components/timeline/PlayableDirector.ts +83 -81
  291. package/src/engine-components/timeline/SignalAsset.ts +4 -1
  292. package/src/engine-components/timeline/TimelineBuilder.ts +824 -0
  293. package/src/engine-components/timeline/TimelineModels.ts +5 -1
  294. package/src/engine-components/timeline/TimelineTracks.ts +96 -27
  295. package/src/engine-components/timeline/index.ts +2 -1
  296. package/src/engine-components/ui/Canvas.ts +2 -8
  297. package/src/engine-components/ui/Text.ts +12 -8
  298. package/src/engine-components/web/CursorFollow.ts +21 -14
  299. package/src/engine-components/webxr/WebXRImageTracking.ts +79 -7
  300. package/dist/needle-engine.bundle-1s2gOoKZ.min.js +0 -1732
  301. package/dist/needle-engine.bundle-j4nGJXCs.umd.cjs +0 -1732
  302. package/lib/engine-components/AvatarLoader.d.ts +0 -80
  303. package/lib/engine-components/AvatarLoader.js +0 -232
  304. package/lib/engine-components/AvatarLoader.js.map +0 -1
  305. package/lib/engine-components/avatar/AvatarBlink_Simple.d.ts +0 -11
  306. package/lib/engine-components/avatar/AvatarBlink_Simple.js +0 -77
  307. package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +0 -1
  308. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.d.ts +0 -14
  309. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js +0 -69
  310. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +0 -1
  311. package/lib/engine-components/avatar/Avatar_Brain_LookAt.d.ts +0 -29
  312. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js +0 -122
  313. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +0 -1
  314. package/lib/engine-components/avatar/Avatar_MouthShapes.d.ts +0 -15
  315. package/lib/engine-components/avatar/Avatar_MouthShapes.js +0 -80
  316. package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +0 -1
  317. package/lib/engine-components/avatar/Avatar_MustacheShake.d.ts +0 -9
  318. package/lib/engine-components/avatar/Avatar_MustacheShake.js +0 -30
  319. package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +0 -1
  320. package/src/engine-components/AvatarLoader.ts +0 -264
  321. package/src/engine-components/avatar/AvatarBlink_Simple.ts +0 -70
  322. package/src/engine-components/avatar/AvatarEyeLook_Rotation.ts +0 -64
  323. package/src/engine-components/avatar/Avatar_Brain_LookAt.ts +0 -140
  324. package/src/engine-components/avatar/Avatar_MouthShapes.ts +0 -84
  325. package/src/engine-components/avatar/Avatar_MustacheShake.ts +0 -32
  326. package/src/vite-env.d.ts +0 -16
@@ -3,7 +3,7 @@ import { Euler, Material, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "t
3
3
 
4
4
  import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../../../engine/debug/index.js";
5
5
  import { findObjectOfType } from "../../../engine/engine_components.js";
6
- import { hasProLicense } from "../../../engine/engine_license.js";
6
+ import { $TXm } from "../../../engine/engine_license.js";
7
7
  import { serializable } from "../../../engine/engine_serialization.js";
8
8
  import { getFormattedDate, Progress } from "../../../engine/engine_time_utils.js";
9
9
  import { DeviceUtilities, getParam } from "../../../engine/engine_utils.js";
@@ -277,7 +277,7 @@ export class USDZExporter extends Behaviour {
277
277
  let name = this.exportFileName ?? this.objectToExport?.name ?? this.name;
278
278
  name += "-" + getFormattedDate(); // seems iOS caches the file in some cases, this ensures we always have a fresh file
279
279
 
280
- if (!hasProLicense()) {
280
+ if (!$TXm()) {
281
281
  if (name !== "") name += "-";
282
282
  name += "MadeWithNeedle";
283
283
  }
@@ -682,7 +682,7 @@ export class USDZExporter extends Behaviour {
682
682
  if (debug)
683
683
  showBalloonMessage("Quicklook url: " + callToActionURL);
684
684
  if (callToActionURL) {
685
- if (!hasProLicense()) {
685
+ if (!$TXm()) {
686
686
  console.warn("Quicklook closed: custom redirects require a Needle Engine Pro license: https://needle.tools/pricing", callToActionURL)
687
687
  }
688
688
  else {
@@ -697,7 +697,7 @@ export class USDZExporter extends Behaviour {
697
697
  private buildQuicklookOverlay(): CustomBranding {
698
698
  const obj: CustomBranding = {};
699
699
  if (this.customBranding) Object.assign(obj, this.customBranding);
700
- if (!hasProLicense()) {
700
+ if (!$TXm()) {
701
701
  console.log("Custom Quicklook banner text requires pro license: https://needle.tools/pricing");
702
702
  obj.callToAction = "Close";
703
703
  obj.checkoutTitle = "🌵 Made with Needle";
@@ -4,7 +4,6 @@ import { isDevEnvironment } from '../../engine/debug/index.js';
4
4
  import { FrameEvent } from '../../engine/engine_context.js';
5
5
  import { isLocalNetwork } from '../../engine/engine_networking_utils.js';
6
6
  import { serializable } from '../../engine/engine_serialization.js';
7
- import type { GuidsMap } from '../../engine/engine_types.js';
8
7
  import { deepClone, delay, getParam } from '../../engine/engine_utils.js';
9
8
  import { Animator } from '../Animator.js';
10
9
  import { AudioListener } from '../AudioListener.js';
@@ -45,7 +44,7 @@ export enum ClipExtrapolation {
45
44
  };
46
45
 
47
46
  /** @internal */
48
- export type CreateTrackFunction = (director: PlayableDirector, track: Models.TrackModel) => Tracks.TrackHandler | undefined | null;
47
+ export type CreateTrackFunction = (director: PlayableDirector, track: Models.TrackModel) => Tracks.TimelineTrackHandler | undefined | null;
49
48
 
50
49
  /**
51
50
  * PlayableDirector is the main component for controlling timelines in Needle Engine.
@@ -115,7 +114,15 @@ export class PlayableDirector extends Behaviour {
115
114
  * The timeline asset containing tracks, clips, and markers that this director will play.
116
115
  * Assign a timeline asset exported from Unity or Blender to enable playback.
117
116
  */
118
- playableAsset?: Models.TimelineAssetModel;
117
+ @serializable()
118
+ get playableAsset(): Models.TimelineAssetModel | undefined { return this._playableAsset; }
119
+ set playableAsset(value: Models.TimelineAssetModel | undefined) {
120
+ if (this._playableAsset !== value) {
121
+ this._playableAsset = value;
122
+ this._needsGraphRebuild = true;
123
+ }
124
+ }
125
+ private _playableAsset?: Models.TimelineAssetModel;
119
126
 
120
127
  /**
121
128
  * When true, the timeline starts playing automatically when the component awakens.
@@ -123,7 +130,7 @@ export class PlayableDirector extends Behaviour {
123
130
  * @default false
124
131
  */
125
132
  @serializable()
126
- playOnAwake?: boolean;
133
+ playOnAwake: boolean = false;
127
134
 
128
135
  /**
129
136
  * Determines how the timeline behaves when it reaches the end of its duration.
@@ -207,14 +214,10 @@ export class PlayableDirector extends Behaviour {
207
214
  onEnable() {
208
215
  if (debug) console.log("[Timeline] OnEnable", this.name, this.playOnAwake);
209
216
 
210
- for (const track of this._audioTracks) {
211
- track.onEnable?.();
212
- }
213
- for (const track of this._customTracks) {
214
- track.onEnable?.();
215
- }
216
- for (const track of this._animationTracks) {
217
- track.onEnable?.();
217
+ for (const tracks of this._allTracks) {
218
+ for (const track of tracks) {
219
+ track.onEnable?.();
220
+ }
218
221
  }
219
222
  if (this.playOnAwake) {
220
223
  this.play();
@@ -265,6 +268,7 @@ export class PlayableDirector extends Behaviour {
265
268
  this.resolveBindings();
266
269
  this.updateTimelineDuration();
267
270
  this.setupAndCreateTrackHandlers();
271
+ this._needsGraphRebuild = false;
268
272
  }
269
273
 
270
274
  /**
@@ -273,6 +277,8 @@ export class PlayableDirector extends Behaviour {
273
277
  */
274
278
  async play() {
275
279
  if (!this.isValid()) return;
280
+ // Ensure graph is built (handles the case where playableAsset is assigned after awake)
281
+ if (this._needsGraphRebuild) this.rebuildGraph();
276
282
  const pauseChanged = this._isPaused == true;
277
283
  this._isPaused = false;
278
284
  if (this._isPlaying) return;
@@ -290,8 +296,13 @@ export class PlayableDirector extends Behaviour {
290
296
  await Promise.all(promises);
291
297
  if (!this._isPlaying) return;
292
298
  }
293
- while (this._audioTracks.length > 0 && this._isPlaying && !AudioSource.userInteractionRegistered && this.waitForAudio)
299
+ let ticks = 0;
300
+ while (this._audioTracks.length > 0 && this._isPlaying && !AudioSource.userInteractionRegistered && this.waitForAudio) {
301
+ if (ticks++ <= 0) {
302
+ if (isDevEnvironment() || debug) console.warn(`[Timeline] Waiting for user interaction to play audio... (timeline '${this.name}' will start as soon as user interacts with the page). To start the timeline immediately without waiting for user interaction, set 'waitForAudio' to false on the PlayableDirector component.`);
303
+ }
294
304
  await delay(200);
305
+ }
295
306
  }
296
307
  this.invokeStateChangedMethodsOnTracks();
297
308
  // Update timeline in LateUpdate to give other scripts time to react to the updated state
@@ -343,6 +354,7 @@ export class PlayableDirector extends Behaviour {
343
354
  * Evaluate the timeline at the current time. This is useful when you want to manually update the timeline e.g. when the timeline is paused and you set `time` to a new value.
344
355
  */
345
356
  evaluate() {
357
+ if (this._needsGraphRebuild) this.rebuildGraph();
346
358
  this.internalEvaluate(true);
347
359
  }
348
360
 
@@ -373,7 +385,7 @@ export class PlayableDirector extends Behaviour {
373
385
  /**
374
386
  * @returns all audio tracks of the timeline
375
387
  */
376
- get audioTracks(): Tracks.AudioTrackHandler[] {
388
+ get audioTracks(): Tracks.TimelineAudioTrack[] {
377
389
  return this._audioTracks;
378
390
  }
379
391
 
@@ -387,10 +399,24 @@ export class PlayableDirector extends Behaviour {
387
399
  /**
388
400
  * @returns all marker tracks of the timeline
389
401
  */
390
- get markerTracks(): Tracks.MarkerTrackHandler[] {
402
+ get markerTracks(): Tracks.TimelineMarkerTrack[] {
391
403
  return this._markerTracks;
392
404
  }
393
405
 
406
+ /**
407
+ * @returns all activation tracks of the timeline
408
+ */
409
+ get activationTracks(): Tracks.TimelineActivationTrack[] {
410
+ return this._activationTracks;
411
+ }
412
+
413
+ /**
414
+ * @returns all tracks of the timeline
415
+ */
416
+ get tracks(): ReadonlyArray<Tracks.TimelineTrackHandler> {
417
+ return this._allTracks.flat();
418
+ }
419
+
394
420
  /**
395
421
  * Iterates over all markers of the timeline, optionally filtering by type
396
422
  *
@@ -412,37 +438,37 @@ export class PlayableDirector extends Behaviour {
412
438
  }
413
439
 
414
440
 
415
- private _guidsMap?: GuidsMap;
416
- /** @internal */
417
- resolveGuids(map: GuidsMap) {
418
- this._guidsMap = map;
419
- }
420
441
 
421
442
  // INTERNALS
422
443
 
444
+ private _needsGraphRebuild: boolean = false;
423
445
  private _isPlaying: boolean = false;
424
446
  private _internalUpdateRoutine: any;
425
447
  private _isPaused: boolean = false;
426
448
  /** internal, true during the time stop() is being processed */
427
449
  private _isStopping: boolean = false;
450
+ /** @internal Whether the current evaluate() was triggered by user code (not the internal update loop or stop/pause). */
451
+ _isUserEvaluation: boolean = false;
428
452
  private _time: number = 0;
429
453
  private _duration: number = 0;
430
454
  private _weight: number = 1;
431
- private readonly _animationTracks: Array<Tracks.AnimationTrackHandler> = [];
432
- private readonly _audioTracks: Array<Tracks.AudioTrackHandler> = [];
455
+ private readonly _animationTracks: Array<Tracks.TimelineAnimationTrack> = [];
456
+ private readonly _audioTracks: Array<Tracks.TimelineAudioTrack> = [];
433
457
  private readonly _signalTracks: Array<Tracks.SignalTrackHandler> = [];
434
- private readonly _markerTracks: Array<Tracks.MarkerTrackHandler> = [];
435
- private readonly _controlTracks: Array<Tracks.ControlTrackHandler> = [];
436
- private readonly _customTracks: Array<Tracks.TrackHandler> = [];
458
+ private readonly _markerTracks: Array<Tracks.TimelineMarkerTrack> = [];
459
+ private readonly _controlTracks: Array<Tracks.TimelineControlTrack> = [];
460
+ private readonly _activationTracks: Array<Tracks.TimelineActivationTrack> = [];
461
+ private readonly _customTracks: Array<Tracks.TimelineTrackHandler> = [];
437
462
 
438
- private readonly _tracksArray: Array<Array<Tracks.TrackHandler>> = [];
439
- private get _allTracks(): Array<Array<Tracks.TrackHandler>> {
463
+ private readonly _tracksArray: Array<Array<Tracks.TimelineTrackHandler>> = [];
464
+ private get _allTracks(): Array<Array<Tracks.TimelineTrackHandler>> {
440
465
  this._tracksArray.length = 0;
441
466
  this._tracksArray.push(this._animationTracks);
442
467
  this._tracksArray.push(this._audioTracks);
443
468
  this._tracksArray.push(this._signalTracks);
444
469
  this._tracksArray.push(this._markerTracks);
445
470
  this._tracksArray.push(this._controlTracks);
471
+ this._tracksArray.push(this._activationTracks);
446
472
  this._tracksArray.push(this._customTracks);
447
473
  return this._tracksArray;
448
474
  }
@@ -503,60 +529,32 @@ export class PlayableDirector extends Behaviour {
503
529
 
504
530
  const time = this._time;
505
531
 
506
- for (const track of this.playableAsset!.tracks) {
507
- if (track.muted) continue;
508
- switch (track.type) {
509
- case Models.TrackType.Activation:
510
- // when the timeline is being disabled or stopped
511
- // then we want to leave objects active state as they were
512
- // see NE-3241
513
- // TODO: support all "post-playback-state" settings an activation track has, this is just "Leave as is"
514
- if (!called_by_user && !this._isPlaying) continue;
515
-
516
- for (let i = 0; i < track.outputs.length; i++) {
517
- const binding = track.outputs[i];
518
- if (typeof binding === "object") {
519
- let isActive: boolean = false;
520
- if (track.clips) {
521
- for (const clip of track.clips) {
522
- if (clip.start <= time && time <= clip.end) {
523
- isActive = true;
524
- }
525
- }
526
- }
527
- const obj = binding as Object3D;
528
- if (obj.visible !== undefined) {
529
- if (obj.visible !== isActive) {
530
- obj.visible = isActive;
531
- if (debug)
532
- console.warn(this.name, "set ActivationTrack-" + i, obj.name, isActive, time);
533
- }
534
- }
535
- }
536
- }
537
- break;
538
-
539
- }
540
- }
541
-
532
+ this._isUserEvaluation = called_by_user;
542
533
  for (const track of this._allTracks) {
543
534
  for (const handler of track) {
544
535
  // When timeline reaches the end "stop()" is called which is evaluating with time 0
545
536
  // We don't want to re-evaluate the animation then in case the timeline is blended with the Animator
546
537
  // e.g then the timeline animation at time 0 is 100% applied on top of the animator animation
547
-
548
- if (this._isStopping && handler instanceof Tracks.AnimationTrackHandler) {
538
+ if (this._isStopping && handler instanceof Tracks.TimelineAnimationTrack) {
549
539
  continue;
550
540
  }
551
541
  handler.evaluate(time);
552
542
  }
553
543
  }
544
+ this._isUserEvaluation = false;
554
545
  }
555
546
 
556
547
  private resolveBindings() {
557
548
  if (!this._clonedPlayableAsset) {
558
549
  this._clonedPlayableAsset = true;
559
- this.playableAsset = deepClone(this.playableAsset);
550
+ // Deep clone so each director owns its own copy of the asset data.
551
+ // Needed because NEEDLE_persistent_assets returns the same shared object for all references —
552
+ // without this, resolving guid strings below would mutate shared data.
553
+ // On instantiated clones this is skipped (_clonedPlayableAsset is copied as true)
554
+ // because the instantiate resolve system already created an independent copy.
555
+ this.playableAsset = deepClone(this.playableAsset, (_obj, _key, val) => {
556
+ return !(val?.isObject3D === true);
557
+ });
560
558
  }
561
559
 
562
560
  if (!this.playableAsset || !this.playableAsset.tracks) return;
@@ -569,15 +567,13 @@ export class PlayableDirector extends Behaviour {
569
567
 
570
568
  for (const track of this.playableAsset.tracks) {
571
569
  for (let i = track.outputs.length - 1; i >= 0; i--) {
572
- let binding = track.outputs[i];
570
+ const binding = track.outputs[i];
573
571
  if (typeof binding === "string") {
574
- if (this._guidsMap && this._guidsMap[binding])
575
- binding = this._guidsMap[binding];
576
572
  const obj = GameObject.findByGuid(binding, root);
577
573
  if (obj === null || typeof obj !== "object") {
578
574
  // if the binding is missing remove it to avoid unnecessary loops
579
575
  track.outputs.splice(i, 1);
580
- console.warn("Failed to resolve binding", binding, track.name, track.type);
576
+ console.warn(`[Timeline] Failed to resolve binding on track '${track.name}' of type '${track.type}' in director '${this.name}' with timeline asset '${this.playableAsset.name}' ('${binding}' not found in scene)`);
581
577
  }
582
578
  else {
583
579
  if (debug)
@@ -592,21 +588,20 @@ export class PlayableDirector extends Behaviour {
592
588
  continue;
593
589
  }
594
590
  // if the binding is missing remove it to avoid unnecessary loops
595
- if (track.type !== Models.TrackType.Audio && track.type !== Models.TrackType.Control && track.type !== Models.TrackType.Marker && track.type !== Models.TrackType.Signal)
596
- console.warn("Missing binding", binding, track.name, track.type, this.name, this.playableAsset.name);
591
+ if (track.type !== Models.TrackType.Audio && track.type !== Models.TrackType.Control && track.type !== Models.TrackType.Marker && track.type !== Models.TrackType.Signal) {
592
+ console.warn(`[Timeline] Missing binding on track '${track.name}' of type '${track.type}' in director '${this.name}' with timeline asset '${this.playableAsset.name}' (null binding)`);
593
+ }
597
594
  }
598
595
  }
599
596
  if (track.type === Models.TrackType.Control) {
600
597
  if (track.clips) {
601
598
  for (let i = 0; i < track.clips.length; i++) {
602
599
  const clip = track.clips[i];
603
- let binding = clip.asset.sourceObject;
600
+ const binding = clip.asset.sourceObject;
604
601
  if (typeof binding === "string") {
605
- if (this._guidsMap && this._guidsMap[binding])
606
- binding = this._guidsMap[binding];
607
602
  const obj = GameObject.findByGuid(binding, root);
608
603
  if (obj === null || typeof obj !== "object") {
609
- console.warn("Failed to resolve sourceObject binding", binding, track.name, clip);
604
+ console.warn(`[Timeline] Failed to resolve sourceObject binding on track '${track.name}' of type '${track.type}' in director '${this.name}' with timeline asset '${this.playableAsset.name}' ('${binding}' not found in scene)`);
610
605
  }
611
606
  else {
612
607
  if (debug)
@@ -649,6 +644,7 @@ export class PlayableDirector extends Behaviour {
649
644
  this._animationTracks.length = 0;
650
645
  this._audioTracks.length = 0;
651
646
  this._signalTracks.length = 0;
647
+ this._activationTracks.length = 0;
652
648
 
653
649
  if (!this.playableAsset) return;
654
650
  let audioListener: AudioListener | null = GameObject.findObjectOfType(AudioListener, this.context);
@@ -656,7 +652,7 @@ export class PlayableDirector extends Behaviour {
656
652
  const type = track.type;
657
653
  const registered = PlayableDirector.createTrackFunctions[type];
658
654
  if (registered !== null && registered !== undefined) {
659
- const res = registered(this, track) as Tracks.TrackHandler;
655
+ const res = registered(this, track) as Tracks.TimelineTrackHandler;
660
656
  if (typeof res.evaluate === "function") {
661
657
  res.director = this;
662
658
  res.track = track;
@@ -679,7 +675,7 @@ export class PlayableDirector extends Behaviour {
679
675
  }
680
676
  const animationClips = binding?.gameObject?.animations;
681
677
  if (animationClips) {
682
- const handler = new Tracks.AnimationTrackHandler();
678
+ const handler = new Tracks.TimelineAnimationTrack();
683
679
  handler.trackOffset = track.trackOffset;
684
680
  handler.director = this;
685
681
  handler.track = track;
@@ -729,7 +725,7 @@ export class PlayableDirector extends Behaviour {
729
725
  }
730
726
  else if (track.type === Models.TrackType.Audio) {
731
727
  if (!track.clips || track.clips.length <= 0) continue;
732
- const audio = new Tracks.AudioTrackHandler();
728
+ const audio = new Tracks.TimelineAudioTrack();
733
729
  audio.director = this;
734
730
  audio.track = track;
735
731
  audio.audioSource = track.outputs.find(o => o instanceof AudioSource) as AudioSource;
@@ -753,7 +749,7 @@ export class PlayableDirector extends Behaviour {
753
749
  signalHandler.director = this;
754
750
  signalHandler.track = track;
755
751
 
756
- const markerHandler: Tracks.MarkerTrackHandler = new Tracks.MarkerTrackHandler();
752
+ const markerHandler: Tracks.TimelineMarkerTrack = new Tracks.TimelineMarkerTrack();
757
753
  markerHandler.director = this;
758
754
  markerHandler.track = track;
759
755
 
@@ -799,7 +795,7 @@ export class PlayableDirector extends Behaviour {
799
795
  this._signalTracks.push(handler);
800
796
  }
801
797
  else if (track.type === Models.TrackType.Control) {
802
- const handler = new Tracks.ControlTrackHandler();
798
+ const handler = new Tracks.TimelineControlTrack();
803
799
  handler.director = this;
804
800
  handler.track = track;
805
801
  if (track.clips) {
@@ -810,6 +806,12 @@ export class PlayableDirector extends Behaviour {
810
806
  handler.resolveSourceObjects(this.context);
811
807
  this._controlTracks.push(handler);
812
808
  }
809
+ else if (track.type === Models.TrackType.Activation) {
810
+ const handler = new Tracks.TimelineActivationTrack();
811
+ handler.director = this;
812
+ handler.track = track;
813
+ this._activationTracks.push(handler);
814
+ }
813
815
  }
814
816
  }
815
817
 
@@ -1,4 +1,5 @@
1
1
  import { serializable } from "../../engine/engine_serialization_decorator.js";
2
+ import { ISignalReceiver } from "../../engine/engine_types.js";
2
3
  import { getParam } from "../../engine/engine_utils.js";
3
4
  import { Behaviour } from "../Component.js";
4
5
  import { EventList } from "../EventList.js";
@@ -33,7 +34,9 @@ export class SignalReceiverEvent {
33
34
  * @category Animation and Sequencing
34
35
  * @group Components
35
36
  */
36
- export class SignalReceiver extends Behaviour {
37
+ export class SignalReceiver extends Behaviour implements ISignalReceiver {
38
+
39
+ readonly isSignalReceiver = true;
37
40
 
38
41
  private static receivers: { [key: string]: SignalReceiver[] } = {};
39
42