@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
|
@@ -33,16 +33,15 @@ jest.mock('../select/SelectTool.ts', () => {
|
|
|
33
33
|
this.SetGizmoMode = jest.fn();
|
|
34
34
|
this.SetGizmoVisibility = jest.fn();
|
|
35
35
|
return this;
|
|
36
|
-
})
|
|
37
|
-
}
|
|
36
|
+
}),
|
|
37
|
+
};
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
const mockController = {
|
|
41
41
|
domElement: mock_Canvas,
|
|
42
|
-
object: {}
|
|
42
|
+
object: {},
|
|
43
43
|
} as unknown as DIVEOrbitControls;
|
|
44
44
|
|
|
45
|
-
|
|
46
45
|
describe('dive/toolbox/DIVEToolBox', () => {
|
|
47
46
|
afterEach(() => {
|
|
48
47
|
jest.clearAllMocks();
|
|
@@ -61,7 +60,9 @@ describe('dive/toolbox/DIVEToolBox', () => {
|
|
|
61
60
|
|
|
62
61
|
it('should throw with incorrect tool', () => {
|
|
63
62
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
64
|
-
expect(() =>
|
|
63
|
+
expect(() =>
|
|
64
|
+
toolBox.UseTool('not a real tool' as unknown as ToolType),
|
|
65
|
+
).toThrow();
|
|
65
66
|
});
|
|
66
67
|
|
|
67
68
|
it('should use no tool', () => {
|
|
@@ -77,30 +78,46 @@ describe('dive/toolbox/DIVEToolBox', () => {
|
|
|
77
78
|
|
|
78
79
|
it('should execute pointer down event on tool', () => {
|
|
79
80
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
80
|
-
expect(() =>
|
|
81
|
+
expect(() =>
|
|
82
|
+
toolBox.onPointerDown({ type: 'pointerdown' } as PointerEvent),
|
|
83
|
+
).not.toThrow();
|
|
81
84
|
expect(() => toolBox.UseTool('select')).not.toThrow();
|
|
82
|
-
expect(() =>
|
|
85
|
+
expect(() =>
|
|
86
|
+
toolBox.onPointerDown({ type: 'pointerdown' } as PointerEvent),
|
|
87
|
+
).not.toThrow();
|
|
83
88
|
});
|
|
84
89
|
|
|
85
90
|
it('should execute pointer move event on tool', () => {
|
|
86
91
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
87
|
-
expect(() =>
|
|
92
|
+
expect(() =>
|
|
93
|
+
toolBox.onPointerMove({ type: 'pointermove' } as PointerEvent),
|
|
94
|
+
).not.toThrow();
|
|
88
95
|
expect(() => toolBox.UseTool('select')).not.toThrow();
|
|
89
|
-
expect(() =>
|
|
96
|
+
expect(() =>
|
|
97
|
+
toolBox.onPointerMove({ type: 'pointermove' } as PointerEvent),
|
|
98
|
+
).not.toThrow();
|
|
90
99
|
});
|
|
91
100
|
|
|
92
101
|
it('should execute pointer up event on tool', () => {
|
|
93
102
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
94
|
-
expect(() =>
|
|
103
|
+
expect(() =>
|
|
104
|
+
toolBox.onPointerUp({ type: 'pointerup' } as PointerEvent),
|
|
105
|
+
).not.toThrow();
|
|
95
106
|
expect(() => toolBox.UseTool('select')).not.toThrow();
|
|
96
|
-
expect(() =>
|
|
107
|
+
expect(() =>
|
|
108
|
+
toolBox.onPointerUp({ type: 'pointerup' } as PointerEvent),
|
|
109
|
+
).not.toThrow();
|
|
97
110
|
});
|
|
98
111
|
|
|
99
112
|
it('should execute wheel event on tool', () => {
|
|
100
113
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
101
|
-
expect(() =>
|
|
114
|
+
expect(() =>
|
|
115
|
+
toolBox.onWheel({ type: 'wheel' } as WheelEvent),
|
|
116
|
+
).not.toThrow();
|
|
102
117
|
expect(() => toolBox.UseTool('select')).not.toThrow();
|
|
103
|
-
expect(() =>
|
|
118
|
+
expect(() =>
|
|
119
|
+
toolBox.onWheel({ type: 'wheel' } as WheelEvent),
|
|
120
|
+
).not.toThrow();
|
|
104
121
|
});
|
|
105
122
|
|
|
106
123
|
it('should get active tool', () => {
|
|
@@ -117,4 +134,4 @@ describe('dive/toolbox/DIVEToolBox', () => {
|
|
|
117
134
|
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
118
135
|
expect(() => toolBox.SetGizmoVisibility(true)).not.toThrow();
|
|
119
136
|
});
|
|
120
|
-
});
|
|
137
|
+
});
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { type Object3D } from
|
|
2
|
-
import { DIVEScene } from
|
|
3
|
-
import DIVETransformTool from
|
|
4
|
-
import { findInterface } from
|
|
5
|
-
import type DIVEOrbitControls from
|
|
6
|
-
import { type DIVESelectable } from
|
|
7
|
-
import { type DIVEMovable } from
|
|
8
|
-
import { type DIVEBaseTool } from
|
|
1
|
+
import { type Object3D } from 'three';
|
|
2
|
+
import { DIVEScene } from '../../scene/Scene.ts';
|
|
3
|
+
import DIVETransformTool from '../transform/TransformTool.ts';
|
|
4
|
+
import { findInterface } from '../../helper/findInterface/findInterface.ts';
|
|
5
|
+
import type DIVEOrbitControls from '../../controls/OrbitControls.ts';
|
|
6
|
+
import { type DIVESelectable } from '../../interface/Selectable.ts';
|
|
7
|
+
import { type DIVEMovable } from '../../interface/Movable.ts';
|
|
8
|
+
import { type DIVEBaseTool } from '../BaseTool.ts';
|
|
9
9
|
|
|
10
10
|
export const isSelectTool = (tool: DIVEBaseTool): tool is DIVESelectTool => {
|
|
11
11
|
return (tool as DIVESelectTool).isSelectTool !== undefined;
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
|
|
14
14
|
export interface DIVEObjectEventMap {
|
|
15
|
-
select: object
|
|
15
|
+
select: object;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -28,11 +28,10 @@ export class DIVESelectTool extends DIVETransformTool {
|
|
|
28
28
|
|
|
29
29
|
constructor(scene: DIVEScene, controller: DIVEOrbitControls) {
|
|
30
30
|
super(scene, controller);
|
|
31
|
-
this.name =
|
|
31
|
+
this.name = 'SelectTool';
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
public Activate(): void {
|
|
35
|
-
|
|
34
|
+
public Activate(): void {}
|
|
36
35
|
|
|
37
36
|
public Select(selectable: DIVESelectable): void {
|
|
38
37
|
if (selectable.onSelect) selectable.onSelect();
|
|
@@ -48,7 +47,9 @@ export class DIVESelectTool extends DIVETransformTool {
|
|
|
48
47
|
|
|
49
48
|
public AttachGizmo(selectable: DIVESelectable): void {
|
|
50
49
|
if ('isMovable' in selectable) {
|
|
51
|
-
const movable = selectable as
|
|
50
|
+
const movable = selectable as Object3D &
|
|
51
|
+
DIVESelectable &
|
|
52
|
+
DIVEMovable;
|
|
52
53
|
this._gizmo.attach(movable);
|
|
53
54
|
this.SetGizmoVisibility(movable.visible);
|
|
54
55
|
}
|
|
@@ -61,8 +62,13 @@ export class DIVESelectTool extends DIVETransformTool {
|
|
|
61
62
|
public onClick(e: PointerEvent): void {
|
|
62
63
|
super.onClick(e);
|
|
63
64
|
|
|
64
|
-
const first = this._raycaster
|
|
65
|
-
|
|
65
|
+
const first = this._raycaster
|
|
66
|
+
.intersectObjects(this._scene.Root.children, true)
|
|
67
|
+
.filter((intersect) => intersect.object.visible)[0];
|
|
68
|
+
const selectable = findInterface<DIVESelectable>(
|
|
69
|
+
first?.object,
|
|
70
|
+
'isSelectable',
|
|
71
|
+
);
|
|
66
72
|
|
|
67
73
|
// if nothing is hit
|
|
68
74
|
if (!first || !selectable) {
|
|
@@ -77,11 +83,10 @@ export class DIVESelectTool extends DIVETransformTool {
|
|
|
77
83
|
if (this._gizmo.object.uuid === selectable.uuid) return;
|
|
78
84
|
|
|
79
85
|
// deselect previous object
|
|
80
|
-
this.Deselect(this._gizmo.object as
|
|
86
|
+
this.Deselect(this._gizmo.object as Object3D & DIVESelectable);
|
|
81
87
|
}
|
|
82
88
|
|
|
83
|
-
|
|
84
89
|
// select clicked object
|
|
85
90
|
this.Select(selectable);
|
|
86
91
|
}
|
|
87
|
-
}
|
|
92
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DIVESelectTool, isSelectTool } from '../SelectTool';
|
|
2
2
|
import { DIVEScene } from '../../../scene/Scene';
|
|
3
3
|
import DIVEOrbitControls from '../../../controls/OrbitControls';
|
|
4
|
-
import { DIVERenderer
|
|
4
|
+
import { DIVERenderer } from '../../../renderer/Renderer';
|
|
5
5
|
import { DIVESelectable } from '../../../interface/Selectable';
|
|
6
6
|
import type DIVEPerspectiveCamera from '../../../camera/PerspectiveCamera';
|
|
7
7
|
import { type Object3D } from 'three';
|
|
@@ -11,9 +11,9 @@ import { Tween } from '@tweenjs/tween.js';
|
|
|
11
11
|
|
|
12
12
|
jest.mock('@tweenjs/tween.js', () => {
|
|
13
13
|
return {
|
|
14
|
-
Tween: jest.fn(() => {
|
|
14
|
+
Tween: jest.fn(() => {}),
|
|
15
15
|
update: jest.fn(),
|
|
16
|
-
}
|
|
16
|
+
};
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
jest.mock('../../../renderer/Renderer', () => {
|
|
@@ -42,13 +42,12 @@ jest.mock('../../../controls/OrbitControls', () => {
|
|
|
42
42
|
this.object = {
|
|
43
43
|
layers: {
|
|
44
44
|
mask: 0,
|
|
45
|
-
}
|
|
45
|
+
},
|
|
46
46
|
};
|
|
47
47
|
return this;
|
|
48
48
|
});
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
|
|
52
51
|
jest.mock('../../../animation/AnimationSystem', () => {
|
|
53
52
|
return {
|
|
54
53
|
DIVEAnimationSystem: jest.fn(function () {
|
|
@@ -61,7 +60,7 @@ jest.mock('../../../animation/AnimationSystem', () => {
|
|
|
61
60
|
|
|
62
61
|
return this;
|
|
63
62
|
}),
|
|
64
|
-
}
|
|
63
|
+
};
|
|
65
64
|
});
|
|
66
65
|
|
|
67
66
|
jest.mock('../../../scene/Scene', () => {
|
|
@@ -71,9 +70,9 @@ jest.mock('../../../scene/Scene', () => {
|
|
|
71
70
|
this.children = [];
|
|
72
71
|
this.Root = {
|
|
73
72
|
children: [],
|
|
74
|
-
}
|
|
73
|
+
};
|
|
75
74
|
return this;
|
|
76
|
-
})
|
|
75
|
+
}),
|
|
77
76
|
};
|
|
78
77
|
});
|
|
79
78
|
|
|
@@ -104,7 +103,10 @@ const mock_detach = jest.fn();
|
|
|
104
103
|
jest.mock('three/examples/jsm/Addons.js', () => {
|
|
105
104
|
return {
|
|
106
105
|
TransformControls: jest.fn(function () {
|
|
107
|
-
this.addEventListener = (
|
|
106
|
+
(this.addEventListener = (
|
|
107
|
+
type: string,
|
|
108
|
+
callback: (e: object) => void,
|
|
109
|
+
) => {
|
|
108
110
|
callback({ value: false });
|
|
109
111
|
this.object = {};
|
|
110
112
|
callback({ value: false });
|
|
@@ -116,12 +118,12 @@ jest.mock('three/examples/jsm/Addons.js', () => {
|
|
|
116
118
|
onMove: jest.fn(),
|
|
117
119
|
};
|
|
118
120
|
callback({ value: false });
|
|
119
|
-
},
|
|
120
|
-
this.attach = mock_attach,
|
|
121
|
-
this.detach = mock_detach,
|
|
122
|
-
this.traverse = function (callback: (obj: object) => void) {
|
|
121
|
+
}),
|
|
122
|
+
(this.attach = mock_attach),
|
|
123
|
+
(this.detach = mock_detach),
|
|
124
|
+
(this.traverse = function (callback: (obj: object) => void) {
|
|
123
125
|
callback(this);
|
|
124
|
-
};
|
|
126
|
+
});
|
|
125
127
|
this.setMode = jest.fn();
|
|
126
128
|
this.getRaycaster = jest.fn().mockReturnValue({
|
|
127
129
|
layers: {
|
|
@@ -143,7 +145,11 @@ const mockRenderer = {
|
|
|
143
145
|
} as unknown as DIVERenderer;
|
|
144
146
|
const mockScene: DIVEScene = new DIVEScene();
|
|
145
147
|
const mockAnimSystem = new DIVEAnimationSystem(mockRenderer);
|
|
146
|
-
const mockController: DIVEOrbitControls = new DIVEOrbitControls(
|
|
148
|
+
const mockController: DIVEOrbitControls = new DIVEOrbitControls(
|
|
149
|
+
mockCamera,
|
|
150
|
+
mockRenderer,
|
|
151
|
+
mockAnimSystem,
|
|
152
|
+
);
|
|
147
153
|
|
|
148
154
|
describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
149
155
|
it('should test if it is SelectTool', () => {
|
|
@@ -163,94 +169,119 @@ describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
|
163
169
|
|
|
164
170
|
it('should execute onClick without hit', () => {
|
|
165
171
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
166
|
-
selectTool['_gizmo'].object = {} as unknown as Object3D &
|
|
167
|
-
|
|
172
|
+
selectTool['_gizmo'].object = {} as unknown as Object3D &
|
|
173
|
+
DIVESelectable;
|
|
174
|
+
expect(() =>
|
|
175
|
+
selectTool.onClick({ offsetX: 0, offsetY: 0 } as PointerEvent),
|
|
176
|
+
).not.toThrow();
|
|
168
177
|
});
|
|
169
178
|
|
|
170
179
|
it('should execute onClick with hit', () => {
|
|
171
|
-
mock_intersectObjects.mockReturnValueOnce(
|
|
172
|
-
|
|
180
|
+
mock_intersectObjects.mockReturnValueOnce([
|
|
181
|
+
{
|
|
173
182
|
object: {
|
|
174
183
|
uuid: 'test',
|
|
175
184
|
visible: true,
|
|
176
|
-
parent: {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
185
|
+
parent: {
|
|
186
|
+
name: 'this is the test scene root!!!',
|
|
187
|
+
parent: null,
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
]);
|
|
180
192
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
181
|
-
expect(() =>
|
|
193
|
+
expect(() =>
|
|
194
|
+
selectTool.onClick({ offsetX: 0, offsetY: 0 } as PointerEvent),
|
|
195
|
+
).not.toThrow();
|
|
182
196
|
});
|
|
183
197
|
|
|
184
198
|
it('should execute onClick with same ISelectable hit', () => {
|
|
185
199
|
const mock_onSelect = jest.fn();
|
|
186
200
|
|
|
187
|
-
mock_intersectObjects.mockReturnValueOnce([
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
201
|
+
mock_intersectObjects.mockReturnValueOnce([
|
|
202
|
+
{
|
|
203
|
+
object: {
|
|
204
|
+
isSelectable: true,
|
|
205
|
+
onSelect: mock_onSelect,
|
|
206
|
+
visible: true,
|
|
207
|
+
parent: {
|
|
208
|
+
name: 'this is the test scene root!!!',
|
|
209
|
+
parent: null,
|
|
210
|
+
},
|
|
211
|
+
uuid: 'test0',
|
|
195
212
|
},
|
|
196
|
-
uuid: 'test0',
|
|
197
213
|
},
|
|
198
|
-
|
|
214
|
+
]);
|
|
199
215
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
200
216
|
selectTool['_gizmo'].object = {
|
|
201
217
|
visible: true,
|
|
202
218
|
isSelectable: true,
|
|
203
219
|
uuid: 'test0',
|
|
204
220
|
} as unknown as Object3D & DIVESelectable;
|
|
205
|
-
expect(() =>
|
|
221
|
+
expect(() =>
|
|
222
|
+
selectTool.onClick({ offsetX: 0, offsetY: 0 } as PointerEvent),
|
|
223
|
+
).not.toThrow();
|
|
206
224
|
});
|
|
207
225
|
|
|
208
226
|
it('should execute onClick with ISelectable hit', () => {
|
|
209
227
|
const mock_onSelect = jest.fn();
|
|
210
228
|
|
|
211
|
-
mock_intersectObjects.mockReturnValueOnce([
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
229
|
+
mock_intersectObjects.mockReturnValueOnce([
|
|
230
|
+
{
|
|
231
|
+
object: {
|
|
232
|
+
isSelectable: true,
|
|
233
|
+
onSelect: mock_onSelect,
|
|
234
|
+
visible: true,
|
|
235
|
+
parent: {
|
|
236
|
+
name: 'this is the test scene root!!!',
|
|
237
|
+
parent: null,
|
|
238
|
+
},
|
|
239
|
+
uuid: 'test0',
|
|
219
240
|
},
|
|
220
|
-
uuid: 'test0',
|
|
221
241
|
},
|
|
222
|
-
|
|
242
|
+
]);
|
|
223
243
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
224
244
|
selectTool['_gizmo'].object = {
|
|
225
245
|
isSelectable: true,
|
|
226
246
|
uuid: 'test1',
|
|
227
247
|
} as unknown as Object3D & DIVESelectable;
|
|
228
|
-
expect(() =>
|
|
248
|
+
expect(() =>
|
|
249
|
+
selectTool.onClick({ offsetX: 0, offsetY: 0 } as PointerEvent),
|
|
250
|
+
).not.toThrow();
|
|
229
251
|
});
|
|
230
252
|
|
|
231
253
|
it('should execute onClick with IMovable hit', () => {
|
|
232
254
|
const mock_onSelect = jest.fn();
|
|
233
255
|
|
|
234
|
-
mock_intersectObjects.mockReturnValueOnce([
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
256
|
+
mock_intersectObjects.mockReturnValueOnce([
|
|
257
|
+
{
|
|
258
|
+
object: {
|
|
259
|
+
isSelectable: true,
|
|
260
|
+
isMovable: true,
|
|
261
|
+
onSelect: mock_onSelect,
|
|
262
|
+
parent: {
|
|
263
|
+
name: 'this is the test scene root!!!',
|
|
264
|
+
parent: null,
|
|
265
|
+
},
|
|
242
266
|
},
|
|
243
267
|
},
|
|
244
|
-
|
|
268
|
+
]);
|
|
245
269
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
246
|
-
expect(() =>
|
|
270
|
+
expect(() =>
|
|
271
|
+
selectTool.onClick({ offsetX: 0, offsetY: 0 } as PointerEvent),
|
|
272
|
+
).not.toThrow();
|
|
247
273
|
});
|
|
248
274
|
|
|
249
275
|
it('should Select', () => {
|
|
250
276
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
251
277
|
const mock_onSelect = jest.fn();
|
|
252
278
|
expect(() => selectTool.Select({ isSelectable: true })).not.toThrow();
|
|
253
|
-
expect(() =>
|
|
279
|
+
expect(() =>
|
|
280
|
+
selectTool.Select({
|
|
281
|
+
isMovable: true,
|
|
282
|
+
onSelect: mock_onSelect,
|
|
283
|
+
} as unknown as DIVESelectable),
|
|
284
|
+
).not.toThrow();
|
|
254
285
|
expect(mock_onSelect).toHaveBeenCalledTimes(1);
|
|
255
286
|
});
|
|
256
287
|
|
|
@@ -258,7 +289,12 @@ describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
|
258
289
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
259
290
|
const mock_onDeselect = jest.fn();
|
|
260
291
|
expect(() => selectTool.Deselect({ isSelectable: true })).not.toThrow();
|
|
261
|
-
expect(() =>
|
|
292
|
+
expect(() =>
|
|
293
|
+
selectTool.Deselect({
|
|
294
|
+
isMovable: true,
|
|
295
|
+
onDeselect: mock_onDeselect,
|
|
296
|
+
} as unknown as DIVESelectable),
|
|
297
|
+
).not.toThrow();
|
|
262
298
|
expect(mock_onDeselect).toHaveBeenCalledTimes(1);
|
|
263
299
|
});
|
|
264
300
|
|
|
@@ -266,4 +302,4 @@ describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
|
266
302
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
267
303
|
expect(() => selectTool.SetGizmoMode('translate')).not.toThrow();
|
|
268
304
|
});
|
|
269
|
-
});
|
|
305
|
+
});
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import { DIVEBaseTool } from
|
|
2
|
-
import { DIVEScene } from
|
|
3
|
-
import DIVEOrbitControls from
|
|
4
|
-
import { TransformControls } from
|
|
5
|
-
import { type DIVEMovable } from
|
|
6
|
-
import { implementsInterface } from
|
|
7
|
-
|
|
8
|
-
export const isTransformTool = (
|
|
1
|
+
import { DIVEBaseTool } from '../BaseTool.ts';
|
|
2
|
+
import { DIVEScene } from '../../scene/Scene.ts';
|
|
3
|
+
import DIVEOrbitControls from '../../controls/OrbitControls.ts';
|
|
4
|
+
import { TransformControls } from 'three/examples/jsm/Addons';
|
|
5
|
+
import { type DIVEMovable } from '../../interface/Movable.ts';
|
|
6
|
+
import { implementsInterface } from '../../helper/isInterface/implementsInterface.ts';
|
|
7
|
+
|
|
8
|
+
export const isTransformTool = (
|
|
9
|
+
tool: DIVEBaseTool,
|
|
10
|
+
): tool is DIVETransformTool => {
|
|
9
11
|
return (tool as DIVETransformTool).isTransformTool !== undefined;
|
|
10
|
-
}
|
|
12
|
+
};
|
|
11
13
|
|
|
12
14
|
export interface DIVEObjectEventMap {
|
|
13
|
-
select: object
|
|
15
|
+
select: object;
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -28,23 +30,38 @@ export default class DIVETransformTool extends DIVEBaseTool {
|
|
|
28
30
|
|
|
29
31
|
constructor(scene: DIVEScene, controller: DIVEOrbitControls) {
|
|
30
32
|
super(scene, controller);
|
|
31
|
-
this.name =
|
|
33
|
+
this.name = 'DIVETransformTool';
|
|
32
34
|
|
|
33
|
-
this._gizmo = new TransformControls(
|
|
35
|
+
this._gizmo = new TransformControls(
|
|
36
|
+
this._controller.object,
|
|
37
|
+
this._controller.domElement,
|
|
38
|
+
);
|
|
34
39
|
this._gizmo.mode = 'translate';
|
|
35
40
|
|
|
36
41
|
// happens when pointerDown event is called on gizmo
|
|
37
42
|
this._gizmo.addEventListener('mouseDown', () => {
|
|
38
43
|
controller.enabled = false;
|
|
39
44
|
|
|
40
|
-
if (
|
|
45
|
+
if (
|
|
46
|
+
!implementsInterface<DIVEMovable>(
|
|
47
|
+
this._gizmo.object,
|
|
48
|
+
'isMovable',
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
return;
|
|
41
52
|
if (!this._gizmo.object.onMoveStart) return;
|
|
42
53
|
this._gizmo.object.onMoveStart();
|
|
43
54
|
});
|
|
44
55
|
|
|
45
56
|
// happens when pointerMove event is called on gizmo
|
|
46
57
|
this._gizmo.addEventListener('objectChange', () => {
|
|
47
|
-
if (
|
|
58
|
+
if (
|
|
59
|
+
!implementsInterface<DIVEMovable>(
|
|
60
|
+
this._gizmo.object,
|
|
61
|
+
'isMovable',
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
return;
|
|
48
65
|
if (!this._gizmo.object.onMove) return;
|
|
49
66
|
this._gizmo.object.onMove();
|
|
50
67
|
});
|
|
@@ -53,7 +70,13 @@ export default class DIVETransformTool extends DIVEBaseTool {
|
|
|
53
70
|
this._gizmo.addEventListener('mouseUp', () => {
|
|
54
71
|
controller.enabled = true;
|
|
55
72
|
|
|
56
|
-
if (
|
|
73
|
+
if (
|
|
74
|
+
!implementsInterface<DIVEMovable>(
|
|
75
|
+
this._gizmo.object,
|
|
76
|
+
'isMovable',
|
|
77
|
+
)
|
|
78
|
+
)
|
|
79
|
+
return;
|
|
57
80
|
if (!this._gizmo.object.onMoveEnd) return;
|
|
58
81
|
this._gizmo.object.onMoveEnd();
|
|
59
82
|
});
|
|
@@ -61,7 +84,7 @@ export default class DIVETransformTool extends DIVEBaseTool {
|
|
|
61
84
|
scene.add(this._gizmo);
|
|
62
85
|
}
|
|
63
86
|
|
|
64
|
-
public Activate(): void {
|
|
87
|
+
public Activate(): void {}
|
|
65
88
|
|
|
66
89
|
public SetGizmoMode(mode: 'translate' | 'rotate' | 'scale'): void {
|
|
67
90
|
this._gizmo.mode = mode;
|
|
@@ -87,4 +110,4 @@ export default class DIVETransformTool extends DIVEBaseTool {
|
|
|
87
110
|
// protected raycast(): Intersection[] {
|
|
88
111
|
// return super.raycast(this._gizmo.gizmoNode.children);
|
|
89
112
|
// }
|
|
90
|
-
}
|
|
113
|
+
}
|
|
@@ -9,9 +9,9 @@ import { DIVEAnimationSystem } from '../../../animation/AnimationSystem';
|
|
|
9
9
|
|
|
10
10
|
jest.mock('@tweenjs/tween.js', () => {
|
|
11
11
|
return {
|
|
12
|
-
Tween: jest.fn(() => {
|
|
12
|
+
Tween: jest.fn(() => {}),
|
|
13
13
|
update: jest.fn(),
|
|
14
|
-
}
|
|
14
|
+
};
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
jest.mock('../../../renderer/Renderer', () => {
|
|
@@ -40,7 +40,7 @@ jest.mock('../../../controls/OrbitControls', () => {
|
|
|
40
40
|
this.object = {
|
|
41
41
|
layers: {
|
|
42
42
|
mask: 0,
|
|
43
|
-
}
|
|
43
|
+
},
|
|
44
44
|
};
|
|
45
45
|
return this;
|
|
46
46
|
});
|
|
@@ -53,10 +53,10 @@ jest.mock('../../../scene/Scene', () => {
|
|
|
53
53
|
this.remove = jest.fn();
|
|
54
54
|
this.Root = {
|
|
55
55
|
children: [],
|
|
56
|
-
}
|
|
56
|
+
};
|
|
57
57
|
this.children = [];
|
|
58
58
|
return this;
|
|
59
|
-
})
|
|
59
|
+
}),
|
|
60
60
|
};
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -72,7 +72,7 @@ jest.mock('../../../animation/AnimationSystem', () => {
|
|
|
72
72
|
|
|
73
73
|
return this;
|
|
74
74
|
}),
|
|
75
|
-
}
|
|
75
|
+
};
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
const mock_intersectObjects = jest.fn().mockReturnValue([]);
|
|
@@ -102,13 +102,16 @@ const mock_detach = jest.fn();
|
|
|
102
102
|
jest.mock('three/examples/jsm/Addons.js', () => {
|
|
103
103
|
return {
|
|
104
104
|
TransformControls: jest.fn(function () {
|
|
105
|
-
this.addEventListener = (
|
|
105
|
+
(this.addEventListener = (
|
|
106
|
+
type: string,
|
|
107
|
+
callback: (e: object) => void,
|
|
108
|
+
) => {
|
|
106
109
|
this.object = null;
|
|
107
110
|
callback({ value: false });
|
|
108
111
|
this.object = {};
|
|
109
112
|
callback({ value: false });
|
|
110
113
|
this.object = {
|
|
111
|
-
isMovable: true
|
|
114
|
+
isMovable: true,
|
|
112
115
|
};
|
|
113
116
|
callback({ value: false });
|
|
114
117
|
this.object = {
|
|
@@ -118,12 +121,12 @@ jest.mock('three/examples/jsm/Addons.js', () => {
|
|
|
118
121
|
onMoveEnd: jest.fn(),
|
|
119
122
|
};
|
|
120
123
|
callback({ value: false });
|
|
121
|
-
},
|
|
122
|
-
this.attach = mock_attach,
|
|
123
|
-
this.detach = mock_detach,
|
|
124
|
-
this.traverse = function (callback: (obj: object) => void) {
|
|
124
|
+
}),
|
|
125
|
+
(this.attach = mock_attach),
|
|
126
|
+
(this.detach = mock_detach),
|
|
127
|
+
(this.traverse = function (callback: (obj: object) => void) {
|
|
125
128
|
callback(this);
|
|
126
|
-
};
|
|
129
|
+
});
|
|
127
130
|
this.setMode = jest.fn();
|
|
128
131
|
this.getRaycaster = jest.fn().mockReturnValue({
|
|
129
132
|
layers: {
|
|
@@ -155,7 +158,11 @@ const mockRenderer = {
|
|
|
155
158
|
} as unknown as DIVERenderer;
|
|
156
159
|
const mockScene: DIVEScene = new DIVEScene();
|
|
157
160
|
const mockAnimSystem = new DIVEAnimationSystem(mockRenderer);
|
|
158
|
-
const mockController: DIVEOrbitControls = new DIVEOrbitControls(
|
|
161
|
+
const mockController: DIVEOrbitControls = new DIVEOrbitControls(
|
|
162
|
+
mockCamera,
|
|
163
|
+
mockRenderer,
|
|
164
|
+
mockAnimSystem,
|
|
165
|
+
);
|
|
159
166
|
|
|
160
167
|
describe('dive/toolbox/select/DIVETransformTool', () => {
|
|
161
168
|
it('should test if it is SelectTool', () => {
|
|
@@ -187,4 +194,4 @@ describe('dive/toolbox/select/DIVETransformTool', () => {
|
|
|
187
194
|
mockScene.children.includes = jest.fn().mockReturnValue(true);
|
|
188
195
|
expect(() => transformTool.SetGizmoVisibility(false)).not.toThrow();
|
|
189
196
|
});
|
|
190
|
-
});
|
|
197
|
+
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { DIVEGroup } from
|
|
2
|
-
import DIVEAmbientLight from
|
|
3
|
-
import DIVEPointLight from
|
|
4
|
-
import DIVESceneLight from
|
|
5
|
-
import { DIVEModel } from
|
|
6
|
-
import { DIVEPrimitive } from
|
|
1
|
+
import { DIVEGroup } from '../group/Group';
|
|
2
|
+
import DIVEAmbientLight from '../light/AmbientLight';
|
|
3
|
+
import DIVEPointLight from '../light/PointLight';
|
|
4
|
+
import DIVESceneLight from '../light/SceneLight';
|
|
5
|
+
import { DIVEModel } from '../model/Model';
|
|
6
|
+
import { DIVEPrimitive } from '../primitive/Primitive';
|
|
7
7
|
|
|
8
8
|
export type DIVESceneObject =
|
|
9
|
-
DIVEModel
|
|
9
|
+
| DIVEModel
|
|
10
10
|
| DIVEGroup
|
|
11
11
|
| DIVEPrimitive
|
|
12
12
|
| DIVEAmbientLight
|
|
13
13
|
| DIVEPointLight
|
|
14
|
-
| DIVESceneLight;
|
|
14
|
+
| DIVESceneLight;
|