@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.
- package/build/dive.cjs +362 -199
- package/build/dive.cjs.map +1 -1
- package/build/dive.js +330 -167
- package/build/dive.js.map +1 -1
- package/build/dive.mjs +10803 -8714
- package/build/dive.mjs.map +1 -1
- package/build/src/converter/Converter.d.ts +3 -12
- package/build/src/dive.d.ts +1 -0
- package/build/src/exporter/Exporter.d.ts +20 -2
- package/build/src/loader/Loader.d.ts +0 -4
- package/build/src/types/error/index.d.ts +12 -0
- package/build/src/types/file/FileTypes.d.ts +17 -0
- package/build/src/types/file/index.d.ts +1 -0
- package/build/src/types/index.d.ts +5 -8
- package/package.json +2 -3
- package/build/src/types/ExporterOptions.d.ts +0 -15
- package/build/src/types/FileTypes.d.ts +0 -27
- package/src/__test__/DIVE.test.ts +0 -274
- package/src/animation/AnimationSystem.ts +0 -34
- package/src/animation/__test__/AnimationSystem.test.ts +0 -40
- package/src/ar/AR.ts +0 -101
- package/src/ar/__test__/AR.test.ts +0 -276
- package/src/ar/arquicklook/ARQuickLook.ts +0 -53
- package/src/ar/arquicklook/__test__/ARQuickLook.test.ts +0 -144
- package/src/ar/sceneviewer/SceneViewer.ts +0 -119
- package/src/ar/sceneviewer/__test__/SceneViewer.test.ts +0 -190
- package/src/ar/webxr/WebXR.ts +0 -177
- package/src/ar/webxr/controller/WebXRController.ts +0 -340
- package/src/ar/webxr/crosshair/WebXRCrosshair.ts +0 -35
- package/src/ar/webxr/origin/WebXROrigin.ts +0 -192
- package/src/ar/webxr/overlay/Overlay.ts +0 -50
- package/src/ar/webxr/raycaster/WebXRRaycaster.ts +0 -131
- package/src/ar/webxr/raycaster/ar/WebXRRaycasterAR.ts +0 -102
- package/src/ar/webxr/raycaster/three/WebXRRaycasterTHREE.ts +0 -49
- package/src/ar/webxr/touchscreencontrols/WebXRTouchscreenControls.ts +0 -356
- package/src/axiscamera/AxisCamera.ts +0 -108
- package/src/axiscamera/__test__/AxisCamera.test.ts +0 -150
- package/src/camera/PerspectiveCamera.ts +0 -63
- package/src/camera/__test__/PerspectiveCamera.test.ts +0 -36
- package/src/com/Communication.ts +0 -806
- package/src/com/__test__/Communication.test.ts +0 -1030
- package/src/com/actions/camera/computeencompassingview.ts +0 -10
- package/src/com/actions/camera/getcameratransform.ts +0 -10
- package/src/com/actions/camera/movecamera.ts +0 -18
- package/src/com/actions/camera/resetcamera.ts +0 -5
- package/src/com/actions/camera/setcameralayer.ts +0 -5
- package/src/com/actions/camera/setcameratransform.ts +0 -10
- package/src/com/actions/camera/zoomcamera.ts +0 -5
- package/src/com/actions/index.ts +0 -61
- package/src/com/actions/media/generatemedia.ts +0 -18
- package/src/com/actions/object/addobject.ts +0 -7
- package/src/com/actions/object/deleteobject.ts +0 -7
- package/src/com/actions/object/deselectobject.ts +0 -7
- package/src/com/actions/object/getallobjects.ts +0 -7
- package/src/com/actions/object/getobjects.ts +0 -7
- package/src/com/actions/object/model/dropit.ts +0 -5
- package/src/com/actions/object/model/modelloaded.ts +0 -5
- package/src/com/actions/object/model/placeonfloor.ts +0 -5
- package/src/com/actions/object/selectobject.ts +0 -7
- package/src/com/actions/object/setparent.ts +0 -10
- package/src/com/actions/object/updateobject.ts +0 -7
- package/src/com/actions/renderer/startrender.ts +0 -5
- package/src/com/actions/scene/exportscene.ts +0 -7
- package/src/com/actions/scene/getallscenedata.ts +0 -7
- package/src/com/actions/scene/launchar.ts +0 -7
- package/src/com/actions/scene/setbackground.ts +0 -5
- package/src/com/actions/scene/updatescene.ts +0 -11
- package/src/com/actions/toolbox/select/setgizmomode.ts +0 -5
- package/src/com/actions/toolbox/transform/setgizmoscalelinked.ts +0 -5
- package/src/com/actions/toolbox/transform/setgizmovisible.ts +0 -5
- package/src/com/actions/toolbox/usetool.ts +0 -7
- package/src/com/types/COMBaseEntity.ts +0 -9
- package/src/com/types/COMEntity.ts +0 -7
- package/src/com/types/COMEntityType.ts +0 -1
- package/src/com/types/COMGeometry.ts +0 -8
- package/src/com/types/COMGeometryType.ts +0 -9
- package/src/com/types/COMGroup.ts +0 -9
- package/src/com/types/COMLight.ts +0 -11
- package/src/com/types/COMMaterial.ts +0 -12
- package/src/com/types/COMModel.ts +0 -12
- package/src/com/types/COMPov.ts +0 -8
- package/src/com/types/COMPrimitive.ts +0 -12
- package/src/com/types/index.ts +0 -23
- package/src/constant/AxisHelperColors.ts +0 -7
- package/src/constant/GridColors.ts +0 -2
- package/src/constant/VisibilityLayerMask.ts +0 -5
- package/src/controls/OrbitControls.ts +0 -211
- package/src/controls/__test__/OrbitControls.test.ts +0 -256
- package/src/converter/Converter.ts +0 -117
- package/src/dive.ts +0 -363
- package/src/events/EventExecutor.ts +0 -35
- package/src/exporter/Exporter.ts +0 -75
- package/src/gizmo/Gizmo.ts +0 -144
- package/src/gizmo/handles/AxisHandle.ts +0 -153
- package/src/gizmo/handles/RadialHandle.ts +0 -149
- package/src/gizmo/handles/ScaleHandle.ts +0 -195
- package/src/gizmo/plane/GizmoPlane.ts +0 -84
- package/src/gizmo/rotate/RotateGizmo.ts +0 -143
- package/src/gizmo/scale/ScaleGizmo.ts +0 -125
- package/src/gizmo/translate/TranslateGizmo.ts +0 -114
- package/src/grid/Grid.ts +0 -34
- package/src/grid/__test__/Grid.test.ts +0 -28
- package/src/group/Group.ts +0 -184
- package/src/group/__test__/Group.test.ts +0 -212
- package/src/helper/applyMixins/__test__/applyMixins.test.ts +0 -30
- package/src/helper/applyMixins/applyMixins.ts +0 -70
- package/src/helper/findInterface/__test__/findInterface.test.ts +0 -63
- package/src/helper/findInterface/findInterface.ts +0 -13
- package/src/helper/findSceneRecursive/__test__/findSceneRecursive.test.ts +0 -40
- package/src/helper/findSceneRecursive/findSceneRecursive.ts +0 -16
- package/src/helper/getObjectDelta/__test__/getObjectDelta.test.ts +0 -186
- package/src/helper/getObjectDelta/getObjectDelta.ts +0 -105
- package/src/helper/isInterface/__test__/implementsInterface.test.ts +0 -19
- package/src/helper/isInterface/implementsInterface.ts +0 -9
- package/src/info/Info.ts +0 -178
- package/src/info/__test__/Info.test.ts +0 -346
- package/src/interface/Draggable.ts +0 -14
- package/src/interface/Hoverable.ts +0 -14
- package/src/interface/Movable.ts +0 -12
- package/src/interface/Rotatable.ts +0 -10
- package/src/interface/Scalable.ts +0 -10
- package/src/interface/Selectable.ts +0 -11
- package/src/io/IO.ts +0 -62
- package/src/io/__test__/IO.test.ts +0 -116
- package/src/io/gltf/GLTFIO.ts +0 -56
- package/src/io/gltf/__test__/GLTFIO.test.ts +0 -108
- package/src/light/AmbientLight.ts +0 -39
- package/src/light/PointLight.ts +0 -115
- package/src/light/SceneLight.ts +0 -63
- package/src/light/__test__/AmbientLight.test.ts +0 -29
- package/src/light/__test__/PointLight.test.ts +0 -74
- package/src/light/__test__/SceneLight.test.ts +0 -47
- package/src/loader/Loader.ts +0 -48
- package/src/math/__test__/DIVEMath.test.ts +0 -12
- package/src/math/ceil/__test__/ceilExp.test.ts +0 -12
- package/src/math/ceil/ceilExp.ts +0 -6
- package/src/math/degToRad/__test__/degToRad.test.ts +0 -172
- package/src/math/degToRad/degToRad.ts +0 -5
- package/src/math/floor/__test__/floorExp.test.ts +0 -14
- package/src/math/floor/floorExp.ts +0 -6
- package/src/math/helper/__test__/shift.test.ts +0 -12
- package/src/math/helper/shift.ts +0 -4
- package/src/math/index.ts +0 -28
- package/src/math/radToDeg/__test__/radToDeg.test.ts +0 -155
- package/src/math/radToDeg/radToDeg.ts +0 -5
- package/src/math/round/__test__/roundExp.test.ts +0 -14
- package/src/math/round/roundExp.ts +0 -10
- package/src/math/signedAngleTo/__test__/signedAngleTo.test.ts +0 -20
- package/src/math/signedAngleTo/signedAngleTo.ts +0 -20
- package/src/math/toFixed/__test__/toFixedExp.test.ts +0 -14
- package/src/math/toFixed/toFixedExp.ts +0 -9
- package/src/math/truncate/__test__/truncateExp.test.ts +0 -14
- package/src/math/truncate/truncateExp.ts +0 -9
- package/src/mediacreator/MediaCreator.ts +0 -75
- package/src/mediacreator/__test__/MediaCreator.test.ts +0 -155
- package/src/model/Model.ts +0 -190
- package/src/model/__test__/Model.test.ts +0 -215
- package/src/module/Module.ts +0 -45
- package/src/module/__test__/Module.test.ts +0 -54
- package/src/node/Node.ts +0 -100
- package/src/node/__test__/Node.test.ts +0 -120
- package/src/primitive/Primitive.ts +0 -299
- package/src/primitive/__test__/Primitive.test.ts +0 -281
- package/src/primitive/floor/Floor.ts +0 -45
- package/src/primitive/floor/__test__/Floor.test.ts +0 -24
- package/src/renderer/Renderer.ts +0 -215
- package/src/renderer/__test__/Renderer.test.ts +0 -228
- package/src/scene/Scene.ts +0 -106
- package/src/scene/__test__/Scene.test.ts +0 -124
- package/src/scene/root/Root.ts +0 -426
- package/src/scene/root/__test__/Root.test.ts +0 -903
- package/src/scene/xrroot/XRRoot.ts +0 -56
- package/src/scene/xrroot/xrlightroot/XRLightRoot.ts +0 -80
- package/src/toolbox/BaseTool.ts +0 -319
- package/src/toolbox/Toolbox.ts +0 -129
- package/src/toolbox/__test__/BaseTool.test.ts +0 -627
- package/src/toolbox/__test__/Toolbox.test.ts +0 -143
- package/src/toolbox/select/SelectTool.ts +0 -92
- package/src/toolbox/select/__test__/SelectTool.test.ts +0 -237
- package/src/toolbox/transform/TransformTool.ts +0 -166
- package/src/toolbox/transform/__test__/TransformTool.test.ts +0 -147
- package/src/types/ExporterOptions.ts +0 -14
- package/src/types/FileTypes.ts +0 -37
- package/src/types/SceneData.ts +0 -26
- package/src/types/SceneObjects.ts +0 -14
- package/src/types/SceneType.ts +0 -14
- package/src/types/index.ts +0 -31
- package/src/types/info/index.ts +0 -76
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import { ARSystem, type ARSystemOptions } from '../AR';
|
|
2
|
-
import { SystemInfo } from '../../info/Info';
|
|
3
|
-
import { ARQuickLook } from '../arquicklook/ARQuickLook';
|
|
4
|
-
import { SceneViewer } from '../sceneviewer/SceneViewer';
|
|
5
|
-
|
|
6
|
-
// Mock Info
|
|
7
|
-
jest.mock('../../info/Info', () => ({
|
|
8
|
-
SystemInfo: {
|
|
9
|
-
GetSystem: jest.fn(),
|
|
10
|
-
GetSupportsARQuickLook: jest.fn(),
|
|
11
|
-
},
|
|
12
|
-
}));
|
|
13
|
-
|
|
14
|
-
// Mock ARQuickLook
|
|
15
|
-
const mockLaunchARQuickLook = jest.fn().mockResolvedValue(undefined);
|
|
16
|
-
jest.mock('../arquicklook/ARQuickLook', () => ({
|
|
17
|
-
ARQuickLook: jest.fn().mockImplementation(() => ({
|
|
18
|
-
launch: mockLaunchARQuickLook,
|
|
19
|
-
})),
|
|
20
|
-
}));
|
|
21
|
-
|
|
22
|
-
// Mock SceneViewer
|
|
23
|
-
const mockSceneViewerLaunch = jest.fn().mockResolvedValue(undefined);
|
|
24
|
-
jest.mock('../sceneviewer/SceneViewer', () => ({
|
|
25
|
-
SceneViewer: jest.fn().mockImplementation(() => ({
|
|
26
|
-
launch: mockSceneViewerLaunch,
|
|
27
|
-
})),
|
|
28
|
-
}));
|
|
29
|
-
|
|
30
|
-
describe('ARSystem', () => {
|
|
31
|
-
let diveAR: ARSystem;
|
|
32
|
-
const mockUri = 'https://example.com/model.glb';
|
|
33
|
-
|
|
34
|
-
beforeEach(() => {
|
|
35
|
-
diveAR = new ARSystem();
|
|
36
|
-
jest.clearAllMocks();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe('launch', () => {
|
|
40
|
-
describe('AR Quick Look', () => {
|
|
41
|
-
it('should launch ARQuickLook on iOS', async () => {
|
|
42
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('iOS');
|
|
43
|
-
(
|
|
44
|
-
SystemInfo.GetSupportsARQuickLook as jest.Mock
|
|
45
|
-
).mockReturnValue(true);
|
|
46
|
-
|
|
47
|
-
const consoleLogSpy = jest
|
|
48
|
-
.spyOn(console, 'log')
|
|
49
|
-
.mockImplementation();
|
|
50
|
-
|
|
51
|
-
await diveAR.launch(mockUri);
|
|
52
|
-
|
|
53
|
-
expect(mockLaunchARQuickLook).toHaveBeenCalledWith(
|
|
54
|
-
mockUri,
|
|
55
|
-
undefined,
|
|
56
|
-
);
|
|
57
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
58
|
-
'DIVE: Launching AR with ARQuickLook ...',
|
|
59
|
-
);
|
|
60
|
-
consoleLogSpy.mockRestore();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should launch ARQuickLook on iOS with options', async () => {
|
|
64
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('iOS');
|
|
65
|
-
(
|
|
66
|
-
SystemInfo.GetSupportsARQuickLook as jest.Mock
|
|
67
|
-
).mockReturnValue(true);
|
|
68
|
-
|
|
69
|
-
const options: ARSystemOptions = {
|
|
70
|
-
arPlacement: 'vertical',
|
|
71
|
-
arScale: 'fixed',
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const consoleLogSpy = jest
|
|
75
|
-
.spyOn(console, 'log')
|
|
76
|
-
.mockImplementation();
|
|
77
|
-
|
|
78
|
-
await diveAR.launch(mockUri, options);
|
|
79
|
-
|
|
80
|
-
expect(mockLaunchARQuickLook).toHaveBeenCalledWith(
|
|
81
|
-
mockUri,
|
|
82
|
-
options,
|
|
83
|
-
);
|
|
84
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
85
|
-
'DIVE: Launching AR with ARQuickLook ...',
|
|
86
|
-
);
|
|
87
|
-
consoleLogSpy.mockRestore();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should not launch ARQuickLook on iOS if not supported', async () => {
|
|
91
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('iOS');
|
|
92
|
-
(
|
|
93
|
-
SystemInfo.GetSupportsARQuickLook as jest.Mock
|
|
94
|
-
).mockReturnValue(false);
|
|
95
|
-
|
|
96
|
-
const consoleLogSpy = jest
|
|
97
|
-
.spyOn(console, 'log')
|
|
98
|
-
.mockImplementation();
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
await diveAR.launch(mockUri);
|
|
102
|
-
fail('Expected launch to reject');
|
|
103
|
-
} catch (error: unknown) {
|
|
104
|
-
if (error instanceof Error) {
|
|
105
|
-
expect(error.message).toBe('ARQuickLook not supported');
|
|
106
|
-
} else {
|
|
107
|
-
fail('Expected error to be an Error instance');
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
111
|
-
'ARQuickLook not supported',
|
|
112
|
-
);
|
|
113
|
-
consoleLogSpy.mockRestore();
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('should handle ARQuickLook launch errors', async () => {
|
|
117
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('iOS');
|
|
118
|
-
(
|
|
119
|
-
SystemInfo.GetSupportsARQuickLook as jest.Mock
|
|
120
|
-
).mockReturnValue(true);
|
|
121
|
-
|
|
122
|
-
const mockError = new Error('Launch failed');
|
|
123
|
-
const mockInstance = {
|
|
124
|
-
launch: jest.fn().mockImplementation(() => {
|
|
125
|
-
throw mockError;
|
|
126
|
-
}),
|
|
127
|
-
};
|
|
128
|
-
(ARQuickLook as jest.Mock).mockImplementation(
|
|
129
|
-
() => mockInstance,
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
const consoleLogSpy = jest
|
|
133
|
-
.spyOn(console, 'log')
|
|
134
|
-
.mockImplementation();
|
|
135
|
-
const consoleErrorSpy = jest
|
|
136
|
-
.spyOn(console, 'error')
|
|
137
|
-
.mockImplementation();
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
await diveAR.launch(mockUri);
|
|
141
|
-
fail('Expected launch to reject');
|
|
142
|
-
} catch (error: unknown) {
|
|
143
|
-
if (error instanceof Error) {
|
|
144
|
-
expect(error.message).toBe('Launch failed');
|
|
145
|
-
} else {
|
|
146
|
-
fail('Expected error to be an Error instance');
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
151
|
-
'DIVE: Launching AR with ARQuickLook ...',
|
|
152
|
-
);
|
|
153
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
154
|
-
'Error launching ARQuickLook:',
|
|
155
|
-
mockError,
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
consoleLogSpy.mockRestore();
|
|
159
|
-
consoleErrorSpy.mockRestore();
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('Scene Viewer', () => {
|
|
164
|
-
it('should launch SceneViewer on Android', async () => {
|
|
165
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('Android');
|
|
166
|
-
|
|
167
|
-
const consoleLogSpy = jest
|
|
168
|
-
.spyOn(console, 'log')
|
|
169
|
-
.mockImplementation();
|
|
170
|
-
|
|
171
|
-
await diveAR.launch(mockUri);
|
|
172
|
-
|
|
173
|
-
expect(mockSceneViewerLaunch).toHaveBeenCalledWith(
|
|
174
|
-
mockUri,
|
|
175
|
-
undefined,
|
|
176
|
-
);
|
|
177
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
178
|
-
'DIVE: Launching AR with SceneViewer ...',
|
|
179
|
-
);
|
|
180
|
-
consoleLogSpy.mockRestore();
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
it('should launch SceneViewer on Android with options', async () => {
|
|
184
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('Android');
|
|
185
|
-
|
|
186
|
-
const options: ARSystemOptions = {
|
|
187
|
-
arPlacement: 'vertical',
|
|
188
|
-
arScale: 'fixed',
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
const consoleLogSpy = jest
|
|
192
|
-
.spyOn(console, 'log')
|
|
193
|
-
.mockImplementation();
|
|
194
|
-
|
|
195
|
-
await diveAR.launch(mockUri, options);
|
|
196
|
-
|
|
197
|
-
expect(mockSceneViewerLaunch).toHaveBeenCalledWith(
|
|
198
|
-
mockUri,
|
|
199
|
-
options,
|
|
200
|
-
);
|
|
201
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
202
|
-
'DIVE: Launching AR with SceneViewer ...',
|
|
203
|
-
);
|
|
204
|
-
consoleLogSpy.mockRestore();
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it('should handle SceneViewer launch errors', async () => {
|
|
208
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('Android');
|
|
209
|
-
|
|
210
|
-
const mockError = new Error('Launch failed');
|
|
211
|
-
const mockInstance = {
|
|
212
|
-
launch: jest.fn().mockImplementation(() => {
|
|
213
|
-
throw mockError;
|
|
214
|
-
}),
|
|
215
|
-
};
|
|
216
|
-
(SceneViewer as jest.Mock).mockImplementation(
|
|
217
|
-
() => mockInstance,
|
|
218
|
-
);
|
|
219
|
-
|
|
220
|
-
const consoleLogSpy = jest
|
|
221
|
-
.spyOn(console, 'log')
|
|
222
|
-
.mockImplementation();
|
|
223
|
-
const consoleErrorSpy = jest
|
|
224
|
-
.spyOn(console, 'error')
|
|
225
|
-
.mockImplementation();
|
|
226
|
-
|
|
227
|
-
try {
|
|
228
|
-
await diveAR.launch(mockUri);
|
|
229
|
-
fail('Expected launch to reject');
|
|
230
|
-
} catch (error: unknown) {
|
|
231
|
-
if (error instanceof Error) {
|
|
232
|
-
expect(error.message).toBe('Launch failed');
|
|
233
|
-
} else {
|
|
234
|
-
fail('Expected error to be an Error instance');
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
239
|
-
'DIVE: Launching AR with SceneViewer ...',
|
|
240
|
-
);
|
|
241
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
242
|
-
'Error launching SceneViewer:',
|
|
243
|
-
mockError,
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
consoleLogSpy.mockRestore();
|
|
247
|
-
consoleErrorSpy.mockRestore();
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
it('should reject on non-mobile systems', async () => {
|
|
252
|
-
(SystemInfo.GetSystem as jest.Mock).mockReturnValue('Windows');
|
|
253
|
-
|
|
254
|
-
const consoleLogSpy = jest
|
|
255
|
-
.spyOn(console, 'log')
|
|
256
|
-
.mockImplementation();
|
|
257
|
-
|
|
258
|
-
try {
|
|
259
|
-
await diveAR.launch(mockUri);
|
|
260
|
-
fail('Expected launch to reject');
|
|
261
|
-
} catch (error: unknown) {
|
|
262
|
-
if (error instanceof Error) {
|
|
263
|
-
expect(error.message).toBe(
|
|
264
|
-
'AR not supported on non-mobile systems',
|
|
265
|
-
);
|
|
266
|
-
} else {
|
|
267
|
-
fail('Expected error to be an Error instance');
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
271
|
-
'DIVE: AR not supported. Not a mobile system. (System is Windows)',
|
|
272
|
-
);
|
|
273
|
-
consoleLogSpy.mockRestore();
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { type ARSystemOptions } from '../AR';
|
|
2
|
-
import { Converter } from '../../converter/Converter';
|
|
3
|
-
import { type USDZExporterOptions } from '../../types';
|
|
4
|
-
|
|
5
|
-
export class ARQuickLook {
|
|
6
|
-
public async launch(uri: string, options?: ARSystemOptions): Promise<void> {
|
|
7
|
-
const usdzUrl = await this.convertToUSDZ(uri, options);
|
|
8
|
-
return this.launchARQuickLook(usdzUrl, options);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
private async convertToUSDZ(
|
|
12
|
-
uri: string,
|
|
13
|
-
options?: ARSystemOptions,
|
|
14
|
-
): Promise<string> {
|
|
15
|
-
// Convert the file to USDZ format
|
|
16
|
-
const usdzBuffer = await Converter.convert(uri).to('usdz', {
|
|
17
|
-
quickLookCompatible: true,
|
|
18
|
-
ar: {
|
|
19
|
-
anchoring: { type: 'plane' },
|
|
20
|
-
planeAnchoring: {
|
|
21
|
-
alignment:
|
|
22
|
-
options?.arPlacement === 'vertical'
|
|
23
|
-
? 'vertical'
|
|
24
|
-
: 'horizontal',
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
} as USDZExporterOptions);
|
|
28
|
-
|
|
29
|
-
// Create a blob from the USDZ buffer
|
|
30
|
-
const blob = new Blob([usdzBuffer], { type: 'model/vnd.usdz+zip' });
|
|
31
|
-
return URL.createObjectURL(blob);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private launchARQuickLook(
|
|
35
|
-
uri: string,
|
|
36
|
-
options?: ARSystemOptions,
|
|
37
|
-
): Promise<void> {
|
|
38
|
-
return new Promise((resolve) => {
|
|
39
|
-
if (options?.arScale === 'fixed') {
|
|
40
|
-
uri = uri.concat('#allowsContentScaling=0');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// launch ARQuickLook
|
|
44
|
-
const a = document.createElement('a');
|
|
45
|
-
a.innerHTML = '<picture></picture>'; // This is actually needed so the viewer opens instantly
|
|
46
|
-
a.rel = 'ar';
|
|
47
|
-
a.href = uri;
|
|
48
|
-
a.download = 'scene.usdz';
|
|
49
|
-
resolve();
|
|
50
|
-
a.click();
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1,144 +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 { ARQuickLook } from '../ARQuickLook';
|
|
5
|
-
import { Converter } from '../../../converter/Converter';
|
|
6
|
-
|
|
7
|
-
jest.mock('../../../scene/Scene', () => {
|
|
8
|
-
return {
|
|
9
|
-
DIVEScene: jest.fn(function () {
|
|
10
|
-
this.add = jest.fn();
|
|
11
|
-
this.children = [];
|
|
12
|
-
this.Root = {
|
|
13
|
-
children: [],
|
|
14
|
-
};
|
|
15
|
-
this.traverse = jest.fn((callback) => {
|
|
16
|
-
this.Root.children.forEach((child: Object3D) => {
|
|
17
|
-
callback(child);
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
return this;
|
|
21
|
-
}),
|
|
22
|
-
};
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// Mock the Converter class
|
|
26
|
-
jest.mock('../../../converter/Converter', () => {
|
|
27
|
-
return {
|
|
28
|
-
Converter: {
|
|
29
|
-
convert: jest.fn().mockReturnThis(),
|
|
30
|
-
to: jest.fn().mockResolvedValue(new ArrayBuffer(0)),
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
// Mock URL.createObjectURL
|
|
36
|
-
URL.createObjectURL = jest.fn(() => 'blob:http://localhost:8080/');
|
|
37
|
-
|
|
38
|
-
// Mock document.createElement
|
|
39
|
-
document.createElement = jest.fn().mockReturnValue({
|
|
40
|
-
innerHTML: '',
|
|
41
|
-
rel: '',
|
|
42
|
-
href: '',
|
|
43
|
-
download: '',
|
|
44
|
-
click: jest.fn(),
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('ARQuickLook', () => {
|
|
48
|
-
let mockOptions: ARSystemOptions;
|
|
49
|
-
let mockModels: Object3D[];
|
|
50
|
-
let quickLook: ARQuickLook;
|
|
51
|
-
const mockUri = 'https://example.com/model.glb';
|
|
52
|
-
|
|
53
|
-
beforeEach(() => {
|
|
54
|
-
mockModels = [
|
|
55
|
-
new Object3D(),
|
|
56
|
-
new Object3D(),
|
|
57
|
-
new Object3D(),
|
|
58
|
-
];
|
|
59
|
-
mockModels[1].userData = {
|
|
60
|
-
uri: 'https://example.com',
|
|
61
|
-
};
|
|
62
|
-
mockOptions = {
|
|
63
|
-
arPlacement: 'horizontal',
|
|
64
|
-
arScale: 'auto',
|
|
65
|
-
};
|
|
66
|
-
quickLook = new ARQuickLook();
|
|
67
|
-
jest.clearAllMocks();
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe('constructor', () => {
|
|
71
|
-
it('should create an instance', () => {
|
|
72
|
-
expect(quickLook).toBeInstanceOf(ARQuickLook);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe('launch', () => {
|
|
77
|
-
it('should convert and launch with default options', async () => {
|
|
78
|
-
await quickLook.launch(mockUri);
|
|
79
|
-
|
|
80
|
-
expect(Converter.convert).toHaveBeenCalledWith(mockUri);
|
|
81
|
-
expect((Converter as any).to).toHaveBeenCalledWith('usdz', {
|
|
82
|
-
quickLookCompatible: true,
|
|
83
|
-
ar: {
|
|
84
|
-
anchoring: { type: 'plane' },
|
|
85
|
-
planeAnchoring: { alignment: 'horizontal' },
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
expect(URL.createObjectURL).toHaveBeenCalled();
|
|
89
|
-
expect(document.createElement).toHaveBeenCalledWith('a');
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should convert and launch with custom options', async () => {
|
|
93
|
-
const options: ARSystemOptions = {
|
|
94
|
-
arPlacement: 'vertical',
|
|
95
|
-
arScale: 'fixed',
|
|
96
|
-
};
|
|
97
|
-
await quickLook.launch(mockUri, options);
|
|
98
|
-
|
|
99
|
-
expect(Converter.convert).toHaveBeenCalledWith(mockUri);
|
|
100
|
-
expect((Converter as any).to).toHaveBeenCalledWith('usdz', {
|
|
101
|
-
quickLookCompatible: true,
|
|
102
|
-
ar: {
|
|
103
|
-
anchoring: { type: 'plane' },
|
|
104
|
-
planeAnchoring: { alignment: 'vertical' },
|
|
105
|
-
},
|
|
106
|
-
});
|
|
107
|
-
expect(URL.createObjectURL).toHaveBeenCalled();
|
|
108
|
-
expect(document.createElement).toHaveBeenCalledWith('a');
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('should handle conversion errors', async () => {
|
|
112
|
-
const error = new Error('Conversion failed');
|
|
113
|
-
((Converter as any).to as jest.Mock).mockRejectedValueOnce(error);
|
|
114
|
-
|
|
115
|
-
await expect(quickLook.launch(mockUri)).rejects.toThrow(error);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('should create a blob with correct MIME type', async () => {
|
|
119
|
-
const mockBuffer = new ArrayBuffer(100);
|
|
120
|
-
((Converter as any).to as jest.Mock).mockResolvedValueOnce(
|
|
121
|
-
mockBuffer,
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
await quickLook.launch(mockUri);
|
|
125
|
-
|
|
126
|
-
expect(URL.createObjectURL).toHaveBeenCalledWith(
|
|
127
|
-
expect.objectContaining({
|
|
128
|
-
type: 'model/vnd.usdz+zip',
|
|
129
|
-
}),
|
|
130
|
-
);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('should add scale parameter when arScale is fixed', async () => {
|
|
134
|
-
const options: ARSystemOptions = {
|
|
135
|
-
arPlacement: 'horizontal',
|
|
136
|
-
arScale: 'fixed',
|
|
137
|
-
};
|
|
138
|
-
await quickLook.launch(mockUri, options);
|
|
139
|
-
|
|
140
|
-
const anchor = document.createElement('a');
|
|
141
|
-
expect(anchor.href).toContain('#allowsContentScaling=0');
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
});
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { type ARSystemOptions } from '../AR';
|
|
2
|
-
|
|
3
|
-
export class SceneViewer {
|
|
4
|
-
public launch(uri: string, options?: ARSystemOptions): void {
|
|
5
|
-
const location = self.location.toString();
|
|
6
|
-
const anchor = document.createElement('a');
|
|
7
|
-
const params = this._createParams(location, uri, options);
|
|
8
|
-
const intent = this._createIntent(location, uri, params);
|
|
9
|
-
|
|
10
|
-
anchor.setAttribute('href', intent);
|
|
11
|
-
anchor.click();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Creates the base URL parameters for SceneViewer
|
|
16
|
-
* @param location Current page location URL
|
|
17
|
-
* @returns URLSearchParams with base configuration
|
|
18
|
-
*/
|
|
19
|
-
private _createParams(
|
|
20
|
-
location: string,
|
|
21
|
-
uri: string,
|
|
22
|
-
options?: ARSystemOptions,
|
|
23
|
-
): URLSearchParams {
|
|
24
|
-
const modelUrl = new URL(uri, location);
|
|
25
|
-
const params = new URLSearchParams(modelUrl.search);
|
|
26
|
-
|
|
27
|
-
// Set AR mode as preferred
|
|
28
|
-
params.set('mode', 'ar_preferred');
|
|
29
|
-
|
|
30
|
-
// Apply any custom options
|
|
31
|
-
this._applyScaleOption(params, options);
|
|
32
|
-
this._applyPlacementOption(params, options);
|
|
33
|
-
|
|
34
|
-
// Apply additional parameters if present
|
|
35
|
-
this._applySoundOption(params, location);
|
|
36
|
-
this._applyLinkOption(params, location);
|
|
37
|
-
|
|
38
|
-
return params;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Applies the scale option to the parameters
|
|
43
|
-
* If scale is set to 'fixed', the model will not be resizable in AR
|
|
44
|
-
* @param params URLSearchParams to modify
|
|
45
|
-
*/
|
|
46
|
-
private _applyScaleOption(
|
|
47
|
-
params: URLSearchParams,
|
|
48
|
-
options?: ARSystemOptions,
|
|
49
|
-
): void {
|
|
50
|
-
if (options?.arScale === 'fixed') {
|
|
51
|
-
params.set('resizable', 'false');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Applies the placement option to the parameters
|
|
57
|
-
* If placement is set to 'vertical', vertical placement will be enabled
|
|
58
|
-
* @param params URLSearchParams to modify
|
|
59
|
-
*/
|
|
60
|
-
private _applyPlacementOption(
|
|
61
|
-
params: URLSearchParams,
|
|
62
|
-
options?: ARSystemOptions,
|
|
63
|
-
): void {
|
|
64
|
-
if (options?.arPlacement === 'vertical') {
|
|
65
|
-
params.set('enable_vertical_placement', 'true');
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Applies the sound option to the parameters if present
|
|
71
|
-
* This will resolve any relative sound URLs to absolute URLs
|
|
72
|
-
* @param params URLSearchParams to modify
|
|
73
|
-
* @param location Current page location URL
|
|
74
|
-
*/
|
|
75
|
-
private _applySoundOption(params: URLSearchParams, location: string): void {
|
|
76
|
-
if (params.has('sound')) {
|
|
77
|
-
const soundUrl = new URL(params.get('sound')!, location);
|
|
78
|
-
params.set('sound', soundUrl.toString());
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Applies the link option to the parameters if present
|
|
84
|
-
* This will resolve any relative link URLs to absolute URLs
|
|
85
|
-
* @param params URLSearchParams to modify
|
|
86
|
-
* @param location Current page location URL
|
|
87
|
-
*/
|
|
88
|
-
private _applyLinkOption(params: URLSearchParams, location: string): void {
|
|
89
|
-
if (params.has('link')) {
|
|
90
|
-
const linkUrl = new URL(params.get('link')!, location);
|
|
91
|
-
params.set('link', linkUrl.toString());
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Creates the Android Intent URL for SceneViewer
|
|
97
|
-
* @param params URLSearchParams containing all configuration
|
|
98
|
-
* @param location Current page location URL
|
|
99
|
-
* @returns The complete Intent URL
|
|
100
|
-
*/
|
|
101
|
-
private _createIntent(
|
|
102
|
-
location: string,
|
|
103
|
-
uri: string,
|
|
104
|
-
params: URLSearchParams,
|
|
105
|
-
): string {
|
|
106
|
-
const locationUrl = new URL(location);
|
|
107
|
-
const modelUrl = new URL(uri, location);
|
|
108
|
-
const noArViewerSigil = '#model-viewer-no-ar-fallback';
|
|
109
|
-
|
|
110
|
-
locationUrl.hash = noArViewerSigil;
|
|
111
|
-
|
|
112
|
-
// Construct the intent URL with all parameters
|
|
113
|
-
return `intent://arvr.google.com/scene-viewer/1.2?${
|
|
114
|
-
params.toString() + '&file=' + modelUrl.toString()
|
|
115
|
-
}#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;S.browser_fallback_url=${encodeURIComponent(
|
|
116
|
-
locationUrl.toString(),
|
|
117
|
-
)};end;`;
|
|
118
|
-
}
|
|
119
|
-
}
|