@needle-tools/engine 4.12.0-next.de80571 → 4.12.0-next.f546e2b

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 (184) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/components.needle.json +1 -1
  3. package/dist/generateMeshBVH.worker-iyfPIK6R.js +21 -0
  4. package/dist/{gltf-progressive-DZrY8VT6.min.js → gltf-progressive-BmSygnAC.min.js} +2 -2
  5. package/dist/{gltf-progressive-DgYz5BYa.js → gltf-progressive-DnLBuGK5.js} +24 -24
  6. package/dist/{gltf-progressive-DWcmTMCh.umd.cjs → gltf-progressive-Rs-ojtXy.umd.cjs} +1 -1
  7. package/dist/{loader.worker-Dip-PthR.js → loader.worker-DWzfDpAl.js} +4 -4
  8. package/dist/{needle-engine.bundle-S3PalR7r.min.js → needle-engine.bundle-BcsvlMBI.min.js} +150 -151
  9. package/dist/needle-engine.bundle-Dw_P6rEZ.umd.cjs +1646 -0
  10. package/dist/{needle-engine.bundle-CbrIHiN8.js → needle-engine.bundle-qhXfGDpR.js} +8564 -8382
  11. package/dist/needle-engine.d.ts +108 -43
  12. package/dist/needle-engine.js +4 -4
  13. package/dist/needle-engine.min.js +1 -1
  14. package/dist/needle-engine.umd.cjs +1 -1
  15. package/dist/{postprocessing-DYDtB188.min.js → postprocessing-B5ksn9-G.min.js} +54 -54
  16. package/dist/{postprocessing-CMgoN5t5.umd.cjs → postprocessing-DZtb9Nnn.umd.cjs} +81 -81
  17. package/dist/{postprocessing-BTW9pD_s.js → postprocessing-__7s9wON.js} +450 -441
  18. package/dist/{three-DfMvBzXi.js → three-BCCkyCA5.js} +1 -7
  19. package/dist/{three-qj71I7J3.umd.cjs → three-Bf2NBxAw.umd.cjs} +2 -2
  20. package/dist/{three-B7CT31Bt.min.js → three-W7zWTcfP.min.js} +1 -1
  21. package/dist/{three-examples-CsW4_6LI.umd.cjs → three-examples-Dho7cuu4.umd.cjs} +4 -4
  22. package/dist/{three-examples-D1P7eEhn.min.js → three-examples-MsJjauyk.min.js} +10 -10
  23. package/dist/{three-examples-D1SK93ek.js → three-examples-y2GeYlze.js} +2 -20
  24. package/dist/{three-mesh-ui-C_uSB5dD.js → three-mesh-ui-3nSSizT4.js} +1 -1
  25. package/dist/{three-mesh-ui-LQ44s0AL.min.js → three-mesh-ui-CIez6qJQ.min.js} +1 -1
  26. package/dist/{three-mesh-ui-DpATDXwU.umd.cjs → three-mesh-ui-zsOOA5Pq.umd.cjs} +1 -1
  27. package/dist/{vendor-D0zoswDa.js → vendor-DMZcbVO1.js} +3707 -3527
  28. package/dist/vendor-sURMCFSI.min.js +1116 -0
  29. package/dist/{vendor-UCpFAwt1.umd.cjs → vendor-tyBvnMF-.umd.cjs} +39 -39
  30. package/lib/engine/codegen/register_types.js +0 -2
  31. package/lib/engine/codegen/register_types.js.map +1 -1
  32. package/lib/engine/debug/debug_console.js +403 -1
  33. package/lib/engine/debug/debug_console.js.map +1 -1
  34. package/lib/engine/engine_components.js +3 -3
  35. package/lib/engine/engine_components.js.map +1 -1
  36. package/lib/engine/engine_input.d.ts +5 -0
  37. package/lib/engine/engine_input.js +6 -0
  38. package/lib/engine/engine_input.js.map +1 -1
  39. package/lib/engine/engine_license.js +3 -9
  40. package/lib/engine/engine_license.js.map +1 -1
  41. package/lib/engine/engine_networking.js +5 -5
  42. package/lib/engine/engine_networking.js.map +1 -1
  43. package/lib/engine/engine_physics.js.map +1 -1
  44. package/lib/engine/engine_physics_rapier.js +1 -1
  45. package/lib/engine/engine_physics_rapier.js.map +1 -1
  46. package/lib/engine/engine_utils.d.ts +4 -1
  47. package/lib/engine/engine_utils.js +28 -4
  48. package/lib/engine/engine_utils.js.map +1 -1
  49. package/lib/engine/extensions/extensions.d.ts +29 -7
  50. package/lib/engine/extensions/extensions.js.map +1 -1
  51. package/lib/engine/webcomponents/WebXRButtons.js +13 -5
  52. package/lib/engine/webcomponents/WebXRButtons.js.map +1 -1
  53. package/lib/engine/webcomponents/needle menu/needle-menu.js +4 -5
  54. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  55. package/lib/engine/webcomponents/needle-engine.ar-overlay.js +4 -0
  56. package/lib/engine/webcomponents/needle-engine.ar-overlay.js.map +1 -1
  57. package/lib/engine/webcomponents/needle-engine.js +1 -1
  58. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  59. package/lib/engine/xr/NeedleXRSession.d.ts +1 -1
  60. package/lib/engine/xr/NeedleXRSession.js +67 -24
  61. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  62. package/lib/engine/xr/TempXRContext.js +12 -2
  63. package/lib/engine/xr/TempXRContext.js.map +1 -1
  64. package/lib/engine/xr/usdz.js +6 -2
  65. package/lib/engine/xr/usdz.js.map +1 -1
  66. package/lib/engine-components/AlignmentConstraint.d.ts +1 -1
  67. package/lib/engine-components/AlignmentConstraint.js +1 -1
  68. package/lib/engine-components/Animation.d.ts +1 -1
  69. package/lib/engine-components/Animation.js +1 -1
  70. package/lib/engine-components/Animator.d.ts +1 -1
  71. package/lib/engine-components/Animator.js +1 -1
  72. package/lib/engine-components/AudioListener.d.ts +1 -1
  73. package/lib/engine-components/AudioListener.js +1 -1
  74. package/lib/engine-components/AudioSource.d.ts +1 -1
  75. package/lib/engine-components/AudioSource.js +1 -1
  76. package/lib/engine-components/Camera.d.ts +1 -1
  77. package/lib/engine-components/Camera.js +1 -1
  78. package/lib/engine-components/CharacterController.d.ts +6 -2
  79. package/lib/engine-components/CharacterController.js +6 -2
  80. package/lib/engine-components/CharacterController.js.map +1 -1
  81. package/lib/engine-components/Collider.d.ts +1 -1
  82. package/lib/engine-components/Collider.js.map +1 -1
  83. package/lib/engine-components/Component.d.ts +2 -1
  84. package/lib/engine-components/Component.js +3 -2
  85. package/lib/engine-components/Component.js.map +1 -1
  86. package/lib/engine-components/DragControls.js +3 -0
  87. package/lib/engine-components/DragControls.js.map +1 -1
  88. package/lib/engine-components/Joints.d.ts +14 -0
  89. package/lib/engine-components/Joints.js +14 -0
  90. package/lib/engine-components/Joints.js.map +1 -1
  91. package/lib/engine-components/LookAtConstraint.d.ts +1 -1
  92. package/lib/engine-components/LookAtConstraint.js +1 -1
  93. package/lib/engine-components/OrbitControls.d.ts +1 -1
  94. package/lib/engine-components/OrbitControls.js +1 -1
  95. package/lib/engine-components/Renderer.d.ts +6 -0
  96. package/lib/engine-components/Renderer.js +6 -0
  97. package/lib/engine-components/Renderer.js.map +1 -1
  98. package/lib/engine-components/RendererInstancing.js +5 -3
  99. package/lib/engine-components/RendererInstancing.js.map +1 -1
  100. package/lib/engine-components/SceneSwitcher.js +18 -14
  101. package/lib/engine-components/SceneSwitcher.js.map +1 -1
  102. package/lib/engine-components/SpectatorCamera.js +15 -7
  103. package/lib/engine-components/SpectatorCamera.js.map +1 -1
  104. package/lib/engine-components/SpriteRenderer.d.ts +2 -1
  105. package/lib/engine-components/SpriteRenderer.js +2 -1
  106. package/lib/engine-components/SpriteRenderer.js.map +1 -1
  107. package/lib/engine-components/api.d.ts +1 -0
  108. package/lib/engine-components/api.js +1 -0
  109. package/lib/engine-components/api.js.map +1 -1
  110. package/lib/engine-components/codegen/components.d.ts +0 -1
  111. package/lib/engine-components/codegen/components.js +0 -1
  112. package/lib/engine-components/codegen/components.js.map +1 -1
  113. package/lib/engine-components/timeline/SignalAsset.d.ts +1 -1
  114. package/lib/engine-components/timeline/SignalAsset.js +1 -1
  115. package/lib/engine-components/ui/Raycaster.d.ts +3 -2
  116. package/lib/engine-components/ui/Raycaster.js +3 -2
  117. package/lib/engine-components/ui/Raycaster.js.map +1 -1
  118. package/lib/engine-components/ui/RectTransform.d.ts +6 -0
  119. package/lib/engine-components/ui/RectTransform.js +6 -0
  120. package/lib/engine-components/ui/RectTransform.js.map +1 -1
  121. package/lib/engine-components/utils/LookAt.d.ts +2 -1
  122. package/lib/engine-components/utils/LookAt.js +2 -1
  123. package/lib/engine-components/utils/LookAt.js.map +1 -1
  124. package/lib/engine-components/web/CursorFollow.d.ts +1 -1
  125. package/lib/engine-components/web/CursorFollow.js +1 -1
  126. package/lib/engine-components/web/HoverAnimation.d.ts +1 -1
  127. package/lib/engine-components/web/HoverAnimation.js +1 -1
  128. package/lib/engine-components/web/ViewBox.d.ts +1 -1
  129. package/lib/engine-components/web/ViewBox.js +1 -1
  130. package/lib/engine-components/webxr/Avatar.js +2 -0
  131. package/lib/engine-components/webxr/Avatar.js.map +1 -1
  132. package/lib/engine-components/webxr/WebXR.js +18 -12
  133. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  134. package/package.json +3 -3
  135. package/plugins/vite/poster-client.js +8 -1
  136. package/src/engine/codegen/register_types.ts +0 -2
  137. package/src/engine/debug/debug_console.ts +449 -1
  138. package/src/engine/engine_components.ts +4 -4
  139. package/src/engine/engine_input.ts +7 -0
  140. package/src/engine/engine_license.ts +3 -8
  141. package/src/engine/engine_networking.ts +5 -5
  142. package/src/engine/engine_physics.ts +3 -3
  143. package/src/engine/engine_physics_rapier.ts +1 -1
  144. package/src/engine/engine_utils.ts +23 -4
  145. package/src/engine/extensions/extensions.ts +30 -6
  146. package/src/engine/webcomponents/WebXRButtons.ts +15 -5
  147. package/src/engine/webcomponents/needle menu/needle-menu.ts +4 -5
  148. package/src/engine/webcomponents/needle-engine.ar-overlay.ts +6 -0
  149. package/src/engine/webcomponents/needle-engine.ts +2 -2
  150. package/src/engine/xr/NeedleXRSession.ts +78 -27
  151. package/src/engine/xr/TempXRContext.ts +12 -2
  152. package/src/engine/xr/usdz.ts +6 -1
  153. package/src/engine-components/AlignmentConstraint.ts +1 -1
  154. package/src/engine-components/Animation.ts +1 -1
  155. package/src/engine-components/Animator.ts +1 -1
  156. package/src/engine-components/AudioListener.ts +1 -1
  157. package/src/engine-components/AudioSource.ts +1 -1
  158. package/src/engine-components/Camera.ts +1 -1
  159. package/src/engine-components/CharacterController.ts +6 -2
  160. package/src/engine-components/Collider.ts +1 -1
  161. package/src/engine-components/Component.ts +5 -4
  162. package/src/engine-components/DragControls.ts +4 -0
  163. package/src/engine-components/Joints.ts +14 -0
  164. package/src/engine-components/LookAtConstraint.ts +1 -1
  165. package/src/engine-components/OrbitControls.ts +1 -1
  166. package/src/engine-components/Renderer.ts +6 -0
  167. package/src/engine-components/RendererInstancing.ts +6 -3
  168. package/src/engine-components/SceneSwitcher.ts +17 -17
  169. package/src/engine-components/SpectatorCamera.ts +21 -10
  170. package/src/engine-components/SpriteRenderer.ts +2 -1
  171. package/src/engine-components/api.ts +2 -1
  172. package/src/engine-components/codegen/components.ts +0 -1
  173. package/src/engine-components/timeline/SignalAsset.ts +1 -1
  174. package/src/engine-components/ui/Raycaster.ts +3 -2
  175. package/src/engine-components/ui/RectTransform.ts +6 -0
  176. package/src/engine-components/utils/LookAt.ts +2 -1
  177. package/src/engine-components/web/CursorFollow.ts +1 -1
  178. package/src/engine-components/web/HoverAnimation.ts +1 -1
  179. package/src/engine-components/web/ViewBox.ts +1 -1
  180. package/src/engine-components/webxr/Avatar.ts +4 -0
  181. package/src/engine-components/webxr/WebXR.ts +19 -11
  182. package/dist/generateMeshBVH.worker-mO20N_b8.js +0 -21
  183. package/dist/needle-engine.bundle-BGixCtrn.umd.cjs +0 -1647
  184. package/dist/vendor-BKGa4GE0.min.js +0 -1116
@@ -110,8 +110,12 @@ export class CharacterController extends Behaviour {
110
110
  }
111
111
 
112
112
  /**
113
- * @category Camera
114
- * @category Interactivity
113
+ * CharacterControllerInput handles user input to control a CharacterController.
114
+ * It supports movement, looking around, jumping, and double jumping.
115
+ * You can customize movement speed, rotation speed, and jump forces.
116
+ * It also integrates with an Animator component for character animations.
117
+ * @summary User Input for Character Controller
118
+ * @category Character
115
119
  * @group Components
116
120
  */
117
121
  export class CharacterControllerInput extends Behaviour {
@@ -26,7 +26,7 @@ import { Rigidbody } from "./RigidBody.js";
26
26
  * @category Physics
27
27
  * @group Components
28
28
  */
29
- export class Collider extends Behaviour implements ICollider {
29
+ export abstract class Collider extends Behaviour implements ICollider {
30
30
 
31
31
  /**
32
32
  * Identifies this component as a collider.
@@ -476,10 +476,11 @@ export abstract class GameObject extends Object3D implements Object3D, IGameObje
476
476
  * Gets a component of the specified type in the gameObject's children hierarchy
477
477
  * @param go GameObject to search in
478
478
  * @param typeName Constructor of the component type
479
+ * @param includeInactive Whether to include inactive objects in the search
479
480
  * @returns The first matching component if found, otherwise null
480
481
  */
481
- public static getComponentInChildren<T extends IComponent>(go: IGameObject | Object3D, typeName: Constructor<T>): T | null {
482
- return getComponentInChildren(go, typeName);
482
+ public static getComponentInChildren<T extends IComponent>(go: IGameObject | Object3D, typeName: Constructor<T>, includeInactive: boolean = false): T | null {
483
+ return getComponentInChildren(go, typeName, includeInactive);
483
484
  }
484
485
 
485
486
  /**
@@ -588,7 +589,7 @@ export abstract class Component implements IComponent, EventTarget,
588
589
  */
589
590
  get [$componentName]() { return TypeStore.getKey(this.constructor as any) || undefined; }
590
591
 
591
-
592
+
592
593
  private __context: Context | undefined;
593
594
 
594
595
  /**
@@ -1106,7 +1107,7 @@ export abstract class Component implements IComponent, EventTarget,
1106
1107
  this.dispatchEvent(new CustomEvent("destroyed", { detail: this }));
1107
1108
  }
1108
1109
  destroyComponentInstance(this as any);
1109
- if(isHotReloadEnabled()) unregisterHotReloadType(this);
1110
+ if (isHotReloadEnabled()) unregisterHotReloadType(this);
1110
1111
  }
1111
1112
 
1112
1113
  /**
@@ -485,6 +485,8 @@ interface IDragHandler {
485
485
  onDragUpdate?(numberOfPointers: number): void;
486
486
  }
487
487
 
488
+
489
+ // #region MultiTouchDragHandler
488
490
  /**
489
491
  * Handles two touch points affecting one object.
490
492
  * Enables multi-touch interactions that allow movement, scaling, and rotation of objects.
@@ -734,6 +736,7 @@ class MultiTouchDragHandler implements IDragHandler {
734
736
  }
735
737
 
736
738
 
739
+ // #region DragPointerHandler
737
740
  /**
738
741
  * Handles a single pointer on an object.
739
742
  * DragPointerHandlers manage determining if a drag operation has started, tracking pointer movement,
@@ -1335,6 +1338,7 @@ class DragPointerHandler implements IDragHandler {
1335
1338
  }
1336
1339
  }
1337
1340
 
1341
+ // #region LegacyDragVisualsHelper
1338
1342
  /**
1339
1343
  * Provides visual helper elements for DragControls.
1340
1344
  * Shows where objects will be placed and their relation to surfaces below them.
@@ -36,6 +36,12 @@ export abstract class Joint extends Behaviour {
36
36
  protected abstract createJoint(self: Rigidbody, other: Rigidbody);
37
37
  }
38
38
 
39
+ /**
40
+ * The FixedJoint groups together 2 rigidbodies, making them stick together in their bound position
41
+ * @summary Connect two Rigidbodies and make them stick together
42
+ * @category Physics
43
+ * @group Components
44
+ */
39
45
  export class FixedJoint extends Joint {
40
46
 
41
47
  protected createJoint(self: Rigidbody, other: Rigidbody) {
@@ -43,6 +49,14 @@ export class FixedJoint extends Joint {
43
49
  }
44
50
  }
45
51
 
52
+ /**
53
+ * The HingeJoint groups together 2 rigid bodies, constraining them to move like connected by a hinge.
54
+ *
55
+ * You can specify the anchor point and axis of rotation for the hinge.
56
+ * @summary Connect two Rigidbodies with a hinge
57
+ * @category Physics
58
+ * @group Components
59
+ */
46
60
  export class HingeJoint extends Joint {
47
61
 
48
62
  @serializable(Vector3)
@@ -9,7 +9,7 @@ import type { OrbitControls } from "./OrbitControls.js";
9
9
  * This component is used by {@link OrbitControls} internally.
10
10
  *
11
11
  * @summary Look At Constraint for OrbitControls
12
- * @category Camera Controls
12
+ * @category Camera and Controls
13
13
  * @group Components
14
14
  */
15
15
  export class LookAtConstraint extends Behaviour {
@@ -64,7 +64,7 @@ declare module 'three/examples/jsm/controls/OrbitControls.js' {
64
64
  * The three OrbitControls object can be accessed via the `controls` property.
65
65
  * The object being controlled by the OrbitControls (usually the camera) can be accessed via the `controllerObject` property.
66
66
  * @summary Camera controller using three.js OrbitControls
67
- * @category Camera
67
+ * @category Camera and Controls
68
68
  * @group Components
69
69
  */
70
70
  export class OrbitControls extends Behaviour implements ICameraController {
@@ -805,6 +805,12 @@ export class Renderer extends Behaviour implements IRenderer {
805
805
  export class MeshRenderer extends Renderer {
806
806
  }
807
807
 
808
+ /**
809
+ * Renders deformable meshes that deform via bones and/or blend shapes.
810
+ * @summary Renderer for deformable meshes
811
+ * @category Rendering
812
+ * @group Components
813
+ **/
808
814
  export class SkinnedMeshRenderer extends MeshRenderer {
809
815
 
810
816
  private _needUpdateBoundingSphere = false;
@@ -669,14 +669,17 @@ class InstancedMeshRenderer {
669
669
  private grow(geometry: BufferGeometry) {
670
670
  const id = ++this._growId;
671
671
  const growFactor = 2;
672
- const newSize = Math.ceil(this._maxInstanceCount * growFactor);
672
+
673
+ const growInstances = this.count >= this._maxInstanceCount;
674
+ const newSize = growInstances ? Math.ceil(this._maxInstanceCount * growFactor) : this._maxInstanceCount;
673
675
 
674
676
  // create a new BatchedMesh instance
675
677
  // TODO: we should keep track of how many instances for each geometry we have and consider that when estimating new space
676
678
  const estimatedSpace = this.tryEstimateVertexCountSize(newSize, [geometry]);// geometry.attributes.position.count;
677
679
  // const indices = geometry.index ? geometry.index.count : 0;
678
- const newMaxVertexCount = Math.max(this._maxVertexCount, estimatedSpace.vertexCount);
679
- const newMaxIndexCount = Math.max(this._maxIndexCount, estimatedSpace.indexCount);//, Math.ceil(this._maxVertexCount * growFactor));
680
+ const vertexGrowFactor = 1.25;
681
+ const newMaxVertexCount = Math.max(this._maxVertexCount, Math.ceil(estimatedSpace.vertexCount * vertexGrowFactor));
682
+ const newMaxIndexCount = Math.max(this._maxIndexCount, Math.ceil(estimatedSpace.indexCount * vertexGrowFactor));
680
683
 
681
684
  if (debugInstancing) {
682
685
  const geometryInfo = getMeshInformation(geometry);
@@ -261,7 +261,7 @@ export class SceneSwitcher extends Behaviour {
261
261
  if (scene && !scene.hasUrl && scene.asset instanceof Object3D) {
262
262
  GameObject.remove(scene.asset);
263
263
  }
264
- else if(scene instanceof Object3D) {
264
+ else if (scene instanceof Object3D) {
265
265
  GameObject.remove(scene);
266
266
  }
267
267
  }
@@ -477,13 +477,13 @@ export class SceneSwitcher extends Behaviour {
477
477
  * @returns a promise that resolves to true if the scene was loaded successfully
478
478
  */
479
479
  select(index: number | string): Promise<boolean> {
480
- if (debug) console.log("select", index);
480
+ if (debug) console.log("[SceneSwitcher] select", index);
481
481
 
482
482
  if (typeof index === "object") {
483
483
  // If a user tries to reference a scene object in a UnityEvent and invoke select(obj)
484
484
  // Then the object will be serialized as a object { guid : ... } or with the index json pointer
485
485
  // This case is not supported right now. Object references in the editor must not be scene references
486
- console.warn("Switching to \"" + index + "\" might not work. Please either use an index or a AssetReference (not a scene reference)");
486
+ console.warn("[SceneSwitcher] Switching to \"" + index + "\" might not work. Please either use an index or a AssetReference (not a scene reference)");
487
487
  }
488
488
 
489
489
  if (typeof index === "string") {
@@ -595,7 +595,7 @@ export class SceneSwitcher extends Behaviour {
595
595
  const current = this._currentScene;
596
596
  this._currentScene = undefined;
597
597
  if (current) {
598
- if (debug) console.log("UNLOAD", current.url, "HasURL?: " + current.hasUrl)
598
+ if (debug) console.log("[SceneSwitcher] UNLOAD", current.url, "HasURL?: " + current.hasUrl)
599
599
  const sceneListener = this.tryGetSceneEventListener(current.asset as any as Object3D);
600
600
  if (sceneListener?.sceneClosing) {
601
601
  const res = sceneListener.sceneClosing();
@@ -620,6 +620,7 @@ export class SceneSwitcher extends Behaviour {
620
620
  const index = this._currentIndex = this.scenes?.indexOf(scene) ?? -1;
621
621
 
622
622
  try {
623
+ if (debug) console.debug(`${Date.now()} [SceneSwitcher] Loading scene start: ${scene.url} (index: ${index})`);
623
624
  this._currentlyLoadingScene = scene;
624
625
  this._currentLoadingProgress = new ProgressEvent("progress", { loaded: 0, total: 1 });
625
626
 
@@ -632,7 +633,7 @@ export class SceneSwitcher extends Behaviour {
632
633
  if (debug) {
633
634
  const t01 = prog.loaded / prog.total;
634
635
  const progressBarString = "[" + "=".repeat(Math.floor(t01 * 20)) + "-".repeat(20 - Math.floor(t01 * 20)) + "]";
635
- console.debug(`[SceneSwitcher] Download ${(t01 * 100).toFixed(1)} % ${progressBarString}`, scene.url);
636
+ console.debug(`${Date.now()} [SceneSwitcher] Loading scene progress: ${(t01 * 100).toFixed(1)} % ${progressBarString}`, scene.url);
636
637
  }
637
638
  this._currentLoadingProgress = prog;
638
639
  this.dispatchEvent(prog);
@@ -646,15 +647,15 @@ export class SceneSwitcher extends Behaviour {
646
647
  this._currentlyLoadingScene = undefined;
647
648
 
648
649
  if (finishedEvt.defaultPrevented) {
649
- if (debug) console.warn("Adding loaded scene prevented:", scene, finishedEvt);
650
+ if (debug) console.warn("[SceneSwitcher] Adding loaded scene prevented:", scene, finishedEvt);
650
651
  return false;
651
652
  }
652
653
  if (!scene.asset) {
653
- if (debug) console.warn("Failed loading scene:", scene);
654
+ if (debug) console.warn("[SceneSwitcher] Failed loading scene:", scene);
654
655
  return false;
655
656
  }
656
657
  if (this._currentIndex === index) {
657
- if (debug) console.log("ADD", scene.url);
658
+ if (debug) console.log("[SceneSwitcher] ADD", scene.url);
658
659
  this._currentScene = scene;
659
660
 
660
661
 
@@ -683,7 +684,7 @@ export class SceneSwitcher extends Behaviour {
683
684
  this.context.scene.background = skybox;
684
685
  }
685
686
  else if (debug) {
686
- console.warn("SceneSwitcher: Can't find skybox for scene " + scene.url);
687
+ console.warn("[SceneSwitcher] Can't find skybox for scene " + scene.url);
687
688
  }
688
689
  }
689
690
 
@@ -713,10 +714,9 @@ export class SceneSwitcher extends Behaviour {
713
714
  const res = sceneListener.sceneOpened(this);
714
715
  if (res instanceof Promise) await res;
715
716
  }
716
-
717
+ if (debug) console.debug(`${Date.now()} [SceneSwitcher] Loading scene finished: ${scene.url} (index: ${index})`);
717
718
  const openedEvt = new CustomEvent<LoadSceneEvent>("scene-opened", { detail: { scene: scene, switcher: this, index: index } });
718
719
  this.dispatchEvent(openedEvt);
719
-
720
720
  this.sceneLoaded?.invoke(this);
721
721
  return true;
722
722
  }
@@ -772,7 +772,7 @@ export class SceneSwitcher extends Behaviour {
772
772
  }
773
773
  }
774
774
 
775
- if (isLocalNetwork()) console.warn("Can not find scene: \"" + value + "\"", this)
775
+ if (isLocalNetwork()) console.warn("[SceneSwitcher] Can not find scene: \"" + value + "\"", this)
776
776
 
777
777
  return couldNotLoadScenePromise;
778
778
  }
@@ -913,7 +913,7 @@ class PreLoadScheduler {
913
913
  */
914
914
  begin(delay: number) {
915
915
  if (this._isRunning) return;
916
- if (debug) console.log("Preload begin", { delay })
916
+ if (debug) console.log("[SceneSwitcher] Preload scheduled", { delay });
917
917
  this._isRunning = true;
918
918
  let lastRoom: number = -10;
919
919
  let searchDistance: number;
@@ -923,7 +923,7 @@ class PreLoadScheduler {
923
923
  const interval = setInterval(() => {
924
924
  if (this.allLoaded()) {
925
925
  if (debug)
926
- console.log("All scenes (pre-)loaded");
926
+ console.log("[SceneSwitcher] All scenes (pre-)loaded");
927
927
  this.stop();
928
928
  }
929
929
  if (!this._isRunning) {
@@ -950,7 +950,7 @@ class PreLoadScheduler {
950
950
  if (roomIndex < 0 || roomIndex >= array.length) return;
951
951
  if (!this._loadTasks.some(t => t.index === roomIndex)) {
952
952
  const scene = array[roomIndex];
953
- if (debug) console.log("Preload scene", { roomIndex, searchForward, lastRoom, currentIndex: this._switcher.currentIndex, tasks: this._loadTasks.length }, scene?.url);
953
+ if (debug) console.log("[SceneSwitcher] Schedule preload scene", { roomIndex, searchForward, lastRoom, currentIndex: this._switcher.currentIndex, tasks: this._loadTasks.length }, scene?.url);
954
954
  new LoadTask(roomIndex, scene, this._loadTasks);
955
955
  }
956
956
  }, 200);
@@ -1019,10 +1019,10 @@ class LoadTask {
1019
1019
  private async awaitLoading() {
1020
1020
  if (this.asset && !this.asset.isLoaded()) {
1021
1021
  if (debug)
1022
- console.log("Preload start: " + this.asset.url, this.index);
1022
+ console.log("[SceneSwitcher] Preload start: " + this.asset.url, this.index);
1023
1023
  await this.asset.preload();
1024
1024
  if (debug)
1025
- console.log("Preload finished: " + this.asset.url, this.index);
1025
+ console.log("[SceneSwitcher] Preload finished: " + this.asset.url, this.index);
1026
1026
  }
1027
1027
 
1028
1028
  const i = this.tasks.indexOf(this);
@@ -1,4 +1,5 @@
1
1
  import { Color, Object3D, PerspectiveCamera, Quaternion, Vector3, WebGLState } from "three";
2
+ import { PlayerState } from "../engine-components-experimental/networking/PlayerSync.js";
2
3
 
3
4
  import { InputEvents } from "../engine/engine_input.js";
4
5
  import { RoomEvents } from "../engine/engine_networking.js";
@@ -8,7 +9,7 @@ import { PlayerView, ViewDevice } from "../engine/engine_playerview.js";
8
9
  import { serializable } from "../engine/engine_serialization.js";
9
10
  import { Context } from "../engine/engine_setup.js";
10
11
  import type { ICamera } from "../engine/engine_types.js";
11
- import { getParam } from "../engine/engine_utils.js";
12
+ import { DeviceUtilities, getParam } from "../engine/engine_utils.js";
12
13
  import { Camera } from "./Camera.js";
13
14
  import { Behaviour, Component, GameObject } from "./Component.js";
14
15
  import { OrbitControls } from "./OrbitControls.js";
@@ -98,7 +99,7 @@ export class SpectatorCamera extends Behaviour {
98
99
  }
99
100
 
100
101
  /** Gets the local player's connection ID */
101
- private get localId() : string {
102
+ private get localId(): string {
102
103
  return this.context.connection.connectionId ?? "local";
103
104
  }
104
105
 
@@ -196,9 +197,8 @@ export class SpectatorCamera extends Behaviour {
196
197
  */
197
198
  private isSupportedPlatform() {
198
199
  const ua = window.navigator.userAgent;
199
- const standalone = /Windows|MacOS/.test(ua);
200
200
  const isHololens = /Windows NT/.test(ua) && /Edg/.test(ua) && !/Win64/.test(ua);
201
- return standalone && !isHololens;
201
+ return DeviceUtilities.isDesktop() && !DeviceUtilities.isMobileDevice() && !isHololens;
202
202
  }
203
203
 
204
204
  /**
@@ -268,11 +268,16 @@ export class SpectatorCamera extends Behaviour {
268
268
  const previousRenderTarget = renderer.getRenderTarget();
269
269
  let oldFramebuffer: WebGLFramebuffer | null = null;
270
270
 
271
+
271
272
  const webglState = renderer.state as WebGLState & { bindXRFramebuffer?: Function };
272
273
 
274
+
273
275
  // seems that in some cases, renderer.getRenderTarget returns null
274
276
  // even when we're rendering to a headset.
275
- if (!previousRenderTarget) {
277
+ if (!previousRenderTarget ||
278
+ // Prevent rendering if in XR - @TODO: check if we need to allow this for VR?
279
+ previousRenderTarget["isXRRenderTarget"] === true)
280
+ {
276
281
  if (!renderer.state.bindFramebuffer || !webglState.bindXRFramebuffer)
277
282
  return;
278
283
 
@@ -557,12 +562,18 @@ class SpectatorSelectionController {
557
562
  for (const hit of hits) {
558
563
  if (hit.distance < .2) continue;
559
564
  const obj = hit.object;
560
- const avatar = GameObject.getComponentInParent(obj, AvatarMarker);
561
- const id = avatar?.connectionId;
565
+ // For WebXR
566
+ const state = PlayerState.getFor(obj);
567
+ let id = state?.owner;
568
+ // for SpectatorCamera
569
+ if (!id) {
570
+ const avatar = GameObject.getComponentInParent(obj, AvatarMarker);
571
+ id = avatar?.connectionId;
572
+ }
562
573
  if (id) {
563
574
  const view = this.context.players.getPlayerView(id);
564
575
  this.spectator.target = view;
565
- if (debug) console.log("spectate", id, avatar);
576
+ if (debug) console.log("spectate", id, state);
566
577
  break;
567
578
  }
568
579
  }
@@ -633,7 +644,7 @@ class SpectatorCamNetworking {
633
644
  this.context.connection.beginListen("spectator-request-follow", this._requestFollowMethod);
634
645
  this.context.connection.beginListen(RoomEvents.JoinedRoom, this._joinedRoomMethod);
635
646
  this.context.domElement.addEventListener("keydown", evt => {
636
- if(!this.spectator.useKeys) return;
647
+ if (!this.spectator.useKeys) return;
637
648
  if (evt.key === "f") {
638
649
  this.onRequestFollowMe();
639
650
  }
@@ -767,7 +778,7 @@ class SpectatorCamNetworking {
767
778
  }
768
779
 
769
780
  private _enforceFollowInterval: any;
770
-
781
+
771
782
  /**
772
783
  * Periodically retries following a user if the initial attempt failed
773
784
  */
@@ -262,7 +262,8 @@ export class SpriteData {
262
262
  *
263
263
  * - Example: https://engine.needle.tools/samples/spritesheet-animation
264
264
  *
265
- * @category Sprites
265
+ * @summary Renders 2D images from a sprite sheet
266
+ * @category Rendering
266
267
  * @group Components
267
268
  */
268
269
  export class SpriteRenderer extends Behaviour {
@@ -35,7 +35,8 @@
35
35
  */
36
36
 
37
37
  export * from "./codegen/components.js";
38
- export { Behaviour, Component, GameObject } from "./Component.js"
38
+ export { Behaviour, Component, GameObject } from "./Component.js";
39
+ export { Collider } from "./Collider.js"; // export abstract type
39
40
 
40
41
  // We dont want to export everything in the extensions
41
42
  export { ClearFlags } from "./Camera.js"
@@ -23,7 +23,6 @@ export { BoxHelperComponent } from "../BoxHelperComponent.js";
23
23
  export { Camera } from "../Camera.js";
24
24
  export { CharacterController } from "../CharacterController.js";
25
25
  export { CharacterControllerInput } from "../CharacterController.js";
26
- export { Collider } from "../Collider.js";
27
26
  export { SphereCollider } from "../Collider.js";
28
27
  export { BoxCollider } from "../Collider.js";
29
28
  export { MeshCollider } from "../Collider.js";
@@ -30,7 +30,7 @@ export class SignalReceiverEvent {
30
30
  * Signals can be added to a signal track on a {@link PlayableDirector}
31
31
  *
32
32
  * @summary Receives signals and invokes reactions
33
- * @category Sequencing and Timelines
33
+ * @category Animation and Sequencing
34
34
  * @group Components
35
35
  */
36
36
  export class SignalReceiver extends Behaviour {
@@ -31,7 +31,7 @@ export abstract class Raycaster extends Behaviour {
31
31
  /**
32
32
  * A Raycaster that performs raycasting against its own GameObject.
33
33
  *
34
- * @category Interaction
34
+ * @category Interactivity
35
35
  * @group Components
36
36
  */
37
37
  export class ObjectRaycaster extends Raycaster {
@@ -75,7 +75,8 @@ export class ObjectRaycaster extends Raycaster {
75
75
  /**
76
76
  * A Raycaster that performs raycasting against UI elements (objects with a CanvasRenderer component).
77
77
  *
78
- * @category UI
78
+ * @summary Raycaster for UI elements
79
+ * @category User Interface
79
80
  * @group Components
80
81
  */
81
82
  export class GraphicRaycaster extends ObjectRaycaster {
@@ -29,6 +29,12 @@ const tempVec = new Vector3();
29
29
  const tempMatrix = new Matrix4();
30
30
  const tempQuaternion = new Quaternion();
31
31
 
32
+ /**
33
+ * RectTransform is a component that defines a rectangle for UI layout.
34
+ * @summary UI Rectangle Transform
35
+ * @category User Interface
36
+ * @group Components
37
+ */
32
38
  export class RectTransform extends BaseUIComponent implements IRectTransform, IRectTransformChangedReceiver {
33
39
 
34
40
  get parent() {
@@ -13,7 +13,8 @@ import { Behaviour } from "../Component.js";
13
13
  * It can also invert the forward direction and keep the up direction.
14
14
  *
15
15
  * @summary Makes the object look at a target object or the camera
16
- * @category Interactivity, Everywhere Actions
16
+ * @category Everywhere Actions
17
+ * @category Interactivity
17
18
  * @group Components
18
19
  */
19
20
  export class LookAt extends Behaviour implements UsdzBehaviour {
@@ -15,7 +15,7 @@ const debug = getParam("debugcursor");
15
15
  * - Example: [Look At Cursor sample](https://engine.needle.tools/samples/look-at-cursor-interactive-3d-header/). This sample combines the CursorFollow component with a LookAt component to create an interactive 3D header that looks at the cursor.
16
16
  *
17
17
  * @summary Makes the object follow the cursor position on screen
18
- * @category Web
18
+ * @category Interactivity
19
19
  * @group Components
20
20
  * @component
21
21
  */
@@ -14,7 +14,7 @@ import { Behaviour } from "../Component.js";
14
14
  * By default, a simple scale-up animation is used. You can customize the hover and idle animations by providing your own animation clips.
15
15
  *
16
16
  * @summary Hover Animation on Pointer Enter/Exit
17
- * @category Web
17
+ * @category Interactivity
18
18
  * @group Components
19
19
  */
20
20
  @registerType
@@ -32,7 +32,7 @@ export type ViewBoxMode = "continuous" | "once";
32
32
  * ```
33
33
 
34
34
  * @summary Automatically fits a box area into the camera view
35
- * @category Camera
35
+ * @category Camera and Controls
36
36
  * @group Components
37
37
  * @component
38
38
  */
@@ -12,6 +12,7 @@ import { Behaviour, GameObject } from "../Component.js";
12
12
  import { SyncedTransform } from "../SyncedTransform.js";
13
13
  import { AvatarMarker } from "./WebXRAvatar.js";
14
14
  import { XRFlag } from "./XRFlag.js";
15
+ import { ViewDevice } from "../../engine/engine_playerview.js";
15
16
 
16
17
  const debug = getParam("debugwebxr");
17
18
 
@@ -55,10 +56,13 @@ export class Avatar extends Behaviour {
55
56
  const marker = this.gameObject.addComponent(AvatarMarker)!;
56
57
  marker.avatar = this.gameObject;
57
58
  marker.connectionId = playerstate.owner;
59
+
60
+ this.context.players.setPlayerView(playerstate.owner, this.head?.asset, ViewDevice.Headset);
58
61
  }
59
62
  else if (this.context.connection.isConnected) console.error("No player state found for avatar", this);
60
63
  // don't destroy the avatar when entering XR and not connected to a networking backend
61
64
  else if (playerstate && !this.context.connection.isConnected) playerstate.dontDestroy = true;
65
+
62
66
  }
63
67
 
64
68
  onLeaveXR(_args: NeedleXREventArgs): void {
@@ -210,17 +210,25 @@ export class WebXR extends Behaviour {
210
210
  showBalloonWarning("<a href=\"https://developer.mozilla.org/en-US/docs/Web/API/WebXR_Device_API\" target=\"_blank\">WebXR</a> only works on secure connections (https).");
211
211
  }
212
212
 
213
- if (this.useQuicklookExport) {
214
- const existingUSDZExporter = GameObject.findObjectOfType(USDZExporter);
215
- if (!existingUSDZExporter) {
216
- // if no USDZ Exporter is found we add one and assign the scene to be exported
217
- if (debug) console.log("WebXR: Adding USDZExporter");
218
- this._usdzExporter = GameObject.addComponent(this.gameObject, USDZExporter);
219
- this._usdzExporter.objectToExport = this.context.scene;
220
- this._usdzExporter.autoExportAnimations = true;
221
- this._usdzExporter.autoExportAudioSources = true;
213
+ // Showing the QuickLook button depends on whether we're on iOS or visionOS –
214
+ // on iOS we have AppClip support, so we don't need QuickLook button there,
215
+ // while on visionOS we use QuickLook for AR experiences for now (unless it happens to have WebXR support by then).
216
+ navigator.xr?.isSessionSupported("immersive-ar").catch(() => false).then((arSupported) => {
217
+
218
+ const isVisionOSFallback = DeviceUtilities.isVisionOS() && !arSupported;
219
+
220
+ if (this.useQuicklookExport || isVisionOSFallback) {
221
+ const existingUSDZExporter = GameObject.findObjectOfType(USDZExporter);
222
+ if (!existingUSDZExporter) {
223
+ // if no USDZ Exporter is found we add one and assign the scene to be exported
224
+ if (debug) console.log("WebXR: Adding USDZExporter");
225
+ this._usdzExporter = GameObject.addComponent(this.gameObject, USDZExporter);
226
+ this._usdzExporter.objectToExport = this.context.scene;
227
+ this._usdzExporter.autoExportAnimations = true;
228
+ this._usdzExporter.autoExportAudioSources = true;
229
+ }
222
230
  }
223
- }
231
+ });
224
232
 
225
233
  this.handleCreatingHTML();
226
234
  this.handleOfferSession();
@@ -360,7 +368,7 @@ export class WebXR extends Behaviour {
360
368
 
361
369
  // Handle AR session root
362
370
  if (args.xr.isAR) {
363
- let sessionroot = GameObject.findObjectOfType(WebARSessionRoot);
371
+ let sessionroot = GameObject.findObjectOfType(WebARSessionRoot, this.context, false);
364
372
  // Only create a WebARSessionRoot if none is in the scene already
365
373
  if (!sessionroot) {
366
374
  if (this.usePlacementReticle) {