@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.
- package/README.md +271 -40
- package/build/dive.cjs +575 -159
- package/build/dive.cjs.map +1 -1
- package/build/dive.d.cts +83 -57
- package/build/dive.d.ts +83 -57
- package/build/dive.js +614 -164
- package/build/dive.js.map +1 -1
- package/package.json +72 -60
- package/src/__test__/DIVE.test.ts +35 -31
- package/src/animation/AnimationSystem.ts +4 -4
- package/src/animation/__test__/AnimationSystem.test.ts +3 -3
- package/src/axiscamera/AxisCamera.ts +31 -11
- package/src/axiscamera/__test__/AxisCamera.test.ts +18 -10
- package/src/camera/PerspectiveCamera.ts +28 -13
- package/src/camera/__test__/PerspectiveCamera.test.ts +2 -2
- package/src/com/Communication.ts +282 -100
- package/src/com/__test__/Communication.test.ts +207 -141
- package/src/com/actions/camera/computeencompassingview.ts +8 -7
- package/src/com/actions/camera/getcameratransform.ts +8 -7
- package/src/com/actions/camera/movecamera.ts +16 -13
- package/src/com/actions/camera/resetcamera.ts +4 -3
- package/src/com/actions/camera/setcameralayer.ts +4 -3
- package/src/com/actions/camera/setcameratransform.ts +8 -7
- package/src/com/actions/camera/zoomcamera.ts +4 -3
- package/src/com/actions/index.ts +54 -54
- package/src/com/actions/media/generatemedia.ts +17 -13
- package/src/com/actions/object/addobject.ts +5 -4
- package/src/com/actions/object/deleteobject.ts +5 -4
- package/src/com/actions/object/deselectobject.ts +5 -4
- package/src/com/actions/object/getallobjects.ts +5 -4
- package/src/com/actions/object/getobjects.ts +5 -4
- package/src/com/actions/object/model/dropit.ts +4 -3
- package/src/com/actions/object/model/modelloaded.ts +4 -3
- package/src/com/actions/object/model/placeonfloor.ts +4 -3
- package/src/com/actions/object/selectobject.ts +5 -4
- package/src/com/actions/object/setparent.ts +8 -7
- package/src/com/actions/object/updateobject.ts +5 -4
- package/src/com/actions/scene/exportscene.ts +5 -4
- package/src/com/actions/scene/getallscenedata.ts +24 -18
- package/src/com/actions/scene/setbackground.ts +4 -3
- package/src/com/actions/scene/updatescene.ts +10 -9
- package/src/com/actions/toolbox/select/setgizmomode.ts +4 -3
- package/src/com/actions/toolbox/transform/setgizmovisible.ts +4 -3
- package/src/com/actions/toolbox/usetool.ts +5 -4
- package/src/com/types/COMBaseEntity.ts +2 -2
- package/src/com/types/COMEntity.ts +6 -6
- package/src/com/types/COMEntityType.ts +1 -1
- package/src/com/types/COMGeometry.ts +2 -2
- package/src/com/types/COMGroup.ts +3 -3
- package/src/com/types/COMLight.ts +3 -3
- package/src/com/types/COMMaterial.ts +2 -2
- package/src/com/types/COMModel.ts +4 -4
- package/src/com/types/COMPov.ts +3 -3
- package/src/com/types/COMPrimitive.ts +5 -5
- package/src/com/types/index.ts +10 -10
- package/src/constant/AxisHelperColors.ts +1 -1
- package/src/constant/GridColors.ts +1 -1
- package/src/controls/OrbitControls.ts +62 -29
- package/src/controls/__test__/OrbitControls.test.ts +133 -39
- package/src/dive.ts +82 -36
- package/src/gizmo/Gizmo.ts +21 -13
- package/src/gizmo/handles/AxisHandle.ts +40 -17
- package/src/gizmo/handles/RadialHandle.ts +39 -15
- package/src/gizmo/handles/ScaleHandle.ts +62 -25
- package/src/gizmo/plane/GizmoPlane.ts +5 -6
- package/src/gizmo/rotate/RotateGizmo.ts +58 -16
- package/src/gizmo/scale/ScaleGizmo.ts +37 -15
- package/src/gizmo/translate/TranslateGizmo.ts +34 -14
- package/src/grid/Grid.ts +13 -5
- package/src/grid/__test__/Grid.test.ts +5 -3
- package/src/group/Group.ts +9 -7
- package/src/group/__test__/Group.test.ts +8 -6
- package/src/helper/applyMixins/__test__/applyMixins.test.ts +9 -6
- package/src/helper/applyMixins/applyMixins.ts +6 -3
- package/src/helper/findInterface/__test__/findInterface.test.ts +28 -18
- package/src/helper/findInterface/findInterface.ts +7 -4
- package/src/helper/findSceneRecursive/__test__/findSceneRecursive.test.ts +1 -1
- package/src/helper/findSceneRecursive/findSceneRecursive.ts +1 -1
- package/src/helper/getObjectDelta/__test__/getObjectDelta.test.ts +43 -7
- package/src/helper/getObjectDelta/getObjectDelta.ts +13 -9
- package/src/helper/isInterface/__test__/implementsInterface.test.ts +1 -1
- package/src/helper/isInterface/implementsInterface.ts +6 -3
- package/src/info/Info.ts +20 -16
- package/src/info/__test__/Info.test.ts +67 -36
- package/src/interface/Draggable.ts +2 -2
- package/src/interface/Hoverable.ts +2 -2
- package/src/interface/Movable.ts +1 -1
- package/src/interface/Rotatable.ts +1 -1
- package/src/interface/Scalable.ts +1 -1
- package/src/io/IO.ts +21 -43
- package/src/io/__test__/IO.test.ts +16 -62
- package/src/io/gltf/GLTFIO.ts +34 -31
- package/src/io/gltf/__test__/GLTFIO.test.ts +88 -78
- package/src/light/PointLight.ts +42 -9
- package/src/light/SceneLight.ts +5 -5
- package/src/light/__test__/AmbientLight.test.ts +5 -4
- package/src/light/__test__/PointLight.test.ts +14 -10
- package/src/light/__test__/SceneLight.test.ts +19 -13
- package/src/loadingmanager/LoadingManager.ts +11 -6
- package/src/loadingmanager/__test__/LoadingManager.test.ts +14 -9
- package/src/math/__test__/DIVEMath.test.ts +1 -1
- package/src/math/ceil/__test__/ceilExp.test.ts +1 -1
- package/src/math/ceil/ceilExp.ts +2 -2
- package/src/math/floor/__test__/floorExp.test.ts +1 -1
- package/src/math/floor/floorExp.ts +2 -2
- package/src/math/helper/__test__/shift.test.ts +1 -1
- package/src/math/helper/shift.ts +1 -1
- package/src/math/index.ts +7 -7
- package/src/math/round/__test__/roundExp.test.ts +1 -1
- package/src/math/round/roundExp.ts +6 -3
- package/src/math/signedAngleTo/__test__/signedAngleTo.test.ts +10 -4
- package/src/math/signedAngleTo/signedAngleTo.ts +11 -4
- package/src/math/toFixed/__test__/toFixedExp.test.ts +9 -9
- package/src/math/toFixed/toFixedExp.ts +6 -3
- package/src/math/truncate/__test__/truncateExp.test.ts +1 -1
- package/src/math/truncate/truncateExp.ts +6 -3
- package/src/mediacreator/MediaCreator.ts +20 -10
- package/src/mediacreator/__test__/MediaCreator.test.ts +27 -12
- package/src/model/Model.ts +35 -7
- package/src/model/__test__/Model.test.ts +71 -44
- package/src/node/Node.ts +34 -12
- package/src/node/__test__/Node.test.ts +17 -13
- package/src/primitive/Primitive.ts +78 -13
- package/src/primitive/__test__/Primitive.test.ts +49 -38
- package/src/primitive/floor/Floor.ts +14 -3
- package/src/primitive/floor/__test__/Floor.test.ts +10 -4
- package/src/renderer/Renderer.ts +46 -15
- package/src/renderer/__test__/Renderer.test.ts +74 -24
- package/src/scene/Scene.ts +9 -3
- package/src/scene/__test__/Scene.test.ts +2 -2
- package/src/scene/root/Root.ts +142 -75
- package/src/scene/root/__test__/Root.test.ts +439 -111
- package/src/toolbox/BaseTool.ts +69 -33
- package/src/toolbox/Toolbox.ts +37 -17
- package/src/toolbox/__test__/BaseTool.test.ts +324 -160
- package/src/toolbox/__test__/Toolbox.test.ts +31 -14
- package/src/toolbox/select/SelectTool.ts +24 -19
- package/src/toolbox/select/__test__/SelectTool.test.ts +95 -59
- package/src/toolbox/transform/TransformTool.ts +40 -17
- package/src/toolbox/transform/__test__/TransformTool.test.ts +22 -15
- package/src/types/SceneObjects.ts +8 -8
- package/src/types/SceneType.ts +3 -3
- package/src/types/index.ts +3 -6
|
@@ -2,7 +2,14 @@ import { DIVEModel } from '../Model';
|
|
|
2
2
|
import { DIVECommunication } from '../../com/Communication';
|
|
3
3
|
import { GLTF } from 'three/examples/jsm/Addons';
|
|
4
4
|
import { DIVEScene } from '../../scene/Scene';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
Vector3,
|
|
7
|
+
Box3,
|
|
8
|
+
Mesh,
|
|
9
|
+
MeshStandardMaterial,
|
|
10
|
+
type Texture,
|
|
11
|
+
Color,
|
|
12
|
+
} from 'three';
|
|
6
13
|
import { type COMMaterial } from '../../com/types';
|
|
7
14
|
|
|
8
15
|
const intersectObjectsMock = jest.fn();
|
|
@@ -37,7 +44,7 @@ jest.mock('three', () => {
|
|
|
37
44
|
this.setY = (y: number) => {
|
|
38
45
|
this.y = y;
|
|
39
46
|
return this;
|
|
40
|
-
}
|
|
47
|
+
};
|
|
41
48
|
this.add = (vec3: Vector3) => {
|
|
42
49
|
this.x += vec3.x;
|
|
43
50
|
this.y += vec3.y;
|
|
@@ -68,15 +75,17 @@ jest.mock('three', () => {
|
|
|
68
75
|
far: 0,
|
|
69
76
|
fov: 0,
|
|
70
77
|
},
|
|
71
|
-
}
|
|
78
|
+
};
|
|
72
79
|
this.add = jest.fn();
|
|
73
80
|
this.sub = jest.fn();
|
|
74
|
-
this.children = [
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
this.children = [
|
|
82
|
+
{
|
|
83
|
+
visible: true,
|
|
84
|
+
material: {
|
|
85
|
+
color: {},
|
|
86
|
+
},
|
|
78
87
|
},
|
|
79
|
-
|
|
88
|
+
];
|
|
80
89
|
this.userData = {};
|
|
81
90
|
this.position = new Vector3();
|
|
82
91
|
this.rotation = {
|
|
@@ -96,7 +105,7 @@ jest.mock('three', () => {
|
|
|
96
105
|
};
|
|
97
106
|
this.mesh = new Mesh();
|
|
98
107
|
this.traverse = jest.fn((callback) => {
|
|
99
|
-
callback(this.children[0])
|
|
108
|
+
callback(this.children[0]);
|
|
100
109
|
});
|
|
101
110
|
return this;
|
|
102
111
|
}),
|
|
@@ -148,7 +157,7 @@ jest.mock('three', () => {
|
|
|
148
157
|
this.set = jest.fn();
|
|
149
158
|
return this;
|
|
150
159
|
}),
|
|
151
|
-
}
|
|
160
|
+
};
|
|
152
161
|
});
|
|
153
162
|
|
|
154
163
|
jest.mock('../../com/Communication.ts', () => {
|
|
@@ -157,10 +166,10 @@ jest.mock('../../com/Communication.ts', () => {
|
|
|
157
166
|
get: jest.fn(() => {
|
|
158
167
|
return {
|
|
159
168
|
PerformAction: jest.fn(),
|
|
160
|
-
}
|
|
169
|
+
};
|
|
161
170
|
}),
|
|
162
171
|
},
|
|
163
|
-
}
|
|
172
|
+
};
|
|
164
173
|
});
|
|
165
174
|
|
|
166
175
|
const gltf = {
|
|
@@ -193,7 +202,9 @@ const gltf = {
|
|
|
193
202
|
},
|
|
194
203
|
} as unknown as GLTF;
|
|
195
204
|
|
|
196
|
-
jest.spyOn(DIVECommunication, 'get').mockReturnValue({
|
|
205
|
+
jest.spyOn(DIVECommunication, 'get').mockReturnValue({
|
|
206
|
+
PerformAction: jest.fn(),
|
|
207
|
+
} as unknown as DIVECommunication);
|
|
197
208
|
|
|
198
209
|
let model: DIVEModel;
|
|
199
210
|
|
|
@@ -245,14 +256,14 @@ describe('dive/model/DIVEModel', () => {
|
|
|
245
256
|
}),
|
|
246
257
|
} as unknown as Box3;
|
|
247
258
|
|
|
248
|
-
|
|
249
259
|
const hitObject = new Mesh();
|
|
250
260
|
hitObject.geometry.boundingBox = new Box3();
|
|
251
261
|
hitObject.geometry.boundingBox.max = new Vector3(0, 2, 0);
|
|
252
|
-
intersectObjectsMock.mockReturnValue([
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
262
|
+
intersectObjectsMock.mockReturnValue([
|
|
263
|
+
{
|
|
264
|
+
object: hitObject,
|
|
265
|
+
},
|
|
266
|
+
]);
|
|
256
267
|
|
|
257
268
|
const scene = {
|
|
258
269
|
parent: null,
|
|
@@ -283,8 +294,6 @@ describe('dive/model/DIVEModel', () => {
|
|
|
283
294
|
jest.spyOn(DIVECommunication, 'get').mockReturnValueOnce(undefined);
|
|
284
295
|
expect(() => model.DropIt()).not.toThrow();
|
|
285
296
|
expect(comMock.PerformAction).toHaveBeenCalledTimes(1);
|
|
286
|
-
|
|
287
|
-
|
|
288
297
|
});
|
|
289
298
|
|
|
290
299
|
it('should set material', () => {
|
|
@@ -292,41 +301,59 @@ describe('dive/model/DIVEModel', () => {
|
|
|
292
301
|
expect(() => model.SetMaterial({} as COMMaterial)).not.toThrow();
|
|
293
302
|
expect(model['_material']).not.toBeNull();
|
|
294
303
|
|
|
295
|
-
expect(() =>
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
304
|
+
expect(() =>
|
|
305
|
+
model.SetMaterial({
|
|
306
|
+
color: 0xffffff,
|
|
307
|
+
roughness: 0,
|
|
308
|
+
metalness: 1,
|
|
309
|
+
} as COMMaterial),
|
|
310
|
+
).not.toThrow();
|
|
300
311
|
expect((model['_material'] as MeshStandardMaterial).roughness).toBe(0);
|
|
301
|
-
expect(
|
|
312
|
+
expect(
|
|
313
|
+
(model['_material'] as MeshStandardMaterial).roughnessMap,
|
|
314
|
+
).toBeUndefined();
|
|
302
315
|
expect((model['_material'] as MeshStandardMaterial).metalness).toBe(1);
|
|
303
|
-
expect(
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
316
|
+
expect(
|
|
317
|
+
(model['_material'] as MeshStandardMaterial).metalnessMap,
|
|
318
|
+
).toBeUndefined();
|
|
319
|
+
|
|
320
|
+
expect(() =>
|
|
321
|
+
model.SetMaterial({
|
|
322
|
+
color: 0xff00ff,
|
|
323
|
+
vertexColors: true,
|
|
324
|
+
map: 'This_Is_A_Texture' as unknown as Texture,
|
|
325
|
+
normalMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
326
|
+
roughness: 0,
|
|
327
|
+
roughnessMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
328
|
+
metalness: 1,
|
|
329
|
+
metalnessMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
330
|
+
} as COMMaterial),
|
|
331
|
+
).not.toThrow();
|
|
315
332
|
expect((model['_material'] as MeshStandardMaterial).roughness).toBe(1);
|
|
316
|
-
expect(
|
|
333
|
+
expect(
|
|
334
|
+
(model['_material'] as MeshStandardMaterial).roughnessMap,
|
|
335
|
+
).toBeDefined();
|
|
317
336
|
expect((model['_material'] as MeshStandardMaterial).metalness).toBe(1);
|
|
318
|
-
expect(
|
|
337
|
+
expect(
|
|
338
|
+
(model['_material'] as MeshStandardMaterial).metalnessMap,
|
|
339
|
+
).toBeDefined();
|
|
319
340
|
});
|
|
320
341
|
|
|
321
342
|
it('should set model material when material already set before', () => {
|
|
322
343
|
model.SetMaterial({ roughness: 0.5 } as COMMaterial);
|
|
323
344
|
expect(() => model.SetModel(gltf)).not.toThrow();
|
|
324
|
-
expect(
|
|
345
|
+
expect(
|
|
346
|
+
(model['_mesh']?.material as MeshStandardMaterial).roughness,
|
|
347
|
+
).toBe(0.5);
|
|
325
348
|
});
|
|
326
349
|
|
|
327
350
|
it('should set material to model when model already set before', () => {
|
|
328
351
|
model.SetModel(gltf);
|
|
329
|
-
expect(() =>
|
|
330
|
-
|
|
352
|
+
expect(() =>
|
|
353
|
+
model.SetMaterial({ roughness: 0.5 } as COMMaterial),
|
|
354
|
+
).not.toThrow();
|
|
355
|
+
expect(
|
|
356
|
+
(model['_mesh']?.material as MeshStandardMaterial).roughness,
|
|
357
|
+
).toBe(0.5);
|
|
331
358
|
});
|
|
332
|
-
});
|
|
359
|
+
});
|
package/src/node/Node.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Box3, Object3D, type Vector3Like } from
|
|
2
|
-
import { PRODUCT_LAYER_MASK } from
|
|
3
|
-
import { DIVECommunication } from
|
|
1
|
+
import { Box3, Object3D, type Vector3Like } from 'three';
|
|
2
|
+
import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
|
|
3
|
+
import { DIVECommunication } from '../com/Communication';
|
|
4
4
|
|
|
5
|
-
import { type DIVEMovable } from
|
|
6
|
-
import { type DIVESelectable } from
|
|
7
|
-
import { type TransformControls } from
|
|
8
|
-
import { type DIVEGroup } from
|
|
5
|
+
import { type DIVEMovable } from '../interface/Movable';
|
|
6
|
+
import { type DIVESelectable } from '../interface/Selectable';
|
|
7
|
+
import { type TransformControls } from 'three/examples/jsm/controls/TransformControls';
|
|
8
|
+
import { type DIVEGroup } from '../group/Group';
|
|
9
9
|
|
|
10
10
|
export class DIVENode extends Object3D implements DIVESelectable, DIVEMovable {
|
|
11
11
|
readonly isDIVENode: true = true;
|
|
@@ -42,11 +42,27 @@ export class DIVENode extends Object3D implements DIVESelectable, DIVEMovable {
|
|
|
42
42
|
|
|
43
43
|
public SetToWorldOrigin(): void {
|
|
44
44
|
this.position.set(0, 0, 0);
|
|
45
|
-
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
45
|
+
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
46
|
+
'UPDATE_OBJECT',
|
|
47
|
+
{
|
|
48
|
+
id: this.userData.id,
|
|
49
|
+
position: this.position,
|
|
50
|
+
rotation: this.rotation,
|
|
51
|
+
scale: this.scale,
|
|
52
|
+
},
|
|
53
|
+
);
|
|
46
54
|
}
|
|
47
55
|
|
|
48
56
|
public onMove(): void {
|
|
49
|
-
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
57
|
+
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
58
|
+
'UPDATE_OBJECT',
|
|
59
|
+
{
|
|
60
|
+
id: this.userData.id,
|
|
61
|
+
position: this.position,
|
|
62
|
+
rotation: this.rotation,
|
|
63
|
+
scale: this.scale,
|
|
64
|
+
},
|
|
65
|
+
);
|
|
50
66
|
|
|
51
67
|
if (this.parent && 'isDIVEGroup' in this.parent) {
|
|
52
68
|
(this.parent as unknown as DIVEGroup).UpdateLineTo(this);
|
|
@@ -54,10 +70,16 @@ export class DIVENode extends Object3D implements DIVESelectable, DIVEMovable {
|
|
|
54
70
|
}
|
|
55
71
|
|
|
56
72
|
public onSelect(): void {
|
|
57
|
-
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
73
|
+
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
74
|
+
'SELECT_OBJECT',
|
|
75
|
+
{ id: this.userData.id },
|
|
76
|
+
);
|
|
58
77
|
}
|
|
59
78
|
|
|
60
79
|
public onDeselect(): void {
|
|
61
|
-
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
80
|
+
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
81
|
+
'DESELECT_OBJECT',
|
|
82
|
+
{ id: this.userData.id },
|
|
83
|
+
);
|
|
62
84
|
}
|
|
63
|
-
}
|
|
85
|
+
}
|
|
@@ -35,7 +35,7 @@ jest.mock('three', () => {
|
|
|
35
35
|
this.setY = (y: number) => {
|
|
36
36
|
this.y = y;
|
|
37
37
|
return this;
|
|
38
|
-
}
|
|
38
|
+
};
|
|
39
39
|
this.add = (vec3: Vector3) => {
|
|
40
40
|
this.x += vec3.x;
|
|
41
41
|
this.y += vec3.y;
|
|
@@ -70,15 +70,17 @@ jest.mock('three', () => {
|
|
|
70
70
|
far: 0,
|
|
71
71
|
fov: 0,
|
|
72
72
|
},
|
|
73
|
-
}
|
|
73
|
+
};
|
|
74
74
|
this.add = jest.fn();
|
|
75
75
|
this.sub = jest.fn();
|
|
76
|
-
this.children = [
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
this.children = [
|
|
77
|
+
{
|
|
78
|
+
visible: true,
|
|
79
|
+
material: {
|
|
80
|
+
color: {},
|
|
81
|
+
},
|
|
80
82
|
},
|
|
81
|
-
|
|
83
|
+
];
|
|
82
84
|
this.userData = {};
|
|
83
85
|
this.position = new Vector3();
|
|
84
86
|
this.rotation = new Euler();
|
|
@@ -88,7 +90,7 @@ jest.mock('three', () => {
|
|
|
88
90
|
};
|
|
89
91
|
this.mesh = new Mesh();
|
|
90
92
|
this.traverse = jest.fn((callback) => {
|
|
91
|
-
callback(this.children[0])
|
|
93
|
+
callback(this.children[0]);
|
|
92
94
|
});
|
|
93
95
|
return this;
|
|
94
96
|
}),
|
|
@@ -140,7 +142,7 @@ jest.mock('three', () => {
|
|
|
140
142
|
this.set = jest.fn();
|
|
141
143
|
return this;
|
|
142
144
|
}),
|
|
143
|
-
}
|
|
145
|
+
};
|
|
144
146
|
});
|
|
145
147
|
|
|
146
148
|
jest.mock('../../com/Communication.ts', () => {
|
|
@@ -149,13 +151,15 @@ jest.mock('../../com/Communication.ts', () => {
|
|
|
149
151
|
get: jest.fn(() => {
|
|
150
152
|
return {
|
|
151
153
|
PerformAction: jest.fn(),
|
|
152
|
-
}
|
|
154
|
+
};
|
|
153
155
|
}),
|
|
154
156
|
},
|
|
155
|
-
}
|
|
157
|
+
};
|
|
156
158
|
});
|
|
157
159
|
|
|
158
|
-
jest.spyOn(DIVECommunication, 'get').mockReturnValue({
|
|
160
|
+
jest.spyOn(DIVECommunication, 'get').mockReturnValue({
|
|
161
|
+
PerformAction: jest.fn(),
|
|
162
|
+
} as unknown as DIVECommunication);
|
|
159
163
|
|
|
160
164
|
let node: DIVENode;
|
|
161
165
|
|
|
@@ -230,4 +234,4 @@ describe('dive/node/DIVENode', () => {
|
|
|
230
234
|
jest.spyOn(DIVECommunication, 'get').mockReturnValueOnce(undefined);
|
|
231
235
|
expect(() => node.onDeselect()).not.toThrow();
|
|
232
236
|
});
|
|
233
|
-
});
|
|
237
|
+
});
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BoxGeometry,
|
|
3
|
+
BufferGeometry,
|
|
4
|
+
Color,
|
|
5
|
+
ConeGeometry,
|
|
6
|
+
CylinderGeometry,
|
|
7
|
+
Mesh,
|
|
8
|
+
MeshStandardMaterial,
|
|
9
|
+
Raycaster,
|
|
10
|
+
SphereGeometry,
|
|
11
|
+
Vector3,
|
|
12
|
+
} from 'three';
|
|
2
13
|
import { DIVECommunication } from '../com/Communication';
|
|
3
14
|
import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
|
|
4
15
|
import { findSceneRecursive } from '../helper/findSceneRecursive/findSceneRecursive';
|
|
@@ -94,24 +105,40 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
94
105
|
|
|
95
106
|
public PlaceOnFloor(): void {
|
|
96
107
|
this.position.y = -this._boundingBox.min.y * this.scale.y;
|
|
97
|
-
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
108
|
+
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
109
|
+
'UPDATE_OBJECT',
|
|
110
|
+
{
|
|
111
|
+
id: this.userData.id,
|
|
112
|
+
position: this.position,
|
|
113
|
+
rotation: this.rotation,
|
|
114
|
+
scale: this.scale,
|
|
115
|
+
},
|
|
116
|
+
);
|
|
98
117
|
}
|
|
99
118
|
|
|
100
119
|
public DropIt(): void {
|
|
101
120
|
if (!this.parent) {
|
|
102
|
-
console.warn(
|
|
121
|
+
console.warn(
|
|
122
|
+
'DIVEPrimitive: DropIt() called on a model that is not in the scene.',
|
|
123
|
+
this,
|
|
124
|
+
);
|
|
103
125
|
return;
|
|
104
126
|
}
|
|
105
127
|
|
|
106
128
|
// calculate the bottom center of the bounding box
|
|
107
129
|
const bottomY = this._boundingBox.min.y * this.scale.y;
|
|
108
|
-
const bbBottomCenter = this.localToWorld(
|
|
130
|
+
const bbBottomCenter = this.localToWorld(
|
|
131
|
+
this._boundingBox.getCenter(new Vector3()).multiply(this.scale),
|
|
132
|
+
);
|
|
109
133
|
bbBottomCenter.y = bottomY + this.position.y;
|
|
110
134
|
|
|
111
135
|
// set up raycaster and raycast all scene objects (product layer)
|
|
112
136
|
const raycaster = new Raycaster(bbBottomCenter, new Vector3(0, -1, 0));
|
|
113
137
|
raycaster.layers.mask = PRODUCT_LAYER_MASK;
|
|
114
|
-
const intersections = raycaster.intersectObjects(
|
|
138
|
+
const intersections = raycaster.intersectObjects(
|
|
139
|
+
findSceneRecursive(this).Root.children,
|
|
140
|
+
true,
|
|
141
|
+
);
|
|
115
142
|
|
|
116
143
|
// if we hit something, move the model to the top on the hit object's bounding box
|
|
117
144
|
if (intersections.length > 0) {
|
|
@@ -121,12 +148,23 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
121
148
|
const worldPos = mesh.localToWorld(meshBB.max.clone());
|
|
122
149
|
|
|
123
150
|
const oldPos = this.position.clone();
|
|
124
|
-
const newPos = this.position
|
|
151
|
+
const newPos = this.position
|
|
152
|
+
.clone()
|
|
153
|
+
.setY(worldPos.y)
|
|
154
|
+
.sub(new Vector3(0, bottomY, 0));
|
|
125
155
|
this.position.copy(newPos);
|
|
126
156
|
|
|
127
157
|
// if the position changed, update the object in communication
|
|
128
158
|
if (this.position.y === oldPos.y) return;
|
|
129
|
-
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
159
|
+
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
160
|
+
'UPDATE_OBJECT',
|
|
161
|
+
{
|
|
162
|
+
id: this.userData.id,
|
|
163
|
+
position: this.position,
|
|
164
|
+
rotation: this.rotation,
|
|
165
|
+
scale: this.scale,
|
|
166
|
+
},
|
|
167
|
+
);
|
|
130
168
|
}
|
|
131
169
|
}
|
|
132
170
|
|
|
@@ -147,14 +185,22 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
147
185
|
case 'plane':
|
|
148
186
|
return this.createPlaneGeometry(geometry);
|
|
149
187
|
default: {
|
|
150
|
-
console.warn(
|
|
188
|
+
console.warn(
|
|
189
|
+
'DIVEPrimitive: Invalid geometry type:',
|
|
190
|
+
geometry.name.toLowerCase(),
|
|
191
|
+
);
|
|
151
192
|
return new BufferGeometry();
|
|
152
193
|
}
|
|
153
194
|
}
|
|
154
195
|
}
|
|
155
196
|
|
|
156
197
|
private createCylinderGeometry(geometry: COMGeometry): BufferGeometry {
|
|
157
|
-
const geo = new CylinderGeometry(
|
|
198
|
+
const geo = new CylinderGeometry(
|
|
199
|
+
geometry.width / 2,
|
|
200
|
+
geometry.width / 2,
|
|
201
|
+
geometry.height,
|
|
202
|
+
64,
|
|
203
|
+
);
|
|
158
204
|
geo.translate(0, geometry.height / 2, 0);
|
|
159
205
|
return geo;
|
|
160
206
|
}
|
|
@@ -165,14 +211,24 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
165
211
|
}
|
|
166
212
|
|
|
167
213
|
private createPyramidGeometry(geometry: COMGeometry): BufferGeometry {
|
|
168
|
-
const geo = new ConeGeometry(
|
|
214
|
+
const geo = new ConeGeometry(
|
|
215
|
+
geometry.width / 2,
|
|
216
|
+
geometry.height,
|
|
217
|
+
4,
|
|
218
|
+
1,
|
|
219
|
+
true,
|
|
220
|
+
);
|
|
169
221
|
geo.rotateY(Math.PI / 4);
|
|
170
222
|
geo.translate(0, geometry.height / 2, 0);
|
|
171
223
|
return geo;
|
|
172
224
|
}
|
|
173
225
|
|
|
174
226
|
private createBoxGeometry(geometry: COMGeometry): BufferGeometry {
|
|
175
|
-
const geo = new BoxGeometry(
|
|
227
|
+
const geo = new BoxGeometry(
|
|
228
|
+
geometry.width,
|
|
229
|
+
geometry.height,
|
|
230
|
+
geometry.depth,
|
|
231
|
+
);
|
|
176
232
|
geo.translate(0, geometry.height / 2, 0);
|
|
177
233
|
return geo;
|
|
178
234
|
}
|
|
@@ -184,13 +240,22 @@ export class DIVEPrimitive extends DIVENode {
|
|
|
184
240
|
}
|
|
185
241
|
|
|
186
242
|
private createWallGeometry(geometry: COMGeometry): BufferGeometry {
|
|
187
|
-
const geo = new BoxGeometry(
|
|
243
|
+
const geo = new BoxGeometry(
|
|
244
|
+
geometry.width,
|
|
245
|
+
geometry.height,
|
|
246
|
+
geometry.depth || 0.05,
|
|
247
|
+
16,
|
|
248
|
+
);
|
|
188
249
|
geo.translate(0, geometry.height / 2, 0);
|
|
189
250
|
return geo;
|
|
190
251
|
}
|
|
191
252
|
|
|
192
253
|
private createPlaneGeometry(geometry: COMGeometry): BufferGeometry {
|
|
193
|
-
const geo = new BoxGeometry(
|
|
254
|
+
const geo = new BoxGeometry(
|
|
255
|
+
geometry.width,
|
|
256
|
+
geometry.height,
|
|
257
|
+
geometry.depth,
|
|
258
|
+
);
|
|
194
259
|
geo.translate(0, geometry.height / 2, 0);
|
|
195
260
|
return geo;
|
|
196
261
|
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { DIVEPrimitive } from '../Primitive';
|
|
2
2
|
import { DIVECommunication } from '../../com/Communication';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Vector3,
|
|
5
|
+
Box3,
|
|
6
|
+
Mesh,
|
|
7
|
+
type Texture,
|
|
8
|
+
type MeshStandardMaterial,
|
|
9
|
+
} from 'three';
|
|
4
10
|
import type { DIVEScene } from '../../scene/Scene';
|
|
5
11
|
import { type COMMaterial, type COMGeometry } from '../../com/types';
|
|
6
12
|
|
|
@@ -36,7 +42,7 @@ jest.mock('three', () => {
|
|
|
36
42
|
this.setY = (y: number) => {
|
|
37
43
|
this.y = y;
|
|
38
44
|
return this;
|
|
39
|
-
}
|
|
45
|
+
};
|
|
40
46
|
this.add = (vec3: Vector3) => {
|
|
41
47
|
this.x += vec3.x;
|
|
42
48
|
this.y += vec3.y;
|
|
@@ -67,15 +73,17 @@ jest.mock('three', () => {
|
|
|
67
73
|
far: 0,
|
|
68
74
|
fov: 0,
|
|
69
75
|
},
|
|
70
|
-
}
|
|
76
|
+
};
|
|
71
77
|
this.add = jest.fn();
|
|
72
78
|
this.sub = jest.fn();
|
|
73
|
-
this.children = [
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
79
|
+
this.children = [
|
|
80
|
+
{
|
|
81
|
+
visible: true,
|
|
82
|
+
material: {
|
|
83
|
+
color: {},
|
|
84
|
+
},
|
|
77
85
|
},
|
|
78
|
-
|
|
86
|
+
];
|
|
79
87
|
this.userData = {};
|
|
80
88
|
this.position = new Vector3();
|
|
81
89
|
this.rotation = {
|
|
@@ -95,7 +103,7 @@ jest.mock('three', () => {
|
|
|
95
103
|
};
|
|
96
104
|
this.mesh = new Mesh();
|
|
97
105
|
this.traverse = jest.fn((callback) => {
|
|
98
|
-
callback(this.children[0])
|
|
106
|
+
callback(this.children[0]);
|
|
99
107
|
});
|
|
100
108
|
return this;
|
|
101
109
|
}),
|
|
@@ -176,7 +184,7 @@ jest.mock('three', () => {
|
|
|
176
184
|
Color: jest.fn(function () {
|
|
177
185
|
return this;
|
|
178
186
|
}),
|
|
179
|
-
}
|
|
187
|
+
};
|
|
180
188
|
});
|
|
181
189
|
|
|
182
190
|
jest.mock('../../com/Communication.ts', () => {
|
|
@@ -185,13 +193,15 @@ jest.mock('../../com/Communication.ts', () => {
|
|
|
185
193
|
get: jest.fn(() => {
|
|
186
194
|
return {
|
|
187
195
|
PerformAction: jest.fn(),
|
|
188
|
-
}
|
|
196
|
+
};
|
|
189
197
|
}),
|
|
190
198
|
},
|
|
191
|
-
}
|
|
199
|
+
};
|
|
192
200
|
});
|
|
193
201
|
|
|
194
|
-
jest.spyOn(DIVECommunication, 'get').mockReturnValue({
|
|
202
|
+
jest.spyOn(DIVECommunication, 'get').mockReturnValue({
|
|
203
|
+
PerformAction: jest.fn(),
|
|
204
|
+
} as unknown as DIVECommunication);
|
|
195
205
|
|
|
196
206
|
let primitive: DIVEPrimitive;
|
|
197
207
|
|
|
@@ -246,14 +256,14 @@ describe('dive/primitive/DIVEPrimitive', () => {
|
|
|
246
256
|
}),
|
|
247
257
|
} as unknown as Box3;
|
|
248
258
|
|
|
249
|
-
|
|
250
259
|
const hitObject = new Mesh();
|
|
251
260
|
hitObject.geometry.boundingBox = new Box3();
|
|
252
261
|
hitObject.geometry.boundingBox.max = new Vector3(0, 2, 0);
|
|
253
|
-
intersectObjectsMock.mockReturnValue([
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
262
|
+
intersectObjectsMock.mockReturnValue([
|
|
263
|
+
{
|
|
264
|
+
object: hitObject,
|
|
265
|
+
},
|
|
266
|
+
]);
|
|
257
267
|
|
|
258
268
|
const scene = {
|
|
259
269
|
parent: null,
|
|
@@ -284,8 +294,6 @@ describe('dive/primitive/DIVEPrimitive', () => {
|
|
|
284
294
|
jest.spyOn(DIVECommunication, 'get').mockReturnValueOnce(undefined);
|
|
285
295
|
expect(() => primitive.DropIt()).not.toThrow();
|
|
286
296
|
expect(comMock.PerformAction).toHaveBeenCalledTimes(1);
|
|
287
|
-
|
|
288
|
-
|
|
289
297
|
});
|
|
290
298
|
|
|
291
299
|
it('should set geometry', () => {
|
|
@@ -363,36 +371,39 @@ describe('dive/primitive/DIVEPrimitive', () => {
|
|
|
363
371
|
});
|
|
364
372
|
|
|
365
373
|
it('should set material', () => {
|
|
366
|
-
const material =
|
|
374
|
+
const material = primitive['_mesh'].material as MeshStandardMaterial;
|
|
367
375
|
|
|
368
376
|
// apply invalid material should not crash
|
|
369
377
|
expect(() => primitive.SetMaterial({} as COMMaterial)).not.toThrow();
|
|
370
378
|
expect(material).toBeDefined();
|
|
371
379
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
380
|
+
expect(() =>
|
|
381
|
+
primitive.SetMaterial({
|
|
382
|
+
color: 0xffffff,
|
|
383
|
+
roughness: 0,
|
|
384
|
+
metalness: 1,
|
|
385
|
+
} as COMMaterial),
|
|
386
|
+
).not.toThrow();
|
|
378
387
|
expect((material as MeshStandardMaterial).roughness).toBe(0);
|
|
379
388
|
expect((material as MeshStandardMaterial).roughnessMap).toBeUndefined();
|
|
380
389
|
expect((material as MeshStandardMaterial).metalness).toBe(1);
|
|
381
390
|
expect((material as MeshStandardMaterial).metalnessMap).toBeUndefined();
|
|
382
391
|
|
|
383
|
-
expect(() =>
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
392
|
+
expect(() =>
|
|
393
|
+
primitive.SetMaterial({
|
|
394
|
+
color: 0xff00ff,
|
|
395
|
+
vertexColors: true,
|
|
396
|
+
map: 'This_Is_A_Texture' as unknown as Texture,
|
|
397
|
+
normalMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
398
|
+
roughness: 0,
|
|
399
|
+
roughnessMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
400
|
+
metalness: 1,
|
|
401
|
+
metalnessMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
402
|
+
} as COMMaterial),
|
|
403
|
+
).not.toThrow();
|
|
393
404
|
expect((material as MeshStandardMaterial).roughness).toBe(1);
|
|
394
405
|
expect((material as MeshStandardMaterial).roughnessMap).toBeDefined();
|
|
395
406
|
expect((material as MeshStandardMaterial).metalness).toBe(0);
|
|
396
407
|
expect((material as MeshStandardMaterial).metalnessMap).toBeDefined();
|
|
397
408
|
});
|
|
398
|
-
});
|
|
409
|
+
});
|