@needle-tools/engine 2.35.4-pre → 2.36.0-pre

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 (142) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/needle-engine.d.ts +213 -144
  3. package/dist/needle-engine.js +414 -358
  4. package/dist/needle-engine.js.map +4 -4
  5. package/dist/needle-engine.min.js +99 -43
  6. package/dist/needle-engine.min.js.map +4 -4
  7. package/lib/engine/api.d.ts +3 -0
  8. package/lib/engine/api.js +3 -0
  9. package/lib/engine/api.js.map +1 -1
  10. package/lib/engine/debug/debug.d.ts +3 -0
  11. package/lib/engine/debug/debug.js +8 -0
  12. package/lib/engine/debug/debug.js.map +1 -0
  13. package/lib/engine/debug/debug_overlay.d.ts +7 -0
  14. package/lib/engine/debug/debug_overlay.js +213 -0
  15. package/lib/engine/debug/debug_overlay.js.map +1 -0
  16. package/lib/engine/engine.js +1 -1
  17. package/lib/engine/engine.js.map +1 -1
  18. package/lib/engine/engine_element_loading.js +1 -1
  19. package/lib/engine/engine_element_loading.js.map +1 -1
  20. package/lib/engine/engine_gameobject.d.ts +1 -0
  21. package/lib/engine/engine_gameobject.js +13 -1
  22. package/lib/engine/engine_gameobject.js.map +1 -1
  23. package/lib/engine/engine_gltf_builtin_components.js +4 -0
  24. package/lib/engine/engine_gltf_builtin_components.js.map +1 -1
  25. package/lib/engine/engine_mainloop_utils.d.ts +1 -1
  26. package/lib/engine/engine_mainloop_utils.js +7 -3
  27. package/lib/engine/engine_mainloop_utils.js.map +1 -1
  28. package/lib/engine/engine_physics.d.ts +29 -28
  29. package/lib/engine/engine_physics.js +85 -86
  30. package/lib/engine/engine_physics.js.map +1 -1
  31. package/lib/engine/engine_serialization_core.js +43 -0
  32. package/lib/engine/engine_serialization_core.js.map +1 -1
  33. package/lib/engine/engine_setup.js +1 -1
  34. package/lib/engine/engine_setup.js.map +1 -1
  35. package/lib/engine/engine_time.d.ts +1 -0
  36. package/lib/engine/engine_time.js +1 -0
  37. package/lib/engine/engine_time.js.map +1 -1
  38. package/lib/engine/engine_types.d.ts +6 -1
  39. package/lib/engine/engine_types.js.map +1 -1
  40. package/lib/engine/engine_typestore.d.ts +1 -0
  41. package/lib/engine/engine_typestore.js +1 -0
  42. package/lib/engine/engine_typestore.js.map +1 -1
  43. package/lib/engine/engine_utils.js +1 -1
  44. package/lib/engine/engine_utils.js.map +1 -1
  45. package/lib/engine/extensions/NEEDLE_animator_controller_model.js.map +1 -1
  46. package/lib/engine/extensions/NEEDLE_render_objects.d.ts +2 -2
  47. package/lib/engine/extensions/NEEDLE_render_objects.js +2 -2
  48. package/lib/engine/extensions/NEEDLE_render_objects.js.map +1 -1
  49. package/lib/engine/extensions/NEEDLE_techniques_webgl.js +5 -0
  50. package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
  51. package/lib/engine-components/Animation.d.ts +5 -1
  52. package/lib/engine-components/Animation.js +21 -0
  53. package/lib/engine-components/Animation.js.map +1 -1
  54. package/lib/engine-components/AnimatorController.d.ts +1 -0
  55. package/lib/engine-components/AnimatorController.js +14 -7
  56. package/lib/engine-components/AnimatorController.js.map +1 -1
  57. package/lib/engine-components/AudioSource.d.ts +1 -1
  58. package/lib/engine-components/AudioSource.js +2 -2
  59. package/lib/engine-components/AudioSource.js.map +1 -1
  60. package/lib/engine-components/BoxHelperComponent.d.ts +2 -2
  61. package/lib/engine-components/BoxHelperComponent.js +27 -9
  62. package/lib/engine-components/BoxHelperComponent.js.map +1 -1
  63. package/lib/engine-components/Component.d.ts +2 -1
  64. package/lib/engine-components/Component.js +11 -5
  65. package/lib/engine-components/Component.js.map +1 -1
  66. package/lib/engine-components/GroundProjection.d.ts +2 -0
  67. package/lib/engine-components/GroundProjection.js +18 -6
  68. package/lib/engine-components/GroundProjection.js.map +1 -1
  69. package/lib/engine-components/ReflectionProbe.d.ts +22 -0
  70. package/lib/engine-components/ReflectionProbe.js +134 -0
  71. package/lib/engine-components/ReflectionProbe.js.map +1 -0
  72. package/lib/engine-components/Renderer.d.ts +16 -4
  73. package/lib/engine-components/Renderer.js +96 -45
  74. package/lib/engine-components/Renderer.js.map +1 -1
  75. package/lib/engine-components/WebARSessionRoot.d.ts +7 -7
  76. package/lib/engine-components/WebARSessionRoot.js +7 -7
  77. package/lib/engine-components/WebARSessionRoot.js.map +1 -1
  78. package/lib/engine-components/WebXR.d.ts +9 -8
  79. package/lib/engine-components/WebXR.js +40 -24
  80. package/lib/engine-components/WebXR.js.map +1 -1
  81. package/lib/engine-components/WebXRAvatar.d.ts +4 -5
  82. package/lib/engine-components/WebXRAvatar.js +9 -8
  83. package/lib/engine-components/WebXRAvatar.js.map +1 -1
  84. package/lib/engine-components/WebXRController.d.ts +21 -21
  85. package/lib/engine-components/WebXRController.js +83 -63
  86. package/lib/engine-components/WebXRController.js.map +1 -1
  87. package/lib/engine-components/WebXRGrabRendering.d.ts +3 -3
  88. package/lib/engine-components/WebXRGrabRendering.js +2 -2
  89. package/lib/engine-components/WebXRGrabRendering.js.map +1 -1
  90. package/lib/engine-components/WebXRSync.d.ts +8 -8
  91. package/lib/engine-components/WebXRSync.js +15 -15
  92. package/lib/engine-components/WebXRSync.js.map +1 -1
  93. package/lib/engine-components/codegen/components.d.ts +1 -0
  94. package/lib/engine-components/codegen/components.js +1 -0
  95. package/lib/engine-components/codegen/components.js.map +1 -1
  96. package/lib/engine-components/js-extensions/ExtensionUtils.js +1 -1
  97. package/lib/engine-components/js-extensions/ExtensionUtils.js.map +1 -1
  98. package/lib/engine-components/ui/EventSystem.d.ts +1 -0
  99. package/lib/engine-components/ui/EventSystem.js +21 -1
  100. package/lib/engine-components/ui/EventSystem.js.map +1 -1
  101. package/package.json +1 -1
  102. package/src/engine/api.ts +3 -0
  103. package/src/engine/codegen/register_types.js +293 -0
  104. package/src/engine/debug/debug.ts +9 -0
  105. package/src/engine/debug/debug_overlay.ts +224 -0
  106. package/src/engine/engine.ts +1 -1
  107. package/src/engine/engine_element_loading.ts +1 -1
  108. package/src/engine/engine_gameobject.ts +17 -4
  109. package/src/engine/engine_gltf_builtin_components.ts +5 -1
  110. package/src/engine/engine_mainloop_utils.ts +7 -3
  111. package/src/engine/engine_physics.ts +130 -130
  112. package/src/engine/engine_serialization_core.ts +41 -0
  113. package/src/engine/engine_setup.ts +1 -1
  114. package/src/engine/engine_time.ts +2 -0
  115. package/src/engine/engine_types.ts +7 -1
  116. package/src/engine/engine_typestore.ts +2 -0
  117. package/src/engine/engine_utils.ts +3 -2
  118. package/src/engine/extensions/EXT_texture_exr.js +1 -1
  119. package/src/engine/extensions/NEEDLE_animator_controller_model.ts +2 -1
  120. package/src/engine/extensions/NEEDLE_render_objects.ts +4 -4
  121. package/src/engine/extensions/NEEDLE_techniques_webgl.ts +7 -0
  122. package/src/engine-components/Animation.ts +16 -1
  123. package/src/engine-components/AnimatorController.ts +19 -9
  124. package/src/engine-components/AudioSource.ts +3 -3
  125. package/src/engine-components/BoxHelperComponent.ts +29 -9
  126. package/src/engine-components/Component.ts +11 -5
  127. package/src/engine-components/GroundProjection.ts +22 -7
  128. package/src/engine-components/ReflectionProbe.ts +141 -0
  129. package/src/engine-components/Renderer.ts +116 -54
  130. package/src/engine-components/WebARSessionRoot.ts +16 -16
  131. package/src/engine-components/WebXR.ts +53 -48
  132. package/src/engine-components/WebXRAvatar.ts +16 -16
  133. package/src/engine-components/WebXRController.ts +133 -107
  134. package/src/engine-components/WebXRGrabRendering.ts +6 -6
  135. package/src/engine-components/WebXRSync.ts +20 -20
  136. package/src/engine-components/codegen/components.ts +1 -0
  137. package/src/engine-components/js-extensions/ExtensionUtils.ts +1 -1
  138. package/src/engine-components/ui/EventSystem.ts +26 -3
  139. package/lib/engine/debug/error_overlay.d.ts +0 -1
  140. package/lib/engine/debug/error_overlay.js +0 -114
  141. package/lib/engine/debug/error_overlay.js.map +0 -1
  142. package/src/engine/debug/error_overlay.ts +0 -126
@@ -5,11 +5,12 @@ import { RendererLightmap } from "./RendererLightmap";
5
5
  import { Context } from "../engine/engine_setup";
6
6
  import { getParam } from "../engine/engine_utils";
7
7
  import { serializeable } from "../engine/engine_serialization_decorator";
8
- import { Material, Mesh, Texture, Vector4 } from "three";
8
+ import { AxesHelper, Material, Mesh, Object3D, Texture, Vector4 } from "three";
9
9
  import { NEEDLE_render_objects } from "../engine/extensions/NEEDLE_render_objects";
10
10
  import { NEEDLE_deferred_texture } from "../engine/extensions/NEEDLE_deferred_texture";
11
11
  import { NEED_UPDATE_INSTANCE_KEY } from "../engine/engine_instancing";
12
- import { IRenderer } from "../engine/engine_types";
12
+ import { IRenderer, ISharedMaterials } from "../engine/engine_types";
13
+ import { debug, ReflectionProbe } from "./ReflectionProbe";
13
14
 
14
15
  // for staying compatible with old code
15
16
  export { InstancingUtil } from "../engine/engine_instancing";
@@ -20,6 +21,15 @@ const debugInstancing = getParam("debuginstancing");
20
21
  const debugProgressiveLoading = getParam("debugprogressive");
21
22
  const suppressProgressiveLoading = getParam("noprogressive");
22
23
 
24
+
25
+ export enum ReflectionProbeUsage {
26
+ Off = 0,
27
+ BlendProbes = 1,
28
+ BlendProbesAndSkybox = 2,
29
+ Simple = 3,
30
+ }
31
+
32
+
23
33
  export class FieldWithDefault {
24
34
  public path: string | null = null;
25
35
  public asset: object | null = null;
@@ -34,11 +44,14 @@ export enum RenderState {
34
44
 
35
45
 
36
46
  // support sharedMaterials[index] assigning materials directly to the objects
37
- class SharedMaterialArray {
47
+ class SharedMaterialArray implements ISharedMaterials {
48
+
49
+ [num: number]: THREE.Material;
38
50
 
39
51
  private _renderer: Renderer;
40
52
  private _targets: THREE.Object3D[] = [];
41
53
 
54
+
42
55
  is(renderer: Renderer) {
43
56
  return this._renderer === renderer;
44
57
  }
@@ -88,7 +101,7 @@ class SharedMaterialArray {
88
101
  private setMaterial(mat: Material, index: number) {
89
102
  if (index < 0 || index >= this._targets.length) return;
90
103
  const target = this._targets[index];
91
- if (!target) return;
104
+ if (!target || target["material"] === undefined) return;
92
105
  target["material"] = mat;
93
106
  }
94
107
 
@@ -120,6 +133,11 @@ export class Renderer extends Behaviour implements IRenderer {
120
133
  @serializeable()
121
134
  allowOcclusionWhenDynamic: boolean = true;
122
135
 
136
+ @serializeable(Object3D)
137
+ probeAnchor?: Object3D;
138
+ @serializeable()
139
+ reflectionProbeUsage: ReflectionProbeUsage = ReflectionProbeUsage.Off;
140
+
123
141
  // custom shader
124
142
  // get materialProperties(): Array<MaterialProperties> | undefined {
125
143
  // return this._materialProperties;
@@ -200,6 +218,10 @@ export class Renderer extends Behaviour implements IRenderer {
200
218
  awake() {
201
219
  this.clearInstancingState();
202
220
 
221
+ if(this.probeAnchor && debug) this.probeAnchor.add(new AxesHelper(.2));
222
+
223
+ this._reflectionProbe = null;
224
+
203
225
  const type = this.gameObject.type;
204
226
  if (type === "Group") {
205
227
  for (const child of this.gameObject.children) {
@@ -344,6 +366,8 @@ export class Renderer extends Behaviour implements IRenderer {
344
366
  this.gameObject.visible = true;
345
367
  this.applyStencil();
346
368
  }
369
+
370
+ this.updateReflectionProbe();
347
371
  }
348
372
 
349
373
  onDisable() {
@@ -368,60 +392,15 @@ export class Renderer extends Behaviour implements IRenderer {
368
392
  NEEDLE_render_objects.applyStencil(this);
369
393
  }
370
394
 
371
- onBeforeRenderThree(_renderer, _scene, _camera, _geometry, material, _group) {
372
-
373
- // progressive load before rendering so we only load textures for visible materials
374
- if (!suppressProgressiveLoading && material._didRequestTextureLOD === undefined) {
375
- material._didRequestTextureLOD = 0;
376
- if (debugProgressiveLoading) {
377
- console.log("Load material LOD (with delay)", material.name);
378
- setTimeout(() => {
379
- NEEDLE_deferred_texture.assignTextureLOD(this.context, this.sourceId, material);
380
- }, 2000);
381
- }
382
- else {
383
- NEEDLE_deferred_texture.assignTextureLOD(this.context, this.sourceId, material);
384
- }
385
- }
386
-
387
- if (material.envMapIntensity !== undefined) {
388
- const factor = this.hasLightmap ? Math.PI : 1;
389
- material.envMapIntensity = Math.max(0, this.context.rendererData.environmentIntensity / factor);
390
- }
391
-
392
- // if (!camera) {
393
- // let isXRCamera = false;
394
- // if (this.context.isInXR) {
395
- // // @ts-ignore
396
- // const arr = this.context.renderer.xr.getCamera() as ArrayCamera;
397
- // if (arr.cameras?.length > 0) {
398
- // camera = arr;
399
- // isXRCamera = true;
400
- // }
401
- // }
402
- // }
403
-
404
- // if (this.customShaderHandler) {
405
- // this.customShaderHandler.onBeforeRender(renderer, scene, camera, geometry, material, group);
406
- // }
407
- // else if (this.rawShaderHandler) {
408
- // for (const h of this.rawShaderHandler) {
409
- // h.onBeforeRender(this.gameObject, camera);
410
- // }
411
- // }
412
-
413
- if (this._lightmaps) {
414
- for (const lm of this._lightmaps) {
415
- lm.onBeforeRenderThree(material);
416
- }
417
- }
418
- }
395
+ static envmap: THREE.Texture | null = null;
419
396
 
420
397
  onBeforeRender() {
421
398
  if (!this.gameObject) {
422
399
  return;
423
400
  }
424
401
 
402
+ Renderer.envmap = this.scene.environment;
403
+
425
404
  const needsUpdate: boolean = this.gameObject[NEED_UPDATE_INSTANCE_KEY] === true || this.gameObject.matrixWorldNeedsUpdate;
426
405
 
427
406
  if (this.gameObject.type === "Group" && this.gameObject.children?.length > 0) {
@@ -464,6 +443,73 @@ export class Renderer extends Behaviour implements IRenderer {
464
443
  handle.object.layers.disableAll();
465
444
  }
466
445
  }
446
+
447
+ if (this.reflectionProbeUsage !== ReflectionProbeUsage.Off && this._reflectionProbe) {
448
+ this._reflectionProbe.onSet(this);
449
+ }
450
+
451
+ }
452
+
453
+ onBeforeRenderThree(_renderer, _scene, _camera, _geometry, material, _group) {
454
+
455
+ // progressive load before rendering so we only load textures for visible materials
456
+ if (!suppressProgressiveLoading && material._didRequestTextureLOD === undefined) {
457
+ material._didRequestTextureLOD = 0;
458
+ if (debugProgressiveLoading) {
459
+ console.log("Load material LOD (with delay)", material.name);
460
+ setTimeout(() => {
461
+ NEEDLE_deferred_texture.assignTextureLOD(this.context, this.sourceId, material);
462
+ }, 2000);
463
+ }
464
+ else {
465
+ NEEDLE_deferred_texture.assignTextureLOD(this.context, this.sourceId, material);
466
+ }
467
+ }
468
+
469
+ if (material.envMapIntensity !== undefined) {
470
+ const factor = this.hasLightmap ? Math.PI : 1;
471
+ material.envMapIntensity = Math.max(0, this.context.rendererData.environmentIntensity / factor);
472
+ }
473
+ // if (this._reflectionProbe?.texture) {
474
+ // material.envMap = this._reflectionProbe.texture;
475
+ // // this.context.renderer.prop
476
+ // // console.log(material.name);
477
+ // // this.context.renderer.properties.get(material);
478
+ // // this.context.renderer.properties.update(material, "environment", this._reflectionProbe.texture);
479
+ // }
480
+
481
+ // _scene.environment = null;
482
+ // else _scene.environment = Renderer.envmap;
483
+ // if (!material.envmap)
484
+ // material.envMap = Renderer.envmap;
485
+ // material.needsUpdate = true;
486
+
487
+ // if (!camera) {
488
+ // let isXRCamera = false;
489
+ // if (this.context.isInXR) {
490
+ // // @ts-ignore
491
+ // const arr = this.context.renderer.xr.getCamera() as ArrayCamera;
492
+ // if (arr.cameras?.length > 0) {
493
+ // camera = arr;
494
+ // isXRCamera = true;
495
+ // }
496
+ // }
497
+ // }
498
+
499
+ // if (this.customShaderHandler) {
500
+ // this.customShaderHandler.onBeforeRender(renderer, scene, camera, geometry, material, group);
501
+ // }
502
+ // else if (this.rawShaderHandler) {
503
+ // for (const h of this.rawShaderHandler) {
504
+ // h.onBeforeRender(this.gameObject, camera);
505
+ // }
506
+ // }
507
+
508
+ if (this._lightmaps) {
509
+ for (const lm of this._lightmaps) {
510
+ lm.onBeforeRenderThree(material);
511
+ }
512
+ }
467
513
  }
468
514
 
469
515
  onAfterRender() {
@@ -473,6 +519,10 @@ export class Renderer extends Behaviour implements IRenderer {
473
519
  handle.object.layers.mask = this.prevLayers[i];
474
520
  }
475
521
  }
522
+
523
+ if (this.reflectionProbeUsage !== ReflectionProbeUsage.Off && this._reflectionProbe) {
524
+ this._reflectionProbe.onUnset(this)
525
+ }
476
526
  }
477
527
 
478
528
  private applySettings(go: THREE.Object3D) {
@@ -483,6 +533,18 @@ export class Renderer extends Behaviour implements IRenderer {
483
533
  else go.castShadow = false;
484
534
  }
485
535
 
536
+ private _reflectionProbe: ReflectionProbe | null = null;
537
+ private updateReflectionProbe() {
538
+ // handle reflection probe
539
+ this._reflectionProbe = null;
540
+ if (this.reflectionProbeUsage !== ReflectionProbeUsage.Off) {
541
+ // if(this.gameObject.name.includes("Tank_Case_Jewlery") === false) return;
542
+ const obj = this.probeAnchor || this.gameObject;
543
+ const isAnchor = this.probeAnchor ? true : false;
544
+ this._reflectionProbe = ReflectionProbe.get(obj, this.context, isAnchor);
545
+ }
546
+ }
547
+
486
548
  }
487
549
 
488
550
  export class MeshRenderer extends Renderer {
@@ -637,7 +699,7 @@ class InstancedMeshRenderer {
637
699
  this.material = material;
638
700
  this.context = context;
639
701
  this.maxCount = count;
640
- if(debugInstancing){
702
+ if (debugInstancing) {
641
703
  material = new THREE.MeshBasicMaterial({ color: this.randomColor() });
642
704
  }
643
705
  this.inst = new THREE.InstancedMesh(geo, material, count);
@@ -655,7 +717,7 @@ class InstancedMeshRenderer {
655
717
  // }, 500);
656
718
  }
657
719
 
658
- private randomColor(){
720
+ private randomColor() {
659
721
  return new THREE.Color(Math.random(), Math.random(), Math.random());
660
722
  }
661
723
 
@@ -1,17 +1,17 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
- import * as THREE from 'three'
2
+ import { XRSession } from 'three'
3
3
  import { Matrix4, Object3D, XRPose } from "three";
4
4
  import { WebAR, WebXR } from "./WebXR";
5
5
  import { InstancingUtil } from "../engine/engine_instancing";
6
6
  import { serializeable } from "../engine/engine_serialization_decorator";
7
7
 
8
- // https://github.com/takahirox/takahirox.github.io/blob/master/three.js.mmdeditor/examples/js/controls/DeviceOrientationControls.js
8
+ // https://github.com/takahirox/takahirox.github.io/blob/master/js.mmdeditor/examples/js/controls/DeviceOrientationControls.js
9
9
 
10
10
  export class WebARSessionRoot extends Behaviour {
11
11
 
12
12
  webAR: WebAR | null = null;
13
13
 
14
- get rig(): THREE.Object3D | undefined {
14
+ get rig(): Object3D | undefined {
15
15
  return this.webAR?.webxr.Rig;
16
16
  }
17
17
 
@@ -28,7 +28,7 @@ export class WebARSessionRoot extends Behaviour {
28
28
  this.setScale(val);
29
29
  }
30
30
 
31
- private readonly _initalMatrix = new THREE.Matrix4();
31
+ private readonly _initalMatrix = new Matrix4();
32
32
  private readonly _selectStartFn = this.onSelectStart.bind(this);
33
33
  private readonly _selectEndFn = this.onSelectEnd.bind(this);
34
34
 
@@ -41,13 +41,13 @@ export class WebARSessionRoot extends Behaviour {
41
41
  }
42
42
 
43
43
  private _arScale: number = 5;
44
- private _rig: THREE.Object3D | null = null;
45
- private _startPose: THREE.Matrix4 | null = null;
46
- private _placementPose: THREE.Matrix4 | null = null;
44
+ private _rig: Object3D | null = null;
45
+ private _startPose: Matrix4 | null = null;
46
+ private _placementPose: Matrix4 | null = null;
47
47
  private _isTouching: boolean = false;
48
- private _rigStartPose: THREE.Matrix4 | undefined | null = null;
48
+ private _rigStartPose: Matrix4 | undefined | null = null;
49
49
 
50
- onBegin(session: THREE.XRSession) {
50
+ onBegin(session: XRSession) {
51
51
  this._placementPose = null;
52
52
  this.gameObject.visible = false;
53
53
  this.gameObject.matrixAutoUpdate = false;
@@ -69,12 +69,12 @@ export class WebARSessionRoot extends Behaviour {
69
69
  }
70
70
  }
71
71
 
72
- onUpdate(rig: THREE.Object3D | null, _session: THREE.XRSession, pose: XRPose | null | undefined): boolean {
72
+ onUpdate(rig: Object3D | null, _session: XRSession, pose: XRPose | null | undefined): boolean {
73
73
 
74
74
  if (pose && !this._placementPose) {
75
75
  if (this._isTouching) {
76
76
  if (this.webAR) this.webAR.setReticleActive(false);
77
- this.placeAt(rig, new THREE.Matrix4().fromArray(pose.transform.matrix).invert());
77
+ this.placeAt(rig, new Matrix4().fromArray(pose.transform.matrix).invert());
78
78
  return true;
79
79
  }
80
80
  }
@@ -90,13 +90,13 @@ export class WebARSessionRoot extends Behaviour {
90
90
  // }
91
91
  }
92
92
 
93
- placeAt(rig: THREE.Object3D | null, mat: Matrix4) {
94
- if (!this._placementPose) this._placementPose = new THREE.Matrix4();
93
+ placeAt(rig: Object3D | null, mat: Matrix4) {
94
+ if (!this._placementPose) this._placementPose = new Matrix4();
95
95
  this._placementPose.copy(mat);
96
96
  if (rig) {
97
97
 
98
98
  if (this.invertForward) {
99
- const rot = new THREE.Matrix4().makeRotationY(Math.PI);
99
+ const rot = new Matrix4().makeRotationY(Math.PI);
100
100
  this._placementPose.premultiply(rot);
101
101
  }
102
102
  this._rig = rig;
@@ -111,7 +111,7 @@ export class WebARSessionRoot extends Behaviour {
111
111
  this.gameObject.visible = true;
112
112
  }
113
113
 
114
- onEnd(rig: THREE.Object3D | null, _session: THREE.XRSession) {
114
+ onEnd(rig: Object3D | null, _session: XRSession) {
115
115
  this._placementPose = null;
116
116
  this.gameObject.visible = false;
117
117
  this.gameObject.matrixAutoUpdate = false;
@@ -151,7 +151,7 @@ export class WebARSessionRoot extends Behaviour {
151
151
  this._rigStartPose = rig.matrix.clone();
152
152
  }
153
153
  rig.matrixAutoUpdate = false;
154
- rig.matrix.multiplyMatrices(new THREE.Matrix4().makeScale(scale, scale, scale), this._placementPose);
154
+ rig.matrix.multiplyMatrices(new Matrix4().makeScale(scale, scale, scale), this._placementPose);
155
155
  rig.matrix.decompose(rig.position, rig.quaternion, rig.scale);
156
156
  rig.updateMatrixWorld();
157
157
  console.log("Place", rig.position);
@@ -1,23 +1,21 @@
1
- import { Behaviour, GameObject } from "./Component";
2
-
1
+ import { ArrayCamera, Color, Euler, EventDispatcher, Group, Matrix4, Mesh, MeshBasicMaterial, Object3D, Quaternion, RingGeometry, Texture, Vector3, XRFrame, XRHitTestSource, XRRigidTransform, XRSession, XRViewerPose } from 'three';
3
2
  import { ARButton } from '../include/three/ARButton.js';
4
3
  import { VRButton } from '../include/three/VRButton.js';
5
4
 
6
- import * as THREE from 'three'
7
- import { ArrayCamera, Matrix4, Vector3, XRHitTestSource } from 'three';
5
+ import { AssetReference } from "../engine/engine_addressables";
6
+ import { serializeable } from "../engine/engine_serialization_decorator";
7
+ import { XRSessionMode } from "../engine/engine_setup";
8
+ import { getWorldPosition, getWorldQuaternion, setWorldPosition, setWorldQuaternion } from "../engine/engine_three_utils";
9
+ import { INeedleEngineComponent } from "../engine/engine_types";
10
+ import { getParam, setOrAddParamsToUrl } from "../engine/engine_utils";
8
11
 
9
- import * as utils from "../engine/engine_utils";
12
+ import { Behaviour, GameObject } from "./Component";
10
13
  import { noVoip } from "./Voip";
11
- import { XRFlag, XRState, XRStateFlag } from "./XRFlag";
12
- import { ControllerType, WebXRController } from "./WebXRController";
13
14
  import { WebARSessionRoot } from "./WebARSessionRoot";
14
- import { getWorldPosition, getWorldQuaternion, setWorldPosition, setWorldQuaternion } from "../engine/engine_three_utils";
15
+ import { ControllerType, WebXRController } from "./WebXRController";
15
16
  import { XRRig } from "./WebXRRig";
16
- import { AssetReference } from "../engine/engine_addressables";
17
- import { serializeable } from "../engine/engine_serialization_decorator";
18
17
  import { WebXRSync } from "./WebXRSync";
19
- import { XRSessionMode } from "../engine/engine_setup";
20
- import { INeedleEngineComponent } from "../engine/engine_types";
18
+ import { XRFlag, XRState, XRStateFlag } from "./XRFlag";
21
19
 
22
20
 
23
21
  export async function detectARSupport() {
@@ -38,7 +36,6 @@ let vrSupported = false;
38
36
  detectARSupport().then(res => arSupported = res);
39
37
  detectVRSupport().then(res => vrSupported = res);
40
38
 
41
-
42
39
  // import TeleportVR from "teleportvr";
43
40
 
44
41
  export enum WebXREvent {
@@ -54,16 +51,23 @@ export declare type CreateButtonOptions = {
54
51
 
55
52
  export class WebXR extends Behaviour {
56
53
 
54
+ @serializeable()
57
55
  enableVR = true;
56
+ @serializeable()
58
57
  enableAR = true;
58
+
59
59
  @serializeable(AssetReference)
60
60
  defaultAvatar?: AssetReference;
61
+ @serializeable()
62
+ handModelPath: string = "";
61
63
 
64
+ @serializeable()
62
65
  createVRButton: boolean = true;
66
+ @serializeable()
63
67
  createARButton: boolean = true;
64
68
 
65
69
  private static _isInXr: boolean = false;
66
- private static events: THREE.EventDispatcher = new THREE.EventDispatcher();
70
+ private static events: EventDispatcher = new EventDispatcher();
67
71
 
68
72
  public static get IsInWebXR(): boolean { return this._isInXr; }
69
73
  public static get XRSupported(): boolean { return 'xr' in navigator && (arSupported || vrSupported); }
@@ -121,7 +125,7 @@ export class WebXR extends Behaviour {
121
125
  if (session) session.end();
122
126
  }
123
127
 
124
- public get Rig(): THREE.Object3D {
128
+ public get Rig(): Object3D {
125
129
  if(!this.rig) this.ensureRig();
126
130
  return this.rig;
127
131
  }
@@ -154,7 +158,7 @@ export class WebXR extends Behaviour {
154
158
  public get IsInVR() { return this._isInVR; }
155
159
  public get IsInAR() { return this._isInAR; }
156
160
 
157
- private rig!: THREE.Object3D;
161
+ private rig!: Object3D;
158
162
  private isInit: boolean = false;
159
163
 
160
164
  private _requestedAR: boolean = false;
@@ -221,11 +225,11 @@ export class WebXR extends Behaviour {
221
225
  }, 1000);
222
226
  }
223
227
 
224
- private _transformOrientation: THREE.Quaternion = new THREE.Quaternion();
225
- public get TransformOrientation(): THREE.Quaternion { return this._transformOrientation; }
228
+ private _transformOrientation: Quaternion = new Quaternion();
229
+ public get TransformOrientation(): Quaternion { return this._transformOrientation; }
226
230
 
227
- private _currentHeadPose: THREE.XRViewerPose | null = null;
228
- public get HeadPose(): THREE.XRViewerPose | null { return this._currentHeadPose; }
231
+ private _currentHeadPose: XRViewerPose | null = null;
232
+ public get HeadPose(): XRViewerPose | null { return this._currentHeadPose; }
229
233
 
230
234
  onBeforeRender(frame) {
231
235
  if (!frame) return;
@@ -237,7 +241,7 @@ export class WebXR extends Behaviour {
237
241
  const pose = frame.getViewerPose(this.context.renderer.xr.getReferenceSpace());
238
242
  this._currentHeadPose = pose;
239
243
  if (!pose) return; // e.g. if user is not wearing headset
240
- const transform: THREE.XRRigidTransform = pose?.transform;
244
+ const transform: XRRigidTransform = pose?.transform;
241
245
 
242
246
  if (transform) {
243
247
  this._transformOrientation.set(transform.orientation.x, transform.orientation.y, transform.orientation.z, transform.orientation.w);
@@ -312,7 +316,7 @@ export class WebXR extends Behaviour {
312
316
  // this.rig.quaternion.premultiply(existing.worldQuaternion);
313
317
  }
314
318
  else {
315
- this.rig = new THREE.Group();
319
+ this.rig = new Group();
316
320
  this.rig.rotateY(Math.PI);
317
321
  this.rig.name = "XRRig";
318
322
  this.context.scene.add(this.rig);
@@ -321,11 +325,11 @@ export class WebXR extends Behaviour {
321
325
  }
322
326
 
323
327
 
324
- private _originalCameraParent: THREE.Object3D | null = null;
325
- private _originalCameraPosition: THREE.Vector3 = new THREE.Vector3();
326
- private _originalCameraRotation: THREE.Quaternion = new THREE.Quaternion();
328
+ private _originalCameraParent: Object3D | null = null;
329
+ private _originalCameraPosition: Vector3 = new Vector3();
330
+ private _originalCameraRotation: Quaternion = new Quaternion();
327
331
 
328
- private onEnterXR(session: THREE.XRSession, frame: THREE.XRFrame) {
332
+ private onEnterXR(session: XRSession, frame: XRFrame) {
329
333
  console.log("[XR] session begin", session);
330
334
  WebXR._isInXr = true;
331
335
 
@@ -336,8 +340,8 @@ export class WebXR extends Behaviour {
336
340
  const pose = frame.getViewerPose(space);
337
341
  const rot = pose?.transform.orientation;
338
342
  if (rot) {
339
- const quat = new THREE.Quaternion(rot.x, rot.y, rot.z, rot.w);
340
- const eu = new THREE.Euler().setFromQuaternion(quat);
343
+ const quat = new Quaternion(rot.x, rot.y, rot.z, rot.w);
344
+ const eu = new Euler().setFromQuaternion(quat);
341
345
  this.rig.rotateY(eu.y);
342
346
  // this.rig.quaternion.multiply(quat);
343
347
  }
@@ -383,7 +387,7 @@ export class WebXR extends Behaviour {
383
387
  WebXR.events.dispatchEvent({ type: WebXREvent.XRStarted, session: session });
384
388
  }
385
389
 
386
- private onExitXR(session: THREE.XRSession | null) {
390
+ private onExitXR(session: XRSession | null) {
387
391
 
388
392
  if (this._isInAR && session) {
389
393
  this.webAR?.onEnd(session);
@@ -413,7 +417,7 @@ export class WebXR extends Behaviour {
413
417
  WebXR.events.dispatchEvent({ type: WebXREvent.XRStopped, session: session });
414
418
  }
415
419
 
416
- private onEnterVR(_session: THREE.XRSession) {
420
+ private onEnterVR(_session: XRSession) {
417
421
  }
418
422
 
419
423
  private destroyControllers() {
@@ -425,13 +429,13 @@ export class WebXR extends Behaviour {
425
429
 
426
430
  private xrMirrorWindow: Window | null = null;
427
431
 
428
- private onEnterXR_HandleMirrorWindow(session: THREE.XRSession) {
429
- if (!utils.getParam("mirror")) return;
432
+ private onEnterXR_HandleMirrorWindow(session: XRSession) {
433
+ if (!getParam("mirror")) return;
430
434
  setTimeout(() => {
431
435
  if (!WebXR.IsInWebXR) return;
432
436
  const url = new URL(window.location.href);
433
- utils.setOrAddParamsToUrl(url.searchParams, noVoip, 1);
434
- utils.setOrAddParamsToUrl(url.searchParams, "isMirror", 1);
437
+ setOrAddParamsToUrl(url.searchParams, noVoip, 1);
438
+ setOrAddParamsToUrl(url.searchParams, "isMirror", 1);
435
439
  const str = url.toString();
436
440
  this.xrMirrorWindow = window.open(str, "webxr sync", "popup=yes");
437
441
  if (this.xrMirrorWindow) {
@@ -456,20 +460,20 @@ export class WebAR {
456
460
 
457
461
  private _webxr: WebXR;
458
462
 
459
- private reticle: THREE.Object3D | null = null;
463
+ private reticle: Object3D | null = null;
460
464
  private hitTestSource: XRHitTestSource | null = null;
461
465
  private reticleActive: boolean = true;
462
466
 
463
467
  // scene.background before entering AR
464
- private previousBackground: THREE.Color | null | THREE.Texture = null;
465
- private previousEnvironment: THREE.Texture | null = null;
468
+ private previousBackground: Color | null | Texture = null;
469
+ private previousEnvironment: Texture | null = null;
466
470
 
467
471
  private sessionRoot: WebARSessionRoot | null = null;
468
- private _previousParent: THREE.Object3D | null = null;
472
+ private _previousParent: Object3D | null = null;
469
473
  // we need this in case the session root is on the same object as the webxr component
470
474
  // so if we disable the session root we attach the webxr component to this temporary object
471
475
  // to still receive updates
472
- private static tempWebXRObject: THREE.Object3D;
476
+ private static tempWebXRObject: Object3D;
473
477
 
474
478
  private get context() { return this.webxr.context; }
475
479
 
@@ -496,13 +500,14 @@ export class WebAR {
496
500
  this.reticleActive = active;
497
501
  }
498
502
 
499
- async onBegin(session: THREE.XRSession) {
503
+ async onBegin(session: XRSession) {
500
504
  const context = this.webxr.context;
501
505
  this.reticleActive = true;
502
506
  this.didPlaceARSessionRoot = false;
503
507
 
504
508
  const deviceType = navigator.userAgent?.includes("OculusBrowser") ? ControllerType.PhysicalDevice : ControllerType.Touch;
505
- for (let i = 0; i < 4; i++) {
509
+ const controllerCount = deviceType === ControllerType.Touch ? 4 : 2;
510
+ for (let i = 0; i < controllerCount; i++) {
506
511
  WebXRController.Create(this.webxr, i, this.webxr.gameObject as GameObject, deviceType)
507
512
  }
508
513
 
@@ -523,9 +528,9 @@ export class WebAR {
523
528
  });
524
529
 
525
530
  if (!this.reticle && this.sessionRoot) {
526
- this.reticle = new THREE.Mesh(
527
- new THREE.RingGeometry(0.07, 0.09, 32).rotateX(- Math.PI / 2),
528
- new THREE.MeshBasicMaterial()
531
+ this.reticle = new Mesh(
532
+ new RingGeometry(0.07, 0.09, 32).rotateX(- Math.PI / 2),
533
+ new MeshBasicMaterial()
529
534
  );
530
535
  this.reticle.name = "AR Placement reticle";
531
536
  this.reticle.matrixAutoUpdate = false;
@@ -538,7 +543,7 @@ export class WebAR {
538
543
  }
539
544
 
540
545
  this._previousParent = this.webxr.gameObject;
541
- if (!WebAR.tempWebXRObject) WebAR.tempWebXRObject = new THREE.Object3D();
546
+ if (!WebAR.tempWebXRObject) WebAR.tempWebXRObject = new Object3D();
542
547
  this.context.scene.add(WebAR.tempWebXRObject);
543
548
  GameObject.addComponent(WebAR.tempWebXRObject as GameObject, this.webxr);
544
549
 
@@ -556,7 +561,7 @@ export class WebAR {
556
561
  this.context.mainCameraComponent?.applyClearFlagsIfIsActiveCamera();
557
562
  }
558
563
 
559
- onEnd(session: THREE.XRSession) {
564
+ onEnd(session: XRSession) {
560
565
  if (this._previousParent) {
561
566
  console.log("ADD", this._previousParent);
562
567
  GameObject.addComponent(this._previousParent as GameObject, this.webxr);
@@ -578,7 +583,7 @@ export class WebAR {
578
583
  this.context.mainCameraComponent?.applyClearFlagsIfIsActiveCamera();
579
584
  }
580
585
 
581
- onUpdate(session: THREE.XRSession, frame: THREE.XRFrame) {
586
+ onUpdate(session: XRSession, frame: XRFrame) {
582
587
 
583
588
  if (this.noHitTestAvailable === true) {
584
589
  if (this.reticle)
@@ -631,4 +636,4 @@ export class WebAR {
631
636
  }
632
637
  }
633
638
 
634
- const arPlacementWithoutHitTestMatrix = new THREE.Matrix4().identity().makeTranslation(0, -0.5, 0);
639
+ const arPlacementWithoutHitTestMatrix = new Matrix4().identity().makeTranslation(0, -0.5, 0);