@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
@@ -185,207 +185,211 @@ export function apply(object: Object3D) {
185
185
  }
186
186
  }
187
187
 
188
- if (NEEDLE_ENGINE_FEATURE_FLAGS.experimentalSmartHierarchyUpdate) {
188
+ let initialized = false;
189
189
 
190
- const addFn = Object3D.prototype.add;
191
- Object3D.prototype.add = function (...args: any) {
192
- markHierarchyDirty();
193
- return addFn.apply(this, args);
194
- }
195
-
196
- const attachFn = Object3D.prototype.attach;
197
- Object3D.prototype.attach = function (...args: any) {
198
- markHierarchyDirty();
199
- return attachFn.apply(this, args);
200
- }
190
+ export function initObject3DExtensions() {
191
+ if (initialized) return;
192
+ initialized = true;
201
193
 
202
- const removeFn = Object3D.prototype.remove;
203
- Object3D.prototype.remove = function (...args: any) {
204
- markHierarchyDirty();
205
- return removeFn.apply(this, args);
206
- }
207
- }
194
+ if (NEEDLE_ENGINE_FEATURE_FLAGS.experimentalSmartHierarchyUpdate) {
208
195
 
209
- // #region Prototype Method Implementations
210
-
211
- Object3D.prototype["SetActive"] = function (active: boolean) {
212
- this.visible = active;
213
- }
214
- // e.g. when called via a UnityEvent
215
- Object3D.prototype["setActive"] = function (active: boolean) {
216
- this.visible = active;
217
- }
196
+ const addFn = Object3D.prototype.add;
197
+ Object3D.prototype.add = function (...args: any) {
198
+ markHierarchyDirty();
199
+ return addFn.apply(this, args);
200
+ }
218
201
 
219
- Object3D.prototype["destroy"] = function () {
220
- destroy(this);
221
- }
202
+ const attachFn = Object3D.prototype.attach;
203
+ Object3D.prototype.attach = function (...args: any) {
204
+ markHierarchyDirty();
205
+ return attachFn.apply(this, args);
206
+ }
222
207
 
223
- Object3D.prototype["addComponent"] = function <T extends IComponent>(comp: T | ConstructorConcrete<T>, init?: ComponentInit<T>) {
224
- return addComponent(this, comp, init);
225
- }
208
+ const removeFn = Object3D.prototype.remove;
209
+ Object3D.prototype.remove = function (...args: any) {
210
+ markHierarchyDirty();
211
+ return removeFn.apply(this, args);
212
+ }
213
+ }
226
214
 
227
- Object3D.prototype["addNewComponent"] = function <T extends Component>(type: ConstructorConcrete<T>, init?: ComponentInit<T>) {
228
- return addComponent(this, type, init);
229
- }
215
+ // #region Prototype Method Implementations
230
216
 
231
- Object3D.prototype["removeComponent"] = function (inst: Component) {
232
- return removeComponent(this, inst);
233
- }
217
+ Object3D.prototype["SetActive"] = function (active: boolean) {
218
+ this.visible = active;
219
+ }
220
+ // e.g. when called via a UnityEvent
221
+ Object3D.prototype["setActive"] = function (active: boolean) {
222
+ this.visible = active;
223
+ }
234
224
 
235
- Object3D.prototype["getOrAddComponent"] = function <T extends IComponent>(typeName: ConstructorConcrete<T>, init?: ComponentInit<T>): T {
236
- return getOrAddComponent<T>(this, typeName, init);
237
- }
225
+ Object3D.prototype["destroy"] = function () {
226
+ destroy(this);
227
+ }
238
228
 
239
- Object3D.prototype["getComponent"] = function <T extends IComponent>(type: Constructor<T>) {
240
- return getComponent(this, type);
241
- }
229
+ Object3D.prototype["addComponent"] = function <T extends IComponent>(comp: T | ConstructorConcrete<T>, init?: ComponentInit<T>) {
230
+ return addComponent(this, comp, init);
231
+ }
242
232
 
243
- Object3D.prototype["getComponents"] = function <T extends IComponent>(type: Constructor<T>, arr?: []) {
244
- return getComponents(this, type, arr);
245
- }
233
+ Object3D.prototype["addNewComponent"] = function <T extends Component>(type: ConstructorConcrete<T>, init?: ComponentInit<T>) {
234
+ return addComponent(this, type, init);
235
+ }
246
236
 
247
- Object3D.prototype["getComponentInChildren"] = function <T extends IComponent>(type: Constructor<T>, includeInactive: boolean = false) {
248
- return getComponentInChildren(this, type, includeInactive);
249
- }
237
+ Object3D.prototype["removeComponent"] = function (inst: Component) {
238
+ return removeComponent(this, inst);
239
+ }
250
240
 
251
- Object3D.prototype["getComponentsInChildren"] = function <T extends IComponent>(type: Constructor<T>, arr?: []) {
252
- return getComponentsInChildren(this, type, arr);
253
- }
241
+ Object3D.prototype["getOrAddComponent"] = function <T extends IComponent>(typeName: ConstructorConcrete<T>, init?: ComponentInit<T>): T {
242
+ return getOrAddComponent<T>(this, typeName, init);
243
+ }
254
244
 
255
- Object3D.prototype["getComponentInParent"] = function <T extends IComponent>(type: Constructor<T>, includeInactive: boolean = false) {
256
- return getComponentInParent(this, type, includeInactive);
257
- }
245
+ Object3D.prototype["getComponent"] = function <T extends IComponent>(type: Constructor<T>) {
246
+ return getComponent(this, type);
247
+ }
258
248
 
259
- Object3D.prototype["getComponentsInParent"] = function <T extends IComponent>(type: Constructor<T>, arr?: []) {
260
- return getComponentsInParent(this, type, arr);
261
- }
249
+ Object3D.prototype["getComponents"] = function <T extends IComponent>(type: Constructor<T>, arr?: []) {
250
+ return getComponents(this, type, arr);
251
+ }
262
252
 
263
- // #region Prototype Property Implementations
253
+ Object3D.prototype["getComponentInChildren"] = function <T extends IComponent>(type: Constructor<T>, includeInactive: boolean = false) {
254
+ return getComponentInChildren(this, type, includeInactive);
255
+ }
264
256
 
265
- // this is a fix to allow gameObject active animation be applied to a three object
266
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "activeSelf")) {
267
- Object.defineProperty(Object3D.prototype, "activeSelf", {
268
- get: function () {
269
- return isActiveSelf(this)
270
- },
271
- set: function (val: boolean | number) {
272
- setActive(this, val);
273
- }
274
- });
275
- }
257
+ Object3D.prototype["getComponentsInChildren"] = function <T extends IComponent>(type: Constructor<T>, arr?: []) {
258
+ return getComponentsInChildren(this, type, arr);
259
+ }
276
260
 
261
+ Object3D.prototype["getComponentInParent"] = function <T extends IComponent>(type: Constructor<T>, includeInactive: boolean = false) {
262
+ return getComponentInParent(this, type, includeInactive);
263
+ }
277
264
 
278
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "raycastAllowed")) {
279
- Object.defineProperty(Object3D.prototype, "raycastAllowed", {
280
- get: function () {
281
- return this.userData && this.userData.raycastAllowed !== false;
282
- },
283
- set: function (val: boolean) {
284
- const self = this as Object3D;
285
- if (!self.userData) self.userData = {};
286
- self.userData.raycastAllowed = val;
287
- }
288
- });
289
- }
265
+ Object3D.prototype["getComponentsInParent"] = function <T extends IComponent>(type: Constructor<T>, arr?: []) {
266
+ return getComponentsInParent(this, type, arr);
267
+ }
290
268
 
269
+ // #region Prototype Property Implementations
291
270
 
292
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldPosition")) {
293
- Object.defineProperty(Object3D.prototype, "worldPosition", {
294
- get: function () {
295
- // TODO: would be great to remove this - just a workaround because the TransformControlsGizmo also defines this
296
- if (this instanceof TransformControlsGizmo) {
297
- return getWorldPosition(this["object"]);
271
+ // this is a fix to allow gameObject active animation be applied to a three object
272
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "activeSelf")) {
273
+ Object.defineProperty(Object3D.prototype, "activeSelf", {
274
+ get: function () {
275
+ return isActiveSelf(this)
276
+ },
277
+ set: function (val: boolean | number) {
278
+ setActive(this, val);
298
279
  }
299
- return getWorldPosition(this);
300
- },
301
- set: function (val: Vector3) {
302
- setWorldPosition(this, val)
303
- }
304
- });
305
- }
280
+ });
281
+ }
306
282
 
307
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldQuaternion")) {
308
- Object.defineProperty(Object3D.prototype, "worldQuaternion", {
309
- get: function () {
310
- if (this instanceof TransformControlsGizmo) {
311
- return getWorldQuaternion(this["object"]);
283
+
284
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "raycastAllowed")) {
285
+ Object.defineProperty(Object3D.prototype, "raycastAllowed", {
286
+ get: function () {
287
+ return this.userData && this.userData.raycastAllowed !== false;
288
+ },
289
+ set: function (val: boolean) {
290
+ const self = this as Object3D;
291
+ if (!self.userData) self.userData = {};
292
+ self.userData.raycastAllowed = val;
312
293
  }
313
- return getWorldQuaternion(this);
314
- },
315
- set: function (val: Quaternion) {
316
- setWorldQuaternion(this, val)
317
- }
318
- });
319
- }
294
+ });
295
+ }
320
296
 
321
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldRotation")) {
322
- Object.defineProperty(Object3D.prototype, "worldRotation", {
323
- get: function () {
324
- return getWorldRotation(this);
325
- },
326
- set: function (val: Vector3) {
327
- setWorldRotation(this, val)
328
- }
329
- });
330
- }
331
297
 
332
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldScale")) {
333
- Object.defineProperty(Object3D.prototype, "worldScale", {
334
- get: function () {
335
- return getWorldScale(this);
336
- },
337
- set: function (val: Vector3) {
338
- setWorldScale(this, val)
339
- }
340
- });
341
- }
298
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldPosition")) {
299
+ Object.defineProperty(Object3D.prototype, "worldPosition", {
300
+ get: function () {
301
+ // TODO: would be great to remove this - just a workaround because the TransformControlsGizmo also defines this
302
+ if (this instanceof TransformControlsGizmo) {
303
+ return getWorldPosition(this["object"]);
304
+ }
305
+ return getWorldPosition(this);
306
+ },
307
+ set: function (val: Vector3) {
308
+ setWorldPosition(this, val)
309
+ }
310
+ });
311
+ }
342
312
 
343
- const tempMatrix = new Matrix4();
344
- const zero = new Vector3(0, 0, 0);
345
- const up = new Vector3(0, 1, 0);
346
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldForward")) {
347
- Object.defineProperty(Object3D.prototype, "worldForward", {
348
- get: function () {
349
- return getTempVector().set(0, 0, 1).applyQuaternion(getWorldQuaternion(this));
350
- },
351
- set: function (v: Vector3) {
352
- const quat = getTempQuaternion().setFromRotationMatrix(tempMatrix.lookAt(zero.set(0, 0, 0), v, up.set(0, 1, 0)));
353
- this.worldQuaternion = quat;
354
- }
355
- });
356
- }
357
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldRight")) {
358
- Object.defineProperty(Object3D.prototype, "worldRight", {
359
- get: function () {
360
- return getTempVector().set(1, 0, 0).applyQuaternion(getWorldQuaternion(this));
361
- },
362
- });
363
- }
364
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldUp")) {
365
- Object.defineProperty(Object3D.prototype, "worldUp", {
366
- get: function () {
367
- return getTempVector().set(0, 1, 0).applyQuaternion(getWorldQuaternion(this));
368
- },
369
- });
370
- }
313
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldQuaternion")) {
314
+ Object.defineProperty(Object3D.prototype, "worldQuaternion", {
315
+ get: function () {
316
+ if (this instanceof TransformControlsGizmo) {
317
+ return getWorldQuaternion(this["object"]);
318
+ }
319
+ return getWorldQuaternion(this);
320
+ },
321
+ set: function (val: Quaternion) {
322
+ setWorldQuaternion(this, val)
323
+ }
324
+ });
325
+ }
371
326
 
327
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldRotation")) {
328
+ Object.defineProperty(Object3D.prototype, "worldRotation", {
329
+ get: function () {
330
+ return getWorldRotation(this);
331
+ },
332
+ set: function (val: Vector3) {
333
+ setWorldRotation(this, val)
334
+ }
335
+ });
336
+ }
372
337
 
338
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldScale")) {
339
+ Object.defineProperty(Object3D.prototype, "worldScale", {
340
+ get: function () {
341
+ return getWorldScale(this);
342
+ },
343
+ set: function (val: Vector3) {
344
+ setWorldScale(this, val)
345
+ }
346
+ });
347
+ }
373
348
 
374
- if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "contains")) {
375
- Object.defineProperty(Object3D.prototype, "contains", {
376
- value: function (object: Object3D | null | undefined): boolean {
377
- if (!object) return false;
378
- if (this === object) return true;
379
- for (const child of this.children) {
380
- if (child.contains(object)) return true;
349
+ const tempMatrix = new Matrix4();
350
+ const zero = new Vector3(0, 0, 0);
351
+ const up = new Vector3(0, 1, 0);
352
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldForward")) {
353
+ Object.defineProperty(Object3D.prototype, "worldForward", {
354
+ get: function () {
355
+ return getTempVector().set(0, 0, 1).applyQuaternion(getWorldQuaternion(this));
356
+ },
357
+ set: function (v: Vector3) {
358
+ const quat = getTempQuaternion().setFromRotationMatrix(tempMatrix.lookAt(zero.set(0, 0, 0), v, up.set(0, 1, 0)));
359
+ this.worldQuaternion = quat;
381
360
  }
382
- return false;
383
- }
384
- });
385
- }
361
+ });
362
+ }
363
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldRight")) {
364
+ Object.defineProperty(Object3D.prototype, "worldRight", {
365
+ get: function () {
366
+ return getTempVector().set(1, 0, 0).applyQuaternion(getWorldQuaternion(this));
367
+ },
368
+ });
369
+ }
370
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "worldUp")) {
371
+ Object.defineProperty(Object3D.prototype, "worldUp", {
372
+ get: function () {
373
+ return getTempVector().set(0, 1, 0).applyQuaternion(getWorldQuaternion(this));
374
+ },
375
+ });
376
+ }
386
377
 
387
378
 
388
379
 
380
+ if (!Object.getOwnPropertyDescriptor(Object3D.prototype, "contains")) {
381
+ Object.defineProperty(Object3D.prototype, "contains", {
382
+ value: function (object: Object3D | null | undefined): boolean {
383
+ if (!object) return false;
384
+ if (this === object) return true;
385
+ for (const child of this.children) {
386
+ if (child.contains(object)) return true;
387
+ }
388
+ return false;
389
+ }
390
+ });
391
+ }
389
392
 
390
- // do this after adding the component extensions
391
- registerPrototypeExtensions(Object3D);
393
+ // do this after adding the component extensions
394
+ registerPrototypeExtensions(Object3D);
395
+ }
@@ -17,8 +17,15 @@ declare module 'three' {
17
17
  }
18
18
  }
19
19
 
20
- Vector3.prototype["slerp"] = function (end: Vector3, t: number) {
21
- return slerp(this, end, t);
22
- }
20
+ let initialized = false;
21
+
22
+ export function initVectorExtensions() {
23
+ if (initialized) return;
24
+ initialized = true;
23
25
 
24
- registerPrototypeExtensions(Vector3);
26
+ Vector3.prototype["slerp"] = function (end: Vector3, t: number) {
27
+ return slerp(this, end, t);
28
+ }
29
+
30
+ registerPrototypeExtensions(Vector3);
31
+ }
@@ -1,6 +1,3 @@
1
- import "./Layers.js";
2
- import "./Camera.js";
3
1
  export * from "./ExtensionUtils.js";
4
2
  export { apply } from "./Object3D.js";
5
3
  export * from "./RGBAColor.js";
6
- export { } from "./Vector.js";
@@ -1,6 +1,4 @@
1
- import { USDZExporter } from "../../engine-components/export/usdz/USDZExporter.js";
2
1
  import { isDevEnvironment, showBalloonMessage } from "../debug/index.js";
3
- import { findObjectOfType } from "../engine_components.js";
4
2
  import { Context } from "../engine_setup.js";
5
3
  import { DeviceUtilities } from "../engine_utils.js";
6
4
  import { NeedleXRSession } from "../engine_xr.js";
@@ -8,6 +6,7 @@ import { onXRSessionEnd, onXRSessionStart } from "../xr/events.js";
8
6
  import { ButtonsFactory } from "./buttons.js";
9
7
  import { getIconElement } from "./icons.js";
10
8
  import { NeedleMenu } from "./needle menu/needle-menu.js";
9
+ import { getOrCreateQuicklookHandler,type IQuicklookHandler } from "./quicklook-handler.js";
11
10
 
12
11
  // TODO: move these buttons into their own web components so their logic is encapsulated (e.g. the CSS animation when a xr session is requested)
13
12
 
@@ -76,22 +75,22 @@ export class WebXRButtonFactory {
76
75
  NeedleMenu.setElementPriority(button, quicklookButtonPriority);
77
76
 
78
77
  let createdExporter = false;
79
- let usdzExporter: USDZExporter | null = null;
78
+ let quicklookHandler: IQuicklookHandler | null = null;
80
79
  button.addEventListener("click", () => {
81
- usdzExporter = findObjectOfType(USDZExporter);
80
+ const result = getOrCreateQuicklookHandler();
82
81
 
83
- // if the scene doesnt have an USDZExporter component, create one
84
- if (!usdzExporter) {
85
- createdExporter = true;
86
- usdzExporter = new USDZExporter();
82
+ if (result) {
83
+ quicklookHandler = result.handler;
84
+ createdExporter = result.created;
87
85
  }
88
- // if we have created a USDZExporter
89
- if (createdExporter)
90
- usdzExporter.objectToExport = Context.Current.scene;
91
86
 
92
- if (usdzExporter) {
87
+ // if we have created a handler
88
+ if (createdExporter && quicklookHandler)
89
+ quicklookHandler.objectToExport = Context.Current.scene;
90
+
91
+ if (quicklookHandler) {
93
92
  button.classList.add("this-mode-is-requested");
94
- usdzExporter.exportAndOpen().then(() => {
93
+ quicklookHandler.exportAndOpen().then(() => {
95
94
  button.classList.remove("this-mode-is-requested");
96
95
  }).catch(err => {
97
96
  button.classList.remove("this-mode-is-requested");
@@ -3,7 +3,7 @@ import { IContext } from "../engine_types.js";
3
3
  import { generateQRCode } from "../engine_utils_qrcode.js";
4
4
  import { onXRSessionEnd, onXRSessionStart } from "../xr/events.js";
5
5
  import { getIconElement } from "./icons.js";
6
- import { NeedleMenu } from "./needle menu/needle-menu.js";
6
+ import { setElementPriority } from "./needle menu/menu-priority.js";
7
7
 
8
8
  /**
9
9
  * Use the ButtonsFactory to create buttons with icons and functionality
@@ -67,7 +67,7 @@ export class ButtonsFactory {
67
67
  this._fullscreenButton = button;
68
68
  button.classList.add("fullscreen-button");
69
69
  button.title = "Click to enter fullscreen mode";
70
- NeedleMenu.setElementPriority(button, 3);
70
+ setElementPriority(button, 3);
71
71
  const enterFullscreenIcon = getIconElement("fullscreen");
72
72
  const exitFullscreenIcon = getIconElement("fullscreen_exit");
73
73
  button.appendChild(enterFullscreenIcon);
@@ -119,7 +119,7 @@ export class ButtonsFactory {
119
119
  const muteIcon = getIconElement("volume_off");
120
120
  const unmuteIcon = getIconElement("volume_up");
121
121
 
122
- NeedleMenu.setElementPriority(button, 1);
122
+ setElementPriority(button, 1);
123
123
 
124
124
  // save state in session storage (this needs consent)
125
125
  // if (sessionStorage.getItem("muted") === "true") {
@@ -191,7 +191,7 @@ export class ButtonsFactory {
191
191
  qrCodeButton.prepend(getIconElement("qr_code"));
192
192
  qrCodeButton.title = "Scan this QR code with your phone to open this page";
193
193
  this.hideElementDuringXRSession(qrCodeButton);
194
- NeedleMenu.setElementPriority(this._qrButton, 20);
194
+ setElementPriority(this._qrButton, 20);
195
195
 
196
196
  const qrCodeContainer = document.createElement("div");
197
197
  qrCodeContainer.style.cssText = `
@@ -0,0 +1,9 @@
1
+ // Font URLs used by Needle Engine UI.
2
+ // Shared between the runtime (fonts.ts) and the build plugin (plugins/vite/asap.js)
3
+ // to keep preload links and runtime loads in sync.
4
+
5
+ export const robotoFlexFontUrl = "https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap";
6
+
7
+ // Using a static (non-variable) font because the variable font is quite large
8
+ // eslint-disable-next-line no-secrets/no-secrets
9
+ export const materialSymbolsFontUrl = "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0&display=block";
@@ -1,3 +1,4 @@
1
+ import { materialSymbolsFontUrl,robotoFlexFontUrl } from "./font-urls.js";
1
2
 
2
3
  declare type LoadFontOptions = {
3
4
  element?: HTMLElement | DocumentFragment,
@@ -10,11 +11,18 @@ export function loadFont(url: string, opts?: LoadFontOptions) {
10
11
  // Add font import to document header.
11
12
  // Note that this is slower than it could be, ideally the font would be prefetched,
12
13
  // but for that it needs to be in the actual document and not added by JS.
13
- const elements = Array.from(element.querySelectorAll(`link[rel=stylesheet][href*='${url}']`));
14
+ const elements = Array.from(element.querySelectorAll(`link[href*='${url}']`));
14
15
  if (elements.length <= 0) {
15
16
  const fontLink = document.createElement("link");
16
17
  fontLink.href = url;
17
- fontLink.rel = "stylesheet";
18
+ // Load fonts without blocking render: use rel="preload" with onload swap
19
+ // to stylesheet. This avoids the ~200ms render-blocking delay per font.
20
+ fontLink.rel = "preload";
21
+ fontLink.as = "style";
22
+ // crossorigin must match the HTML <link> attribute (set by asap.js) so the browser
23
+ // can reuse the cached CORS response instead of making a separate non-CORS request
24
+ fontLink.crossOrigin = "";
25
+ fontLink.onload = () => { fontLink.rel = "stylesheet"; };
18
26
  element.appendChild(fontLink);
19
27
  elements.push(fontLink);
20
28
  }
@@ -32,11 +40,8 @@ export function loadFont(url: string, opts?: LoadFontOptions) {
32
40
 
33
41
  /** Ensure the fonts that needle engine uses are loaded */
34
42
  export function ensureFonts() {
35
- loadFont("https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap");
43
+ loadFont(robotoFlexFontUrl);
36
44
  }
37
45
 
38
- // add to document head AND shadow dom to work
39
- // using a static font because the variable font is quite large
40
- // eslint-disable-next-line no-secrets/no-secrets
41
- export const iconFontUrl = "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0&display=block";
46
+ export { materialSymbolsFontUrl as iconFontUrl };
42
47
  // const fontUrl = "./include/fonts/MaterialSymbolsOutlined.css"; // for offline support
@@ -0,0 +1,23 @@
1
+ import { NeedleLogoElement } from "./logo-element.js";
2
+ import { NeedleMenuElement } from "./needle menu/needle-menu.js";
3
+ import { NeedleButtonElement } from "./needle-button.js";
4
+ import { NeedleEngineWebComponent } from "./needle-engine.js";
5
+
6
+ /** Register all built-in web components. Called from {@link initEngine} as a
7
+ * safeguard against aggressive tree-shaking that may drop the top-level
8
+ * `customElements.define` calls in the individual component files. */
9
+ export function initWebComponents() {
10
+ if (typeof window === "undefined") return;
11
+
12
+ if (!window.customElements.get("needle-engine"))
13
+ window.customElements.define("needle-engine", NeedleEngineWebComponent);
14
+
15
+ if (!window.customElements.get("needle-button"))
16
+ window.customElements.define("needle-button", NeedleButtonElement);
17
+
18
+ if (!window.customElements.get("needle-logo-element"))
19
+ window.customElements.define("needle-logo-element", NeedleLogoElement);
20
+
21
+ if (!window.customElements.get("needle-menu"))
22
+ window.customElements.define("needle-menu", NeedleMenuElement);
23
+ }
@@ -17,6 +17,8 @@ export class NeedleLogoElement extends HTMLElement {
17
17
  static get elementName() { return elementName; }
18
18
 
19
19
  static create(): NeedleLogoElement {
20
+ if (!customElements.get(elementName))
21
+ customElements.define(elementName, NeedleLogoElement);
20
22
  return document.createElement(elementName) as NeedleLogoElement;
21
23
  }
22
24
 
@@ -131,5 +133,3 @@ export class NeedleLogoElement extends HTMLElement {
131
133
  }
132
134
 
133
135
  }
134
- if (!customElements.get(elementName))
135
- customElements.define(elementName, NeedleLogoElement);
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Sets the priority attribute on a menu element, determining its position in the menu.
3
+ * Lower priority elements appear on the left, higher priority on the right.
4
+ */
5
+ export function setElementPriority(button: HTMLElement, priority: number) {
6
+ button.setAttribute("priority", String(priority));
7
+ }
8
+
9
+ /**
10
+ * Gets the priority attribute from a menu element.
11
+ * @returns The priority value, or undefined if not set or not a valid number.
12
+ */
13
+ export function getElementPriority(button: HTMLElement): number | undefined {
14
+ const priority = button.getAttribute("priority");
15
+ if (priority) {
16
+ const val = Number.parseFloat(priority);
17
+ if (!Number.isNaN(val)) return val;
18
+ }
19
+ return undefined;
20
+ }