@needle-tools/engine 2.63.3-pre.1 → 2.65.0-pre

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 (289) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/needle-engine.js +7853 -7746
  3. package/dist/needle-engine.umd.cjs +215 -214
  4. package/lib/engine/api.js.map +1 -1
  5. package/lib/engine/assets/index.js.map +1 -1
  6. package/lib/engine/assets/logo.svg +1 -0
  7. package/lib/engine/codegen/register_types.js +169 -169
  8. package/lib/engine/codegen/register_types.js.map +1 -1
  9. package/lib/engine/debug/debug.js.map +1 -1
  10. package/lib/engine/debug/debug_console.js.map +1 -1
  11. package/lib/engine/debug/debug_overlay.js.map +1 -1
  12. package/lib/engine/debug/index.js.map +1 -1
  13. package/lib/engine/engine.js.map +1 -1
  14. package/lib/engine/engine_addressables.js.map +1 -1
  15. package/lib/engine/engine_application.js.map +1 -1
  16. package/lib/engine/engine_assetdatabase.js.map +1 -1
  17. package/lib/engine/engine_camera.js.map +1 -1
  18. package/lib/engine/engine_components.js.map +1 -1
  19. package/lib/engine/engine_constants.d.ts +1 -1
  20. package/lib/engine/engine_constants.js +1 -1
  21. package/lib/engine/engine_constants.js.map +1 -1
  22. package/lib/engine/engine_context_registry.js.map +1 -1
  23. package/lib/engine/engine_coroutine.js.map +1 -1
  24. package/lib/engine/engine_create_objects.js.map +1 -1
  25. package/lib/engine/engine_default_parameters.js.map +1 -1
  26. package/lib/engine/engine_element.d.ts +6 -4
  27. package/lib/engine/engine_element.js +152 -165
  28. package/lib/engine/engine_element.js.map +1 -1
  29. package/lib/engine/engine_element_loading.js.map +1 -1
  30. package/lib/engine/engine_element_overlay.js.map +1 -1
  31. package/lib/engine/engine_fileloader.js.map +1 -1
  32. package/lib/engine/engine_gameobject.d.ts +4 -2
  33. package/lib/engine/engine_gameobject.js +34 -15
  34. package/lib/engine/engine_gameobject.js.map +1 -1
  35. package/lib/engine/engine_generic_utils.js.map +1 -1
  36. package/lib/engine/engine_gizmos.js.map +1 -1
  37. package/lib/engine/engine_gltf.d.ts +1 -1
  38. package/lib/engine/engine_gltf.js.map +1 -1
  39. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  40. package/lib/engine/engine_hot_reload.js.map +1 -1
  41. package/lib/engine/engine_input.js.map +1 -1
  42. package/lib/engine/engine_input_utils.js.map +1 -1
  43. package/lib/engine/engine_instancing.d.ts +1 -0
  44. package/lib/engine/engine_instancing.js +3 -2
  45. package/lib/engine/engine_instancing.js.map +1 -1
  46. package/lib/engine/engine_license.js +14 -13
  47. package/lib/engine/engine_license.js.map +1 -1
  48. package/lib/engine/engine_lightdata.js.map +1 -1
  49. package/lib/engine/engine_loaders.js.map +1 -1
  50. package/lib/engine/engine_mainloop_utils.js +62 -57
  51. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  52. package/lib/engine/engine_math.js.map +1 -1
  53. package/lib/engine/engine_networking.js.map +1 -1
  54. package/lib/engine/engine_networking_auto.js.map +1 -1
  55. package/lib/engine/engine_networking_files.js.map +1 -1
  56. package/lib/engine/engine_networking_files_default_components.js.map +1 -1
  57. package/lib/engine/engine_networking_instantiate.js.map +1 -1
  58. package/lib/engine/engine_networking_peer.js.map +1 -1
  59. package/lib/engine/engine_networking_types.js.map +1 -1
  60. package/lib/engine/engine_networking_utils.js.map +1 -1
  61. package/lib/engine/engine_networking_websocket.js.map +1 -1
  62. package/lib/engine/engine_physics.d.ts +1 -0
  63. package/lib/engine/engine_physics.js +30 -0
  64. package/lib/engine/engine_physics.js.map +1 -1
  65. package/lib/engine/engine_physics.types.js.map +1 -1
  66. package/lib/engine/engine_playerview.js.map +1 -1
  67. package/lib/engine/engine_rendererdata.js.map +1 -1
  68. package/lib/engine/engine_scenetools.js.map +1 -1
  69. package/lib/engine/engine_serialization.js.map +1 -1
  70. package/lib/engine/engine_serialization_builtin_serializer.js.map +1 -1
  71. package/lib/engine/engine_serialization_core.js.map +1 -1
  72. package/lib/engine/engine_serialization_decorator.js.map +1 -1
  73. package/lib/engine/engine_setup.d.ts +6 -3
  74. package/lib/engine/engine_setup.js +14 -5
  75. package/lib/engine/engine_setup.js.map +1 -1
  76. package/lib/engine/engine_shaders.js.map +1 -1
  77. package/lib/engine/engine_texture.js.map +1 -1
  78. package/lib/engine/engine_three_utils.js.map +1 -1
  79. package/lib/engine/engine_time.d.ts +1 -0
  80. package/lib/engine/engine_time.js +5 -1
  81. package/lib/engine/engine_time.js.map +1 -1
  82. package/lib/engine/engine_types.d.ts +12 -0
  83. package/lib/engine/engine_types.js.map +1 -1
  84. package/lib/engine/engine_typestore.js.map +1 -1
  85. package/lib/engine/engine_util_decorator.js.map +1 -1
  86. package/lib/engine/engine_utils.js.map +1 -1
  87. package/lib/engine/engine_utils_screenshot.js.map +1 -1
  88. package/lib/engine/engine_web_api.js.map +1 -1
  89. package/lib/engine/extensions/EXT_texture_exr.js.map +1 -1
  90. package/lib/engine/extensions/NEEDLE_animator_controller_model.js.map +1 -1
  91. package/lib/engine/extensions/NEEDLE_components.js.map +1 -1
  92. package/lib/engine/extensions/NEEDLE_gameobject_data.js.map +1 -1
  93. package/lib/engine/extensions/NEEDLE_lighting_settings.js.map +1 -1
  94. package/lib/engine/extensions/NEEDLE_lightmaps.js.map +1 -1
  95. package/lib/engine/extensions/NEEDLE_persistent_assets.js.map +1 -1
  96. package/lib/engine/extensions/NEEDLE_progressive.js.map +1 -1
  97. package/lib/engine/extensions/NEEDLE_render_objects.js.map +1 -1
  98. package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
  99. package/lib/engine/extensions/extension_resolver.js.map +1 -1
  100. package/lib/engine/extensions/extension_utils.js.map +1 -1
  101. package/lib/engine/extensions/extensions.js.map +1 -1
  102. package/lib/engine/js-extensions/Camera.js.map +1 -1
  103. package/lib/engine/js-extensions/Layers.js.map +1 -1
  104. package/lib/engine/js-extensions/index.js.map +1 -1
  105. package/lib/engine/shaders/shaderData.js.map +1 -1
  106. package/lib/engine/tests/test_utils.js.map +1 -1
  107. package/lib/engine-components/AlignmentConstraint.js.map +1 -1
  108. package/lib/engine-components/Animation.js +6 -6
  109. package/lib/engine-components/Animation.js.map +1 -1
  110. package/lib/engine-components/AnimationCurve.js.map +1 -1
  111. package/lib/engine-components/Animator.js.map +1 -1
  112. package/lib/engine-components/AnimatorController.js +2 -0
  113. package/lib/engine-components/AnimatorController.js.map +1 -1
  114. package/lib/engine-components/AudioListener.js.map +1 -1
  115. package/lib/engine-components/AudioSource.js +1 -1
  116. package/lib/engine-components/AudioSource.js.map +1 -1
  117. package/lib/engine-components/AvatarLoader.js.map +1 -1
  118. package/lib/engine-components/AxesHelper.js.map +1 -1
  119. package/lib/engine-components/BasicIKConstraint.js.map +1 -1
  120. package/lib/engine-components/BoxCollider.js.map +1 -1
  121. package/lib/engine-components/BoxHelperComponent.js.map +1 -1
  122. package/lib/engine-components/Camera.d.ts +3 -1
  123. package/lib/engine-components/Camera.js +11 -10
  124. package/lib/engine-components/Camera.js.map +1 -1
  125. package/lib/engine-components/CameraUtils.js.map +1 -1
  126. package/lib/engine-components/CharacterController.js.map +1 -1
  127. package/lib/engine-components/Collider.js.map +1 -1
  128. package/lib/engine-components/Component.d.ts +2 -1
  129. package/lib/engine-components/Component.js +2 -2
  130. package/lib/engine-components/Component.js.map +1 -1
  131. package/lib/engine-components/DeleteBox.js.map +1 -1
  132. package/lib/engine-components/DeviceFlag.js.map +1 -1
  133. package/lib/engine-components/DragControls.js.map +1 -1
  134. package/lib/engine-components/DropListener.js.map +1 -1
  135. package/lib/engine-components/Duplicatable.js.map +1 -1
  136. package/lib/engine-components/EventList.js.map +1 -1
  137. package/lib/engine-components/EventTrigger.js.map +1 -1
  138. package/lib/engine-components/EventType.js.map +1 -1
  139. package/lib/engine-components/FlyControls.js.map +1 -1
  140. package/lib/engine-components/Fog.js.map +1 -1
  141. package/lib/engine-components/Gizmos.js.map +1 -1
  142. package/lib/engine-components/GridHelper.js.map +1 -1
  143. package/lib/engine-components/GroundProjection.js.map +1 -1
  144. package/lib/engine-components/Interactable.js.map +1 -1
  145. package/lib/engine-components/Joints.js.map +1 -1
  146. package/lib/engine-components/LODGroup.js.map +1 -1
  147. package/lib/engine-components/Light.d.ts +0 -2
  148. package/lib/engine-components/Light.js +22 -14
  149. package/lib/engine-components/Light.js.map +1 -1
  150. package/lib/engine-components/LookAtConstraint.js.map +1 -1
  151. package/lib/engine-components/NestedGltf.js.map +1 -1
  152. package/lib/engine-components/Networking.js.map +1 -1
  153. package/lib/engine-components/OffsetConstraint.js.map +1 -1
  154. package/lib/engine-components/OrbitControls.js.map +1 -1
  155. package/lib/engine-components/ParticleSystem.js +13 -1
  156. package/lib/engine-components/ParticleSystem.js.map +1 -1
  157. package/lib/engine-components/ParticleSystemModules.js.map +1 -1
  158. package/lib/engine-components/ParticleSystemSubEmitter.js.map +1 -1
  159. package/lib/engine-components/PlayerColor.js.map +1 -1
  160. package/lib/engine-components/ReflectionProbe.js.map +1 -1
  161. package/lib/engine-components/Renderer.d.ts +5 -1
  162. package/lib/engine-components/Renderer.js +78 -29
  163. package/lib/engine-components/Renderer.js.map +1 -1
  164. package/lib/engine-components/RendererLightmap.js.map +1 -1
  165. package/lib/engine-components/RigidBody.js.map +1 -1
  166. package/lib/engine-components/ScreenCapture.js.map +1 -1
  167. package/lib/engine-components/ShadowCatcher.js.map +1 -1
  168. package/lib/engine-components/Skybox.d.ts +2 -0
  169. package/lib/engine-components/Skybox.js +43 -21
  170. package/lib/engine-components/Skybox.js.map +1 -1
  171. package/lib/engine-components/SmoothFollow.js.map +1 -1
  172. package/lib/engine-components/SpatialTrigger.js.map +1 -1
  173. package/lib/engine-components/SpectatorCamera.js.map +1 -1
  174. package/lib/engine-components/SphereCollider.js.map +1 -1
  175. package/lib/engine-components/SpriteRenderer.js.map +1 -1
  176. package/lib/engine-components/SyncedCamera.js.map +1 -1
  177. package/lib/engine-components/SyncedRoom.js.map +1 -1
  178. package/lib/engine-components/SyncedTransform.js.map +1 -1
  179. package/lib/engine-components/TestRunner.js.map +1 -1
  180. package/lib/engine-components/TransformGizmo.js.map +1 -1
  181. package/lib/engine-components/VideoPlayer.js.map +1 -1
  182. package/lib/engine-components/Voip.js.map +1 -1
  183. package/lib/engine-components/Volume.js +2 -0
  184. package/lib/engine-components/Volume.js.map +1 -1
  185. package/lib/engine-components/WebARSessionRoot.js.map +1 -1
  186. package/lib/engine-components/WebXR.js.map +1 -1
  187. package/lib/engine-components/WebXRAvatar.js.map +1 -1
  188. package/lib/engine-components/WebXRController.js.map +1 -1
  189. package/lib/engine-components/WebXRGrabRendering.js.map +1 -1
  190. package/lib/engine-components/WebXRRig.js.map +1 -1
  191. package/lib/engine-components/WebXRSync.js.map +1 -1
  192. package/lib/engine-components/XRFlag.js.map +1 -1
  193. package/lib/engine-components/avatar/AvatarBlink_Simple.js.map +1 -1
  194. package/lib/engine-components/avatar/AvatarEyeLook_Rotation.js.map +1 -1
  195. package/lib/engine-components/avatar/Avatar_Brain_LookAt.js.map +1 -1
  196. package/lib/engine-components/avatar/Avatar_MouthShapes.js.map +1 -1
  197. package/lib/engine-components/avatar/Avatar_MustacheShake.js.map +1 -1
  198. package/lib/engine-components/codegen/components.js.map +1 -1
  199. package/lib/engine-components/debug/LogStats.js.map +1 -1
  200. package/lib/engine-components/export/gltf/GltfExport.js.map +1 -1
  201. package/lib/engine-components/export/usdz/Extension.js.map +1 -1
  202. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  203. package/lib/engine-components/export/usdz/extensions/Animation.js.map +1 -1
  204. package/lib/engine-components/export/usdz/types.js.map +1 -1
  205. package/lib/engine-components/export/usdz/utils/animationutils.js.map +1 -1
  206. package/lib/engine-components/export/usdz/utils/quicklook.js.map +1 -1
  207. package/lib/engine-components/export/usdz/utils/timeutils.js.map +1 -1
  208. package/lib/engine-components/js-extensions/ExtensionUtils.js.map +1 -1
  209. package/lib/engine-components/js-extensions/Object3D.js +8 -1
  210. package/lib/engine-components/js-extensions/Object3D.js.map +1 -1
  211. package/lib/engine-components/js-extensions/RGBAColor.js.map +1 -1
  212. package/lib/engine-components/js-extensions/Vector.js.map +1 -1
  213. package/lib/engine-components/timeline/PlayableDirector.d.ts +5 -0
  214. package/lib/engine-components/timeline/PlayableDirector.js +36 -23
  215. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  216. package/lib/engine-components/timeline/SignalAsset.js.map +1 -1
  217. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  218. package/lib/engine-components/timeline/TimelineTracks.d.ts +9 -0
  219. package/lib/engine-components/timeline/TimelineTracks.js +112 -19
  220. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  221. package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
  222. package/lib/engine-components/ui/Button.js.map +1 -1
  223. package/lib/engine-components/ui/Canvas.js +2 -2
  224. package/lib/engine-components/ui/Canvas.js.map +1 -1
  225. package/lib/engine-components/ui/CanvasGroup.js.map +1 -1
  226. package/lib/engine-components/ui/EventSystem.js.map +1 -1
  227. package/lib/engine-components/ui/Graphic.js.map +1 -1
  228. package/lib/engine-components/ui/Image.js.map +1 -1
  229. package/lib/engine-components/ui/InputField.js.map +1 -1
  230. package/lib/engine-components/ui/Interfaces.js.map +1 -1
  231. package/lib/engine-components/ui/Keyboard.js.map +1 -1
  232. package/lib/engine-components/ui/Layout.js.map +1 -1
  233. package/lib/engine-components/ui/PointerEvents.js.map +1 -1
  234. package/lib/engine-components/ui/RaycastUtils.js.map +1 -1
  235. package/lib/engine-components/ui/Raycaster.js.map +1 -1
  236. package/lib/engine-components/ui/RectTransform.js.map +1 -1
  237. package/lib/engine-components/ui/SpatialHtml.js.map +1 -1
  238. package/lib/engine-components/ui/Text.js.map +1 -1
  239. package/lib/engine-components/ui/Utils.js.map +1 -1
  240. package/lib/engine-components-experimental/Presentation.js.map +1 -1
  241. package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -1
  242. package/lib/engine-schemes/schemes.js.map +1 -1
  243. package/lib/engine-schemes/synced-camera-model.js.map +1 -1
  244. package/lib/engine-schemes/synced-transform-model.js.map +1 -1
  245. package/lib/engine-schemes/transform.js.map +1 -1
  246. package/lib/engine-schemes/vec2.js.map +1 -1
  247. package/lib/engine-schemes/vec3.js.map +1 -1
  248. package/lib/engine-schemes/vec4.js.map +1 -1
  249. package/lib/engine-schemes/vr-user-state-buffer.js.map +1 -1
  250. package/lib/include/three/ARButton.js.map +1 -1
  251. package/lib/include/three/EXT_mesh_gpu_instancing_exporter.js.map +1 -1
  252. package/lib/include/three/VRButton.js.map +1 -1
  253. package/lib/needle-engine.js.map +1 -1
  254. package/package.json +16 -3
  255. package/plugins/generate-font.js +65 -0
  256. package/plugins/vite/poster-client.js +3 -5
  257. package/plugins/vite/reload.js +2 -2
  258. package/src/engine/codegen/register_types.js +171 -171
  259. package/src/engine/engine_constants.ts +1 -1
  260. package/src/engine/engine_element.ts +162 -178
  261. package/src/engine/engine_gameobject.ts +583 -558
  262. package/src/engine/engine_gltf.ts +1 -1
  263. package/src/engine/engine_instancing.ts +3 -3
  264. package/src/engine/engine_license.ts +14 -13
  265. package/src/engine/engine_mainloop_utils.ts +66 -63
  266. package/src/engine/engine_physics.ts +23 -0
  267. package/src/engine/engine_setup.ts +21 -8
  268. package/src/engine/engine_time.ts +9 -4
  269. package/src/engine/engine_types.ts +36 -22
  270. package/src/engine-components/Animation.ts +6 -5
  271. package/src/engine-components/AnimatorController.ts +1 -0
  272. package/src/engine-components/AudioSource.ts +1 -1
  273. package/src/engine-components/Camera.ts +14 -12
  274. package/src/engine-components/Component.ts +5 -2
  275. package/src/engine-components/Light.ts +20 -13
  276. package/src/engine-components/ParticleSystem.ts +15 -2
  277. package/src/engine-components/Renderer.ts +92 -33
  278. package/src/engine-components/Skybox.ts +49 -22
  279. package/src/engine-components/Volume.ts +1 -0
  280. package/src/engine-components/js-extensions/Object3D.ts +8 -2
  281. package/src/engine-components/timeline/PlayableDirector.ts +35 -24
  282. package/src/engine-components/timeline/TimelineTracks.ts +124 -20
  283. package/src/engine-components/ui/Canvas.ts +2 -2
  284. package/lib/tsconfig.tsbuildinfo +0 -1
  285. package/lib/vite.config.d.ts +0 -2
  286. package/lib/vite.config.js +0 -26
  287. package/lib/vite.config.js.map +0 -1
  288. package/src/engine/codegen/license.js +0 -1
  289. package/src/tsconfig.json +0 -33
@@ -84,9 +84,13 @@ export class PlayableDirector extends Behaviour {
84
84
  set duration(value: number) { this._duration = value; }
85
85
  get weight(): number { return this._weight; };
86
86
  set weight(value: number) { this._weight = value; }
87
+ get speed(): number { return this._speed; }
88
+ set speed(value: number) { this._speed = value; }
89
+
87
90
 
88
91
  private _visibilityChangeEvt?: any;
89
92
  private _clonedPlayableAsset: boolean = false;
93
+ private _speed: number = 1;
90
94
 
91
95
  awake(): void {
92
96
  if (debug)
@@ -149,7 +153,9 @@ export class PlayableDirector extends Behaviour {
149
153
 
150
154
  play() {
151
155
  if (!this.isValid()) return;
156
+ const pauseChanged = this._isPaused == true;
152
157
  this._isPaused = false;
158
+ if (pauseChanged) this.invokePauseChangedMethodsOnTracks();
153
159
  if (this._isPlaying) return;
154
160
  this._isPlaying = true;
155
161
  this._internalUpdateRoutine = this.startCoroutine(this.internalUpdate());
@@ -161,18 +167,23 @@ export class PlayableDirector extends Behaviour {
161
167
  if (this._isPaused) return;
162
168
  this._isPaused = true;
163
169
  this.evaluate();
170
+ this.invokePauseChangedMethodsOnTracks();
164
171
  }
165
172
 
166
173
  stop() {
167
- for(const track of this._audioTracks) track.stop();
174
+ for (const track of this._audioTracks) track.stop();
175
+ const pauseChanged = this._isPaused == true;
176
+ const wasPlaying = this._isPlaying;
168
177
  if (this._isPlaying) {
169
178
  this._time = 0;
170
179
  this._isPlaying = false;
171
180
  this._isPaused = false;
172
181
  this.evaluate();
182
+ if (pauseChanged) this.invokePauseChangedMethodsOnTracks();
173
183
  }
174
184
  this._isPlaying = false;
175
185
  this._isPaused = false;
186
+ if (pauseChanged && !wasPlaying) this.invokePauseChangedMethodsOnTracks();
176
187
  if (this._internalUpdateRoutine)
177
188
  this.stopCoroutine(this._internalUpdateRoutine);
178
189
  this._internalUpdateRoutine = null;
@@ -183,10 +194,15 @@ export class PlayableDirector extends Behaviour {
183
194
  let t = this._time;
184
195
  switch (this.extrapolationMode) {
185
196
  case DirectorWrapMode.Hold:
186
- t = Math.min(t, this._duration);
197
+ if(this._speed > 0)
198
+ t = Math.min(t, this._duration);
199
+ else if(this._speed < 0)
200
+ t = Math.max(t, 0);
201
+ this._time = t;
187
202
  break;
188
203
  case DirectorWrapMode.Loop:
189
204
  t %= this._duration;
205
+ this._time = t;
190
206
  break;
191
207
  case DirectorWrapMode.None:
192
208
  if (t > this._duration) {
@@ -240,10 +256,17 @@ export class PlayableDirector extends Behaviour {
240
256
  this._customTracks
241
257
  ];
242
258
 
259
+ /** should be called after evaluate if the director was playing */
260
+ private invokePauseChangedMethodsOnTracks() {
261
+ for (const track of this.forEachTrack()) {
262
+ track.onPauseChanged?.call(track);
263
+ }
264
+ }
265
+
243
266
  private *internalUpdate() {
244
267
  while (this._isPlaying && this.activeAndEnabled) {
245
268
  if (!this._isPaused && this._isPlaying) {
246
- this._time += this.context.time.deltaTime;
269
+ this._time += this.context.time.deltaTime * this.speed;
247
270
  this.evaluate();
248
271
  }
249
272
  // for (let i = 0; i < 5; i++)
@@ -278,10 +301,8 @@ export class PlayableDirector extends Behaviour {
278
301
  for (const handler of this._animationTracks) {
279
302
  handler.evaluate(time);
280
303
  }
281
- if (AudioSource.userInteractionRegistered) {
282
- for (const handler of this._audioTracks) {
283
- handler.evaluate(time);
284
- }
304
+ for (const handler of this._audioTracks) {
305
+ handler.evaluate(time);
285
306
  }
286
307
  for (const sig of this._signalTracks) {
287
308
  sig.evaluate(time);
@@ -369,8 +390,7 @@ export class PlayableDirector extends Behaviour {
369
390
  this._signalTracks.length = 0;
370
391
 
371
392
  if (!this.playableAsset) return;
372
- const audioTracks: Array<Models.TrackModel> = [];
373
- const audioAllowedCallbacks : any = [];
393
+ const audioListener: AudioListener | null = GameObject.findObjectOfType(AudioListener, this.context);
374
394
  for (const track of this.playableAsset!.tracks) {
375
395
  const type = track.type;
376
396
  const registered = PlayableDirector.createTrackFunctions[type];
@@ -442,16 +462,12 @@ export class PlayableDirector extends Behaviour {
442
462
  audio.director = this;
443
463
  audio.track = track;
444
464
  this._audioTracks.push(audio);
445
-
446
- audioAllowedCallbacks.push(() => {
447
- const listener = GameObject.findObjectOfType(AudioListener, this.context) as AudioListener;
448
- if (!listener) return;
449
- audio.listener = listener.listener;
450
- for (let i = 0; i < track.clips.length; i++) {
451
- const clipModel = track.clips[i];
452
- audio.addModel(clipModel);
453
- }
454
- });
465
+ if (!audioListener) continue;
466
+ audio.listener = audioListener.listener;
467
+ for (let i = 0; i < track.clips.length; i++) {
468
+ const clipModel = track.clips[i];
469
+ audio.addModel(clipModel);
470
+ }
455
471
  }
456
472
  else if (track.type === Models.TrackType.Marker) {
457
473
  const signalHandler: Tracks.SignalTrackHandler = new Tracks.SignalTrackHandler();
@@ -497,11 +513,6 @@ export class PlayableDirector extends Behaviour {
497
513
  this._controlTracks.push(handler);
498
514
  }
499
515
  }
500
-
501
- AudioSource.registerWaitForAllowAudio(() => {
502
- audioAllowedCallbacks.forEach((cb: any) => cb());
503
- audioAllowedCallbacks.length = 0;
504
- });
505
516
  }
506
517
 
507
518
  private setAudioTracksAllowPlaying(allow: boolean) {
@@ -6,6 +6,8 @@ import { Context } from "../../engine/engine_setup";
6
6
  import { SignalReceiver } from "./SignalAsset";
7
7
  import { AnimationClip, Quaternion, Vector3 } from "three";
8
8
  import { getParam, getPath } from "../../engine/engine_utils";
9
+ import { AudioSource } from "../AudioSource";
10
+ import { Animator } from "../Animator"
9
11
 
10
12
  const debug = getParam("debugtimeline");
11
13
 
@@ -40,6 +42,7 @@ export abstract class TrackHandler {
40
42
  onDestroy?();
41
43
  abstract evaluate(time: number);
42
44
  onMuteChanged?();
45
+ onPauseChanged?();
43
46
 
44
47
  getClipTime(time: number, model: Models.ClipModel) {
45
48
  return model.clipIn + (time - model.start) * model.timeScale;
@@ -136,6 +139,16 @@ export class AnimationTrackHandler extends TrackHandler {
136
139
  /** holds data/info about clips differences */
137
140
  private _actionOffsets: Array<AnimationClipOffsetData> = [];
138
141
  private _didBind: boolean = false;
142
+ private _animator: Animator | null = null;
143
+ private _animatorWasEnabled?: boolean = false;
144
+
145
+ onPauseChanged() {
146
+ // When the timeline is paused the original animator will be enabled again if it was before
147
+ if (this._animator && this._animatorWasEnabled !== undefined) {
148
+ this._animator.enabled = this.director.isPaused ? this._animatorWasEnabled : false;
149
+ }
150
+ }
151
+
139
152
 
140
153
  createHooks(clipModel: Models.AnimationClipModel, clip) {
141
154
  if (clip.tracks?.length <= 0) {
@@ -208,6 +221,13 @@ export class AnimationTrackHandler extends TrackHandler {
208
221
  this._actionOffsets.push(off);
209
222
  }
210
223
 
224
+ if (this.target) {
225
+ // We need to disable the animator component in case it also animates
226
+ // which overrides the timeline
227
+ this._animator = GameObject.getComponent(this.target, Animator) ?? null;
228
+ this._animatorWasEnabled = this._animator?.enabled;
229
+ }
230
+
211
231
  // Clip Offsets
212
232
  for (const model of this.models) {
213
233
  const clipData = model.asset as Models.AnimationClipModel;
@@ -261,6 +281,8 @@ export class AnimationTrackHandler extends TrackHandler {
261
281
  if (!this.mixer) return;
262
282
  this.bind();
263
283
 
284
+ if (this._animator && this.director.isPlaying && this.director.weight > 0) this._animator.enabled = false;
285
+
264
286
  this._totalOffsetPosition.set(0, 0, 0);
265
287
  this._totalOffsetRotation.set(0, 0, 0, 1);
266
288
  this._totalOffsetPosition2.set(0, 0, 0);
@@ -268,38 +290,60 @@ export class AnimationTrackHandler extends TrackHandler {
268
290
  let activeClips = 0;
269
291
  let blend: number = 0;
270
292
  let didPostExtrapolate = false;
293
+ let didPreExtrapolate = false;
271
294
  for (let i = 0; i < this.clips.length; i++) {
272
295
  const model = this.models[i];
273
296
  const action = this.actions[i];
274
297
  const clipModel = model.asset as Models.AnimationClipModel;
275
298
  action.weight = 0;
299
+
276
300
  const isInTimeRange = time >= model.start && time <= model.end;
301
+ const preExtrapolation: Models.ClipExtrapolation = model.preExtrapolationMode;
277
302
  const postExtrapolation: Models.ClipExtrapolation = model.postExtrapolationMode;
303
+ const nextClip = i < this.clips.length - 1 ? this.models[i + 1] : null;
278
304
  let isActive = isInTimeRange;
305
+ let doPreExtrapolate = false;
306
+
279
307
  if (!isActive && !didPostExtrapolate && model.end < time && postExtrapolation !== Models.ClipExtrapolation.None) {
280
- const nextClip = i < this.clips.length - 1 ? this.models[i + 1] : null;
281
308
  // use post extrapolate if its the last clip of the next clip has not yet started
282
309
  if (!nextClip || nextClip.start > time) {
283
310
  isActive = true;
284
311
  didPostExtrapolate = true;
285
312
  }
286
313
  }
287
- const preExtrapolation: Models.ClipExtrapolation = model.preExtrapolationMode;
288
- if (i == 0 && !isActive && !didPostExtrapolate && model.start > time && preExtrapolation !== Models.ClipExtrapolation.None) {
289
- isActive = true;
290
- if (preExtrapolation !== Models.ClipExtrapolation.Hold)
291
- time += model.start;
314
+ else if (i == 0 && !isActive && !didPreExtrapolate && model.start > time && preExtrapolation !== Models.ClipExtrapolation.None) {
315
+ if (!nextClip || nextClip.start < time) {
316
+ isActive = true;
317
+ doPreExtrapolate = true;
318
+ didPreExtrapolate = true;
319
+ }
292
320
  }
321
+
293
322
  if (isActive) {
294
323
  // const clip = this.clips[i];
295
324
  let weight = 1;
296
325
  weight *= this.evaluateWeight(time, i, this.models, isActive);
326
+
327
+ let handleLoop = isInTimeRange;
328
+ if(doPreExtrapolate){
329
+ if (preExtrapolation !== Models.ClipExtrapolation.Hold) {
330
+ time += model.start;
331
+ handleLoop = true;
332
+ }
333
+ }
334
+
297
335
  // TODO: handle clipIn again
298
336
  let t = this.getClipTime(time, model);
299
337
  let loops = 0;
300
338
  const duration = clipModel.duration;
301
339
 
302
- if (isInTimeRange) {
340
+ if (doPreExtrapolate) {
341
+ if (preExtrapolation === Models.ClipExtrapolation.Hold) {
342
+ t = 0;
343
+ }
344
+ }
345
+
346
+ if (handleLoop) {
303
347
  if (clipModel.loop) {
304
348
  // const t0 = t - .001;
305
349
  loops += Math.floor(t / (duration + .000001));
@@ -468,6 +512,8 @@ export class AudioTrackHandler extends TrackHandler {
468
512
  audioContextTimeOffset: Array<number> = [];
469
513
  lastTime: number = 0;
470
514
 
515
+ private _audioLoader: THREE.AudioLoader | null = null;
516
+
471
517
  private getAudioFilePath(path: string) {
472
518
  // TODO: this should be the timeline asset location probably which MIGHT be different
473
519
  const glbLocation = this.director.sourceId;
@@ -483,18 +529,9 @@ export class AudioTrackHandler extends TrackHandler {
483
529
  }
484
530
 
485
531
  addModel(model: Models.ClipModel) {
486
- const path = this.getAudioFilePath(model.asset.clip);
487
532
  const audio = new THREE.Audio(this.listener);
488
- audio.setVolume(model.asset.volume);
489
- const loader = new THREE.AudioLoader();
490
- if (debug)
491
- console.log(path, this.director.sourceId);
492
- loader.load(path, (buffer) => {
493
- audio.setBuffer(buffer);
494
- audio.loop = model.asset.loop;
495
- this.audio.push(audio);
496
- this.models.push(model);
497
- });
533
+ this.audio.push(audio);
534
+ this.models.push(model);
498
535
  }
499
536
 
500
537
  onDisable() {
@@ -521,9 +558,14 @@ export class AudioTrackHandler extends TrackHandler {
521
558
  audio.stop();
522
559
  }
523
560
  }
561
+
524
562
  evaluate(time: number) {
525
563
  if (muteAudioTracks) return;
526
564
  if (this.track.muted) return;
565
+ if (this.director.speed < 0) {
566
+ // Reversed audio playback is currently not supported
567
+ return;
568
+ }
527
569
  const isMuted = this.director.context.application.muted;
528
570
  // this is just so that we dont hear the very first beat when the audio starts but is muted
529
571
  // if we dont add a delay we hear a little bit of the audio before it shuts down
@@ -532,7 +574,15 @@ export class AudioTrackHandler extends TrackHandler {
532
574
  for (let i = 0; i < this.models.length; i++) {
533
575
  const model = this.models[i];
534
576
  const audio = this.audio[i];
535
- if (time >= model.start && time <= model.end) {
577
+ // only trigger loading for tracks that are CLOSE to being played
578
+ if ((!audio || !audio.buffer) && this.isInTimeRange(model, time - 1, time + 1)) {
579
+ this.handleAudioLoading(model, audio);
580
+ }
581
+ if (AudioSource.userInteractionRegistered === false) continue;
582
+ if (audio === null || !audio.buffer) continue;
583
+ audio.playbackRate = this.director.context.time.timeScale;
584
+ audio.loop = model.asset.loop;
585
+ if (time >= model.start && time <= model.end && time < this.director.duration) {
536
586
  if (this.director.isPlaying == false) {
537
587
  if (audio.isPlaying)
538
588
  audio.stop();
@@ -556,7 +606,7 @@ export class AudioTrackHandler extends TrackHandler {
556
606
  }
557
607
  }
558
608
  let vol = model.asset.volume as number;
559
- if(isMuted) vol = 0;
609
+ if (isMuted) vol = 0;
560
610
  if (model.easeInDuration > 0) {
561
611
  const easeIn = Math.min((time - model.start) / model.easeInDuration, 1);
562
612
  vol *= easeIn;
@@ -574,6 +624,60 @@ export class AudioTrackHandler extends TrackHandler {
574
624
  }
575
625
  this.lastTime = time;
576
626
  }
627
+
628
+ /** Call to load audio buffer for a specific time in the track. Can be used to preload the timeline audio */
629
+ loadAudio(time: number, lookAhead: number = 0, lookBehind: number = 0) {
630
+ let promises: Array<Promise<AudioBuffer | null>> | null = null;
631
+ const rangeStart = time - lookBehind;
632
+ const rangeEnd = time + lookAhead;
633
+ for (const model of this.models) {
634
+ if (this.isInTimeRange(model, rangeStart, rangeEnd)) {
635
+ const audio = this.audio[this.models.indexOf(model)];
636
+ const promise = this.handleAudioLoading(model, audio);
637
+ if (promise !== null) {
638
+ if (promises === null) promises = [];
639
+ promises.push(promise);
640
+ }
641
+ }
642
+ }
643
+ if (promises !== null) {
644
+ return Promise.all(promises);
645
+ }
646
+ return null;
647
+ }
648
+
649
+ private isInTimeRange(model: Models.ClipModel, start: number, end: number) {
650
+ // Range surrounds clip range
651
+ if (start <= model.start && end >= model.end) return true;
652
+ // Range start is in clip range
653
+ if (start >= model.start && start <= model.end) return true;
654
+ // Range end is in clip range
655
+ if (end >= model.start && end <= model.end) return true;
656
+ return false;
657
+ }
658
+
659
+ private handleAudioLoading(model: Models.ClipModel, audio: THREE.Audio): Promise<AudioBuffer | null> | null {
660
+ if (!this._audioLoader) {
661
+ const path = this.getAudioFilePath(model.asset.clip);
662
+ this._audioLoader = new THREE.AudioLoader();
663
+ // TODO: maybe we should cache the loaders / buffers here by path
664
+ if (debug) console.warn("LOAD audio track", path, this.director.sourceId);
665
+ const loadingPromise = new Promise<AudioBuffer | null>((resolve, _reject) => {
666
+ this._audioLoader!.load(path,
667
+ buffer => {
668
+ audio.setBuffer(buffer);
669
+ resolve(buffer);
670
+ },
671
+ undefined,
672
+ err => {
673
+ console.error("Error loading audio", err);
674
+ resolve(null);
675
+ });
676
+ });
677
+ return loadingPromise;
678
+ }
679
+ return null;
680
+ }
577
681
  }
578
682
 
579
683
  export class SignalTrackHandler extends TrackHandler {
@@ -53,7 +53,7 @@ export class Canvas extends UIRootComponent {
53
53
  this.onRenderSettingsChanged();
54
54
  }
55
55
  get castShadows() { return this._castShadows; }
56
- private _castShadows: boolean = true;
56
+ private _castShadows: boolean = false;
57
57
 
58
58
  @serializable()
59
59
  set receiveShadows(val: boolean) {
@@ -62,7 +62,7 @@ export class Canvas extends UIRootComponent {
62
62
  this.onRenderSettingsChanged();
63
63
  }
64
64
  get receiveShadows() { return this._receiveShadows; }
65
- private _receiveShadows: boolean = true;
65
+ private _receiveShadows: boolean = false;
66
66
 
67
67
 
68
68
  @serializable()