@shopware-ag/dive 1.19.1-beta.0 → 1.19.1-beta.2

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 (188) hide show
  1. package/build/dive.cjs +362 -199
  2. package/build/dive.cjs.map +1 -1
  3. package/build/dive.js +330 -167
  4. package/build/dive.js.map +1 -1
  5. package/build/dive.mjs +10803 -8714
  6. package/build/dive.mjs.map +1 -1
  7. package/build/src/converter/Converter.d.ts +3 -12
  8. package/build/src/dive.d.ts +1 -0
  9. package/build/src/exporter/Exporter.d.ts +20 -2
  10. package/build/src/loader/Loader.d.ts +0 -4
  11. package/build/src/types/error/index.d.ts +12 -0
  12. package/build/src/types/file/FileTypes.d.ts +17 -0
  13. package/build/src/types/file/index.d.ts +1 -0
  14. package/build/src/types/index.d.ts +5 -8
  15. package/package.json +2 -3
  16. package/build/src/types/ExporterOptions.d.ts +0 -15
  17. package/build/src/types/FileTypes.d.ts +0 -27
  18. package/src/__test__/DIVE.test.ts +0 -274
  19. package/src/animation/AnimationSystem.ts +0 -34
  20. package/src/animation/__test__/AnimationSystem.test.ts +0 -40
  21. package/src/ar/AR.ts +0 -101
  22. package/src/ar/__test__/AR.test.ts +0 -276
  23. package/src/ar/arquicklook/ARQuickLook.ts +0 -53
  24. package/src/ar/arquicklook/__test__/ARQuickLook.test.ts +0 -144
  25. package/src/ar/sceneviewer/SceneViewer.ts +0 -119
  26. package/src/ar/sceneviewer/__test__/SceneViewer.test.ts +0 -190
  27. package/src/ar/webxr/WebXR.ts +0 -177
  28. package/src/ar/webxr/controller/WebXRController.ts +0 -340
  29. package/src/ar/webxr/crosshair/WebXRCrosshair.ts +0 -35
  30. package/src/ar/webxr/origin/WebXROrigin.ts +0 -192
  31. package/src/ar/webxr/overlay/Overlay.ts +0 -50
  32. package/src/ar/webxr/raycaster/WebXRRaycaster.ts +0 -131
  33. package/src/ar/webxr/raycaster/ar/WebXRRaycasterAR.ts +0 -102
  34. package/src/ar/webxr/raycaster/three/WebXRRaycasterTHREE.ts +0 -49
  35. package/src/ar/webxr/touchscreencontrols/WebXRTouchscreenControls.ts +0 -356
  36. package/src/axiscamera/AxisCamera.ts +0 -108
  37. package/src/axiscamera/__test__/AxisCamera.test.ts +0 -150
  38. package/src/camera/PerspectiveCamera.ts +0 -63
  39. package/src/camera/__test__/PerspectiveCamera.test.ts +0 -36
  40. package/src/com/Communication.ts +0 -806
  41. package/src/com/__test__/Communication.test.ts +0 -1030
  42. package/src/com/actions/camera/computeencompassingview.ts +0 -10
  43. package/src/com/actions/camera/getcameratransform.ts +0 -10
  44. package/src/com/actions/camera/movecamera.ts +0 -18
  45. package/src/com/actions/camera/resetcamera.ts +0 -5
  46. package/src/com/actions/camera/setcameralayer.ts +0 -5
  47. package/src/com/actions/camera/setcameratransform.ts +0 -10
  48. package/src/com/actions/camera/zoomcamera.ts +0 -5
  49. package/src/com/actions/index.ts +0 -61
  50. package/src/com/actions/media/generatemedia.ts +0 -18
  51. package/src/com/actions/object/addobject.ts +0 -7
  52. package/src/com/actions/object/deleteobject.ts +0 -7
  53. package/src/com/actions/object/deselectobject.ts +0 -7
  54. package/src/com/actions/object/getallobjects.ts +0 -7
  55. package/src/com/actions/object/getobjects.ts +0 -7
  56. package/src/com/actions/object/model/dropit.ts +0 -5
  57. package/src/com/actions/object/model/modelloaded.ts +0 -5
  58. package/src/com/actions/object/model/placeonfloor.ts +0 -5
  59. package/src/com/actions/object/selectobject.ts +0 -7
  60. package/src/com/actions/object/setparent.ts +0 -10
  61. package/src/com/actions/object/updateobject.ts +0 -7
  62. package/src/com/actions/renderer/startrender.ts +0 -5
  63. package/src/com/actions/scene/exportscene.ts +0 -7
  64. package/src/com/actions/scene/getallscenedata.ts +0 -7
  65. package/src/com/actions/scene/launchar.ts +0 -7
  66. package/src/com/actions/scene/setbackground.ts +0 -5
  67. package/src/com/actions/scene/updatescene.ts +0 -11
  68. package/src/com/actions/toolbox/select/setgizmomode.ts +0 -5
  69. package/src/com/actions/toolbox/transform/setgizmoscalelinked.ts +0 -5
  70. package/src/com/actions/toolbox/transform/setgizmovisible.ts +0 -5
  71. package/src/com/actions/toolbox/usetool.ts +0 -7
  72. package/src/com/types/COMBaseEntity.ts +0 -9
  73. package/src/com/types/COMEntity.ts +0 -7
  74. package/src/com/types/COMEntityType.ts +0 -1
  75. package/src/com/types/COMGeometry.ts +0 -8
  76. package/src/com/types/COMGeometryType.ts +0 -9
  77. package/src/com/types/COMGroup.ts +0 -9
  78. package/src/com/types/COMLight.ts +0 -11
  79. package/src/com/types/COMMaterial.ts +0 -12
  80. package/src/com/types/COMModel.ts +0 -12
  81. package/src/com/types/COMPov.ts +0 -8
  82. package/src/com/types/COMPrimitive.ts +0 -12
  83. package/src/com/types/index.ts +0 -23
  84. package/src/constant/AxisHelperColors.ts +0 -7
  85. package/src/constant/GridColors.ts +0 -2
  86. package/src/constant/VisibilityLayerMask.ts +0 -5
  87. package/src/controls/OrbitControls.ts +0 -211
  88. package/src/controls/__test__/OrbitControls.test.ts +0 -256
  89. package/src/converter/Converter.ts +0 -117
  90. package/src/dive.ts +0 -363
  91. package/src/events/EventExecutor.ts +0 -35
  92. package/src/exporter/Exporter.ts +0 -75
  93. package/src/gizmo/Gizmo.ts +0 -144
  94. package/src/gizmo/handles/AxisHandle.ts +0 -153
  95. package/src/gizmo/handles/RadialHandle.ts +0 -149
  96. package/src/gizmo/handles/ScaleHandle.ts +0 -195
  97. package/src/gizmo/plane/GizmoPlane.ts +0 -84
  98. package/src/gizmo/rotate/RotateGizmo.ts +0 -143
  99. package/src/gizmo/scale/ScaleGizmo.ts +0 -125
  100. package/src/gizmo/translate/TranslateGizmo.ts +0 -114
  101. package/src/grid/Grid.ts +0 -34
  102. package/src/grid/__test__/Grid.test.ts +0 -28
  103. package/src/group/Group.ts +0 -184
  104. package/src/group/__test__/Group.test.ts +0 -212
  105. package/src/helper/applyMixins/__test__/applyMixins.test.ts +0 -30
  106. package/src/helper/applyMixins/applyMixins.ts +0 -70
  107. package/src/helper/findInterface/__test__/findInterface.test.ts +0 -63
  108. package/src/helper/findInterface/findInterface.ts +0 -13
  109. package/src/helper/findSceneRecursive/__test__/findSceneRecursive.test.ts +0 -40
  110. package/src/helper/findSceneRecursive/findSceneRecursive.ts +0 -16
  111. package/src/helper/getObjectDelta/__test__/getObjectDelta.test.ts +0 -186
  112. package/src/helper/getObjectDelta/getObjectDelta.ts +0 -105
  113. package/src/helper/isInterface/__test__/implementsInterface.test.ts +0 -19
  114. package/src/helper/isInterface/implementsInterface.ts +0 -9
  115. package/src/info/Info.ts +0 -178
  116. package/src/info/__test__/Info.test.ts +0 -346
  117. package/src/interface/Draggable.ts +0 -14
  118. package/src/interface/Hoverable.ts +0 -14
  119. package/src/interface/Movable.ts +0 -12
  120. package/src/interface/Rotatable.ts +0 -10
  121. package/src/interface/Scalable.ts +0 -10
  122. package/src/interface/Selectable.ts +0 -11
  123. package/src/io/IO.ts +0 -62
  124. package/src/io/__test__/IO.test.ts +0 -116
  125. package/src/io/gltf/GLTFIO.ts +0 -56
  126. package/src/io/gltf/__test__/GLTFIO.test.ts +0 -108
  127. package/src/light/AmbientLight.ts +0 -39
  128. package/src/light/PointLight.ts +0 -115
  129. package/src/light/SceneLight.ts +0 -63
  130. package/src/light/__test__/AmbientLight.test.ts +0 -29
  131. package/src/light/__test__/PointLight.test.ts +0 -74
  132. package/src/light/__test__/SceneLight.test.ts +0 -47
  133. package/src/loader/Loader.ts +0 -48
  134. package/src/math/__test__/DIVEMath.test.ts +0 -12
  135. package/src/math/ceil/__test__/ceilExp.test.ts +0 -12
  136. package/src/math/ceil/ceilExp.ts +0 -6
  137. package/src/math/degToRad/__test__/degToRad.test.ts +0 -172
  138. package/src/math/degToRad/degToRad.ts +0 -5
  139. package/src/math/floor/__test__/floorExp.test.ts +0 -14
  140. package/src/math/floor/floorExp.ts +0 -6
  141. package/src/math/helper/__test__/shift.test.ts +0 -12
  142. package/src/math/helper/shift.ts +0 -4
  143. package/src/math/index.ts +0 -28
  144. package/src/math/radToDeg/__test__/radToDeg.test.ts +0 -155
  145. package/src/math/radToDeg/radToDeg.ts +0 -5
  146. package/src/math/round/__test__/roundExp.test.ts +0 -14
  147. package/src/math/round/roundExp.ts +0 -10
  148. package/src/math/signedAngleTo/__test__/signedAngleTo.test.ts +0 -20
  149. package/src/math/signedAngleTo/signedAngleTo.ts +0 -20
  150. package/src/math/toFixed/__test__/toFixedExp.test.ts +0 -14
  151. package/src/math/toFixed/toFixedExp.ts +0 -9
  152. package/src/math/truncate/__test__/truncateExp.test.ts +0 -14
  153. package/src/math/truncate/truncateExp.ts +0 -9
  154. package/src/mediacreator/MediaCreator.ts +0 -75
  155. package/src/mediacreator/__test__/MediaCreator.test.ts +0 -155
  156. package/src/model/Model.ts +0 -190
  157. package/src/model/__test__/Model.test.ts +0 -215
  158. package/src/module/Module.ts +0 -45
  159. package/src/module/__test__/Module.test.ts +0 -54
  160. package/src/node/Node.ts +0 -100
  161. package/src/node/__test__/Node.test.ts +0 -120
  162. package/src/primitive/Primitive.ts +0 -299
  163. package/src/primitive/__test__/Primitive.test.ts +0 -281
  164. package/src/primitive/floor/Floor.ts +0 -45
  165. package/src/primitive/floor/__test__/Floor.test.ts +0 -24
  166. package/src/renderer/Renderer.ts +0 -215
  167. package/src/renderer/__test__/Renderer.test.ts +0 -228
  168. package/src/scene/Scene.ts +0 -106
  169. package/src/scene/__test__/Scene.test.ts +0 -124
  170. package/src/scene/root/Root.ts +0 -426
  171. package/src/scene/root/__test__/Root.test.ts +0 -903
  172. package/src/scene/xrroot/XRRoot.ts +0 -56
  173. package/src/scene/xrroot/xrlightroot/XRLightRoot.ts +0 -80
  174. package/src/toolbox/BaseTool.ts +0 -319
  175. package/src/toolbox/Toolbox.ts +0 -129
  176. package/src/toolbox/__test__/BaseTool.test.ts +0 -627
  177. package/src/toolbox/__test__/Toolbox.test.ts +0 -143
  178. package/src/toolbox/select/SelectTool.ts +0 -92
  179. package/src/toolbox/select/__test__/SelectTool.test.ts +0 -237
  180. package/src/toolbox/transform/TransformTool.ts +0 -166
  181. package/src/toolbox/transform/__test__/TransformTool.test.ts +0 -147
  182. package/src/types/ExporterOptions.ts +0 -14
  183. package/src/types/FileTypes.ts +0 -37
  184. package/src/types/SceneData.ts +0 -26
  185. package/src/types/SceneObjects.ts +0 -14
  186. package/src/types/SceneType.ts +0 -14
  187. package/src/types/index.ts +0 -31
  188. package/src/types/info/index.ts +0 -76
@@ -1,190 +0,0 @@
1
- import { Box3, Color, Euler, Mesh, Object3D, Vector3 } from 'three';
2
- import { DIVEScene } from '../../../scene/Scene';
3
- import { ARSystemOptions } from '../../AR';
4
- import { SceneViewer } from '../SceneViewer';
5
- import { SystemInfo } from '../../../info/Info';
6
-
7
- // Mock DIVEInfo
8
- jest.mock('../../../info/Info', () => ({
9
- DIVEInfo: {
10
- GetSystem: jest.fn().mockReturnValue('Android'),
11
- GetSupportsARQuickLook: jest.fn().mockReturnValue(false),
12
- },
13
- }));
14
-
15
- jest.mock('../../../scene/Scene', () => {
16
- return {
17
- DIVEScene: jest.fn(function () {
18
- this.add = jest.fn();
19
- this.children = [];
20
- this.Root = {
21
- children: [],
22
- };
23
- this.traverse = jest.fn((callback) => {
24
- this.Root.children.forEach((child: Object3D) => {
25
- callback(child);
26
- });
27
- });
28
- return this;
29
- }),
30
- };
31
- });
32
-
33
- // Mock URL and document APIs
34
- const mockLocation = new URL('https://example.com');
35
- const mockCreateElement = jest.fn();
36
- const mockSetAttribute = jest.fn();
37
- const mockClick = jest.fn();
38
-
39
- Object.defineProperty(window, 'location', {
40
- value: mockLocation,
41
- writable: true,
42
- });
43
-
44
- document.createElement = mockCreateElement.mockReturnValue({
45
- setAttribute: mockSetAttribute,
46
- click: mockClick,
47
- });
48
-
49
- describe('DIVESceneViewer', () => {
50
- const mockUri = 'https://example.com/model.glb';
51
- let mockOptions: ARSystemOptions;
52
-
53
- beforeEach(() => {
54
- mockOptions = {
55
- arPlacement: 'horizontal',
56
- arScale: 'auto',
57
- };
58
- jest.clearAllMocks();
59
- });
60
-
61
- describe('constructor', () => {
62
- it('should create an instance', () => {
63
- const sceneViewer = new SceneViewer();
64
- expect(sceneViewer).toBeInstanceOf(SceneViewer);
65
- });
66
- });
67
-
68
- describe('launch', () => {
69
- it('should launch with default options', () => {
70
- const sceneViewer = new SceneViewer();
71
- sceneViewer.launch(mockUri);
72
-
73
- expect(mockCreateElement).toHaveBeenCalledWith('a');
74
- expect(mockSetAttribute).toHaveBeenCalledWith(
75
- 'href',
76
- expect.stringContaining('mode=ar_preferred'),
77
- );
78
- expect(mockClick).toHaveBeenCalled();
79
- });
80
-
81
- it('should launch with custom options', () => {
82
- const options: ARSystemOptions = {
83
- arPlacement: 'vertical',
84
- arScale: 'fixed',
85
- };
86
- const sceneViewer = new SceneViewer();
87
- sceneViewer.launch(mockUri, options);
88
-
89
- expect(mockCreateElement).toHaveBeenCalledWith('a');
90
- expect(mockSetAttribute).toHaveBeenCalledWith(
91
- 'href',
92
- expect.stringContaining('enable_vertical_placement=true'),
93
- );
94
- expect(mockSetAttribute).toHaveBeenCalledWith(
95
- 'href',
96
- expect.stringContaining('resizable=false'),
97
- );
98
- expect(mockClick).toHaveBeenCalled();
99
- });
100
-
101
- it('should handle sound parameter in URL', () => {
102
- const sceneViewer = new SceneViewer();
103
- const params = new URLSearchParams();
104
- params.set('sound', 'sound.mp3');
105
-
106
- // Access private method for testing
107
- const applySoundOption = (sceneViewer as any)._applySoundOption;
108
- applySoundOption(params, mockLocation.toString());
109
-
110
- expect(params.get('sound')).toBe('https://example.com/sound.mp3');
111
- });
112
-
113
- it('should handle link parameter in URL', () => {
114
- const sceneViewer = new SceneViewer();
115
- const params = new URLSearchParams();
116
- params.set('link', 'details.html');
117
-
118
- // Access private method for testing
119
- const applyLinkOption = (sceneViewer as any)._applyLinkOption;
120
- applyLinkOption(params, mockLocation.toString());
121
-
122
- expect(params.get('link')).toBe('https://example.com/details.html');
123
- });
124
-
125
- it('should create intent URL with correct parameters', () => {
126
- const sceneViewer = new SceneViewer();
127
- const params = new URLSearchParams();
128
- params.set('mode', 'ar_preferred');
129
-
130
- // Access private method for testing and bind it to the instance
131
- const createIntent = (sceneViewer as any)._createIntent.bind(
132
- sceneViewer,
133
- );
134
- const intentUrl = createIntent(
135
- mockLocation.toString(),
136
- mockUri,
137
- params,
138
- );
139
-
140
- expect(intentUrl).toContain(
141
- 'intent://arvr.google.com/scene-viewer/1.2',
142
- );
143
- expect(intentUrl).toContain('mode=ar_preferred');
144
- expect(intentUrl).toContain('file=' + mockUri);
145
- expect(intentUrl).toContain('scheme=https');
146
- expect(intentUrl).toContain(
147
- 'package=com.google.android.googlequicksearchbox',
148
- );
149
- });
150
-
151
- it('should handle relative model URLs', () => {
152
- const relativeUri = '/models/model.glb';
153
- const sceneViewer = new SceneViewer();
154
- sceneViewer.launch(relativeUri);
155
-
156
- expect(mockSetAttribute).toHaveBeenCalledWith(
157
- 'href',
158
- expect.stringContaining(
159
- 'file=https://example.com/models/model.glb',
160
- ),
161
- );
162
- });
163
-
164
- it('should handle absolute model URLs', () => {
165
- const absoluteUri = 'https://cdn.example.com/model.glb';
166
- const sceneViewer = new SceneViewer();
167
- sceneViewer.launch(absoluteUri);
168
-
169
- expect(mockSetAttribute).toHaveBeenCalledWith(
170
- 'href',
171
- expect.stringContaining(
172
- 'file=https://cdn.example.com/model.glb',
173
- ),
174
- );
175
- });
176
-
177
- it('should handle special characters in model URL', () => {
178
- const specialUri = 'https://example.com/model with spaces.glb';
179
- const sceneViewer = new SceneViewer();
180
- sceneViewer.launch(specialUri);
181
-
182
- expect(mockSetAttribute).toHaveBeenCalledWith(
183
- 'href',
184
- expect.stringContaining(
185
- 'file=https://example.com/model%20with%20spaces.glb',
186
- ),
187
- );
188
- });
189
- });
190
- });
@@ -1,177 +0,0 @@
1
- import { Vector3 } from 'three';
2
- import DIVEOrbitControls from '../../controls/OrbitControls';
3
- import { type DIVERenderer } from '../../renderer/Renderer';
4
- import { type DIVEScene } from '../../scene/Scene';
5
- import { Overlay } from './overlay/Overlay';
6
- import { DIVEWebXRController } from './controller/WebXRController';
7
-
8
- export class DIVEWebXR {
9
- // general members
10
- private static _renderer: DIVERenderer;
11
- private static _scene: DIVEScene;
12
- private static _controller: DIVEOrbitControls;
13
-
14
- // camera reset members
15
- private static _cameraPosition: Vector3;
16
- private static _cameraTarget: Vector3;
17
-
18
- // render loop members
19
- private static _renderCallbackId: string | null = null;
20
-
21
- // setup members
22
- private static _session: XRSession | null = null;
23
- private static _referenceSpaceType: XRReferenceSpaceType = 'local';
24
- private static _overlay: Overlay | null = null;
25
- private static _options = {
26
- requiredFeatures: [
27
- 'local',
28
- 'hit-test',
29
- ],
30
- optionalFeatures: [
31
- 'light-estimation',
32
- 'local-floor',
33
- 'dom-overlay',
34
- 'depth-sensing',
35
- ],
36
- depthSensing: {
37
- usagePreference: ['gpu-optimized'],
38
- dataFormatPreference: [],
39
- },
40
- domOverlay: { root: {} as HTMLElement },
41
- };
42
-
43
- private static _xrController: DIVEWebXRController | null = null;
44
-
45
- public static async Launch(
46
- renderer: DIVERenderer,
47
- scene: DIVEScene,
48
- controller: DIVEOrbitControls,
49
- ): Promise<void> {
50
- this._renderer = renderer;
51
- this._scene = scene;
52
- this._controller = controller;
53
-
54
- // setting camera reset values
55
- this._cameraPosition = this._controller.object.position.clone();
56
- this._cameraTarget = this._controller.target.clone();
57
-
58
- if (!navigator.xr) {
59
- console.error('WebXR not supported');
60
- return Promise.reject();
61
- }
62
-
63
- // setup current instance
64
- this._renderer.xr.enabled = true;
65
- this._scene.InitXR(renderer);
66
-
67
- // creating overlay
68
- if (!DIVEWebXR._overlay) {
69
- const overlay = new Overlay();
70
- DIVEWebXR._overlay = overlay;
71
- }
72
- DIVEWebXR._options.domOverlay = { root: DIVEWebXR._overlay.Element };
73
-
74
- // request session
75
- const session = await navigator.xr
76
- .requestSession('immersive-ar', this._options)
77
- .catch((reason) => {
78
- return Promise.reject(reason);
79
- });
80
- session.addEventListener('end', () => {
81
- this._onSessionEnded();
82
- });
83
-
84
- // build up session
85
- renderer.xr.setReferenceSpaceType(this._referenceSpaceType);
86
- await renderer.xr.setSession(session);
87
- DIVEWebXR._overlay.Element.style.display = '';
88
- this._session = session;
89
-
90
- // add end session event listener
91
- DIVEWebXR._overlay.CloseButton.addEventListener('click', () =>
92
- this.End(),
93
- );
94
-
95
- // start session
96
- await this._onSessionStarted();
97
-
98
- return Promise.resolve();
99
- }
100
-
101
- public static Update(_time: DOMHighResTimeStamp, frame: XRFrame): void {
102
- if (!this._session) return;
103
-
104
- if (this._xrController) {
105
- this._xrController.Update(frame);
106
- }
107
- }
108
-
109
- public static End(): void {
110
- if (!this._session) return;
111
- this._session.end();
112
- }
113
-
114
- private static async _onSessionStarted(): Promise<void> {
115
- if (!this._session) return;
116
-
117
- // add update callback to render loop
118
- this._renderCallbackId = this._renderer.AddPreRenderCallback(
119
- (time: DOMHighResTimeStamp, frame: XRFrame) => {
120
- this.Update(time, frame);
121
- },
122
- );
123
-
124
- this._xrController = new DIVEWebXRController(
125
- this._session,
126
- this._renderer,
127
- this._scene,
128
- );
129
- await this._xrController.Init().catch(() => {
130
- this.End();
131
- });
132
-
133
- return Promise.resolve();
134
- }
135
-
136
- private static _onSessionEnded(): void {
137
- if (!this._session) return;
138
-
139
- if (this._xrController) {
140
- this._xrController.Dispose();
141
- }
142
-
143
- // remove Update() callback
144
- if (this._renderCallbackId) {
145
- this._renderer.RemovePreRenderCallback(this._renderCallbackId);
146
- this._renderCallbackId = null;
147
- }
148
-
149
- // disable XR on renderer to restore canvas rendering
150
- this._renderer.xr.enabled = false;
151
-
152
- // resize renderer
153
- const canvasWrapper = this._renderer.domElement.parentElement;
154
- if (canvasWrapper) {
155
- const { clientWidth, clientHeight } = canvasWrapper;
156
- this._renderer.OnResize(clientWidth, clientHeight);
157
-
158
- // resize camera
159
- this._controller.object.OnResize(clientWidth, clientHeight);
160
- }
161
-
162
- // reset camera
163
- this._controller.object.position.copy(this._cameraPosition);
164
- this._controller.target.copy(this._cameraTarget);
165
-
166
- // reset camera values
167
- this._cameraPosition.set(0, 0, 0);
168
- this._cameraTarget.set(0, 0, 0);
169
-
170
- // dispose xr scene
171
- this._scene.DisposeXR();
172
-
173
- this._session.removeEventListener('end', this._onSessionEnded);
174
- DIVEWebXR._overlay!.Element.style.display = 'none';
175
- this._session = null;
176
- }
177
- }
@@ -1,340 +0,0 @@
1
- import {
2
- Matrix4,
3
- Mesh,
4
- Object3D,
5
- Quaternion,
6
- Vector3,
7
- WebXRArrayCamera,
8
- } from 'three';
9
- import { DIVERenderer } from '../../../renderer/Renderer';
10
- import { DIVEScene } from '../../../scene/Scene';
11
- import { DIVEWebXRCrosshair } from '../crosshair/WebXRCrosshair';
12
- import { DIVEWebXRRaycaster } from '../raycaster/WebXRRaycaster';
13
- import { DIVEWebXROrigin } from '../origin/WebXROrigin';
14
- import {
15
- DIVETouchscreenEvents,
16
- DIVEWebXRTouchscreenControls,
17
- } from '../touchscreencontrols/WebXRTouchscreenControls';
18
- import { type DIVEMovable } from '../.././../interface/Movable';
19
- import { findInterface } from '../../../helper/findInterface/findInterface';
20
-
21
- export class DIVEWebXRController extends Object3D {
22
- // general members
23
- private _renderer: DIVERenderer;
24
- private _scene: DIVEScene;
25
- private _session: XRSession;
26
-
27
- private _frameBuffer: XRFrame | null = null;
28
-
29
- // raycaster members
30
- private _xrRaycaster: DIVEWebXRRaycaster;
31
- private _origin: DIVEWebXROrigin;
32
-
33
- // crosshair
34
- private _crosshair: DIVEWebXRCrosshair;
35
-
36
- // controller members
37
- private _touchscreenControls: DIVEWebXRTouchscreenControls;
38
- private _handNodeInitialPosition = new Vector3();
39
- private _xrCamera: WebXRArrayCamera;
40
- private _placed: boolean = false;
41
-
42
- // grabbing
43
- private _grabbedObject: Object3D | null = null;
44
- private _arHitPosition: Vector3 = new Vector3();
45
- private _arHitQuaternion: Quaternion = new Quaternion();
46
- private _arHitScale: Vector3 = new Vector3(1, 1, 1);
47
-
48
- // grabbing position
49
- private _initialObjectPosition: Vector3 | null = null;
50
- private _initialRaycastHit: Vector3 | null = null;
51
- private _deltaRaycastHit: Vector3 = new Vector3();
52
-
53
- // grabbing rotation
54
- private _touchQuaterion: Quaternion = new Quaternion();
55
-
56
- // grabbing scale
57
- private _touchScale: number = 1;
58
- private _scaleThreshold: number = 0.1;
59
-
60
- constructor(session: XRSession, renderer: DIVERenderer, scene: DIVEScene) {
61
- super();
62
-
63
- this._renderer = renderer;
64
- this._scene = scene;
65
- this._session = session;
66
-
67
- this._xrRaycaster = new DIVEWebXRRaycaster(session, renderer, scene);
68
- this._origin = new DIVEWebXROrigin(this._session, this._renderer, [
69
- 'plane',
70
- ]);
71
-
72
- this._crosshair = new DIVEWebXRCrosshair();
73
- this._crosshair.visible = false;
74
-
75
- this._xrCamera = this._renderer.xr.getCamera();
76
-
77
- this._scene.XRRoot.XRHandNode.position.set(0, -0.05, -0.25);
78
- this._handNodeInitialPosition =
79
- this._scene.XRRoot.XRHandNode.position.clone();
80
-
81
- this._touchscreenControls = new DIVEWebXRTouchscreenControls(
82
- this._session,
83
- );
84
-
85
- // translating
86
- this._touchscreenControls.Subscribe('TOUCH_START', () =>
87
- this.onTouchStart(),
88
- );
89
- this._touchscreenControls.Subscribe('TOUCH_MOVE', () =>
90
- this.onTouchMove(),
91
- );
92
- this._touchscreenControls.Subscribe('TOUCH_END', (p) =>
93
- this.onTouchEnd(p),
94
- );
95
-
96
- // rotating
97
- this._touchscreenControls.Subscribe('ROTATE_START', () =>
98
- this.onRotateStart(),
99
- );
100
- this._touchscreenControls.Subscribe('ROTATE_MOVE', (p) =>
101
- this.onRotateMove(p),
102
- );
103
-
104
- // scaling
105
- this._touchscreenControls.Subscribe('PINCH_START', () =>
106
- this.onPinchStart(),
107
- );
108
- this._touchscreenControls.Subscribe('PINCH_MOVE', (p) =>
109
- this.onPinchMove(p),
110
- );
111
- }
112
-
113
- public async Init(): Promise<this> {
114
- this.prepareScene();
115
-
116
- await this.initOrigin();
117
- await this.initRaycaster();
118
-
119
- return Promise.resolve(this);
120
- }
121
-
122
- public Dispose(): void {
123
- this.restoreScene();
124
-
125
- this._origin.Dispose();
126
- this._xrRaycaster.Dispose();
127
-
128
- // reset placement members
129
- this._placed = false;
130
- }
131
-
132
- public Update(frame: XRFrame): void {
133
- this._frameBuffer = frame;
134
-
135
- if (!this._placed) {
136
- this.updateHandNode();
137
-
138
- if (this._origin) {
139
- this._origin.Update(frame);
140
- }
141
- }
142
- }
143
-
144
- private updateHandNode(): void {
145
- this._xrCamera.updateMatrixWorld();
146
- this._scene.XRRoot.XRHandNode.position.copy(
147
- this._handNodeInitialPosition
148
- .clone()
149
- .applyMatrix4(this._xrCamera.matrixWorld),
150
- );
151
- this._scene.XRRoot.XRHandNode.quaternion.setFromRotationMatrix(
152
- this._xrCamera.matrixWorld,
153
- );
154
- }
155
-
156
- // placement
157
- private async initOrigin(): Promise<void> {
158
- // initialize origin
159
- this._origin = await this._origin.Init();
160
-
161
- // set resolve callback: place objects at origin when it is set
162
- this._origin.originSet.then(() => {
163
- this.placeObjects(this._origin.matrix);
164
- });
165
- }
166
-
167
- private placeObjects(matrix: Matrix4): void {
168
- this._scene.XRRoot.XRModelRoot.matrix.copy(matrix);
169
-
170
- // we are copying children to a new array to keep the original array intact
171
- [...this._scene.XRRoot.XRHandNode.children].forEach((child) => {
172
- this._scene.XRRoot.XRModelRoot.add(child);
173
- });
174
- this._placed = true;
175
- }
176
-
177
- // grabbing
178
- private updateObject(): void {
179
- if (!this._grabbedObject) return;
180
-
181
- this._grabbedObject.position.copy(this._arHitPosition);
182
- this._grabbedObject.quaternion.copy(
183
- this._arHitQuaternion.clone().multiply(this._touchQuaterion),
184
- );
185
- this._grabbedObject.scale.copy(
186
- new Vector3(
187
- this._touchScale,
188
- this._touchScale,
189
- this._touchScale,
190
- ).multiply(this._arHitScale),
191
- );
192
- }
193
-
194
- private onTouchStart(): void {
195
- const sceneHits = this._xrRaycaster.GetSceneIntersections();
196
- console.log('sceneHits', sceneHits);
197
- if (sceneHits.length === 0) return;
198
- if (!sceneHits[0].object) return;
199
-
200
- const moveable = findInterface<DIVEMovable>(
201
- sceneHits[0].object,
202
- 'isMovable',
203
- );
204
- if (!moveable) return;
205
-
206
- this._grabbedObject = moveable;
207
- }
208
-
209
- private onTouchMove(): void {
210
- // raycast ar
211
- if (!this._frameBuffer) return;
212
- if (!this._grabbedObject) return;
213
-
214
- const intersections = this._xrRaycaster.GetARIntersections(
215
- this._frameBuffer,
216
- );
217
- if (intersections.length === 0) {
218
- this._crosshair.visible = false;
219
- return;
220
- }
221
-
222
- const hit = intersections[0];
223
-
224
- this._crosshair.visible = true;
225
- this._crosshair.matrix.copy(hit.matrix);
226
-
227
- if (!this._grabbedObject) return;
228
-
229
- // if initial values have been reset by TOUCH_END event then set them again
230
- if (!this._initialObjectPosition || !this._initialRaycastHit) {
231
- this._initialObjectPosition = this._grabbedObject.position.clone();
232
- this._initialRaycastHit = hit.point.clone();
233
- }
234
-
235
- // decompose hit matrix to apply hit matrix to object
236
- hit.matrix.decompose(
237
- this._arHitPosition,
238
- this._arHitQuaternion,
239
- this._arHitScale,
240
- );
241
-
242
- // calculate raycast hit delta
243
- this._deltaRaycastHit.copy(
244
- hit.point.clone().sub(this._initialRaycastHit),
245
- );
246
-
247
- // apply moved raycast delta to actual object position
248
- this._arHitPosition.copy(
249
- this._initialObjectPosition.clone().add(this._deltaRaycastHit),
250
- );
251
-
252
- console.log('arHitPosition', this._arHitPosition);
253
-
254
- this.updateObject();
255
- }
256
-
257
- private onTouchEnd(payload: DIVETouchscreenEvents['TOUCH_END']): void {
258
- if (payload.touchCount === 0) {
259
- this._crosshair.visible = false;
260
-
261
- // reset grab
262
- this._initialObjectPosition = null;
263
- this._initialRaycastHit = null;
264
- this._grabbedObject = null;
265
- }
266
- }
267
-
268
- private _startTouchQuaternion: Quaternion = new Quaternion();
269
- private onRotateStart(): void {
270
- this._startTouchQuaternion = this._touchQuaterion.clone();
271
- }
272
-
273
- private onRotateMove(payload: DIVETouchscreenEvents['ROTATE_MOVE']): void {
274
- this._touchQuaterion.setFromAxisAngle(
275
- new Vector3(0, -1, 0),
276
- payload.delta * 3,
277
- );
278
- this._touchQuaterion.multiply(this._startTouchQuaternion);
279
- this.updateObject();
280
- }
281
-
282
- private _startTouchScale: number = 1;
283
- private onPinchStart(): void {
284
- this._startTouchScale = this._touchScale;
285
- }
286
-
287
- private onPinchMove(payload: DIVETouchscreenEvents['PINCH_MOVE']): void {
288
- this._touchScale = this._startTouchScale * payload.current;
289
- this.updateObject();
290
- }
291
-
292
- // prepare & cleanup scene
293
- private prepareScene(): void {
294
- this._scene.XRRoot.XRModelRoot.matrixAutoUpdate = false;
295
-
296
- // initialize crosshair
297
- this._scene.add(this._crosshair);
298
-
299
- // hang current scene children to hand node
300
- const children: Object3D[] = [];
301
- this._scene.Root.children.forEach((child) => {
302
- const clone = child.clone();
303
- clone.layers.enableAll();
304
- clone.traverse((obj) => {
305
- obj.layers.enableAll();
306
- if (obj instanceof Mesh) {
307
- obj.scale.set(0.1, 0.1, 0.1);
308
- }
309
- });
310
- clone.position.set(0, 0, 0);
311
- children.push(clone);
312
- });
313
- this._scene.XRRoot.XRHandNode.add(...children);
314
- }
315
-
316
- private restoreScene(): void {
317
- this._scene.remove(this._crosshair);
318
-
319
- // clear hand node and remove attached models
320
- this._scene.XRRoot.XRHandNode.clear();
321
- this._scene.XRRoot.XRModelRoot.clear();
322
-
323
- this._scene.XRRoot.XRModelRoot.matrixAutoUpdate = true;
324
- }
325
-
326
- // raycast
327
- private async initRaycaster(): Promise<void> {
328
- // initialize raycaster
329
- await this._xrRaycaster.Init();
330
-
331
- // check if successful
332
- if (!this._xrRaycaster) {
333
- console.error(
334
- 'Raycaster not initialized successfully. Aborting WebXR...',
335
- );
336
- this.Dispose();
337
- return Promise.reject();
338
- }
339
- }
340
- }