@shopware-ag/dive 1.16.7 → 1.16.9
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 +116 -21
- package/build/dive.cjs.map +1 -1
- package/build/dive.d.cts +86 -72
- package/build/dive.d.ts +86 -72
- package/build/dive.js +137 -35
- package/build/dive.js.map +1 -1
- package/package.json +1 -1
- package/src/com/actions/scene/getallscenedata.ts +2 -25
- package/src/com/types/COMLight.ts +1 -0
- package/src/dive.ts +1 -0
- package/src/group/Group.ts +16 -1
- package/src/group/__test__/Group.test.ts +97 -0
- package/src/math/degToRad/__test__/degToRad.test.ts +179 -0
- package/src/math/degToRad/degToRad.ts +5 -0
- package/src/math/index.ts +6 -0
- package/src/math/radToDeg/__test__/radToDeg.test.ts +162 -0
- package/src/math/radToDeg/radToDeg.ts +5 -0
- package/src/model/Model.ts +21 -5
- package/src/model/__test__/Model.test.ts +34 -4
- package/src/node/Node.ts +21 -8
- package/src/node/__test__/Node.test.ts +35 -3
- package/src/primitive/Primitive.ts +56 -15
- package/src/primitive/__test__/Primitive.test.ts +39 -1
- package/src/scene/root/__test__/Root.test.ts +39 -0
- package/src/types/SceneData.ts +26 -0
- package/src/types/index.ts +2 -1
package/src/node/Node.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box3, Object3D, type Vector3Like } from 'three';
|
|
1
|
+
import { Box3, Object3D, Vector3, type Vector3Like } from 'three';
|
|
2
2
|
import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
|
|
3
3
|
import { DIVECommunication } from '../com/Communication';
|
|
4
4
|
|
|
@@ -14,6 +14,7 @@ export class DIVENode extends Object3D implements DIVESelectable, DIVEMovable {
|
|
|
14
14
|
|
|
15
15
|
public gizmo: TransformControls | null = null;
|
|
16
16
|
|
|
17
|
+
protected _positionWorldBuffer: Vector3;
|
|
17
18
|
protected _boundingBox: Box3;
|
|
18
19
|
|
|
19
20
|
constructor() {
|
|
@@ -21,11 +22,24 @@ export class DIVENode extends Object3D implements DIVESelectable, DIVEMovable {
|
|
|
21
22
|
|
|
22
23
|
this.layers.mask = PRODUCT_LAYER_MASK;
|
|
23
24
|
|
|
25
|
+
this._positionWorldBuffer = new Vector3();
|
|
24
26
|
this._boundingBox = new Box3();
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
public SetPosition(position: Vector3Like): void {
|
|
28
|
-
|
|
30
|
+
// if there is no parent, the object will be attached later and keep it's world position
|
|
31
|
+
if (!this.parent) {
|
|
32
|
+
this.position.set(position.x, position.y, position.z);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// if we have a parent, we have to calculate the position in the parent's coordinate system to keep the world position
|
|
37
|
+
const newPosition = new Vector3(position.x, position.y, position.z);
|
|
38
|
+
this.position.copy(this.parent.worldToLocal(newPosition));
|
|
39
|
+
|
|
40
|
+
if ('isDIVEGroup' in this.parent) {
|
|
41
|
+
(this.parent as unknown as DIVEGroup).UpdateLineTo(this);
|
|
42
|
+
}
|
|
29
43
|
}
|
|
30
44
|
|
|
31
45
|
public SetRotation(rotation: Vector3Like): void {
|
|
@@ -46,27 +60,26 @@ export class DIVENode extends Object3D implements DIVESelectable, DIVEMovable {
|
|
|
46
60
|
'UPDATE_OBJECT',
|
|
47
61
|
{
|
|
48
62
|
id: this.userData.id,
|
|
49
|
-
position: this.
|
|
63
|
+
position: this.getWorldPosition(this._positionWorldBuffer),
|
|
50
64
|
rotation: this.rotation,
|
|
51
65
|
scale: this.scale,
|
|
52
66
|
},
|
|
53
67
|
);
|
|
54
68
|
}
|
|
55
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Can be called when the object is moved from a foreign object (gizmo, parent, etc.) to update the object's position.
|
|
72
|
+
*/
|
|
56
73
|
public onMove(): void {
|
|
57
74
|
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
58
75
|
'UPDATE_OBJECT',
|
|
59
76
|
{
|
|
60
77
|
id: this.userData.id,
|
|
61
|
-
position: this.
|
|
78
|
+
position: this.getWorldPosition(this._positionWorldBuffer),
|
|
62
79
|
rotation: this.rotation,
|
|
63
80
|
scale: this.scale,
|
|
64
81
|
},
|
|
65
82
|
);
|
|
66
|
-
|
|
67
|
-
if (this.parent && 'isDIVEGroup' in this.parent) {
|
|
68
|
-
(this.parent as unknown as DIVEGroup).UpdateLineTo(this);
|
|
69
|
-
}
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
public onSelect(): void {
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { DIVENode } from '../Node';
|
|
2
2
|
import { DIVECommunication } from '../../com/Communication';
|
|
3
|
-
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
4
3
|
import { Vector3, Box3, Mesh, Color, Euler } from 'three';
|
|
4
|
+
import { type DIVEGroup } from '../../group/Group';
|
|
5
5
|
|
|
6
6
|
const intersectObjectsMock = jest.fn();
|
|
7
7
|
|
|
8
8
|
jest.mock('three', () => {
|
|
9
9
|
return {
|
|
10
|
-
Vector3: jest.fn(function (
|
|
10
|
+
Vector3: jest.fn(function (
|
|
11
|
+
x: number = 0,
|
|
12
|
+
y: number = 0,
|
|
13
|
+
z: number = 0,
|
|
14
|
+
) {
|
|
11
15
|
this.x = x;
|
|
12
16
|
this.y = y;
|
|
13
17
|
this.z = z;
|
|
@@ -92,6 +96,9 @@ jest.mock('three', () => {
|
|
|
92
96
|
this.traverse = jest.fn((callback) => {
|
|
93
97
|
callback(this.children[0]);
|
|
94
98
|
});
|
|
99
|
+
this.getWorldPosition = jest.fn(() => {
|
|
100
|
+
return new Vector3();
|
|
101
|
+
});
|
|
95
102
|
return this;
|
|
96
103
|
}),
|
|
97
104
|
Box3: jest.fn(function () {
|
|
@@ -177,7 +184,32 @@ describe('dive/node/DIVENode', () => {
|
|
|
177
184
|
});
|
|
178
185
|
|
|
179
186
|
it('should set position', () => {
|
|
180
|
-
|
|
187
|
+
const spySet = jest.spyOn(node.position, 'set');
|
|
188
|
+
const spyCopy = jest.spyOn(node.position, 'copy');
|
|
189
|
+
|
|
190
|
+
// without a parent, the node should only set it's local position
|
|
191
|
+
node.parent = null;
|
|
192
|
+
expect(() => node.SetPosition({ x: 1, y: 2, z: 3 })).not.toThrow();
|
|
193
|
+
expect(spySet).toHaveBeenCalledWith(1, 2, 3);
|
|
194
|
+
expect(spyCopy).not.toHaveBeenCalled();
|
|
195
|
+
|
|
196
|
+
// with a parent, the node should set it's position relative to the parent
|
|
197
|
+
spySet.mockClear();
|
|
198
|
+
spyCopy.mockClear();
|
|
199
|
+
node.parent = {
|
|
200
|
+
worldToLocal: jest.fn(() => new Vector3(4, 5, 6)),
|
|
201
|
+
isDIVEGroup: true,
|
|
202
|
+
UpdateLineTo: jest.fn(),
|
|
203
|
+
} as unknown as DIVENode;
|
|
204
|
+
const spyUpdateLineTo = jest.spyOn(
|
|
205
|
+
node.parent as DIVEGroup,
|
|
206
|
+
'UpdateLineTo',
|
|
207
|
+
);
|
|
208
|
+
expect(() => node.SetPosition({ x: 4, y: 5, z: 6 })).not.toThrow();
|
|
209
|
+
expect(spySet).not.toHaveBeenCalled();
|
|
210
|
+
expect(spyCopy).toHaveBeenCalledWith(
|
|
211
|
+
expect.objectContaining({ x: 4, y: 5, z: 6 }),
|
|
212
|
+
);
|
|
181
213
|
});
|
|
182
214
|
|
|
183
215
|
it('should set rotation', () => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BoxGeometry,
|
|
3
|
+
BufferAttribute,
|
|
3
4
|
BufferGeometry,
|
|
4
5
|
Color,
|
|
5
6
|
ConeGeometry,
|
|
@@ -14,6 +15,7 @@ import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
|
|
|
14
15
|
import { findSceneRecursive } from '../helper/findSceneRecursive/findSceneRecursive';
|
|
15
16
|
import { DIVENode } from '../node/Node';
|
|
16
17
|
import { type COMGeometry, type COMMaterial } from '../com/types';
|
|
18
|
+
import { DIVECommunication } from '../com/Communication';
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* A basic model class.
|
|
@@ -24,7 +26,6 @@ import { type COMGeometry, type COMMaterial } from '../com/types';
|
|
|
24
26
|
*
|
|
25
27
|
* @module
|
|
26
28
|
*/
|
|
27
|
-
|
|
28
29
|
export class DIVEPrimitive extends DIVENode {
|
|
29
30
|
readonly isDIVEPrimitive: true = true;
|
|
30
31
|
|
|
@@ -106,11 +107,25 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
public PlaceOnFloor(): void {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
110
|
+
// calculate and temporary save world position
|
|
111
|
+
const worldPos = this.getWorldPosition(this._positionWorldBuffer);
|
|
112
|
+
const oldWorldPos = worldPos.clone();
|
|
113
|
+
|
|
114
|
+
// calculate the bottom center of the bounding box and set it to world posion
|
|
115
|
+
worldPos.y = -this._boundingBox.min.y * this.scale.y;
|
|
116
|
+
|
|
117
|
+
// skip any action when the position did not change
|
|
118
|
+
if (worldPos.y === oldWorldPos.y) return;
|
|
119
|
+
|
|
120
|
+
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
121
|
+
'UPDATE_OBJECT',
|
|
122
|
+
{
|
|
123
|
+
id: this.userData.id,
|
|
124
|
+
position: worldPos,
|
|
125
|
+
rotation: this.rotation,
|
|
126
|
+
scale: this.scale,
|
|
127
|
+
},
|
|
128
|
+
);
|
|
114
129
|
}
|
|
115
130
|
|
|
116
131
|
public DropIt(): void {
|
|
@@ -159,12 +174,18 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
159
174
|
}
|
|
160
175
|
|
|
161
176
|
private assembleGeometry(geometry: COMGeometry): BufferGeometry | null {
|
|
177
|
+
// reset material to smooth shading
|
|
178
|
+
(this._mesh.material as MeshStandardMaterial).flatShading = false;
|
|
179
|
+
|
|
162
180
|
switch (geometry.name.toLowerCase()) {
|
|
163
181
|
case 'cylinder':
|
|
164
182
|
return this.createCylinderGeometry(geometry);
|
|
165
183
|
case 'sphere':
|
|
166
184
|
return this.createSphereGeometry(geometry);
|
|
167
185
|
case 'pyramid':
|
|
186
|
+
// set material to flat shading for pyramid
|
|
187
|
+
(this._mesh.material as MeshStandardMaterial).flatShading =
|
|
188
|
+
true;
|
|
168
189
|
return this.createPyramidGeometry(geometry);
|
|
169
190
|
case 'cube':
|
|
170
191
|
case 'box':
|
|
@@ -202,16 +223,36 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
202
223
|
}
|
|
203
224
|
|
|
204
225
|
private createPyramidGeometry(geometry: COMGeometry): BufferGeometry {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
geometry.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
226
|
+
// prettier-multiline-arrays-next-line-pattern: 3
|
|
227
|
+
const vertices = new Float32Array([
|
|
228
|
+
-geometry.width / 2, 0, -geometry.depth / 2, // 0
|
|
229
|
+
geometry.width / 2, 0, -geometry.depth / 2, // 1
|
|
230
|
+
geometry.width / 2, 0, geometry.depth / 2, // 2
|
|
231
|
+
-geometry.width / 2, 0, geometry.depth / 2, // 3
|
|
232
|
+
0, geometry.height, 0,
|
|
233
|
+
]);
|
|
234
|
+
|
|
235
|
+
// prettier-multiline-arrays-next-line-pattern: 3
|
|
236
|
+
const indices = new Uint16Array([
|
|
237
|
+
0, 1, 2,
|
|
238
|
+
0, 2, 3,
|
|
239
|
+
0, 4, 1,
|
|
240
|
+
1, 4, 2,
|
|
241
|
+
2, 4, 3,
|
|
242
|
+
3, 4, 0,
|
|
243
|
+
]);
|
|
244
|
+
|
|
245
|
+
const geometryBuffer = new BufferGeometry();
|
|
246
|
+
geometryBuffer.setAttribute(
|
|
247
|
+
'position',
|
|
248
|
+
new BufferAttribute(vertices, 3),
|
|
211
249
|
);
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
250
|
+
geometryBuffer.setIndex(new BufferAttribute(indices, 1));
|
|
251
|
+
geometryBuffer.computeVertexNormals();
|
|
252
|
+
|
|
253
|
+
geometryBuffer.computeBoundingBox();
|
|
254
|
+
geometryBuffer.computeBoundingSphere();
|
|
255
|
+
return geometryBuffer;
|
|
215
256
|
}
|
|
216
257
|
|
|
217
258
|
private createBoxGeometry(geometry: COMGeometry): BufferGeometry {
|
|
@@ -18,7 +18,11 @@ const intersectObjectsMock = jest.fn();
|
|
|
18
18
|
|
|
19
19
|
jest.mock('three', () => {
|
|
20
20
|
return {
|
|
21
|
-
Vector3: jest.fn(function (
|
|
21
|
+
Vector3: jest.fn(function (
|
|
22
|
+
x: number = 0,
|
|
23
|
+
y: number = 0,
|
|
24
|
+
z: number = 0,
|
|
25
|
+
) {
|
|
22
26
|
this.x = x;
|
|
23
27
|
this.y = y;
|
|
24
28
|
this.z = z;
|
|
@@ -109,6 +113,9 @@ jest.mock('three', () => {
|
|
|
109
113
|
this.traverse = jest.fn((callback) => {
|
|
110
114
|
callback(this.children[0]);
|
|
111
115
|
});
|
|
116
|
+
this.getWorldPosition = jest.fn(() => {
|
|
117
|
+
return this.position.clone();
|
|
118
|
+
});
|
|
112
119
|
return this;
|
|
113
120
|
}),
|
|
114
121
|
Box3: jest.fn(function () {
|
|
@@ -152,6 +159,12 @@ jest.mock('three', () => {
|
|
|
152
159
|
this.setAttribute = jest.fn();
|
|
153
160
|
this.setIndex = jest.fn();
|
|
154
161
|
this.translate = jest.fn();
|
|
162
|
+
this.computeVertexNormals = jest.fn();
|
|
163
|
+
this.computeBoundingBox = jest.fn();
|
|
164
|
+
this.computeBoundingSphere = jest.fn();
|
|
165
|
+
return this;
|
|
166
|
+
}),
|
|
167
|
+
BufferAttribute: jest.fn(function () {
|
|
155
168
|
return this;
|
|
156
169
|
}),
|
|
157
170
|
CylinderGeometry: jest.fn(function () {
|
|
@@ -241,12 +254,37 @@ describe('dive/primitive/DIVEPrimitive', () => {
|
|
|
241
254
|
});
|
|
242
255
|
|
|
243
256
|
it('should place on floor', () => {
|
|
257
|
+
const com = DIVECommunication.get('id')!;
|
|
258
|
+
const spyPerformAction = jest.spyOn(com, 'PerformAction');
|
|
259
|
+
|
|
244
260
|
primitive.userData.id = 'something';
|
|
245
261
|
|
|
262
|
+
primitive['_boundingBox'] = {
|
|
263
|
+
min: new Vector3(0, -1, 0),
|
|
264
|
+
} as unknown as Box3;
|
|
265
|
+
|
|
266
|
+
expect(() => primitive.PlaceOnFloor()).not.toThrow();
|
|
267
|
+
expect(spyPerformAction).toHaveBeenCalledWith(
|
|
268
|
+
'UPDATE_OBJECT',
|
|
269
|
+
expect.objectContaining({
|
|
270
|
+
position: expect.objectContaining({
|
|
271
|
+
y: 1,
|
|
272
|
+
}),
|
|
273
|
+
}),
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
// skip any action when the position did not change
|
|
277
|
+
spyPerformAction.mockClear();
|
|
278
|
+
primitive.position.y = 1;
|
|
246
279
|
expect(() => primitive.PlaceOnFloor()).not.toThrow();
|
|
280
|
+
expect(spyPerformAction).not.toHaveBeenCalled();
|
|
247
281
|
|
|
282
|
+
// mock that the communication is not available
|
|
283
|
+
spyPerformAction.mockClear();
|
|
248
284
|
jest.spyOn(DIVECommunication, 'get').mockReturnValueOnce(undefined);
|
|
285
|
+
primitive.position.y = 0;
|
|
249
286
|
expect(() => primitive.PlaceOnFloor()).not.toThrow();
|
|
287
|
+
expect(spyPerformAction).not.toHaveBeenCalled();
|
|
250
288
|
});
|
|
251
289
|
|
|
252
290
|
it('should drop it', () => {
|
|
@@ -413,6 +413,8 @@ jest.mock('../../../group/Group.ts', () => {
|
|
|
413
413
|
|
|
414
414
|
let root: DIVERoot;
|
|
415
415
|
|
|
416
|
+
let spyConsoleWarn = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
417
|
+
|
|
416
418
|
describe('DIVE/scene/root/DIVERoot', () => {
|
|
417
419
|
beforeEach(() => {
|
|
418
420
|
root = new DIVERoot();
|
|
@@ -422,6 +424,10 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
422
424
|
jest.clearAllMocks();
|
|
423
425
|
});
|
|
424
426
|
|
|
427
|
+
afterAll(() => {
|
|
428
|
+
spyConsoleWarn.mockRestore();
|
|
429
|
+
});
|
|
430
|
+
|
|
425
431
|
it('should instantiate', () => {
|
|
426
432
|
expect(root).toBeDefined();
|
|
427
433
|
});
|
|
@@ -474,6 +480,7 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
474
480
|
} as COMPov),
|
|
475
481
|
).not.toThrow();
|
|
476
482
|
|
|
483
|
+
spyConsoleWarn.mockClear();
|
|
477
484
|
expect(() =>
|
|
478
485
|
root.AddSceneObject({
|
|
479
486
|
id: 'id',
|
|
@@ -482,6 +489,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
482
489
|
visible: true,
|
|
483
490
|
} as COMLight),
|
|
484
491
|
).not.toThrow();
|
|
492
|
+
expect(spyConsoleWarn).toHaveBeenCalled();
|
|
493
|
+
|
|
494
|
+
spyConsoleWarn.mockClear();
|
|
485
495
|
expect(() =>
|
|
486
496
|
root.AddSceneObject({
|
|
487
497
|
id: 'id_scene',
|
|
@@ -491,6 +501,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
491
501
|
type: 'scene',
|
|
492
502
|
} as COMLight),
|
|
493
503
|
).not.toThrow();
|
|
504
|
+
expect(spyConsoleWarn).not.toHaveBeenCalled();
|
|
505
|
+
|
|
506
|
+
spyConsoleWarn.mockClear();
|
|
494
507
|
expect(() =>
|
|
495
508
|
root.AddSceneObject({
|
|
496
509
|
id: 'id_ambient',
|
|
@@ -500,6 +513,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
500
513
|
type: 'ambient',
|
|
501
514
|
} as COMLight),
|
|
502
515
|
).not.toThrow();
|
|
516
|
+
expect(spyConsoleWarn).not.toHaveBeenCalled();
|
|
517
|
+
|
|
518
|
+
spyConsoleWarn.mockClear();
|
|
503
519
|
expect(() =>
|
|
504
520
|
root.AddSceneObject({
|
|
505
521
|
id: 'id_point',
|
|
@@ -514,6 +530,7 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
514
530
|
parentId: 'id',
|
|
515
531
|
} as COMLight),
|
|
516
532
|
).not.toThrow();
|
|
533
|
+
expect(spyConsoleWarn).not.toHaveBeenCalled();
|
|
517
534
|
|
|
518
535
|
expect(() =>
|
|
519
536
|
root.AddSceneObject({
|
|
@@ -754,6 +771,7 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
754
771
|
} as unknown as Object3D,
|
|
755
772
|
];
|
|
756
773
|
|
|
774
|
+
spyConsoleWarn.mockClear();
|
|
757
775
|
expect(() =>
|
|
758
776
|
root.DeleteSceneObject({
|
|
759
777
|
id: 'does_not_exist',
|
|
@@ -762,6 +780,8 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
762
780
|
visible: true,
|
|
763
781
|
} as COMPov),
|
|
764
782
|
).not.toThrow();
|
|
783
|
+
|
|
784
|
+
spyConsoleWarn.mockClear();
|
|
765
785
|
expect(() =>
|
|
766
786
|
root.DeleteSceneObject({
|
|
767
787
|
id: 'id',
|
|
@@ -770,7 +790,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
770
790
|
visible: true,
|
|
771
791
|
} as COMPov),
|
|
772
792
|
).not.toThrow();
|
|
793
|
+
expect(spyConsoleWarn).not.toHaveBeenCalled();
|
|
773
794
|
|
|
795
|
+
spyConsoleWarn.mockClear();
|
|
774
796
|
expect(() =>
|
|
775
797
|
root.DeleteSceneObject({
|
|
776
798
|
id: 'does_not_exist',
|
|
@@ -780,6 +802,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
780
802
|
type: 'scene',
|
|
781
803
|
} as COMLight),
|
|
782
804
|
).not.toThrow();
|
|
805
|
+
expect(spyConsoleWarn).toHaveBeenCalled();
|
|
806
|
+
|
|
807
|
+
spyConsoleWarn.mockClear();
|
|
783
808
|
expect(() =>
|
|
784
809
|
root.DeleteSceneObject({
|
|
785
810
|
id: 'id',
|
|
@@ -789,7 +814,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
789
814
|
type: 'scene',
|
|
790
815
|
} as COMLight),
|
|
791
816
|
).not.toThrow();
|
|
817
|
+
expect(spyConsoleWarn).not.toHaveBeenCalled();
|
|
792
818
|
|
|
819
|
+
spyConsoleWarn.mockClear();
|
|
793
820
|
expect(() =>
|
|
794
821
|
root.DeleteSceneObject({
|
|
795
822
|
id: 'does_not_exist',
|
|
@@ -798,6 +825,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
798
825
|
visible: true,
|
|
799
826
|
} as COMModel),
|
|
800
827
|
).not.toThrow();
|
|
828
|
+
expect(spyConsoleWarn).toHaveBeenCalled();
|
|
829
|
+
|
|
830
|
+
spyConsoleWarn.mockClear();
|
|
801
831
|
expect(() =>
|
|
802
832
|
root.DeleteSceneObject({
|
|
803
833
|
id: 'id',
|
|
@@ -815,6 +845,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
815
845
|
visible: true,
|
|
816
846
|
} as COMPrimitive),
|
|
817
847
|
).not.toThrow();
|
|
848
|
+
expect(spyConsoleWarn).toHaveBeenCalled();
|
|
849
|
+
|
|
850
|
+
spyConsoleWarn.mockClear();
|
|
818
851
|
expect(() =>
|
|
819
852
|
root.DeleteSceneObject({
|
|
820
853
|
id: 'id',
|
|
@@ -823,7 +856,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
823
856
|
visible: true,
|
|
824
857
|
} as COMPrimitive),
|
|
825
858
|
).not.toThrow();
|
|
859
|
+
expect(spyConsoleWarn).not.toHaveBeenCalled();
|
|
826
860
|
|
|
861
|
+
spyConsoleWarn.mockClear();
|
|
827
862
|
expect(() =>
|
|
828
863
|
root.DeleteSceneObject({
|
|
829
864
|
id: 'does_not_exist',
|
|
@@ -832,6 +867,9 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
832
867
|
visible: true,
|
|
833
868
|
} as COMGroup),
|
|
834
869
|
).not.toThrow();
|
|
870
|
+
expect(spyConsoleWarn).toHaveBeenCalled();
|
|
871
|
+
|
|
872
|
+
spyConsoleWarn.mockClear();
|
|
835
873
|
expect(() =>
|
|
836
874
|
root.DeleteSceneObject({
|
|
837
875
|
id: 'id',
|
|
@@ -840,6 +878,7 @@ describe('DIVE/scene/root/DIVERoot', () => {
|
|
|
840
878
|
visible: true,
|
|
841
879
|
} as COMGroup),
|
|
842
880
|
).not.toThrow();
|
|
881
|
+
expect(spyConsoleWarn).not.toHaveBeenCalled();
|
|
843
882
|
|
|
844
883
|
const firstFind = root.GetSceneObject({ id: 'id' });
|
|
845
884
|
jest.spyOn(root, 'GetSceneObject').mockReturnValueOnce({
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Vector3Like } from 'three';
|
|
2
|
+
import type {
|
|
3
|
+
COMGroup,
|
|
4
|
+
COMLight,
|
|
5
|
+
COMModel,
|
|
6
|
+
COMPov,
|
|
7
|
+
COMPrimitive,
|
|
8
|
+
} from '../dive';
|
|
9
|
+
|
|
10
|
+
export type DIVESceneData = {
|
|
11
|
+
name: string;
|
|
12
|
+
mediaItem: null;
|
|
13
|
+
backgroundColor: string;
|
|
14
|
+
floorEnabled: boolean;
|
|
15
|
+
floorColor: string;
|
|
16
|
+
userCamera: {
|
|
17
|
+
position: Vector3Like;
|
|
18
|
+
target: Vector3Like;
|
|
19
|
+
};
|
|
20
|
+
spotmarks: object[];
|
|
21
|
+
lights: COMLight[];
|
|
22
|
+
objects: COMModel[];
|
|
23
|
+
cameras: COMPov[];
|
|
24
|
+
primitives: COMPrimitive[];
|
|
25
|
+
groups: COMGroup[];
|
|
26
|
+
};
|
package/src/types/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type DIVESceneObject } from './SceneObjects';
|
|
2
2
|
import { type DIVESceneFileType } from './SceneType';
|
|
3
|
+
import { type DIVESceneData } from './SceneData';
|
|
3
4
|
|
|
4
|
-
export { type DIVESceneObject, type DIVESceneFileType };
|
|
5
|
+
export { type DIVESceneObject, type DIVESceneFileType, type DIVESceneData };
|