@needle-tools/engine 4.17.0-next.36dcae2 → 4.17.0-next.4989636

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 (238) hide show
  1. package/components.needle.json +1 -1
  2. package/dist/gltf-progressive-BryRjllq.min.js +10 -0
  3. package/dist/gltf-progressive-Cl167Vjx.js +1537 -0
  4. package/dist/gltf-progressive-DJBMx-zB.umd.cjs +10 -0
  5. package/dist/gltf-progressive.worker-BqODMeeW.js +23 -0
  6. package/dist/needle-engine.bundle-BTIpdDE9.umd.cjs +1654 -0
  7. package/dist/{needle-engine.bundle-CQFEuAQB.js → needle-engine.bundle-CH2ZOagS.js} +35829 -35882
  8. package/dist/needle-engine.bundle-D5h7xxUH.min.js +1654 -0
  9. package/dist/needle-engine.d.ts +105 -39
  10. package/dist/needle-engine.js +608 -607
  11. package/dist/needle-engine.min.js +1 -1
  12. package/dist/needle-engine.umd.cjs +1 -1
  13. package/dist/three-examples.js +7815 -6828
  14. package/dist/three-examples.min.js +17 -15
  15. package/dist/three-examples.umd.cjs +17 -15
  16. package/dist/three.js +15994 -24892
  17. package/dist/three.min.js +214 -214
  18. package/dist/three.umd.cjs +208 -208
  19. package/dist/vendor-CntUvmJu.umd.cjs +1116 -0
  20. package/dist/{vendor-BPp9F5vR.min.js → vendor-DPbfJJ4d.min.js} +94 -94
  21. package/dist/{vendor-CQMI3jTS.js → vendor-vHLk8sXu.js} +8558 -8516
  22. package/lib/engine/analytics/index.js.map +1 -1
  23. package/lib/engine/codegen/register_types.d.ts +1 -1
  24. package/lib/engine/codegen/register_types.js +159 -157
  25. package/lib/engine/codegen/register_types.js.map +1 -1
  26. package/lib/engine/debug/debug.d.ts +1 -4
  27. package/lib/engine/debug/debug.js +1 -25
  28. package/lib/engine/debug/debug.js.map +1 -1
  29. package/lib/engine/debug/debug_environment.d.ts +4 -0
  30. package/lib/engine/debug/debug_environment.js +26 -0
  31. package/lib/engine/debug/debug_environment.js.map +1 -0
  32. package/lib/engine/debug/debug_overlay.js +2 -1
  33. package/lib/engine/debug/debug_overlay.js.map +1 -1
  34. package/lib/engine/debug/debug_spatial_console.js +1 -1
  35. package/lib/engine/debug/debug_spatial_console.js.map +1 -1
  36. package/lib/engine/engine_audio.js +0 -1
  37. package/lib/engine/engine_audio.js.map +1 -1
  38. package/lib/engine/engine_components.js +6 -3
  39. package/lib/engine/engine_components.js.map +1 -1
  40. package/lib/engine/engine_gltf_builtin_components.d.ts +0 -1
  41. package/lib/engine/engine_gltf_builtin_components.js +5 -4
  42. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  43. package/lib/engine/engine_init.d.ts +10 -0
  44. package/lib/engine/engine_init.js +44 -0
  45. package/lib/engine/engine_init.js.map +1 -0
  46. package/lib/engine/engine_loaders.d.ts +2 -0
  47. package/lib/engine/engine_loaders.js +2 -1
  48. package/lib/engine/engine_loaders.js.map +1 -1
  49. package/lib/engine/engine_modules.d.ts +8 -0
  50. package/lib/engine/engine_modules.js +1 -0
  51. package/lib/engine/engine_modules.js.map +1 -1
  52. package/lib/engine/engine_networking.d.ts +2 -1
  53. package/lib/engine/engine_networking.js +3 -1
  54. package/lib/engine/engine_networking.js.map +1 -1
  55. package/lib/engine/engine_networking_blob.js +3 -3
  56. package/lib/engine/engine_networking_blob.js.map +1 -1
  57. package/lib/engine/engine_networking_peer.d.ts +2 -2
  58. package/lib/engine/engine_networking_peer.js +7 -6
  59. package/lib/engine/engine_networking_peer.js.map +1 -1
  60. package/lib/engine/engine_networking_streams.d.ts +2 -1
  61. package/lib/engine/engine_networking_streams.js +2 -2
  62. package/lib/engine/engine_networking_streams.js.map +1 -1
  63. package/lib/engine/engine_physics_rapier.d.ts +2 -0
  64. package/lib/engine/engine_physics_rapier.js +35 -4
  65. package/lib/engine/engine_physics_rapier.js.map +1 -1
  66. package/lib/engine/engine_shims.d.ts +1 -0
  67. package/lib/engine/engine_shims.js +20 -19
  68. package/lib/engine/engine_shims.js.map +1 -1
  69. package/lib/engine/engine_tonemapping.js +0 -1
  70. package/lib/engine/engine_tonemapping.js.map +1 -1
  71. package/lib/engine/engine_types.d.ts +8 -0
  72. package/lib/engine/engine_typestore.d.ts +11 -0
  73. package/lib/engine/engine_typestore.js +29 -0
  74. package/lib/engine/engine_typestore.js.map +1 -1
  75. package/lib/engine/extensions/NEEDLE_animator_controller_model.d.ts +1 -1
  76. package/lib/engine/js-extensions/Camera.d.ts +1 -1
  77. package/lib/engine/js-extensions/Camera.js +43 -37
  78. package/lib/engine/js-extensions/Camera.js.map +1 -1
  79. package/lib/engine/js-extensions/Layers.js +0 -1
  80. package/lib/engine/js-extensions/Layers.js.map +1 -1
  81. package/lib/engine/js-extensions/Object3D.d.ts +1 -0
  82. package/lib/engine/js-extensions/Object3D.js +173 -167
  83. package/lib/engine/js-extensions/Object3D.js.map +1 -1
  84. package/lib/engine/js-extensions/Vector.d.ts +1 -0
  85. package/lib/engine/js-extensions/Vector.js +10 -4
  86. package/lib/engine/js-extensions/Vector.js.map +1 -1
  87. package/lib/engine/js-extensions/index.d.ts +0 -3
  88. package/lib/engine/js-extensions/index.js +0 -2
  89. package/lib/engine/js-extensions/index.js.map +1 -1
  90. package/lib/engine/webcomponents/WebXRButtons.js +11 -13
  91. package/lib/engine/webcomponents/WebXRButtons.js.map +1 -1
  92. package/lib/engine/webcomponents/buttons.js +4 -4
  93. package/lib/engine/webcomponents/buttons.js.map +1 -1
  94. package/lib/engine/webcomponents/font-urls.d.ts +2 -0
  95. package/lib/engine/webcomponents/font-urls.js +8 -0
  96. package/lib/engine/webcomponents/font-urls.js.map +1 -0
  97. package/lib/engine/webcomponents/fonts.d.ts +2 -2
  98. package/lib/engine/webcomponents/fonts.js +12 -7
  99. package/lib/engine/webcomponents/fonts.js.map +1 -1
  100. package/lib/engine/webcomponents/init.d.ts +4 -0
  101. package/lib/engine/webcomponents/init.js +20 -0
  102. package/lib/engine/webcomponents/init.js.map +1 -0
  103. package/lib/engine/webcomponents/logo-element.js +2 -2
  104. package/lib/engine/webcomponents/logo-element.js.map +1 -1
  105. package/lib/engine/webcomponents/needle menu/menu-priority.d.ts +10 -0
  106. package/lib/engine/webcomponents/needle menu/menu-priority.js +21 -0
  107. package/lib/engine/webcomponents/needle menu/menu-priority.js.map +1 -0
  108. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.d.ts +1 -1
  109. package/lib/engine/webcomponents/needle menu/needle-menu.d.ts +1 -1
  110. package/lib/engine/webcomponents/needle menu/needle-menu.js +7 -11
  111. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  112. package/lib/engine/webcomponents/needle-button.js +0 -3
  113. package/lib/engine/webcomponents/needle-button.js.map +1 -1
  114. package/lib/engine/webcomponents/needle-engine.js +4 -10
  115. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  116. package/lib/engine/webcomponents/quicklook-handler.d.ts +29 -0
  117. package/lib/engine/webcomponents/quicklook-handler.js +21 -0
  118. package/lib/engine/webcomponents/quicklook-handler.js.map +1 -0
  119. package/lib/engine/xr/NeedleXRSession.d.ts +1 -0
  120. package/lib/engine/xr/NeedleXRSession.js +1 -0
  121. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  122. package/lib/engine-components/AnimationUtilsAutoplay.d.ts +1 -1
  123. package/lib/engine-components/AnimationUtilsAutoplay.js +29 -23
  124. package/lib/engine-components/AnimationUtilsAutoplay.js.map +1 -1
  125. package/lib/engine-components/Animator.d.ts +1 -1
  126. package/lib/engine-components/AnimatorController.d.ts +1 -1
  127. package/lib/engine-components/CameraUtils.d.ts +1 -1
  128. package/lib/engine-components/CameraUtils.js +79 -73
  129. package/lib/engine-components/CameraUtils.js.map +1 -1
  130. package/lib/engine-components/Collider.d.ts +2 -0
  131. package/lib/engine-components/Collider.js +25 -3
  132. package/lib/engine-components/Collider.js.map +1 -1
  133. package/lib/engine-components/LookAtConstraint.d.ts +34 -1
  134. package/lib/engine-components/LookAtConstraint.js +54 -1
  135. package/lib/engine-components/LookAtConstraint.js.map +1 -1
  136. package/lib/engine-components/Networking.d.ts +2 -1
  137. package/lib/engine-components/Networking.js +2 -1
  138. package/lib/engine-components/Networking.js.map +1 -1
  139. package/lib/engine-components/SceneSwitcher.d.ts +1 -0
  140. package/lib/engine-components/SceneSwitcher.js +3 -1
  141. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  142. package/lib/engine-components/Skybox.d.ts +1 -0
  143. package/lib/engine-components/Skybox.js +4 -2
  144. package/lib/engine-components/Skybox.js.map +1 -1
  145. package/lib/engine-components/SyncedRoom.d.ts +1 -0
  146. package/lib/engine-components/SyncedRoom.js +1 -0
  147. package/lib/engine-components/SyncedRoom.js.map +1 -1
  148. package/lib/engine-components/api.d.ts +5 -8
  149. package/lib/engine-components/api.js +4 -7
  150. package/lib/engine-components/api.js.map +1 -1
  151. package/lib/engine-components/export/usdz/USDZExporter.js +8 -0
  152. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  153. package/lib/engine-components/postprocessing/PostProcessingHandler.js +18 -5
  154. package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
  155. package/lib/engine-components/postprocessing/utils.js +7 -2
  156. package/lib/engine-components/postprocessing/utils.js.map +1 -1
  157. package/lib/engine-components/timeline/TimelineTracks.d.ts +1 -1
  158. package/lib/engine-components/timeline/TimelineTracks.js +4 -2
  159. package/lib/engine-components/timeline/TimelineTracks.js.map +1 -1
  160. package/lib/engine-components/web/ScrollFollow.d.ts +0 -8
  161. package/lib/engine-components/webxr/WebXR.d.ts +15 -2
  162. package/lib/engine-components/webxr/WebXR.js +15 -2
  163. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  164. package/lib/needle-engine.d.ts +0 -1
  165. package/lib/needle-engine.js +2 -1
  166. package/lib/needle-engine.js.map +1 -1
  167. package/package.json +11 -3
  168. package/plugins/vite/ai.d.ts +11 -7
  169. package/plugins/vite/ai.js +21 -16
  170. package/plugins/vite/asap.js +42 -2
  171. package/plugins/vite/dependencies.js +110 -16
  172. package/plugins/vite/index.d.ts +1 -0
  173. package/plugins/vite/index.js +4 -0
  174. package/plugins/vite/treeshake.d.ts +11 -0
  175. package/plugins/vite/treeshake.js +216 -0
  176. package/src/engine/analytics/index.ts +1 -1
  177. package/src/engine/codegen/register_types.ts +159 -157
  178. package/src/engine/debug/debug.ts +1 -26
  179. package/src/engine/debug/debug_environment.ts +26 -0
  180. package/src/engine/debug/debug_overlay.ts +2 -1
  181. package/src/engine/debug/debug_spatial_console.ts +1 -1
  182. package/src/engine/engine_audio.ts +1 -2
  183. package/src/engine/engine_components.ts +6 -3
  184. package/src/engine/engine_gltf_builtin_components.ts +4 -5
  185. package/src/engine/engine_init.ts +45 -0
  186. package/src/engine/engine_loaders.ts +2 -1
  187. package/src/engine/engine_modules.ts +3 -0
  188. package/src/engine/engine_networking.ts +5 -1
  189. package/src/engine/engine_networking_blob.ts +3 -3
  190. package/src/engine/engine_networking_peer.ts +8 -6
  191. package/src/engine/engine_networking_streams.ts +4 -3
  192. package/src/engine/engine_physics_rapier.ts +37 -4
  193. package/src/engine/engine_shims.ts +22 -20
  194. package/src/engine/engine_tonemapping.ts +0 -1
  195. package/src/engine/engine_types.ts +9 -0
  196. package/src/engine/engine_typestore.ts +29 -0
  197. package/src/engine/extensions/NEEDLE_animator_controller_model.ts +1 -1
  198. package/src/engine/js-extensions/Camera.ts +40 -33
  199. package/src/engine/js-extensions/Layers.ts +1 -2
  200. package/src/engine/js-extensions/Object3D.ts +174 -170
  201. package/src/engine/js-extensions/Vector.ts +11 -4
  202. package/src/engine/js-extensions/index.ts +0 -3
  203. package/src/engine/webcomponents/WebXRButtons.ts +12 -13
  204. package/src/engine/webcomponents/buttons.ts +4 -4
  205. package/src/engine/webcomponents/font-urls.js +9 -0
  206. package/src/engine/webcomponents/fonts.ts +12 -7
  207. package/src/engine/webcomponents/init.ts +23 -0
  208. package/src/engine/webcomponents/logo-element.ts +2 -2
  209. package/src/engine/webcomponents/needle menu/menu-priority.ts +20 -0
  210. package/src/engine/webcomponents/needle menu/needle-menu.ts +8 -13
  211. package/src/engine/webcomponents/needle-button.ts +0 -3
  212. package/src/engine/webcomponents/needle-engine.ts +4 -13
  213. package/src/engine/webcomponents/quicklook-handler.ts +37 -0
  214. package/src/engine/xr/NeedleXRSession.ts +2 -1
  215. package/src/engine-components/AnimationUtilsAutoplay.ts +8 -3
  216. package/src/engine-components/AnimatorController.ts +1 -1
  217. package/src/engine-components/CameraUtils.ts +15 -8
  218. package/src/engine-components/Collider.ts +24 -3
  219. package/src/engine-components/LookAtConstraint.ts +46 -1
  220. package/src/engine-components/Networking.ts +3 -1
  221. package/src/engine-components/SceneSwitcher.ts +3 -1
  222. package/src/engine-components/Skybox.ts +4 -2
  223. package/src/engine-components/SyncedRoom.ts +2 -0
  224. package/src/engine-components/api.ts +5 -10
  225. package/src/engine-components/export/usdz/USDZExporter.ts +9 -0
  226. package/src/engine-components/postprocessing/PostProcessingHandler.ts +19 -7
  227. package/src/engine-components/postprocessing/utils.ts +7 -2
  228. package/src/engine-components/timeline/TimelineTracks.ts +6 -2
  229. package/src/engine-components/web/ScrollFollow.ts +0 -2
  230. package/src/engine-components/webxr/WebXR.ts +15 -2
  231. package/src/needle-engine.ts +2 -1
  232. package/dist/gltf-progressive-BBIL1q1j.umd.cjs +0 -4022
  233. package/dist/gltf-progressive-BbHl9z0v.js +0 -28272
  234. package/dist/gltf-progressive-Clq_N7Zx.min.js +0 -4022
  235. package/dist/gltf-progressive.worker-CCrD-Ycm.js +0 -3
  236. package/dist/needle-engine.bundle-CrqNZdEN.umd.cjs +0 -1657
  237. package/dist/needle-engine.bundle-DyVf6QdN.min.js +0 -1657
  238. package/dist/vendor-CipoooTV.umd.cjs +0 -1116
@@ -8,6 +8,7 @@ import { ButtonsFactory } from "../buttons.js";
8
8
  import { ensureFonts, iconFontUrl, loadFont } from "../fonts.js";
9
9
  import { getIconElement } from "../icons.js";
10
10
  import { NeedleLogoElement } from "../logo-element.js";
11
+ import { getElementPriority, setElementPriority as _setElementPriority } from "./menu-priority.js";
11
12
  import { NeedleSpatialMenu } from "./needle-menu-spatial.js";
12
13
 
13
14
  declare global {
@@ -111,16 +112,11 @@ export declare type ButtonInfo = {
111
112
  export class NeedleMenu {
112
113
 
113
114
  static setElementPriority(button: HTMLElement, priority: number) {
114
- button.setAttribute("priority", String(priority));
115
+ _setElementPriority(button, priority);
115
116
  }
116
117
 
117
118
  static getElementPriority(button: HTMLElement): number | undefined {
118
- const priority = button.getAttribute("priority");
119
- if (priority) {
120
- const val = Number.parseFloat(priority);
121
- if (!Number.isNaN(val)) return val;
122
- }
123
- return undefined;
119
+ return getElementPriority(button);
124
120
  }
125
121
 
126
122
  private readonly _context: Context;
@@ -310,7 +306,10 @@ export class NeedleMenu {
310
306
  export class NeedleMenuElement extends HTMLElement {
311
307
 
312
308
  static create() {
313
- // https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement#is
309
+ // Ensure the element is registered before creating — guards against
310
+ // cases where this is called before initWebComponents() has run.
311
+ if (!customElements.get(elementName))
312
+ customElements.define(elementName, NeedleMenuElement);
314
313
  return document.createElement(elementName);
315
314
  }
316
315
 
@@ -1335,8 +1334,4 @@ export class NeedleMenuElement extends HTMLElement {
1335
1334
  });
1336
1335
  this.appendChild(anotherButton);
1337
1336
  }
1338
- }
1339
-
1340
-
1341
- if (!customElements.get(elementName))
1342
- customElements.define(elementName, NeedleMenuElement);
1337
+ }
@@ -9,7 +9,6 @@ declare global {
9
9
  }
10
10
  }
11
11
 
12
- const htmlTagName = "needle-button";
13
12
  const isDev = isDevEnvironment();
14
13
 
15
14
  /**
@@ -219,5 +218,3 @@ export class NeedleButtonElement extends HTMLElement {
219
218
 
220
219
 
221
220
 
222
- if (typeof window !== "undefined" && !window.customElements.get(htmlTagName))
223
- window.customElements.define(htmlTagName, NeedleButtonElement);
@@ -1,18 +1,17 @@
1
1
  import { isDevEnvironment, showBalloonWarning } from "../debug/index.js";
2
2
  import { PUBLIC_KEY, VERSION } from "../engine_constants.js";
3
3
  import { ContextEvent, ContextRegistry } from "../engine_context_registry.js";
4
- import { registerLoader } from "../engine_gltf.js";
5
4
  import { hasCommercialLicense } from "../engine_license.js";
6
5
  import { onStart } from "../engine_lifecycle_api.js";
7
6
  import { setDracoDecoderPath, setDracoDecoderType, setKtx2TranscoderPath } from "../engine_loaders.gltf.js";
8
- import { NeedleLoader } from "../engine_loaders.js";
9
7
  import { Context, ContextCreateArgs } from "../engine_setup.js";
10
8
  import { nameToThreeTonemapping } from "../engine_tonemapping.js";
11
9
  import { type INeedleEngineComponent, type LoadedModel } from "../engine_types.js";
12
10
  import type { addAttributeChangeCallback } from "../engine_utils.js";
13
11
  import { getParam } from "../engine_utils.js";
14
12
  import { RGBAColor } from "../js-extensions/RGBAColor.js";
15
- import { ensureFonts } from "./fonts.js";
13
+ import { robotoFlexFontUrl } from "./font-urls.js";
14
+ import { ensureFonts, loadFont } from "./fonts.js";
16
15
  import { arContainerClassName, AROverlayHandler } from "./needle-engine.ar-overlay.js";
17
16
  import type { registerObservableAttribute } from "./needle-engine.extras.js";
18
17
  import { calculateProgress01, EngineLoadingView, type ILoadingViewHandler } from "./needle-engine.loading.js";
@@ -23,13 +22,8 @@ declare global {
23
22
  }
24
23
  }
25
24
 
26
-
27
- // registering loader here too to make sure it's imported when using engine via vanilla js
28
- registerLoader(NeedleLoader);
29
-
30
25
  const debug = getParam("debugwebcomponent");
31
26
 
32
- const htmlTagName = "needle-engine";
33
27
  const vrContainerClassName = "vr";
34
28
  const desktopContainerClassname = "desktop";
35
29
  const knownClasses = [arContainerClassName, vrContainerClassName, desktopContainerClassname];
@@ -234,8 +228,6 @@ export class NeedleEngineWebComponent extends HTMLElement implements INeedleEngi
234
228
  this.attachShadow({ mode: 'open', delegatesFocus: true });
235
229
  const template = document.createElement('template');
236
230
  template.innerHTML = `<style>
237
- @import url('https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap');
238
-
239
231
  :host {
240
232
  position: absolute;
241
233
  display: block;
@@ -313,6 +305,8 @@ export class NeedleEngineWebComponent extends HTMLElement implements INeedleEngi
313
305
  `;
314
306
 
315
307
  this.shadowRoot!.appendChild(template.content.cloneNode(true));
308
+ // Load Roboto font into shadow DOM (instead of @import in CSS to avoid duplicate network requests)
309
+ loadFont(robotoFlexFontUrl, { element: this.shadowRoot! });
316
310
 
317
311
  // TODO: do we want to rename this event?
318
312
  this.addEventListener("ready", this.onReady);
@@ -1021,9 +1015,6 @@ export class NeedleEngineWebComponent extends HTMLElement implements INeedleEngi
1021
1015
  }
1022
1016
  }
1023
1017
 
1024
- if (typeof window !== "undefined" && !window.customElements.get(htmlTagName))
1025
- window.customElements.define(htmlTagName, NeedleEngineWebComponent);
1026
-
1027
1018
  /** Quick testing for the types as declared above */
1028
1019
  /*
1029
1020
  const elem = document.querySelector("needle-engine")!;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Interface for a quicklook handler that can export and open a USDZ file.
3
+ * Used as an abstraction layer to break the circular dependency between
4
+ * WebXRButtons and USDZExporter.
5
+ */
6
+ export interface IQuicklookHandler {
7
+ objectToExport: any;
8
+ exportAndOpen(): Promise<any>;
9
+ }
10
+
11
+ type QuicklookHandlerFactory = {
12
+ /** Find an existing quicklook handler in the scene */
13
+ find(): IQuicklookHandler | null;
14
+ /** Create a new quicklook handler instance */
15
+ create(): IQuicklookHandler;
16
+ };
17
+
18
+ let _factory: QuicklookHandlerFactory | undefined;
19
+
20
+ /**
21
+ * Register a factory for creating quicklook handlers.
22
+ * Called by USDZExporter to register itself as the handler.
23
+ */
24
+ export function setQuicklookHandlerFactory(factory: QuicklookHandlerFactory) {
25
+ _factory = factory;
26
+ }
27
+
28
+ /**
29
+ * Find an existing quicklook handler in the scene, or create a new one if none exists.
30
+ * @returns A quicklook handler, or null if no factory has been registered.
31
+ */
32
+ export function getOrCreateQuicklookHandler(): { readonly handler: IQuicklookHandler, readonly created: boolean } | null {
33
+ if (!_factory) return null;
34
+ const existing = _factory.find();
35
+ if (existing) return { handler: existing, created: false };
36
+ return { handler: _factory.create(), created: true };
37
+ }
@@ -843,9 +843,10 @@ export class NeedleXRSession implements INeedleXRSession {
843
843
  *
844
844
  * **For AR**
845
845
  * If you want to modify the scale in AR at runtime get the WebARSessionRoot component via `findObjectOfType(WebARSessionRoot)` and then set the `arScale` value.
846
+ * @returns the scale of the XR rig
846
847
  *
847
848
  */
848
- get rigScale() {
849
+ get rigScale(): number {
849
850
  // const ar_scaleValue = this.context.domElement.getAttribute("ar-scale");
850
851
  // if (ar_scaleValue) {
851
852
  // const scale = parseFloat(ar_scaleValue);
@@ -7,7 +7,13 @@ import { Animator } from "./Animator.js";
7
7
  import { GameObject } from "./Component.js";
8
8
  import { PlayableDirector } from "./timeline/PlayableDirector.js";
9
9
 
10
- ContextRegistry.registerCallback(ContextEvent.ContextCreated, args => {
10
+ let initialized = false;
11
+
12
+ export function initAnimationAutoplay() {
13
+ if (initialized) return;
14
+ initialized = true;
15
+
16
+ ContextRegistry.registerCallback(ContextEvent.ContextCreated, args => {
11
17
  const autoplay = args.context.domElement.getAttribute("autoplay");
12
18
  if (autoplay !== undefined && (autoplay === "" || autoplay === "true" || autoplay === "1")) {
13
19
  if (args.files) {
@@ -34,5 +40,4 @@ ContextRegistry.registerCallback(ContextEvent.ContextCreated, args => {
34
40
  }
35
41
  }
36
42
  });
37
-
38
-
43
+ }
@@ -11,7 +11,7 @@ import { TypeStore } from "../engine/engine_typestore.js";
11
11
  import { deepClone, getParam } from "../engine/engine_utils.js";
12
12
  import type { AnimatorControllerModel, Condition, State, Transition } from "../engine/extensions/NEEDLE_animator_controller_model.js";
13
13
  import { AnimatorConditionMode, AnimatorControllerParameterType, AnimatorStateInfo, createMotion, StateMachineBehaviour } from "../engine/extensions/NEEDLE_animator_controller_model.js";
14
- import { Animator } from "./Animator.js";
14
+ import type { Animator } from "./Animator.js";
15
15
 
16
16
  const debug = getParam("debuganimatorcontroller");
17
17
  const debugRootMotion = getParam("debugrootmotion");
@@ -13,14 +13,20 @@ import { EnvironmentScene } from "./utils/EnvironmentScene.js";
13
13
 
14
14
  const debug = getParam("debugmissingcamera");
15
15
 
16
- /**
17
- * Handler for missing camera events. Creates a default fallback camera when no camera is found in the scene.
18
- * Sets up camera properties based on the context and HTML element attributes.
19
- *
20
- * @param evt The context event containing scene and configuration information
21
- * @returns The created camera component
22
- */
23
- ContextRegistry.registerCallback(ContextEvent.MissingCamera, (evt) => {
16
+ let initialized = false;
17
+
18
+ export function initCameraUtils() {
19
+ if (initialized) return;
20
+ initialized = true;
21
+
22
+ /**
23
+ * Handler for missing camera events. Creates a default fallback camera when no camera is found in the scene.
24
+ * Sets up camera properties based on the context and HTML element attributes.
25
+ *
26
+ * @param evt The context event containing scene and configuration information
27
+ * @returns The created camera component
28
+ */
29
+ ContextRegistry.registerCallback(ContextEvent.MissingCamera, (evt) => {
24
30
  if (debug) console.warn("Creating missing camera")
25
31
  const scene = evt.context.scene;
26
32
 
@@ -101,6 +107,7 @@ ContextRegistry.registerCallback(ContextEvent.ContextCreated, (evt) => {
101
107
  createDefaultCameraControls(evt.context);
102
108
  }
103
109
  })
110
+ }
104
111
 
105
112
  /**
106
113
  * Creates default orbit camera controls for the specified camera.
@@ -113,6 +113,16 @@ export abstract class Collider extends Behaviour implements ICollider {
113
113
  }
114
114
  /** @internal */
115
115
  onDisable() {
116
+ // Use setEnabled(false) to disable the collider without destroying it.
117
+ // This avoids the cost of recreating the rapier collider on re-enable.
118
+ if (!this.context.physics.engine?.setColliderEnabled(this, false)) {
119
+ // Fallback: if the collider wasn't found (e.g. not yet created), remove it
120
+ this.context.physics.engine?.removeBody(this);
121
+ }
122
+ }
123
+ /** @internal */
124
+ onDestroy() {
125
+ // Actually remove the collider from the physics world on destroy
116
126
  this.context.physics.engine?.removeBody(this);
117
127
  }
118
128
 
@@ -183,7 +193,10 @@ export class SphereCollider extends Collider implements ISphereCollider {
183
193
  */
184
194
  onEnable() {
185
195
  super.onEnable();
186
- this.context.physics.engine?.addSphereCollider(this);
196
+ // Re-enable existing collider instead of recreating it
197
+ if (!this.context.physics.engine?.setColliderEnabled(this, true)) {
198
+ this.context.physics.engine?.addSphereCollider(this);
199
+ }
187
200
  watchWrite(this.gameObject.scale, this.updateProperties);
188
201
  }
189
202
 
@@ -267,7 +280,10 @@ export class BoxCollider extends Collider implements IBoxCollider {
267
280
  */
268
281
  onEnable() {
269
282
  super.onEnable();
270
- this.context.physics.engine?.addBoxCollider(this, this.size);
283
+ // Re-enable existing collider instead of recreating it
284
+ if (!this.context.physics.engine?.setColliderEnabled(this, true)) {
285
+ this.context.physics.engine?.addBoxCollider(this, this.size);
286
+ }
271
287
  watchWrite(this.gameObject.scale, this.updateProperties);
272
288
  }
273
289
 
@@ -362,6 +378,8 @@ export class MeshCollider extends Collider {
362
378
  onEnable() {
363
379
  super.onEnable();
364
380
  if (!this.context.physics.engine) return;
381
+ // Re-enable existing collider instead of recreating it
382
+ if (this.context.physics.engine.setColliderEnabled(this, true)) return;
365
383
 
366
384
  if (!this.sharedMesh?.isMesh) {
367
385
  // HACK using the renderer mesh
@@ -453,6 +471,9 @@ export class CapsuleCollider extends Collider {
453
471
  */
454
472
  onEnable() {
455
473
  super.onEnable();
456
- this.context.physics.engine?.addCapsuleCollider(this, this.height, this.radius);
474
+ // Re-enable existing collider instead of recreating it
475
+ if (!this.context.physics.engine?.setColliderEnabled(this, true)) {
476
+ this.context.physics.engine?.addCapsuleCollider(this, this.height, this.radius);
477
+ }
457
478
  }
458
479
  }
@@ -1,7 +1,52 @@
1
+ import { Object3D, Vector3 } from "three";
2
+
3
+ import { serializable } from "../engine/engine_serialization.js";
1
4
  import { Behaviour } from "./Component.js";
2
5
 
3
6
  /**
4
- * @deprecated LookAtConstraint has been removed. Use a plain Object3D/Transform reference on OrbitControls instead.
7
+ * @deprecated LookAtConstraint will be removed in future versions. Please either use a direct object reference instead (e.g. assigning an Object3D as a look target in scripts that reply on the LookAtConstraint) or implement the LookAtConstraint signature in your web project:
8
+ * ```ts
9
+ * export class LookAtConstraint extends Behaviour {
10
+ * constraintActive: boolean = true;
11
+ * locked: boolean = false;
12
+ * sources: Object3D[] = [];
13
+ * setConstraintPosition(worldPosition: Vector3) {
14
+ * const source = this.sources[0];
15
+ * if (source) source.worldPosition = worldPosition;
16
+ * }
17
+ * }
18
+ * ```
5
19
  */
6
20
  export class LookAtConstraint extends Behaviour {
21
+
22
+ /**
23
+ * When true, the constraint is active and affects the target.
24
+ * Set to false to temporarily disable without removing sources.
25
+ */
26
+ @serializable()
27
+ constraintActive: boolean = true;
28
+
29
+ /**
30
+ * When true, the look-at position is locked and won't update
31
+ * even if source objects move.
32
+ */
33
+ @serializable()
34
+ locked: boolean = false;
35
+
36
+ /**
37
+ * Objects to look at. The first object in the array is used
38
+ * as the primary look-at target.
39
+ */
40
+ @serializable(Object3D)
41
+ sources: Object3D[] = [];
42
+
43
+ /**
44
+ * Sets the world position that the constraint should look at.
45
+ * Updates the first source object's position.
46
+ * @param worldPosition The world-space position to look at
47
+ */
48
+ setConstraintPosition(worldPosition: Vector3) {
49
+ const source = this.sources[0];
50
+ if (source) source.worldPosition = worldPosition;
51
+ }
7
52
  }
@@ -1,4 +1,5 @@
1
1
  import type { INetworkingWebsocketUrlProvider } from "../engine/engine_networking.js";
2
+ import type { NetworkConnection } from "../engine/engine_networking.js";
2
3
  import { isLocalNetwork } from "../engine/engine_networking_utils.js";
3
4
  import { serializable } from "../engine/engine_serialization.js";
4
5
  import { getParam } from "../engine/engine_utils.js";
@@ -7,7 +8,7 @@ import { Behaviour } from "./Component.js";
7
8
  const debug = getParam("debugnet");
8
9
 
9
10
  /**
10
- * Provides websocket URL configuration for the built-in networking system.
11
+ * Provides websocket URL configuration for the {@link NetworkConnection | built-in networking system}.
11
12
  * Add this component to override the default networking backend URL used by {@link NetworkConnection} (`this.context.connection`).
12
13
  *
13
14
  * The component registers itself as a URL provider on `awake()`. When the networking system connects,
@@ -34,6 +35,7 @@ const debug = getParam("debugnet");
34
35
  * @see {@link SyncedRoom} for automatic room joining
35
36
  * @see {@link OwnershipModel} for networked object ownership
36
37
  * @see {@link RoomEvents} for room lifecycle events
38
+ * @see {@link isLocalNetwork} for local network detection
37
39
  * @link https://engine.needle.tools/docs/how-to-guides/networking/
38
40
  * @summary Networking configuration
39
41
  * @category Networking
@@ -14,7 +14,9 @@ const debug = getParam("debugsceneswitcher");
14
14
  const experimental_clearSceneOnLoad = getParam("sceneswitcher:clearscene");
15
15
 
16
16
  const ENGINE_ELEMENT_SCENE_ATTRIBUTE_NAME = "scene";
17
- registerObservableAttribute(ENGINE_ELEMENT_SCENE_ATTRIBUTE_NAME);
17
+ export function initSceneSwitcherAttributes() {
18
+ registerObservableAttribute(ENGINE_ELEMENT_SCENE_ATTRIBUTE_NAME);
19
+ }
18
20
 
19
21
  // ContextRegistry.registerCallback(ContextEvent.ContextRegistered, async _ => {
20
22
  // // We need to defer import to not get issues with circular dependencies
@@ -13,8 +13,10 @@ import { Behaviour, GameObject } from "./Component.js";
13
13
 
14
14
  const debug = getParam("debugskybox");
15
15
 
16
- registerObservableAttribute("background-image");
17
- registerObservableAttribute("environment-image");
16
+ export function initSkyboxAttributes() {
17
+ registerObservableAttribute("background-image");
18
+ registerObservableAttribute("environment-image");
19
+ }
18
20
 
19
21
 
20
22
  type MagicSkyboxName = "studio" | "blurred-skybox" | "quicklook-ar" | "quicklook";
@@ -1,5 +1,6 @@
1
1
  import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../engine/debug/index.js";
2
2
  import { Mathf } from "../engine/engine_math.js";
3
+ import type { NetworkConnection } from "../engine/engine_networking.js";
3
4
  import { RoomEvents } from "../engine/engine_networking.js";
4
5
  import { serializable } from "../engine/engine_serialization_decorator.js";
5
6
  import * as utils from "../engine/engine_utils.js"
@@ -38,6 +39,7 @@ const debug = utils.getParam("debugsyncedroom");
38
39
  * @summary Joins a networked room based on URL parameters or a random room
39
40
  * @category Networking
40
41
  * @group Components
42
+ * @see {@link NetworkConnection} for the main networking API (`this.context.connection`)
41
43
  * @see {@link SyncedTransform} for synchronizing object transforms
42
44
  * @see {@link Voip} for voice communication in rooms
43
45
  * @see {@link ScreenCapture} for screen/video sharing
@@ -40,24 +40,19 @@ export { Behaviour, Component, GameObject } from "./Component.js";
40
40
 
41
41
  // We dont want to export everything in the extensions
42
42
  export { ClearFlags } from "./Camera.js"
43
+ export { DragMode } from "./DragControls.js";
44
+ export type { DropListenerNetworkEventArguments, DropListenerOnDropArguments } from "./DropListener.js";
43
45
  export * from "./export/index.js"
46
+ export * from "./particlesystem/api.js"
44
47
  export * from "./postprocessing/index.js"
45
48
  export { type ISceneEventListener } from "./SceneSwitcher.js";
49
+ export * from "./splines/index.js";
46
50
  export * from "./timeline/index.js"
47
51
  export * from "./ui/index.js"
52
+ export * from "./web/index.js";
48
53
  export * from "./webxr/index.js"
49
54
  export * from "./webxr/XRFlag.js"
50
55
 
51
- import "./CameraUtils.js"
52
- import "./AnimationUtils.js"
53
- import "./AnimationUtilsAutoplay.js"
54
-
55
- export { DragMode } from "./DragControls.js";
56
- export type { DropListenerNetworkEventArguments, DropListenerOnDropArguments } from "./DropListener.js";
57
- export * from "./particlesystem/api.js"
58
- export * from "./splines/index.js";
59
- export * from "./web/index.js";
60
-
61
56
  // for correct type resolution in JSDoc
62
57
  import type { PhysicsMaterial } from "../engine/engine_physics.types.js";
63
58
  import type { Animation } from "./Animation.js";
@@ -2,10 +2,12 @@ import { NEEDLE_progressive } from "@needle-tools/gltf-progressive";
2
2
  import { Euler, Material, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "three";
3
3
 
4
4
  import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../../../engine/debug/index.js";
5
+ import { findObjectOfType } from "../../../engine/engine_components.js";
5
6
  import { hasProLicense } from "../../../engine/engine_license.js";
6
7
  import { serializable } from "../../../engine/engine_serialization.js";
7
8
  import { getFormattedDate, Progress } from "../../../engine/engine_time_utils.js";
8
9
  import { DeviceUtilities, getParam } from "../../../engine/engine_utils.js";
10
+ import { setQuicklookHandlerFactory } from "../../../engine/webcomponents/quicklook-handler.js";
9
11
  import { WebXRButtonFactory } from "../../../engine/webcomponents/WebXRButtons.js";
10
12
  import { InternalUSDZRegistry } from "../../../engine/xr/usdz.js"
11
13
  import { InstancingHandler } from "../../../engine-components/RendererInstancing.js";
@@ -793,3 +795,10 @@ export class USDZExporter extends Behaviour {
793
795
  return button;
794
796
  }
795
797
  }
798
+
799
+ // Register USDZExporter as the quicklook handler so that WebXRButtons
800
+ // can create/find exporters without a direct import (avoids circular dependency).
801
+ setQuicklookHandlerFactory({
802
+ find: () => findObjectOfType(USDZExporter),
803
+ create: () => new USDZExporter(),
804
+ });
@@ -1,5 +1,5 @@
1
1
  import type { Effect, EffectComposer, Pass, ToneMappingEffect as _TonemappingEffect } from "postprocessing";
2
- import { Camera as Camera3, DepthTexture, HalfFloatType, LinearFilter, NoToneMapping, Scene, Texture, ToneMapping, WebGLRenderTarget } from "three";
2
+ import { Camera as Camera3, DepthTexture, HalfFloatType, LinearFilter, NoToneMapping, Scene, Source, Texture, ToneMapping, WebGLRenderTarget } from "three";
3
3
 
4
4
  import { isDevEnvironment, showBalloonWarning } from "../../engine/debug/index.js";
5
5
  // import { internal_SetSharpeningEffectModule } from "./Effects/Sharpening.js";
@@ -435,14 +435,15 @@ export class PostProcessingHandler {
435
435
  this._customInputBuffer.depthTexture.format = inputBuffer.depthTexture.format;
436
436
  this._customInputBuffer.depthTexture.type = inputBuffer.depthTexture.type;
437
437
  }
438
- // https://github.com/pmndrs/postprocessing/blob/ad338df710ef41fee4e5d10ad2c2c299030d46ef/src/core/EffectComposer.js#L366
439
- if (this._customInputBuffer.samples > 0)
440
- (this._customInputBuffer as any).ignoreDepthForMultisampleCopy = false;
441
-
442
438
  if (debug) console.warn(`[PostProcessing] Input buffer created with size ${this._customInputBuffer.width}x${this._customInputBuffer.height} and samples ${this._customInputBuffer.samples}`);
443
439
  }
444
- // Calling the original render function with the input buffer
440
+ // Calling the original render function with the custom multisampled buffer
445
441
  screenPassRender.call(screenpass, renderer, this._customInputBuffer, outputBuffer, deltaTime, stencilTest);
442
+ // Switch to inputBuffer before the blit so that Graphics.blit's save/restore
443
+ // doesn't restore _customInputBuffer (multisampled) as the active render target.
444
+ // This triggers the MSAA resolve of _customInputBuffer exactly once and avoids
445
+ // subsequent unnecessary resolves that can cause glBlitFramebuffer depth errors.
446
+ renderer.setRenderTarget(inputBuffer);
446
447
  // Blit the resulting buffer to the input buffer passed in by the composer so it's used for subsequent effects
447
448
  Graphics.blit(this._customInputBuffer.texture, inputBuffer, {
448
449
  renderer,
@@ -568,7 +569,18 @@ export class PostProcessingHandler {
568
569
 
569
570
  }
570
571
 
571
-
572
+ // Fix: the postprocessing EffectComposer uses DepthTexture.clone() to create a stable depth target,
573
+ // but Three.js's Texture.copy() shares the Source object between original and clone.
574
+ // Since Three.js deduplicates GL textures by Source + cache key, both depth textures end up
575
+ // as the same GL texture, causing "glBlitFramebuffer: Read and write depth stencil attachments
576
+ // cannot be the same image" when blitDepthBuffer copies between them.
577
+ // Assigning a new Source breaks the deduplication so they get separate GL textures.
578
+ const composerDepthTexture = (composer as any).depthTexture as DepthTexture | null;
579
+ if (composerDepthTexture) {
580
+ composerDepthTexture.source = new Source({ width: 0, height: 0 });
581
+ composerDepthTexture.needsUpdate = true;
582
+ }
583
+
572
584
  this.handleDevicePixelRatio();
573
585
 
574
586
 
@@ -114,8 +114,13 @@ export function orderEffects(effects: Array<PostprocessingEffectData>) {
114
114
  builtinOrder.set(MODULES.POSTPROCESSING.MODULE.DepthDownsamplingPass, PostProcessingEffectOrder.DepthDownsamplingPass);
115
115
  builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SMAAEffect, PostProcessingEffectOrder.SMAA);
116
116
  builtinOrder.set(MODULES.POSTPROCESSING.MODULE.SSAOEffect, PostProcessingEffectOrder.SSAO);
117
- builtinOrder.set(MODULES.POSTPROCESSING_AO.MODULE.N8AOPostPass, PostProcessingEffectOrder.SSAO);
118
- builtinOrder.set(MODULES.POSTPROCESSING_AO.MODULE.N8AOPass, PostProcessingEffectOrder.SSAO);
117
+ // Use MAYBEMODULE to avoid creating a static dependency on n8ao — otherwise the
118
+ // bundler eagerly loads the 481 KB chunk even when AO is not used.
119
+ const n8ao = MODULES.POSTPROCESSING_AO.MAYBEMODULE;
120
+ if (n8ao) {
121
+ builtinOrder.set(n8ao.N8AOPostPass, PostProcessingEffectOrder.SSAO);
122
+ builtinOrder.set(n8ao.N8AOPass, PostProcessingEffectOrder.SSAO);
123
+ }
119
124
  builtinOrder.set(MODULES.POSTPROCESSING.MODULE.TiltShiftEffect, PostProcessingEffectOrder.TiltShift);
120
125
  builtinOrder.set(MODULES.POSTPROCESSING.MODULE.DepthOfFieldEffect, PostProcessingEffectOrder.DepthOfField);
121
126
  builtinOrder.set(MODULES.POSTPROCESSING.MODULE.ChromaticAberrationEffect, PostProcessingEffectOrder.ChromaticAberration);
@@ -2,12 +2,13 @@ import { AnimationAction, AnimationClip, AnimationMixer, Audio, AudioListener, A
2
2
 
3
3
  import { isDevEnvironment } from "../../engine/debug/index.js";
4
4
  import { Context } from "../../engine/engine_setup.js";
5
+ import type { Constructor } from "../../engine/engine_types.js";
5
6
  import { getParam, resolveUrl } from "../../engine/engine_utils.js";
6
7
  import { setObjectAnimated } from "../AnimationUtils.js";
7
8
  import { Animator } from "../Animator.js"
8
9
  import { AudioSource } from "../AudioSource.js";
9
10
  import { GameObject } from "../Component.js";
10
- import { PlayableDirector } from "./PlayableDirector.js";
11
+ import type { PlayableDirector } from "./PlayableDirector.js";
11
12
  import { SignalReceiver } from "./SignalAsset.js";
12
13
  import * as Models from "./TimelineModels.js";
13
14
 
@@ -940,7 +941,10 @@ export class ControlTrackHandler extends TrackHandler {
940
941
  continue;
941
942
  }
942
943
  else {
943
- const timeline = GameObject.getComponent(asset.sourceObject, PlayableDirector)!;
944
+ // Use the director's constructor to get the PlayableDirector class reference
945
+ // without a runtime import, avoiding a circular dependency.
946
+ const DirectorType = this.director.constructor as Constructor<PlayableDirector>;
947
+ const timeline = GameObject.getComponent(asset.sourceObject, DirectorType)!;
944
948
  // always add it to keep size of timelines and models in sync (index of model is index of timeline)
945
949
  this.timelines.push(timeline);
946
950
  if (timeline) {
@@ -514,7 +514,5 @@ declare global {
514
514
  currentTime: { unit: 'seconds' | 'percent', value: number };
515
515
  duration: { unit: 'seconds' | 'percent', value: number };
516
516
  source: Element | null;
517
- startOffset: { unit: 'px', value: number };
518
- endOffset: { unit: 'px', value: number };
519
517
  }
520
518
  }
@@ -23,7 +23,7 @@ const debug = getParam("debugwebxr");
23
23
  const debugQuicklook = getParam("debugusdz");
24
24
 
25
25
  /**
26
- * Use the WebXR component to enable VR and AR on **iOS and Android** in your scene. VisionOS support is also provided via QuickLook USDZ export.
26
+ * Use the [WebXR](https://engine.needle.tools/docs/api/WebXR) component to enable VR and AR on **iOS and Android** in your scene. VisionOS support is also provided via QuickLook USDZ export.
27
27
  *
28
28
  * The WebXR component is a simple to use wrapper around the {@link NeedleXRSession} API and adds some additional features like creating buttons for AR, VR, enabling default movement behaviour ({@link XRControllerMovement}) and controller rendering ({@link XRControllerModel}), as well as handling AR placement and Quicklook USDZ export.
29
29
  *
@@ -52,12 +52,25 @@ const debugQuicklook = getParam("debugusdz");
52
52
  * });
53
53
  * ```
54
54
  *
55
+ *
56
+ * @example Start AR session with placement reticle and touch to place and adjust the scene
57
+ * ```ts
58
+ * import { onStart, WebXR } from "@needle-tools/engine";
59
+ * onStart(context => {
60
+ * const webxr = context.scene.addComponent(WebXR);
61
+ * webxr.autoPlace = false; // disable auto placement, we want the user to tap to place the scene
62
+ * webxr.usePlacementReticle = true; // show the placement reticle to help the user find surfaces to place the scene
63
+ * webxr.usePlacementAdjustment = true; // allow the user to adjust the position, rotation and scale of the scene with touch after placing
64
+ * webxr.arScale = 2; // set the initial scale of the scene in AR. Larger values make the scene appear smaller in AR.
65
+ * webxr.enterAR(); // start AR session
66
+ * });
67
+ *
55
68
  * @summary WebXR Component for VR and AR support
56
69
  * @category XR
57
70
  * @group Components
58
71
  * @see {@link NeedleXRSession} for low-level XR API
59
72
  * @see {@link XRControllerMovement} for VR locomotion
60
- * @see {@link WebARSessionRoot} for AR session configuration
73
+ * @see {@link WebARSessionRoot} for AR session configuration and an AR content placement event
61
74
  * @see {@link Avatar} for networked user avatars
62
75
  * @see {@link screenshot2} for taking screenshots in XR (including AR camera feed compositing)
63
76
  * @link https://engine.needle.tools/docs/xr.html
@@ -1,6 +1,7 @@
1
+ import { initEngine } from "./engine/engine_init.js";
2
+ initEngine();
1
3
  import "./engine/webcomponents/needle-engine.js";
2
4
  import "./engine/engine_setup.js";
3
- import "./engine/engine_audio.js";
4
5
  export * from "./engine/api.js";
5
6
  export * from "./engine-components/api.js";
6
7
  export * from "./engine-components-experimental/api.js";