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

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 (133) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/components.needle.json +1 -1
  3. package/dist/{needle-engine.bundle-DQCuBTVp.umd.cjs → needle-engine.bundle-5avtTUMM.umd.cjs} +149 -148
  4. package/dist/{needle-engine.bundle-AjVIot3d.min.js → needle-engine.bundle-BHcw4C8f.min.js} +187 -186
  5. package/dist/{needle-engine.bundle-B7cqsI4c.js → needle-engine.bundle-C0gPOq4m.js} +7522 -7092
  6. package/dist/needle-engine.d.ts +715 -176
  7. package/dist/needle-engine.js +595 -593
  8. package/dist/needle-engine.min.js +1 -1
  9. package/dist/needle-engine.umd.cjs +1 -1
  10. package/dist/three.js +1 -0
  11. package/dist/three.min.js +21 -21
  12. package/dist/three.umd.cjs +16 -16
  13. package/lib/engine/api.d.ts +3 -1
  14. package/lib/engine/api.js +3 -1
  15. package/lib/engine/api.js.map +1 -1
  16. package/lib/engine/codegen/register_types.js +10 -10
  17. package/lib/engine/codegen/register_types.js.map +1 -1
  18. package/lib/engine/engine_camera.fit.js +16 -4
  19. package/lib/engine/engine_camera.fit.js.map +1 -1
  20. package/lib/engine/engine_context.d.ts +20 -7
  21. package/lib/engine/engine_context.js +36 -14
  22. package/lib/engine/engine_context.js.map +1 -1
  23. package/lib/engine/engine_context_eventbus.d.ts +47 -0
  24. package/lib/engine/engine_context_eventbus.js +47 -0
  25. package/lib/engine/engine_context_eventbus.js.map +1 -0
  26. package/lib/engine/engine_init.js +2 -2
  27. package/lib/engine/engine_init.js.map +1 -1
  28. package/lib/engine/engine_input.d.ts +23 -4
  29. package/lib/engine/engine_input.js +2 -1
  30. package/lib/engine/engine_input.js.map +1 -1
  31. package/lib/engine/engine_license.d.ts +7 -7
  32. package/lib/engine/engine_license.js +185 -57
  33. package/lib/engine/engine_license.js.map +1 -1
  34. package/lib/engine/engine_networking_blob.js +3 -3
  35. package/lib/engine/engine_networking_blob.js.map +1 -1
  36. package/lib/engine/engine_physics_rapier.d.ts +10 -0
  37. package/lib/engine/engine_physics_rapier.js +6 -0
  38. package/lib/engine/engine_physics_rapier.js.map +1 -1
  39. package/lib/engine/engine_types.d.ts +10 -0
  40. package/lib/engine/engine_utils_qrcode.js +2 -2
  41. package/lib/engine/engine_utils_qrcode.js.map +1 -1
  42. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
  43. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  44. package/lib/engine/webcomponents/needle menu/needle-menu.js +5 -5
  45. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  46. package/lib/engine/webcomponents/needle-engine.js +2 -2
  47. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  48. package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
  49. package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
  50. package/lib/engine/xr/TempXRContext.js +2 -2
  51. package/lib/engine/xr/TempXRContext.js.map +1 -1
  52. package/lib/engine-components/AnimationBuilder.d.ts +158 -0
  53. package/lib/engine-components/AnimationBuilder.js +305 -0
  54. package/lib/engine-components/AnimationBuilder.js.map +1 -0
  55. package/lib/engine-components/Animator.js +6 -1
  56. package/lib/engine-components/Animator.js.map +1 -1
  57. package/lib/engine-components/AnimatorController.builder.d.ts +101 -23
  58. package/lib/engine-components/AnimatorController.builder.js +88 -20
  59. package/lib/engine-components/AnimatorController.builder.js.map +1 -1
  60. package/lib/engine-components/AnimatorController.js +2 -0
  61. package/lib/engine-components/AnimatorController.js.map +1 -1
  62. package/lib/engine-components/ContactShadows.d.ts +1 -0
  63. package/lib/engine-components/ContactShadows.js +14 -1
  64. package/lib/engine-components/ContactShadows.js.map +1 -1
  65. package/lib/engine-components/DropListener.js +3 -0
  66. package/lib/engine-components/DropListener.js.map +1 -1
  67. package/lib/engine-components/OrbitControls.d.ts +0 -2
  68. package/lib/engine-components/OrbitControls.js +14 -1
  69. package/lib/engine-components/OrbitControls.js.map +1 -1
  70. package/lib/engine-components/SceneSwitcher.js +3 -0
  71. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  72. package/lib/engine-components/api.d.ts +1 -0
  73. package/lib/engine-components/api.js +1 -0
  74. package/lib/engine-components/api.js.map +1 -1
  75. package/lib/engine-components/codegen/components.d.ts +6 -6
  76. package/lib/engine-components/codegen/components.js +6 -6
  77. package/lib/engine-components/codegen/components.js.map +1 -1
  78. package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
  79. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  80. package/lib/engine-components/postprocessing/Effects/Tonemapping.utils.d.ts +1 -1
  81. package/lib/engine-components/timeline/PlayableDirector.d.ts +7 -7
  82. package/lib/engine-components/timeline/PlayableDirector.js +6 -6
  83. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  84. package/lib/engine-components/timeline/TimelineBuilder.d.ts +175 -9
  85. package/lib/engine-components/timeline/TimelineBuilder.js +108 -2
  86. package/lib/engine-components/timeline/TimelineBuilder.js.map +1 -1
  87. package/lib/engine-components/timeline/TimelineTracks.d.ts +15 -7
  88. package/lib/engine-components/timeline/TimelineTracks.js +22 -14
  89. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  90. package/lib/engine-components/web/CursorFollow.d.ts +0 -1
  91. package/lib/engine-components/web/CursorFollow.js +0 -1
  92. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  93. package/lib/engine-components/webxr/WebXRImageTracking.d.ts +62 -1
  94. package/lib/engine-components/webxr/WebXRImageTracking.js +55 -2
  95. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  96. package/package.json +1 -1
  97. package/plugins/common/cloud.js +6 -1
  98. package/plugins/common/license.js +26 -8
  99. package/plugins/vite/license.js +42 -7
  100. package/src/engine/api.ts +4 -1
  101. package/src/engine/codegen/register_types.ts +10 -10
  102. package/src/engine/engine_camera.fit.ts +15 -4
  103. package/src/engine/engine_context.ts +41 -16
  104. package/src/engine/engine_context_eventbus.ts +73 -0
  105. package/src/engine/engine_init.ts +2 -2
  106. package/src/engine/engine_input.ts +27 -6
  107. package/src/engine/engine_license.ts +201 -55
  108. package/src/engine/engine_networking_blob.ts +3 -3
  109. package/src/engine/engine_physics_rapier.ts +20 -6
  110. package/src/engine/engine_types.ts +22 -12
  111. package/src/engine/engine_utils_qrcode.ts +2 -2
  112. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
  113. package/src/engine/webcomponents/needle menu/needle-menu.ts +5 -5
  114. package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
  115. package/src/engine/webcomponents/needle-engine.ts +2 -2
  116. package/src/engine/xr/TempXRContext.ts +2 -2
  117. package/src/engine-components/AnimationBuilder.ts +472 -0
  118. package/src/engine-components/Animator.ts +6 -1
  119. package/src/engine-components/AnimatorController.builder.ts +163 -37
  120. package/src/engine-components/AnimatorController.ts +1 -0
  121. package/src/engine-components/ContactShadows.ts +15 -1
  122. package/src/engine-components/DropListener.ts +3 -0
  123. package/src/engine-components/OrbitControls.ts +16 -5
  124. package/src/engine-components/SceneSwitcher.ts +3 -0
  125. package/src/engine-components/api.ts +1 -0
  126. package/src/engine-components/codegen/components.ts +6 -6
  127. package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
  128. package/src/engine-components/timeline/PlayableDirector.ts +20 -20
  129. package/src/engine-components/timeline/TimelineBuilder.ts +277 -17
  130. package/src/engine-components/timeline/TimelineTracks.ts +24 -16
  131. package/src/engine-components/web/CursorFollow.ts +0 -1
  132. package/src/engine-components/webxr/WebXRImageTracking.ts +77 -7
  133. package/src/vite-env.d.ts +0 -16
@@ -4,13 +4,14 @@ import { isDevEnvironment } from "../../engine/debug/index.js";
4
4
  import { Context } from "../../engine/engine_setup.js";
5
5
  import type { Constructor } from "../../engine/engine_types.js";
6
6
  import { getParam, resolveUrl } from "../../engine/engine_utils.js";
7
- import { setObjectAnimated } from "../AnimationUtils.js";
8
7
  import { Animator } from "../Animator.js"
9
8
  import { AudioSource } from "../AudioSource.js";
10
9
  import { GameObject } from "../Component.js";
11
10
  import type { PlayableDirector } from "./PlayableDirector.js";
12
11
  import { SignalReceiver } from "./SignalAsset.js";
13
12
  import * as Models from "./TimelineModels.js";
13
+ import type { TimelineBuilder } from "./TimelineBuilder.js";
14
+ import { AnimationUtils } from "../../engine/engine_animation.js";
14
15
 
15
16
  const debug = getParam("debugtimeline");
16
17
 
@@ -18,7 +19,7 @@ const debug = getParam("debugtimeline");
18
19
  * A TrackHandler is responsible for evaluating a specific type of timeline track.
19
20
  * A timeline track can be an animation track, audio track, signal track, control track etc and is controlled by a {@link PlayableDirector}.
20
21
  */
21
- export abstract class TrackHandler {
22
+ export abstract class TimelineTrackHandler {
22
23
  director!: PlayableDirector;
23
24
  track!: Models.TrackModel;
24
25
 
@@ -136,7 +137,7 @@ class AnimationClipOffsetData {
136
137
  }
137
138
 
138
139
  // TODO: add support for clip clamp modes (loop, pingpong, clamp)
139
- export class AnimationTrackHandler extends TrackHandler {
140
+ export class TimelineAnimationTrack extends TimelineTrackHandler {
140
141
  /** @internal */
141
142
  models: Array<Models.ClipModel> = [];
142
143
  /** @internal */
@@ -178,7 +179,7 @@ export class AnimationTrackHandler extends TrackHandler {
178
179
  onStateChanged() {
179
180
  if (this._animator) {
180
181
  // We can not check the *isPlaying* state here because the timeline might be paused and evaluated by e.g. ScrollFollow
181
- setObjectAnimated(this._animator.gameObject, this, this.director.enabled && this.director.weight > 0);
182
+ AnimationUtils.setObjectAnimated(this._animator.gameObject, this, this.director.enabled && this.director.weight > 0);
182
183
  }
183
184
  }
184
185
 
@@ -262,7 +263,7 @@ export class AnimationTrackHandler extends TrackHandler {
262
263
  // which overrides the timeline
263
264
  this._animator = GameObject.getComponent(this.target, Animator) ?? null;
264
265
  if (this._animator) {
265
- setObjectAnimated(this._animator.gameObject, this, true);
266
+ AnimationUtils.setObjectAnimated(this._animator.gameObject, this, true);
266
267
  }
267
268
  }
268
269
 
@@ -605,7 +606,7 @@ declare type AudioClipModel = Models.ClipModel & { _didTriggerPlay: boolean };
605
606
  * - The director is paused (`director.pause()`)
606
607
  * - The director is disabled or destroyed
607
608
  */
608
- export class AudioTrackHandler extends TrackHandler {
609
+ export class TimelineAudioTrack extends TimelineTrackHandler {
609
610
 
610
611
  models: Array<AudioClipModel> = [];
611
612
  listener!: AudioListener;
@@ -814,7 +815,7 @@ export class AudioTrackHandler extends TrackHandler {
814
815
  private static _audioBuffers: Map<string, Promise<AudioBuffer | null>> = new Map();
815
816
 
816
817
  public static dispose() {
817
- AudioTrackHandler._audioBuffers.clear();
818
+ TimelineAudioTrack._audioBuffers.clear();
818
819
  }
819
820
 
820
821
  private handleAudioLoading(model: Models.ClipModel, audio: Audio): Promise<AudioBuffer | null> | null {
@@ -824,8 +825,8 @@ export class AudioTrackHandler extends TrackHandler {
824
825
  // TODO: maybe we should cache the loaders / buffers here by path
825
826
  const path = this.getAudioFilePath(model.asset.clip);
826
827
 
827
- if (AudioTrackHandler._audioBuffers.get(path)) {
828
- const promise = AudioTrackHandler._audioBuffers.get(path)!
828
+ if (TimelineAudioTrack._audioBuffers.get(path)) {
829
+ const promise = TimelineAudioTrack._audioBuffers.get(path)!
829
830
  promise.then((buffer) => {
830
831
  if (buffer) audio.setBuffer(buffer);
831
832
  });
@@ -845,17 +846,17 @@ export class AudioTrackHandler extends TrackHandler {
845
846
  resolve(null);
846
847
  });
847
848
  });
848
- AudioTrackHandler._audioBuffers.set(path, loadingPromise);
849
+ TimelineAudioTrack._audioBuffers.set(path, loadingPromise);
849
850
  return loadingPromise;
850
851
  }
851
852
  }
852
853
 
853
- export class MarkerTrackHandler extends TrackHandler {
854
+ export class TimelineMarkerTrack extends TimelineTrackHandler {
854
855
  models: Array<Models.MarkerModel & Record<string, any>> = [];
855
856
  needsSorting = true;
856
857
 
857
858
  *foreachMarker<T>(type: string | null = null) {
858
- if(this.needsSorting) this.sort();
859
+ if (this.needsSorting) this.sort();
859
860
  for (const model of this.models) {
860
861
  if (model && model.type === type) yield model as T;
861
862
  }
@@ -876,7 +877,7 @@ export class MarkerTrackHandler extends TrackHandler {
876
877
  }
877
878
  }
878
879
 
879
- export class SignalTrackHandler extends TrackHandler {
880
+ export class SignalTrackHandler extends TimelineTrackHandler {
880
881
  models: Models.SignalMarkerModel[] = [];
881
882
  didTrigger: boolean[] = [];
882
883
  receivers: Array<SignalReceiver | null> = [];
@@ -954,8 +955,15 @@ export class SignalTrackHandler extends TrackHandler {
954
955
  }
955
956
  }
956
957
 
957
-
958
- export class ActivationTrackHandler extends TrackHandler {
958
+ /**
959
+ * Handles activation (visibility) of bound objects for a timeline activation track.
960
+ *
961
+ * Each clip on the track defines a time range during which the bound objects should be active (visible).
962
+ * @see TimelineTrackHandler for details on how tracks and clips work in general, and how to mutate them at runtime.
963
+ * @see PlayableDirector for how to control timeline playback and time.
964
+ * @see TimelineBuilder for how to create and configure timelines and tracks in the editor.
965
+ */
966
+ export class TimelineActivationTrack extends TimelineTrackHandler {
959
967
 
960
968
  evaluate(time: number) {
961
969
  if (this.track.muted) return;
@@ -987,7 +995,7 @@ export class ActivationTrackHandler extends TrackHandler {
987
995
  }
988
996
 
989
997
 
990
- export class ControlTrackHandler extends TrackHandler {
998
+ export class TimelineControlTrack extends TimelineTrackHandler {
991
999
  models: Array<Models.ClipModel> = [];
992
1000
  timelines: Array<PlayableDirector | null> = [];
993
1001
 
@@ -178,7 +178,6 @@ export class CursorFollow extends Behaviour {
178
178
  * - Cursor that follows terrain or mesh surfaces
179
179
  *
180
180
  * **Important notes:**
181
- * - Requires objects in the scene to have colliders for raycasting to work
182
181
  * - Works best with {@link keepDistance} set to `false` to allow depth changes
183
182
  * - Can be combined with {@link damping} for smooth surface following
184
183
  * - The raycast uses the physics system's raycast functionality
@@ -12,6 +12,7 @@ import { IUSDExporterExtension } from "../../engine-components/export/usdz/Exten
12
12
  import { imageToCanvas, USDObject, USDWriter, USDZExporterContext } from "../../engine-components/export/usdz/ThreeUSDZExporter.js";
13
13
  import { USDZExporter } from "../../engine-components/export/usdz/USDZExporter.js";
14
14
  import { Behaviour, GameObject } from "../Component.js";
15
+ import { EventList } from "../EventList.js";
15
16
  import { Renderer } from "../Renderer.js";
16
17
 
17
18
  // https://github.com/immersive-web/marker-tracking/blob/main/explainer.md
@@ -41,8 +42,41 @@ export class WebXRTrackedImage {
41
42
  get widthInMeters() { return this._trackedImage.widthInMeters ?? undefined; }
42
43
  /** The ImageBitmap used for tracking */
43
44
  get bitmap(): ImageBitmap { return this._bitmap; }
44
- /** The {@link WebXRImageTrackingModel} configuration for this tracked image */
45
+ /**
46
+ * The {@link WebXRImageTrackingModel} configuration for this tracked image.
47
+ * Use this to access the assigned 3D object, marker settings, and other image tracking configuration.
48
+ * Available on each {@link WebXRTrackedImage} received from the `image-tracking` {@link CustomEvent} (`event.detail`).
49
+ * @example
50
+ * ```ts
51
+ * tracker.addEventListener("image-tracking", event => {
52
+ * for (const img of event.detail.trackedImages) {
53
+ * const model = img.model;
54
+ * // Access the assigned 3D object
55
+ * const obj = model.object;
56
+ * // Access other settings
57
+ * console.log(model.widthInMeters, model.hideWhenTrackingIsLost);
58
+ * }
59
+ * });
60
+ * ```
61
+ */
45
62
  get model(): WebXRImageTrackingModel { return this._trackedImage; }
63
+
64
+ /**
65
+ * The 3D object or prefab assigned to this tracked image marker in the {@link WebXRImageTrackingModel}.
66
+ * Use this to access the object associated with an AR image tracking marker from the `image-tracking` {@link CustomEvent}.
67
+ * Shorthand for `this.model.object`.
68
+ * @example
69
+ * ```ts
70
+ * tracker.addEventListener("image-tracking", event => {
71
+ * for (const img of event.detail.trackedImages) {
72
+ * const obj = img.trackedModel;
73
+ * // verbose alternative: img.model.object
74
+ * }
75
+ * });
76
+ * ```
77
+ */
78
+ get trackedModel(): AssetReference | undefined { return this._trackedImage.object; }
79
+
46
80
  /**
47
81
  * The measured size of the detected image in the real world.
48
82
  * May differ from `widthInMeters` if the physical marker doesn't match the configured size.
@@ -133,11 +167,6 @@ export class WebXRTrackedImage {
133
167
 
134
168
  }
135
169
 
136
- /**
137
- * Event callback type for image tracking updates.
138
- * @param images Array of currently tracked images
139
- */
140
- declare type WebXRImageTrackingEvent = (images: WebXRImageTrackingEvent[]) => void;
141
170
 
142
171
  /**
143
172
  * Initial state of tracked image objects before entering an XR session.
@@ -293,6 +322,17 @@ export class WebXRImageTrackingModel {
293
322
  }
294
323
  }
295
324
 
325
+ /** Data passed to image tracking event listeners. */
326
+ export interface WebXRImageTrackingEvent {
327
+ /** The images currently being tracked this frame. */
328
+ readonly trackedImages: readonly WebXRTrackedImage[];
329
+ }
330
+
331
+ /** Event map for {@link WebXRImageTracking} events. Use with `addEventListener` for typed event handling. */
332
+ export interface WebXRImageTrackingEventMap {
333
+ /** Dispatched every frame when images are being tracked. The event detail contains the tracking data for the current frame. */
334
+ "image-tracking": CustomEvent<WebXRImageTrackingEvent>;
335
+ }
296
336
 
297
337
  // #region USDZ Extension
298
338
  class ImageTrackingExtension implements IUSDExporterExtension {
@@ -515,6 +555,34 @@ class ImageTrackingExtension implements IUSDExporterExtension {
515
555
  */
516
556
  export class WebXRImageTracking extends Behaviour {
517
557
 
558
+ /**
559
+ * Event invoked every frame when images are being tracked.
560
+ * @example
561
+ * ```ts
562
+ * const tracker = this.gameObject.getComponent(WebXRImageTracking);
563
+ * tracker?.imageTracked.addEventListener(evt => {
564
+ * for (const img of evt.trackedImages) {
565
+ * console.log(img.url, img.state);
566
+ * }
567
+ * });
568
+ * ```
569
+ */
570
+ imageTracked: EventList<WebXRImageTrackingEvent> = new EventList();
571
+
572
+ /** @inheritdoc */
573
+ addEventListener<K extends keyof WebXRImageTrackingEventMap>(type: K, listener: (evt: WebXRImageTrackingEventMap[K]) => any): void;
574
+ addEventListener<T extends Event>(type: string, listener: (evt: T) => any): void;
575
+ addEventListener(type: string, listener: (evt: any) => any): void {
576
+ super.addEventListener(type, listener);
577
+ }
578
+
579
+ /** @inheritdoc */
580
+ removeEventListener<K extends keyof WebXRImageTrackingEventMap>(type: K, listener: (evt: WebXRImageTrackingEventMap[K]) => any): void;
581
+ removeEventListener<T extends Event>(type: string, listener: (evt: T) => any): void;
582
+ removeEventListener(type: string, listener: (evt: any) => any): void {
583
+ super.removeEventListener(type, listener);
584
+ }
585
+
518
586
  /**
519
587
  * Set which marker should be primary (first in the list).
520
588
  * Useful when deploying to QuickLook mode where one marker is tracked at a time.
@@ -763,7 +831,9 @@ export class WebXRImageTracking extends Behaviour {
763
831
  }
764
832
  if (this.currentImages.length > 0) {
765
833
  try {
766
- this.dispatchEvent(new CustomEvent("image-tracking", { detail: this.currentImages }));
834
+ const eventData: WebXRImageTrackingEvent = { trackedImages: this.currentImages };
835
+ this.dispatchEvent(new CustomEvent("image-tracking", { detail: eventData }));
836
+ this.imageTracked.invoke(eventData);
767
837
  this.onImageTrackingUpdate(this.currentImages);
768
838
  }
769
839
  catch (e) {
package/src/vite-env.d.ts DELETED
@@ -1,16 +0,0 @@
1
- // Vite global defines — see plugins/vite/defines.js
2
- // declare const entries here are picked up globally (ambient, no import/export).
3
- // Vite sets these as globals in dev and statically replaces them at build time.
4
- // Webpack DefinePlugin replaces them at build time too.
5
- // The globalThis fallbacks for vanilla JS are in engine_constants.ts.
6
-
7
- declare const NEEDLE_ENGINE_VERSION: string;
8
- declare const NEEDLE_ENGINE_GENERATOR: string;
9
- declare const NEEDLE_PROJECT_BUILD_TIME: string;
10
- declare const NEEDLE_PUBLIC_KEY: string;
11
-
12
- // #region treeshake flags
13
- // declare var (not const) so globalThis["NEEDLE_USE_*"] access is also type-safe
14
- declare var NEEDLE_USE_RAPIER: boolean;
15
- declare var NEEDLE_USE_POSTPROCESSING: boolean;
16
- // #endregion treeshake flags