@shopware-ag/dive 1.16.0 → 1.16.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 (143) hide show
  1. package/README.md +271 -40
  2. package/build/dive.cjs +575 -159
  3. package/build/dive.cjs.map +1 -1
  4. package/build/dive.d.cts +83 -57
  5. package/build/dive.d.ts +83 -57
  6. package/build/dive.js +614 -164
  7. package/build/dive.js.map +1 -1
  8. package/package.json +72 -60
  9. package/src/__test__/DIVE.test.ts +35 -31
  10. package/src/animation/AnimationSystem.ts +4 -4
  11. package/src/animation/__test__/AnimationSystem.test.ts +3 -3
  12. package/src/axiscamera/AxisCamera.ts +31 -11
  13. package/src/axiscamera/__test__/AxisCamera.test.ts +18 -10
  14. package/src/camera/PerspectiveCamera.ts +28 -13
  15. package/src/camera/__test__/PerspectiveCamera.test.ts +2 -2
  16. package/src/com/Communication.ts +282 -100
  17. package/src/com/__test__/Communication.test.ts +207 -141
  18. package/src/com/actions/camera/computeencompassingview.ts +8 -7
  19. package/src/com/actions/camera/getcameratransform.ts +8 -7
  20. package/src/com/actions/camera/movecamera.ts +16 -13
  21. package/src/com/actions/camera/resetcamera.ts +4 -3
  22. package/src/com/actions/camera/setcameralayer.ts +4 -3
  23. package/src/com/actions/camera/setcameratransform.ts +8 -7
  24. package/src/com/actions/camera/zoomcamera.ts +4 -3
  25. package/src/com/actions/index.ts +54 -54
  26. package/src/com/actions/media/generatemedia.ts +17 -13
  27. package/src/com/actions/object/addobject.ts +5 -4
  28. package/src/com/actions/object/deleteobject.ts +5 -4
  29. package/src/com/actions/object/deselectobject.ts +5 -4
  30. package/src/com/actions/object/getallobjects.ts +5 -4
  31. package/src/com/actions/object/getobjects.ts +5 -4
  32. package/src/com/actions/object/model/dropit.ts +4 -3
  33. package/src/com/actions/object/model/modelloaded.ts +4 -3
  34. package/src/com/actions/object/model/placeonfloor.ts +4 -3
  35. package/src/com/actions/object/selectobject.ts +5 -4
  36. package/src/com/actions/object/setparent.ts +8 -7
  37. package/src/com/actions/object/updateobject.ts +5 -4
  38. package/src/com/actions/scene/exportscene.ts +5 -4
  39. package/src/com/actions/scene/getallscenedata.ts +24 -18
  40. package/src/com/actions/scene/setbackground.ts +4 -3
  41. package/src/com/actions/scene/updatescene.ts +10 -9
  42. package/src/com/actions/toolbox/select/setgizmomode.ts +4 -3
  43. package/src/com/actions/toolbox/transform/setgizmovisible.ts +4 -3
  44. package/src/com/actions/toolbox/usetool.ts +5 -4
  45. package/src/com/types/COMBaseEntity.ts +2 -2
  46. package/src/com/types/COMEntity.ts +6 -6
  47. package/src/com/types/COMEntityType.ts +1 -1
  48. package/src/com/types/COMGeometry.ts +2 -2
  49. package/src/com/types/COMGroup.ts +3 -3
  50. package/src/com/types/COMLight.ts +3 -3
  51. package/src/com/types/COMMaterial.ts +2 -2
  52. package/src/com/types/COMModel.ts +4 -4
  53. package/src/com/types/COMPov.ts +3 -3
  54. package/src/com/types/COMPrimitive.ts +5 -5
  55. package/src/com/types/index.ts +10 -10
  56. package/src/constant/AxisHelperColors.ts +1 -1
  57. package/src/constant/GridColors.ts +1 -1
  58. package/src/controls/OrbitControls.ts +62 -29
  59. package/src/controls/__test__/OrbitControls.test.ts +133 -39
  60. package/src/dive.ts +82 -36
  61. package/src/gizmo/Gizmo.ts +21 -13
  62. package/src/gizmo/handles/AxisHandle.ts +40 -17
  63. package/src/gizmo/handles/RadialHandle.ts +39 -15
  64. package/src/gizmo/handles/ScaleHandle.ts +62 -25
  65. package/src/gizmo/plane/GizmoPlane.ts +5 -6
  66. package/src/gizmo/rotate/RotateGizmo.ts +58 -16
  67. package/src/gizmo/scale/ScaleGizmo.ts +37 -15
  68. package/src/gizmo/translate/TranslateGizmo.ts +34 -14
  69. package/src/grid/Grid.ts +13 -5
  70. package/src/grid/__test__/Grid.test.ts +5 -3
  71. package/src/group/Group.ts +9 -7
  72. package/src/group/__test__/Group.test.ts +8 -6
  73. package/src/helper/applyMixins/__test__/applyMixins.test.ts +9 -6
  74. package/src/helper/applyMixins/applyMixins.ts +6 -3
  75. package/src/helper/findInterface/__test__/findInterface.test.ts +28 -18
  76. package/src/helper/findInterface/findInterface.ts +7 -4
  77. package/src/helper/findSceneRecursive/__test__/findSceneRecursive.test.ts +1 -1
  78. package/src/helper/findSceneRecursive/findSceneRecursive.ts +1 -1
  79. package/src/helper/getObjectDelta/__test__/getObjectDelta.test.ts +43 -7
  80. package/src/helper/getObjectDelta/getObjectDelta.ts +13 -9
  81. package/src/helper/isInterface/__test__/implementsInterface.test.ts +1 -1
  82. package/src/helper/isInterface/implementsInterface.ts +6 -3
  83. package/src/info/Info.ts +20 -16
  84. package/src/info/__test__/Info.test.ts +67 -36
  85. package/src/interface/Draggable.ts +2 -2
  86. package/src/interface/Hoverable.ts +2 -2
  87. package/src/interface/Movable.ts +1 -1
  88. package/src/interface/Rotatable.ts +1 -1
  89. package/src/interface/Scalable.ts +1 -1
  90. package/src/io/IO.ts +21 -43
  91. package/src/io/__test__/IO.test.ts +16 -62
  92. package/src/io/gltf/GLTFIO.ts +34 -31
  93. package/src/io/gltf/__test__/GLTFIO.test.ts +88 -78
  94. package/src/light/PointLight.ts +42 -9
  95. package/src/light/SceneLight.ts +5 -5
  96. package/src/light/__test__/AmbientLight.test.ts +5 -4
  97. package/src/light/__test__/PointLight.test.ts +14 -10
  98. package/src/light/__test__/SceneLight.test.ts +19 -13
  99. package/src/loadingmanager/LoadingManager.ts +11 -6
  100. package/src/loadingmanager/__test__/LoadingManager.test.ts +14 -9
  101. package/src/math/__test__/DIVEMath.test.ts +1 -1
  102. package/src/math/ceil/__test__/ceilExp.test.ts +1 -1
  103. package/src/math/ceil/ceilExp.ts +2 -2
  104. package/src/math/floor/__test__/floorExp.test.ts +1 -1
  105. package/src/math/floor/floorExp.ts +2 -2
  106. package/src/math/helper/__test__/shift.test.ts +1 -1
  107. package/src/math/helper/shift.ts +1 -1
  108. package/src/math/index.ts +7 -7
  109. package/src/math/round/__test__/roundExp.test.ts +1 -1
  110. package/src/math/round/roundExp.ts +6 -3
  111. package/src/math/signedAngleTo/__test__/signedAngleTo.test.ts +10 -4
  112. package/src/math/signedAngleTo/signedAngleTo.ts +11 -4
  113. package/src/math/toFixed/__test__/toFixedExp.test.ts +9 -9
  114. package/src/math/toFixed/toFixedExp.ts +6 -3
  115. package/src/math/truncate/__test__/truncateExp.test.ts +1 -1
  116. package/src/math/truncate/truncateExp.ts +6 -3
  117. package/src/mediacreator/MediaCreator.ts +20 -10
  118. package/src/mediacreator/__test__/MediaCreator.test.ts +27 -12
  119. package/src/model/Model.ts +35 -7
  120. package/src/model/__test__/Model.test.ts +71 -44
  121. package/src/node/Node.ts +34 -12
  122. package/src/node/__test__/Node.test.ts +17 -13
  123. package/src/primitive/Primitive.ts +78 -13
  124. package/src/primitive/__test__/Primitive.test.ts +49 -38
  125. package/src/primitive/floor/Floor.ts +14 -3
  126. package/src/primitive/floor/__test__/Floor.test.ts +10 -4
  127. package/src/renderer/Renderer.ts +46 -15
  128. package/src/renderer/__test__/Renderer.test.ts +74 -24
  129. package/src/scene/Scene.ts +9 -3
  130. package/src/scene/__test__/Scene.test.ts +2 -2
  131. package/src/scene/root/Root.ts +142 -75
  132. package/src/scene/root/__test__/Root.test.ts +439 -111
  133. package/src/toolbox/BaseTool.ts +69 -33
  134. package/src/toolbox/Toolbox.ts +37 -17
  135. package/src/toolbox/__test__/BaseTool.test.ts +324 -160
  136. package/src/toolbox/__test__/Toolbox.test.ts +31 -14
  137. package/src/toolbox/select/SelectTool.ts +24 -19
  138. package/src/toolbox/select/__test__/SelectTool.test.ts +95 -59
  139. package/src/toolbox/transform/TransformTool.ts +40 -17
  140. package/src/toolbox/transform/__test__/TransformTool.test.ts +22 -15
  141. package/src/types/SceneObjects.ts +8 -8
  142. package/src/types/SceneType.ts +3 -3
  143. package/src/types/index.ts +3 -6
@@ -2,8 +2,10 @@
2
2
  * Find the difference between two objects.
3
3
  */
4
4
 
5
- export const getObjectDelta = <T extends object>(a: T, b: Partial<T>): Partial<T> => {
6
-
5
+ export const getObjectDelta = <T extends object>(
6
+ a: T,
7
+ b: Partial<T>,
8
+ ): Partial<T> => {
7
9
  // if a and b have no entries we have no delta
8
10
  if (Object.keys(a).length === 0 && Object.keys(b).length === 0) {
9
11
  return {};
@@ -17,7 +19,6 @@ export const getObjectDelta = <T extends object>(a: T, b: Partial<T>): Partial<T
17
19
  let delta = {};
18
20
 
19
21
  Object.keys(b).forEach((key) => {
20
-
21
22
  // if key is not in a we have a delta
22
23
  if (!Object.keys(a).includes(key)) {
23
24
  delta = { ...delta, [key]: b[key as keyof object] };
@@ -26,7 +27,6 @@ export const getObjectDelta = <T extends object>(a: T, b: Partial<T>): Partial<T
26
27
 
27
28
  // assumption: b[key] is an array
28
29
  if (Array.isArray(b[key as keyof object])) {
29
-
30
30
  // if a[key] is not an array we have a delta
31
31
  if (!Array.isArray(a[key as keyof object])) {
32
32
  delta = { ...delta, [key]: b[key as keyof object] };
@@ -54,7 +54,10 @@ export const getObjectDelta = <T extends object>(a: T, b: Partial<T>): Partial<T
54
54
 
55
55
  bArray.forEach((entry, index) => {
56
56
  // getObjectDelta in array
57
- const inArrayDelta = getObjectDelta(aArray[index], bArray[index]);
57
+ const inArrayDelta = getObjectDelta(
58
+ aArray[index],
59
+ bArray[index],
60
+ );
58
61
 
59
62
  // if inArrayDelta has more then 0 entries we have a delta
60
63
  if (Object.keys(inArrayDelta).length) {
@@ -68,13 +71,11 @@ export const getObjectDelta = <T extends object>(a: T, b: Partial<T>): Partial<T
68
71
  return;
69
72
  }
70
73
 
71
-
72
74
  return;
73
75
  }
74
76
 
75
77
  // assumption: b[key] is an object
76
78
  if (typeof b[key as keyof object] === 'object') {
77
-
78
79
  // if a[key] is not an object we have a delta
79
80
  if (typeof a[key as keyof object] !== 'object') {
80
81
  delta = { ...delta, [key]: b[key as keyof object] };
@@ -82,7 +83,10 @@ export const getObjectDelta = <T extends object>(a: T, b: Partial<T>): Partial<T
82
83
  }
83
84
 
84
85
  // recursive: find objectDelta in a and b
85
- const objectDelta = getObjectDelta(a[key as keyof object], b[key as keyof object]);
86
+ const objectDelta = getObjectDelta(
87
+ a[key as keyof object],
88
+ b[key as keyof object],
89
+ );
86
90
 
87
91
  // if objectDelta has more than 0 entries we have a delta
88
92
  if (Object.keys(objectDelta).length) {
@@ -98,4 +102,4 @@ export const getObjectDelta = <T extends object>(a: T, b: Partial<T>): Partial<T
98
102
  });
99
103
 
100
104
  return delta;
101
- }
105
+ };
@@ -16,4 +16,4 @@ describe('dive/helper/implementsInterface', () => {
16
16
  const obj = { isInterface: true } as unknown as Object3D;
17
17
  expect(implementsInterface(obj, 'isInterface')).toBe(true);
18
18
  });
19
- });
19
+ });
@@ -1,6 +1,9 @@
1
- import { type Object3D } from "three";
1
+ import { type Object3D } from 'three';
2
2
 
3
- export function implementsInterface<T>(object: Object3D | null | undefined, discriminator: string): object is (Object3D & T) {
3
+ export function implementsInterface<T>(
4
+ object: Object3D | null | undefined,
5
+ discriminator: string,
6
+ ): object is Object3D & T {
4
7
  if (!object) return false;
5
8
  return discriminator in object;
6
- }
9
+ }
package/src/info/Info.ts CHANGED
@@ -8,17 +8,17 @@ export class DIVEInfo {
8
8
  public static GetSystem(): string {
9
9
  const platform = navigator.platform;
10
10
  if (/Android/.test(navigator.userAgent)) {
11
- return "Android";
11
+ return 'Android';
12
12
  } else if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
13
- return "iOS";
14
- } else if (platform.startsWith("Win")) {
15
- return "Windows";
16
- } else if (platform.startsWith("Mac")) {
17
- return "MacOS";
18
- } else if (platform.startsWith("Linux")) {
19
- return "Linux";
13
+ return 'iOS';
14
+ } else if (platform.startsWith('Win')) {
15
+ return 'Windows';
16
+ } else if (platform.startsWith('Mac')) {
17
+ return 'MacOS';
18
+ } else if (platform.startsWith('Linux')) {
19
+ return 'Linux';
20
20
  } else {
21
- return "Unknown";
21
+ return 'Unknown';
22
22
  }
23
23
  }
24
24
 
@@ -36,7 +36,8 @@ export class DIVEInfo {
36
36
  }
37
37
  // Check if immersive-vr session mode is supported
38
38
  try {
39
- const supported = await navigator.xr.isSessionSupported('immersive-ar');
39
+ const supported =
40
+ await navigator.xr.isSessionSupported('immersive-ar');
40
41
  this._supportsWebXR = supported;
41
42
  } catch (error) {
42
43
  this._supportsWebXR = false;
@@ -48,8 +49,8 @@ export class DIVEInfo {
48
49
  * @returns A boolean indicating whether the user's device supports AR Quick Look.
49
50
  */
50
51
  public static GetSupportsARQuickLook(): boolean {
51
- const a = document.createElement("a");
52
- if (a.relList.supports("ar")) {
52
+ const a = document.createElement('a');
53
+ if (a.relList.supports('ar')) {
53
54
  return true;
54
55
  }
55
56
 
@@ -57,7 +58,9 @@ export class DIVEInfo {
57
58
  const userAgent = navigator.userAgent;
58
59
 
59
60
  // Check if the device is running iOS
60
- const isIOS = /iPad|iPhone|iPod/.test(userAgent) && !(window as unknown as Window & { MSStream?: string }).MSStream;
61
+ const isIOS =
62
+ /iPad|iPhone|iPod/.test(userAgent) &&
63
+ !(window as unknown as Window & { MSStream?: string }).MSStream;
61
64
  if (!isIOS) {
62
65
  return false;
63
66
  }
@@ -78,7 +81,8 @@ export class DIVEInfo {
78
81
  }
79
82
 
80
83
  // Check for supported browser
81
- const isSupportedBrowser = /^((?!chrome|android).)*safari|CriOS|FxiOS/i.test(userAgent);
84
+ const isSupportedBrowser =
85
+ /^((?!chrome|android).)*safari|CriOS|FxiOS/i.test(userAgent);
82
86
  if (isSupportedBrowser) {
83
87
  return true;
84
88
  }
@@ -91,7 +95,7 @@ export class DIVEInfo {
91
95
  * @returns A boolean indicating whether the user's device is a mobile device.
92
96
  */
93
97
  public static get isMobile(): boolean {
94
- return this.GetSystem() === "Android" || this.GetSystem() === "iOS";
98
+ return this.GetSystem() === 'Android' || this.GetSystem() === 'iOS';
95
99
  }
96
100
 
97
101
  /**
@@ -111,4 +115,4 @@ export class DIVEInfo {
111
115
 
112
116
  return await this.GetSupportsWebXR();
113
117
  }
114
- }
118
+ }
@@ -3,7 +3,7 @@ import { DIVEInfo } from '../Info';
3
3
  const mockNavigator = (navigator: any) => {
4
4
  Object.defineProperty(global, 'navigator', {
5
5
  value: navigator,
6
- writable: true
6
+ writable: true,
7
7
  });
8
8
  };
9
9
 
@@ -15,44 +15,46 @@ describe('dive/info/DIVEInfo', () => {
15
15
 
16
16
  it('should get system: Windows', () => {
17
17
  mockNavigator({
18
- platform: 'Win64'
18
+ platform: 'Win64',
19
19
  });
20
20
  expect(DIVEInfo.GetSystem()).toBe('Windows');
21
21
  });
22
22
 
23
23
  it('should get system: MacOS', () => {
24
24
  mockNavigator({
25
- platform: 'MacIntel'
25
+ platform: 'MacIntel',
26
26
  });
27
27
  expect(DIVEInfo.GetSystem()).toBe('MacOS');
28
28
  });
29
29
 
30
30
  it('should get system: Linux', () => {
31
31
  mockNavigator({
32
- platform: 'Linux'
32
+ platform: 'Linux',
33
33
  });
34
34
  expect(DIVEInfo.GetSystem()).toBe('Linux');
35
35
  });
36
36
 
37
37
  it('should get system: Android', () => {
38
38
  mockNavigator({
39
- userAgent: 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
40
- platform: 'Linux'
39
+ userAgent:
40
+ 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
41
+ platform: 'Linux',
41
42
  });
42
43
  expect(DIVEInfo.GetSystem()).toBe('Android');
43
44
  });
44
45
 
45
46
  it('should get system: iOS', () => {
46
47
  mockNavigator({
47
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_1 like Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
48
- platform: 'iPhone'
48
+ userAgent:
49
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_1 like Mac OS X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
50
+ platform: 'iPhone',
49
51
  });
50
52
  expect(DIVEInfo.GetSystem()).toBe('iOS');
51
53
  });
52
54
 
53
55
  it('should get system: Unknown', () => {
54
56
  mockNavigator({
55
- platform: 'Unknown'
57
+ platform: 'Unknown',
56
58
  });
57
59
  expect(DIVEInfo.GetSystem()).toBe('Unknown');
58
60
  });
@@ -62,7 +64,7 @@ describe('dive/info/DIVEInfo', () => {
62
64
  mockNavigator({
63
65
  xr: {
64
66
  isSessionSupported: jest.fn().mockResolvedValue(true),
65
- }
67
+ },
66
68
  });
67
69
  const supports = await DIVEInfo.GetSupportsWebXR();
68
70
  expect(supports).toBe(true);
@@ -71,7 +73,7 @@ describe('dive/info/DIVEInfo', () => {
71
73
  it('should not support webXR (xr undefined)', async () => {
72
74
  DIVEInfo['_supportsWebXR'] = null;
73
75
  mockNavigator({
74
- xr: undefined
76
+ xr: undefined,
75
77
  });
76
78
  const supports = await DIVEInfo.GetSupportsWebXR();
77
79
  expect(supports).toBe(false);
@@ -82,7 +84,7 @@ describe('dive/info/DIVEInfo', () => {
82
84
  mockNavigator({
83
85
  xr: {
84
86
  isSessionSupported: jest.fn().mockResolvedValue(false),
85
- }
87
+ },
86
88
  });
87
89
  const supports = await DIVEInfo.GetSupportsWebXR();
88
90
  expect(supports).toBe(false);
@@ -93,7 +95,7 @@ describe('dive/info/DIVEInfo', () => {
93
95
  mockNavigator({
94
96
  xr: {
95
97
  isSessionSupported: jest.fn().mockRejectedValue('error'),
96
- }
98
+ },
97
99
  });
98
100
  const supports = await DIVEInfo.GetSupportsWebXR();
99
101
  expect(supports).toBe(false);
@@ -104,7 +106,7 @@ describe('dive/info/DIVEInfo', () => {
104
106
  mockNavigator({
105
107
  xr: {
106
108
  isSessionSupported: jest.fn().mockRejectedValue('error'),
107
- }
109
+ },
108
110
  });
109
111
  const supports = await DIVEInfo.GetSupportsWebXR();
110
112
  expect(supports).toBe(true);
@@ -115,7 +117,7 @@ describe('dive/info/DIVEInfo', () => {
115
117
  mockNavigator({
116
118
  xr: {
117
119
  isSessionSupported: jest.fn().mockRejectedValue('error'),
118
- }
120
+ },
119
121
  });
120
122
  const supports = await DIVEInfo.GetSupportsWebXR();
121
123
  expect(supports).toBe(false);
@@ -123,90 +125,119 @@ describe('dive/info/DIVEInfo', () => {
123
125
 
124
126
  it('should support ARQuickLook with feature detection', () => {
125
127
  mockNavigator({
126
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.'
128
+ userAgent:
129
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.',
127
130
  });
128
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => true } } as unknown as HTMLAnchorElement);
131
+ jest.spyOn(document, 'createElement').mockReturnValue({
132
+ relList: { supports: () => true },
133
+ } as unknown as HTMLAnchorElement);
129
134
  const supports = DIVEInfo.GetSupportsARQuickLook();
130
135
  expect(supports).toBe(true);
131
136
  });
132
137
 
133
138
  it('should support ARQuickLook (iPhone, iOS 15, Safari)', () => {
134
139
  mockNavigator({
135
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.'
140
+ userAgent:
141
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Mobile/15E148 Safari/604.',
136
142
  });
137
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
143
+ jest.spyOn(document, 'createElement').mockReturnValue({
144
+ relList: { supports: () => false },
145
+ } as unknown as HTMLAnchorElement);
138
146
  const supports = DIVEInfo.GetSupportsARQuickLook();
139
147
  expect(supports).toBe(true);
140
148
  });
141
149
 
142
150
  it('should support ARQuickLook (iPhone, iOS 17, Google)', () => {
143
151
  mockNavigator({
144
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/277.0.555192628 Mobile/15E148 Safari/604.'
152
+ userAgent:
153
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) GSA/277.0.555192628 Mobile/15E148 Safari/604.',
145
154
  });
146
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
155
+ jest.spyOn(document, 'createElement').mockReturnValue({
156
+ relList: { supports: () => false },
157
+ } as unknown as HTMLAnchorElement);
147
158
  const supports = DIVEInfo.GetSupportsARQuickLook();
148
159
  expect(supports).toBe(true);
149
160
  });
150
161
 
151
162
  it('should support ARQuickLook (iPhone, iOS 17, Chrome)', () => {
152
163
  mockNavigator({
153
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/126.0.6478.153 Mobile/15E148 Safari/604.'
164
+ userAgent:
165
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/126.0.6478.153 Mobile/15E148 Safari/604.',
154
166
  });
155
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
167
+ jest.spyOn(document, 'createElement').mockReturnValue({
168
+ relList: { supports: () => false },
169
+ } as unknown as HTMLAnchorElement);
156
170
  const supports = DIVEInfo.GetSupportsARQuickLook();
157
171
  expect(supports).toBe(true);
158
172
  });
159
173
 
160
174
  it('should support ARQuickLook (iPhone, iOS 17, Chrome)', () => {
161
175
  mockNavigator({
162
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 CriOS/604.'
176
+ userAgent:
177
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 CriOS/604.',
163
178
  });
164
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
179
+ jest.spyOn(document, 'createElement').mockReturnValue({
180
+ relList: { supports: () => false },
181
+ } as unknown as HTMLAnchorElement);
165
182
  const supports = DIVEInfo.GetSupportsARQuickLook();
166
183
  expect(supports).toBe(true);
167
184
  });
168
185
 
169
186
  it('should support ARQuickLook (iPhone, iOS 17, Firefox)', () => {
170
187
  mockNavigator({
171
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 FxiOS/604.'
188
+ userAgent:
189
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 FxiOS/604.',
172
190
  });
173
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
191
+ jest.spyOn(document, 'createElement').mockReturnValue({
192
+ relList: { supports: () => false },
193
+ } as unknown as HTMLAnchorElement);
174
194
  const supports = DIVEInfo.GetSupportsARQuickLook();
175
195
  expect(supports).toBe(true);
176
196
  });
177
197
 
178
198
  it('should not support ARQuickLook (Android)', () => {
179
199
  mockNavigator({
180
- userAgent: 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.3'
200
+ userAgent:
201
+ 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.3',
181
202
  });
182
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
203
+ jest.spyOn(document, 'createElement').mockReturnValue({
204
+ relList: { supports: () => false },
205
+ } as unknown as HTMLAnchorElement);
183
206
  const supports = DIVEInfo.GetSupportsARQuickLook();
184
207
  expect(supports).toBe(false);
185
208
  });
186
209
 
187
210
  it('should not support ARQuickLook (iPhone, no iOS version)', () => {
188
211
  mockNavigator({
189
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 Safari/604.'
212
+ userAgent:
213
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 Safari/604.',
190
214
  });
191
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
215
+ jest.spyOn(document, 'createElement').mockReturnValue({
216
+ relList: { supports: () => false },
217
+ } as unknown as HTMLAnchorElement);
192
218
  const supports = DIVEInfo.GetSupportsARQuickLook();
193
219
  expect(supports).toBe(false);
194
220
  });
195
221
 
196
222
  it('should not support ARQuickLook (iPhone, iOS 17, no browser)', () => {
197
223
  mockNavigator({
198
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X)'
224
+ userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X)',
199
225
  });
200
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
226
+ jest.spyOn(document, 'createElement').mockReturnValue({
227
+ relList: { supports: () => false },
228
+ } as unknown as HTMLAnchorElement);
201
229
  const supports = DIVEInfo.GetSupportsARQuickLook();
202
230
  expect(supports).toBe(false);
203
231
  });
204
232
 
205
233
  it('should not support ARQuickLook (iPhone, iOS <12, Safari)', () => {
206
234
  mockNavigator({
207
- userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_1 like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 Safari/604.'
235
+ userAgent:
236
+ 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_1 like Mac OS X) AppleWebKit/605.1.11 (KHTML, like Gecko) Version/11.1 Mobile/11E148 Safari/604.',
208
237
  });
209
- jest.spyOn(document, 'createElement').mockReturnValue({ relList: { supports: () => false } } as unknown as HTMLAnchorElement);
238
+ jest.spyOn(document, 'createElement').mockReturnValue({
239
+ relList: { supports: () => false },
240
+ } as unknown as HTMLAnchorElement);
210
241
  const supports = DIVEInfo.GetSupportsARQuickLook();
211
242
  expect(supports).toBe(false);
212
243
  });
@@ -264,4 +295,4 @@ describe('dive/info/DIVEInfo', () => {
264
295
  jest.spyOn(DIVEInfo, 'GetSupportsWebXR').mockResolvedValue(false);
265
296
  expect(await DIVEInfo.GetIsARCapable()).toBe(false);
266
297
  });
267
- });
298
+ });
@@ -4,11 +4,11 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import { type DraggableEvent } from "../toolbox/BaseTool";
7
+ import { type DraggableEvent } from '../toolbox/BaseTool';
8
8
 
9
9
  export interface DIVEDraggable {
10
10
  isDraggable: true;
11
11
  onDragStart?: (e: DraggableEvent) => void;
12
12
  onDrag?: (e: DraggableEvent) => void;
13
13
  onDragEnd?: (e: DraggableEvent) => void;
14
- }
14
+ }
@@ -4,11 +4,11 @@
4
4
  * @module
5
5
  */
6
6
 
7
- import { type Intersection } from "three";
7
+ import { type Intersection } from 'three';
8
8
 
9
9
  export interface DIVEHoverable {
10
10
  isHoverable: true;
11
11
  onPointerEnter?: (i: Intersection) => void;
12
12
  onPointerOver?: (i: Intersection) => void;
13
13
  onPointerLeave?: () => void;
14
- }
14
+ }
@@ -9,4 +9,4 @@ export interface DIVEMovable {
9
9
  onMoveStart?: () => void;
10
10
  onMove?: () => void;
11
11
  onMoveEnd?: () => void;
12
- }
12
+ }
@@ -7,4 +7,4 @@
7
7
  export interface DIVERotatable {
8
8
  isRotatable: true;
9
9
  onRotate?: () => void;
10
- }
10
+ }
@@ -7,4 +7,4 @@
7
7
  export interface DIVEScalable {
8
8
  isScalable: true;
9
9
  onScale?: () => void;
10
- }
10
+ }
package/src/io/IO.ts CHANGED
@@ -1,107 +1,85 @@
1
- import { DIVEGLTFIO } from "./gltf/GLTFIO";
1
+ import { DIVEGLTFIO } from './gltf/GLTFIO';
2
2
 
3
- import { type DIVESceneFileType } from "../types";
4
- import { type DIVEScene } from "../scene/Scene";
3
+ import { type DIVESceneFileType } from '../types';
4
+ import { type DIVEScene } from '../scene/Scene';
5
5
 
6
6
  export class DIVEIO {
7
-
8
7
  private _scene: DIVEScene;
9
8
 
10
9
  private _gltfIO: DIVEGLTFIO;
11
10
 
12
11
  constructor(scene: DIVEScene) {
13
-
14
12
  this._scene = scene;
15
13
 
16
14
  this._gltfIO = new DIVEGLTFIO();
17
-
18
15
  }
19
16
 
20
- public Import<FileType extends keyof DIVESceneFileType>(type: FileType, url: string): Promise<DIVESceneFileType[FileType] | null> {
21
-
17
+ public Import<FileType extends keyof DIVESceneFileType>(
18
+ type: FileType,
19
+ url: string,
20
+ ): Promise<DIVESceneFileType[FileType] | null> {
22
21
  return this._importFromURL(type, url)
23
22
 
24
23
  .catch((error) => {
25
-
26
24
  console.error(error);
27
25
 
28
26
  return null;
29
-
30
27
  });
31
-
32
28
  }
33
29
 
34
- public Export<FileType extends keyof DIVESceneFileType>(type: FileType): Promise<string | null> {
35
-
30
+ public Export<FileType extends keyof DIVESceneFileType>(
31
+ type: FileType,
32
+ ): Promise<string | null> {
36
33
  return this._exportToURL(type)
37
34
 
38
35
  .catch((error) => {
39
-
40
36
  console.error(error);
41
37
 
42
38
  return null;
43
-
44
39
  });
45
-
46
40
  }
47
41
 
48
- private _importFromURL<FileType extends keyof DIVESceneFileType>(type: FileType, url: string): Promise<DIVESceneFileType[FileType]> {
49
-
42
+ private _importFromURL<FileType extends keyof DIVESceneFileType>(
43
+ type: FileType,
44
+ url: string,
45
+ ): Promise<DIVESceneFileType[FileType]> {
50
46
  switch (type) {
51
-
52
47
  case 'glb': {
53
-
54
48
  return this._gltfIO.Import(url);
55
-
56
49
  }
57
50
 
58
51
  default: {
59
-
60
52
  return Promise.reject('Unsupported file type: ' + type);
61
-
62
53
  }
63
-
64
54
  }
65
55
  }
66
56
 
67
- private _exportToURL<FileType extends keyof DIVESceneFileType>(type: FileType): Promise<string> {
68
-
57
+ private _exportToURL<FileType extends keyof DIVESceneFileType>(
58
+ type: FileType,
59
+ ): Promise<string> {
69
60
  switch (type) {
70
-
71
61
  case 'glb': {
72
-
73
62
  return new Promise((resolve, reject) => {
74
-
75
- this._gltfIO.Export(this._scene, true, true)
63
+ this._gltfIO
64
+ .Export(this._scene, true, true)
76
65
 
77
66
  .then((data) => {
78
-
79
- resolve(this._createBlobURL(data))
80
-
67
+ resolve(this._createBlobURL(data));
81
68
  })
82
69
 
83
70
  .catch((error) => {
84
-
85
71
  reject(error);
86
-
87
72
  });
88
73
  });
89
-
90
74
  }
91
75
 
92
76
  default: {
93
-
94
77
  return Promise.reject('Unsupported file type: ' + type);
95
-
96
78
  }
97
-
98
79
  }
99
80
  }
100
81
 
101
82
  private _createBlobURL(data: ArrayBuffer): string {
102
-
103
83
  return URL.createObjectURL(new Blob([data]));
104
-
105
84
  }
106
-
107
- }
85
+ }