@needle-tools/engine 4.8.6-next.f3ce848 → 4.8.7-next.1715881

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 (84) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/components.needle.json +1 -1
  3. package/dist/{gltf-progressive-DXRy9EQz.js → gltf-progressive-BcHT3Nyo.js} +1 -1
  4. package/dist/{gltf-progressive-C-U_onhf.umd.cjs → gltf-progressive-CH3Q4H06.umd.cjs} +1 -1
  5. package/dist/{gltf-progressive-DViD_J_l.min.js → gltf-progressive-DR6HqF_h.min.js} +1 -1
  6. package/dist/{needle-engine.bundle-fXDFH_oR.js → needle-engine.bundle-BAha1j_T.js} +4866 -4813
  7. package/dist/{needle-engine.bundle-CJSl-mXb.min.js → needle-engine.bundle-Bw0zm_81.min.js} +130 -130
  8. package/dist/{needle-engine.bundle-C4N-adas.umd.cjs → needle-engine.bundle-_RVu0BLh.umd.cjs} +131 -131
  9. package/dist/needle-engine.js +394 -393
  10. package/dist/needle-engine.min.js +1 -1
  11. package/dist/needle-engine.umd.cjs +1 -1
  12. package/dist/{postprocessing-61aXdqNz.umd.cjs → postprocessing-CVb_x9YY.umd.cjs} +1 -1
  13. package/dist/{postprocessing-D9jDHD0U.js → postprocessing-ORx-0eCx.js} +1 -1
  14. package/dist/{postprocessing-Be9Ds4NK.min.js → postprocessing-Ywv5oKkX.min.js} +1 -1
  15. package/dist/three-examples-BX_Sktc9.min.js +501 -0
  16. package/dist/{three-examples-BihZ_R96.js → three-examples-CNexix3E.js} +2436 -2781
  17. package/dist/{three-examples-Ce6Th3bv.umd.cjs → three-examples-DWxXVnws.umd.cjs} +21 -21
  18. package/dist/{vendor-BRpzuoJE.min.js → vendor-C43vobGc.min.js} +37 -37
  19. package/dist/{vendor-p_xp9KuJ.js → vendor-Z4SPrTcP.js} +2402 -2047
  20. package/dist/vendor-xfQ8tKF3.umd.cjs +1121 -0
  21. package/lib/engine/api.d.ts +1 -0
  22. package/lib/engine/api.js +1 -0
  23. package/lib/engine/api.js.map +1 -1
  24. package/lib/engine/engine_addressables.d.ts +12 -12
  25. package/lib/engine/engine_addressables.js +30 -23
  26. package/lib/engine/engine_addressables.js.map +1 -1
  27. package/lib/engine/engine_animation.d.ts +1 -3
  28. package/lib/engine/engine_animation.js +15 -9
  29. package/lib/engine/engine_animation.js.map +1 -1
  30. package/lib/engine/engine_feature_flags.d.ts +3 -0
  31. package/lib/engine/engine_feature_flags.js +6 -0
  32. package/lib/engine/engine_feature_flags.js.map +1 -0
  33. package/lib/engine/engine_loaders.js +15 -11
  34. package/lib/engine/engine_loaders.js.map +1 -1
  35. package/lib/engine/engine_mainloop_utils.d.ts +2 -1
  36. package/lib/engine/engine_mainloop_utils.js +16 -4
  37. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  38. package/lib/engine/extensions/extensions.js +2 -2
  39. package/lib/engine/extensions/extensions.js.map +1 -1
  40. package/lib/engine/js-extensions/Object3D.js +19 -0
  41. package/lib/engine/js-extensions/Object3D.js.map +1 -1
  42. package/lib/engine-components/Animation.js +2 -1
  43. package/lib/engine-components/Animation.js.map +1 -1
  44. package/lib/engine-components/AnimationUtilsAutoplay.js +1 -6
  45. package/lib/engine-components/AnimationUtilsAutoplay.js.map +1 -1
  46. package/lib/engine-components/DropListener.d.ts +17 -12
  47. package/lib/engine-components/DropListener.js +34 -31
  48. package/lib/engine-components/DropListener.js.map +1 -1
  49. package/lib/engine-components/LookAtConstraint.d.ts +5 -1
  50. package/lib/engine-components/LookAtConstraint.js +8 -0
  51. package/lib/engine-components/LookAtConstraint.js.map +1 -1
  52. package/lib/engine-components/OrbitControls.d.ts +5 -7
  53. package/lib/engine-components/OrbitControls.js +12 -11
  54. package/lib/engine-components/OrbitControls.js.map +1 -1
  55. package/lib/engine-components/export/usdz/Extension.d.ts +1 -1
  56. package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +1 -1
  57. package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -1
  58. package/lib/engine-components/export/usdz/USDZExporter.d.ts +7 -0
  59. package/lib/engine-components/export/usdz/USDZExporter.js +8 -1
  60. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  61. package/lib/engine-components/webxr/WebXRImageTracking.d.ts +4 -2
  62. package/lib/engine-components/webxr/WebXRImageTracking.js +117 -81
  63. package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
  64. package/package.json +3 -2
  65. package/plugins/vite/alias.js +45 -23
  66. package/src/engine/api.ts +2 -1
  67. package/src/engine/engine_addressables.ts +44 -33
  68. package/src/engine/engine_animation.ts +17 -9
  69. package/src/engine/engine_feature_flags.ts +8 -0
  70. package/src/engine/engine_loaders.ts +18 -13
  71. package/src/engine/engine_mainloop_utils.ts +21 -6
  72. package/src/engine/extensions/extensions.ts +2 -2
  73. package/src/engine/js-extensions/Object3D.ts +25 -2
  74. package/src/engine-components/Animation.ts +1 -1
  75. package/src/engine-components/AnimationUtilsAutoplay.ts +1 -6
  76. package/src/engine-components/DropListener.ts +40 -31
  77. package/src/engine-components/LookAtConstraint.ts +9 -1
  78. package/src/engine-components/OrbitControls.ts +19 -16
  79. package/src/engine-components/export/usdz/Extension.ts +1 -1
  80. package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +1 -1
  81. package/src/engine-components/export/usdz/USDZExporter.ts +21 -12
  82. package/src/engine-components/webxr/WebXRImageTracking.ts +138 -90
  83. package/dist/three-examples-DKY9Nfge.min.js +0 -501
  84. package/dist/vendor-Ja-vKV-a.umd.cjs +0 -1121
@@ -143,13 +143,6 @@ const blobKeyName = "blob";
143
143
  */
144
144
  export class DropListener extends Behaviour {
145
145
 
146
- /**
147
- * When enabled, the DropListener will automatically synchronize dropped files to other connected clients.
148
- * When a file is dropped locally, it will be uploaded to blob storage and the URL will be shared with other clients.
149
- */
150
- @serializable()
151
- useNetworking: boolean = true;
152
-
153
146
  /**
154
147
  * When assigned, the DropListener will only accept files that are dropped on this specific object.
155
148
  * This allows creating designated drop zones in your scene.
@@ -159,7 +152,10 @@ export class DropListener extends Behaviour {
159
152
 
160
153
  /**
161
154
  * When enabled, dropped objects will be automatically scaled to fit within the volume defined by fitVolumeSize.
162
- * Useful for ensuring dropped models appear at an appropriate scale.
155
+ * Useful for ensuring dropped models appear at an appropriate scale.
156
+ *
157
+ * **Tip**: Use the handy `fitObjectIntoVolume` function (`import { fitObjectIntoVolume } from "@needle-tools/engine"`) for custom fitting needs.
158
+ *
163
159
  * @default false
164
160
  */
165
161
  @serializable()
@@ -180,6 +176,14 @@ export class DropListener extends Behaviour {
180
176
  @serializable()
181
177
  placeAtHitPosition: boolean = true;
182
178
 
179
+ /**
180
+ * When enabled, the DropListener will automatically synchronize dropped files to other connected clients.
181
+ * When a file is dropped locally, it will be uploaded to blob storage and the URL will be shared with other clients.
182
+ * @default false
183
+ */
184
+ @serializable()
185
+ useNetworking: boolean = false;
186
+
183
187
  /**
184
188
  * Event list that gets invoked after a file has been successfully added to the scene.
185
189
  * Receives {@link DropListenerOnDropArguments} containing the added object and related information.
@@ -193,6 +197,27 @@ export class DropListener extends Behaviour {
193
197
  @serializable(EventList)
194
198
  onDropped: EventList<DropListenerOnDropArguments> = new EventList();
195
199
 
200
+ /**
201
+ * Loads a file from the given URL and adds it to the scene.
202
+ * @returns A promise that resolves to the loaded object or null if loading failed.
203
+ */
204
+ loadFromURL(url: string, data?: { point?: Vec3, size?: Vec3 }): Promise<Object3D | null> {
205
+ return this.addFromUrl(url, { screenposition: new Vector2(), point: data?.point, size: data?.size, }, false);
206
+ }
207
+
208
+ /**
209
+ * Forgets all previously added objects.
210
+ * The droplistener will then not be able to remove previously added objects.
211
+ */
212
+ forgetObjects() {
213
+ this.removePreviouslyAddedObjects(false);
214
+ }
215
+
216
+
217
+
218
+
219
+ // #region internals
220
+
196
221
  /** @internal */
197
222
  onEnable(): void {
198
223
  this.context.renderer.domElement.addEventListener("dragover", this.onDrag);
@@ -208,21 +233,6 @@ export class DropListener extends Behaviour {
208
233
  this.context.connection.stopListen("droplistener", this.onNetworkEvent);
209
234
  }
210
235
 
211
- /**
212
- * Loads a file from the given URL and adds it to the scene.
213
- */
214
- loadFromURL(url: string, data?: { point?: Vec3, size?: Vec3 }) {
215
- this.addFromUrl(url, { screenposition: new Vector2(), point: data?.point, size: data?.size, }, true);
216
- }
217
-
218
- /**
219
- * Forgets all previously added objects.
220
- * The droplistener will then not be able to remove previously added objects.
221
- */
222
- forgetObjects() {
223
- this.removePreviouslyAddedObjects(false);
224
- }
225
-
226
236
  /**
227
237
  * Handles network events received from other clients containing information about dropped objects
228
238
  * @param evt Network event data containing object information, position, and content URL
@@ -326,7 +336,7 @@ export class DropListener extends Behaviour {
326
336
  }
327
337
  }
328
338
  if (files.length > 0) {
329
- await this.addDroppedFiles(files, ctx);
339
+ await this.addFromFiles(files, ctx);
330
340
  }
331
341
  }
332
342
 
@@ -359,6 +369,7 @@ export class DropListener extends Behaviour {
359
369
  // Ignore dropped images
360
370
  const lowercaseUrl = url.toLowerCase();
361
371
  if (lowercaseUrl.endsWith(".hdr") || lowercaseUrl.endsWith(".hdri") || lowercaseUrl.endsWith(".exr") || lowercaseUrl.endsWith(".png") || lowercaseUrl.endsWith(".jpg") || lowercaseUrl.endsWith(".jpeg")) {
372
+ console.warn(`Fileformat is not supported: ${lowercaseUrl}`);
362
373
  return null;
363
374
  }
364
375
 
@@ -374,7 +385,7 @@ export class DropListener extends Behaviour {
374
385
  });
375
386
  if (res && this._addedObjects.length <= 0) {
376
387
  ctx.url = url;
377
- const obj = this.addObject(res, ctx, isRemote);
388
+ const obj = this.onObjectLoaded(res, ctx, isRemote);
378
389
  return obj;
379
390
  }
380
391
  }
@@ -393,7 +404,7 @@ export class DropListener extends Behaviour {
393
404
  * @param fileList Array of dropped files
394
405
  * @param ctx Context information about where the drop occurred
395
406
  */
396
- private async addDroppedFiles(fileList: Array<File>, ctx: DropContext) {
407
+ private async addFromFiles(fileList: Array<File>, ctx: DropContext) {
397
408
  if (debug) console.log("Add files", fileList)
398
409
  if (!Array.isArray(fileList)) return;
399
410
  if (!fileList.length) return;
@@ -427,7 +438,7 @@ export class DropListener extends Behaviour {
427
438
  if (res) {
428
439
  this.dispatchEvent(new CustomEvent(DropListenerEvents.FileDropped, { detail: file }));
429
440
  ctx.file = file;
430
- const obj = this.addObject(res, ctx, false);
441
+ const obj = this.onObjectLoaded(res, ctx, false);
431
442
 
432
443
  // handle uploading the dropped object and networking the event
433
444
  if (obj && this.context.connection.isConnected && this.useNetworking) {
@@ -478,7 +489,7 @@ export class DropListener extends Behaviour {
478
489
  * @param isRemote Whether this object was shared from a remote client
479
490
  * @returns The added object or null if adding failed
480
491
  */
481
- private addObject(data: { model: Model, contentMD5: string }, ctx: DropContext, isRemote: boolean): Object3D | null {
492
+ private onObjectLoaded(data: { model: Model, contentMD5: string }, ctx: DropContext, isRemote: boolean): Object3D | null {
482
493
 
483
494
  const { model, contentMD5 } = data;
484
495
 
@@ -522,9 +533,7 @@ export class DropListener extends Behaviour {
522
533
  }
523
534
  }
524
535
 
525
- AnimationUtils.assignAnimationsFromFile(model, {
526
- createAnimationComponent: obj => addComponent(obj, Animation)
527
- });
536
+ AnimationUtils.autoplayAnimations(model);
528
537
 
529
538
  const evt = new DropListenerAddedEvent({
530
539
  sender: this,
@@ -1,4 +1,4 @@
1
- import { Object3D } from "three";
1
+ import { Object3D, Vector3 } from "three";
2
2
 
3
3
  import { serializable } from "../engine/engine_serialization_decorator.js";
4
4
  import { Behaviour } from "./Component.js";
@@ -23,4 +23,12 @@ export class LookAtConstraint extends Behaviour {
23
23
  */
24
24
  @serializable(Object3D)
25
25
  sources: Object3D[] = [];
26
+
27
+ /**
28
+ * Set the position of the constraint.
29
+ */
30
+ setConstraintPosition(worldPosition: Vector3) {
31
+ const source = this.sources[0];
32
+ if (source) source.worldPosition = worldPosition;
33
+ }
26
34
  }
@@ -649,12 +649,12 @@ export class OrbitControls extends Behaviour implements ICameraController {
649
649
  if (this._lookTargetLerpActive) {
650
650
  this._lookTargetLerp01 += this.context.time.deltaTime / this._lookTargetLerpDuration;
651
651
  if (this._lookTargetLerp01 >= 1) {
652
- this._controls.target.copy(this._lookTargetEndPosition);
652
+ this.lerpLookTarget(this._lookTargetEndPosition, this._lookTargetEndPosition, 1);
653
653
  this._lookTargetLerpActive = false;
654
654
  this.dispatchEvent(new CameraTargetReachedEvent(this, "lookat"));
655
655
  } else {
656
656
  const t = Mathf.easeInOutCubic(this._lookTargetLerp01);
657
- this._controls.target.lerpVectors(this._lookTargetStartPosition, this._lookTargetEndPosition, t);
657
+ this.lerpLookTarget(this._lookTargetStartPosition, this._lookTargetEndPosition, t);
658
658
  }
659
659
  }
660
660
 
@@ -729,7 +729,9 @@ export class OrbitControls extends Behaviour implements ICameraController {
729
729
 
730
730
  // this._controls.zoomToCursor = this.zoomToCursor;
731
731
  if (!this.context.isInXR) {
732
- if (!freeCam && this.lookAtConstraint?.locked) this.setLookTargetFromConstraint(0, this.lookAtConstraint01);
732
+ if (!freeCam && this.lookAtConstraint?.locked && !this._lookTargetLerpActive) {
733
+ this.setLookTargetFromConstraint(0, this.lookAtConstraint01);
734
+ }
733
735
  this._controls.update(this.context.time.deltaTime);
734
736
 
735
737
  if (debug) {
@@ -910,7 +912,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
910
912
  }
911
913
 
912
914
  if (immediateOrDuration === true) {
913
- this._controls.target.copy(this._lookTargetEndPosition);
915
+ this.lerpLookTarget(this._lookTargetEndPosition, this._lookTargetEndPosition, 1);
914
916
  }
915
917
  else {
916
918
  this._lookTargetLerpActive = true;
@@ -941,20 +943,18 @@ export class OrbitControls extends Behaviour implements ICameraController {
941
943
  const target = sources[index];
942
944
  if (target) {
943
945
  target.getWorldPosition(this._lookTargetEndPosition);
944
- this.lerpLookTarget(this._lookTargetEndPosition, t);
946
+ this.lerpLookTarget(this._controls.target, this._lookTargetEndPosition, t);
945
947
  return true;
946
948
  }
947
949
  }
948
950
  return false;
949
951
  }
950
952
 
951
- /** @deprecated use `controls.target.lerp(position, delta)` */
952
- public lerpTarget(position: Vector3, delta: number) { return this.lerpLookTarget(position, delta); }
953
-
954
- private lerpLookTarget(position: Vector3, delta: number) {
953
+ private lerpLookTarget(start: Vector3, position: Vector3, t: number) {
955
954
  if (!this._controls) return;
956
- if (delta >= 1) this._controls.target.copy(position);
957
- else this._controls.target.lerp(position, delta);
955
+ if (t >= 1) this._controls.target.copy(position);
956
+ else this._controls.target.lerpVectors(start, position, t);
957
+ if (this.lookAtConstraint) this.lookAtConstraint.setConstraintPosition(this._controls.target);
958
958
  }
959
959
 
960
960
  private setTargetFromRaycast(ray?: Ray, immediateOrDuration: number | boolean = false): boolean {
@@ -1063,7 +1063,7 @@ export class OrbitControls extends Behaviour implements ICameraController {
1063
1063
  return;
1064
1064
  }
1065
1065
 
1066
- const verticalFov = options.fov || camera.fov;
1066
+ const verticalFov = fov;
1067
1067
  const horizontalFov = 2 * Math.atan(Math.tan(verticalFov * Math.PI / 360 / 2) * camera.aspect) / Math.PI * 360;
1068
1068
  const fitHeightDistance = size.y / (2 * Math.atan(Math.PI * verticalFov / 360));
1069
1069
  const fitWidthDistance = size.x / (2 * Math.atan(Math.PI * horizontalFov / 360));
@@ -1161,16 +1161,19 @@ declare type FitCameraOptions = {
1161
1161
  * The objects to fit the camera to. If not provided the scene children will be used
1162
1162
  */
1163
1163
  objects?: Object3D[] | Object3D;
1164
- /** Fit offset: A factor to multiply the distance to the objects by
1165
- * @default 1.1
1166
- */
1167
- fitOffset?: number,
1168
1164
  /** If true the camera will move immediately to the new position, otherwise it will lerp
1169
1165
  * @default false
1170
1166
  */
1171
1167
  immediate?: boolean,
1168
+
1172
1169
  /** If set to "y" the camera will be centered in the y axis */
1173
1170
  centerCamera?: "none" | "y",
1174
1171
  cameraNearFar?: "keep" | "auto",
1172
+
1175
1173
  fov?: number,
1174
+
1175
+ /** Fit offset: A factor to multiply the distance to the objects by
1176
+ * @default 1.1
1177
+ */
1178
+ fitOffset?: number,
1176
1179
  }
@@ -21,5 +21,5 @@ export interface IUSDExporterExtension {
21
21
  onAfterBuildDocument?(context: USDZExporterContext);
22
22
  onExportObject?(object: Object3D, model: USDObject, context: USDZExporterContext);
23
23
  onAfterSerialize?(context: USDZExporterContext);
24
- onAfterHierarchy?(context: USDZExporterContext, writer: USDWriter);
24
+ onAfterHierarchy?(context: USDZExporterContext, writer: USDWriter) : void | Promise<void>;
25
25
  }
@@ -1082,7 +1082,7 @@ async function parseDocument( context: USDZExporterContext, afterStageRoot: () =
1082
1082
  Progress.end("export-usdz-xforms");
1083
1083
 
1084
1084
  Progress.report("export-usdz", "invoke onAfterHierarchy");
1085
- invokeAll( context, 'onAfterHierarchy', writer );
1085
+ await invokeAll( context, 'onAfterHierarchy', writer );
1086
1086
 
1087
1087
  writer.closeBlock();
1088
1088
  writer.closeBlock();
@@ -1,5 +1,5 @@
1
1
  import { NEEDLE_progressive } from "@needle-tools/gltf-progressive";
2
- import { Euler, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "three";
2
+ import { Euler, EventDispatcher, Matrix4, Mesh, Object3D, Quaternion, Vector3 } from "three";
3
3
 
4
4
  import { isDevEnvironment, showBalloonMessage, showBalloonWarning } from "../../../engine/debug/index.js";
5
5
  import { hasProLicense } from "../../../engine/engine_license.js";
@@ -29,6 +29,7 @@ import { USDZUIExtension } from "./extensions/USDZUI.js";
29
29
  import { USDZExporter as ThreeUSDZExporter } from "./ThreeUSDZExporter.js";
30
30
  import { disableObjectsAtStart, registerAnimatorsImplictly, registerAudioSourcesImplictly } from "./utils/animationutils.js";
31
31
  import { ensureQuicklookLinkIsCreated } from "./utils/quicklook.js";
32
+ import { EventList } from "../../EventList.js";
32
33
 
33
34
  const debug = getParam("debugusdz");
34
35
  const debugUsdzPruning = getParam("debugusdzpruning");
@@ -71,6 +72,9 @@ export class CustomBranding {
71
72
  */
72
73
  export class USDZExporter extends Behaviour {
73
74
 
75
+ static readonly beforeExport = new EventList<{ exporter: USDZExporter }>();
76
+ static readonly afterExport = new EventList<{ exporter: USDZExporter }>();
77
+
74
78
  /**
75
79
  * Assign the object to export as USDZ file. If undefined or null, the whole scene will be exported.
76
80
  */
@@ -210,7 +214,7 @@ export class USDZExporter extends Behaviour {
210
214
  * Creates an USDZ file from the current scene or assigned objectToExport and opens it in QuickLook.
211
215
  * @returns a Promise<Blob> containing the USDZ file
212
216
  */
213
- async exportAndOpen() : Promise<Blob | null> {
217
+ async exportAndOpen(): Promise<Blob | null> {
214
218
 
215
219
  let name = this.exportFileName ?? this.objectToExport?.name ?? this.name;
216
220
  name += "-" + getFormattedDate(); // seems iOS caches the file in some cases, this ensures we always have a fresh file
@@ -221,7 +225,7 @@ export class USDZExporter extends Behaviour {
221
225
  }
222
226
 
223
227
  if (!this.link) this.link = ensureQuicklookLinkIsCreated(this.context, DeviceUtilities.supportsQuickLookAR());
224
-
228
+
225
229
  // ability to specify a custom USDZ file to be used instead of a dynamic one
226
230
  if (this.customUsdzFile) {
227
231
  if (debug) console.log("Exporting custom usdz", this.customUsdzFile)
@@ -234,14 +238,19 @@ export class USDZExporter extends Behaviour {
234
238
  return null;
235
239
  }
236
240
 
237
- const blob = await this.export(this.objectToExport);
241
+ USDZExporter.beforeExport.invoke({ exporter: this });
242
+ const blob = await this.export(this.objectToExport)
243
+ .finally(() => {
244
+ USDZExporter.afterExport.invoke({ exporter: this });
245
+ });
246
+
238
247
  if (!blob) {
239
248
  console.error("USDZ generation failed. Please report a bug", this);
240
249
  return null;
241
250
  }
242
251
 
243
252
  if (debug) console.log("USDZ generation done. Downloading as " + name);
244
-
253
+
245
254
  // TODO Potentially we have to detect QuickLook availability here,
246
255
  // and download the file instead. But browsers keep changing how they deal with non-user-initiated downloads...
247
256
  // https://webkit.org/blog/8421/viewing-augmented-reality-assets-in-safari-for-ios/#:~:text=inside%20the%20anchor.-,Feature%20Detection,-To%20detect%20support
@@ -364,7 +373,7 @@ export class USDZExporter extends Behaviour {
364
373
  if (this.interactive) {
365
374
  defaultExtensions.push(new BehaviorExtension());
366
375
  defaultExtensions.push(new AudioExtension());
367
-
376
+
368
377
  // If physics are enabled, and there are any Rigidbody components in the scene,
369
378
  // add the PhysicsExtension to the default extensions.
370
379
  if (globalThis["NEEDLE_USE_RAPIER"]) {
@@ -632,13 +641,13 @@ export class USDZExporter extends Behaviour {
632
641
  private _rootPositionBeforeExport: Vector3 = new Vector3();
633
642
  private _rootRotationBeforeExport: Quaternion = new Quaternion();
634
643
  private _rootScaleBeforeExport: Vector3 = new Vector3();
635
-
636
- getARScaleAndTarget(): { scale: number, _invertForward: boolean, target: Object3D, sessionRoot: Object3D | null} {
637
- if (!this.objectToExport) return { scale: 1, _invertForward: false, target: this.gameObject, sessionRoot: null};
644
+
645
+ getARScaleAndTarget(): { scale: number, _invertForward: boolean, target: Object3D, sessionRoot: Object3D | null } {
646
+ if (!this.objectToExport) return { scale: 1, _invertForward: false, target: this.gameObject, sessionRoot: null };
638
647
 
639
648
  const xr = GameObject.findObjectOfType(WebXR);
640
649
  let sessionRoot = GameObject.getComponentInParent(this.objectToExport, WebARSessionRoot);
641
- if(!sessionRoot) sessionRoot = GameObject.getComponentInChildren(this.objectToExport, WebARSessionRoot);
650
+ if (!sessionRoot) sessionRoot = GameObject.getComponentInChildren(this.objectToExport, WebARSessionRoot);
642
651
 
643
652
  let arScale = 1;
644
653
  let _invertForward = false;
@@ -653,7 +662,7 @@ export class USDZExporter extends Behaviour {
653
662
  // eslint-disable-next-line deprecation/deprecation
654
663
  _invertForward = sessionRoot.invertForward;
655
664
  }
656
-
665
+
657
666
  const scale = 1 / arScale;
658
667
  const result = { scale, _invertForward, target, sessionRoot: sessionRoot?.gameObject ?? null };
659
668
  return result;
@@ -699,7 +708,7 @@ export class USDZExporter extends Behaviour {
699
708
  private createQuicklookButton() {
700
709
  const buttoncontainer = WebXRButtonFactory.getOrCreate();
701
710
  const button = buttoncontainer.createQuicklookButton();
702
- if(!button.parentNode) this.context.menu.appendChild(button);
711
+ if (!button.parentNode) this.context.menu.appendChild(button);
703
712
  return button;
704
713
  }
705
714
  }