@shopware-ag/dive 1.4.2 → 1.5.0
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 +25 -24
- package/build/dive.cjs +29 -4
- package/build/dive.cjs.map +1 -1
- package/build/dive.d.cts +8 -0
- package/build/dive.d.ts +8 -0
- package/build/dive.js +29 -4
- package/build/dive.js.map +1 -1
- package/package.json +1 -1
- package/src/com/Communication.ts +9 -0
- package/src/com/__test__/Communication.test.ts +10 -0
- package/src/com/actions/index.ts +2 -0
- package/src/com/actions/toolbox/transform/setgizmovisible.ts +4 -0
- package/src/model/Model.ts +6 -0
- package/src/model/__test__/Model.test.ts +9 -0
- package/src/scene/root/modelroot/ModelRoot.ts +1 -1
- package/src/scene/root/modelroot/__test__/ModelRoot.test.ts +1 -0
- package/src/toolbox/BaseTool.ts +2 -2
- package/src/toolbox/Toolbox.ts +4 -0
- package/src/toolbox/__test__/BaseTool.test.ts +6 -0
- package/src/toolbox/__test__/Toolbox.test.ts +8 -0
- package/src/toolbox/select/SelectTool.ts +2 -1
- package/src/toolbox/select/__test__/SelectTool.test.ts +13 -3
- package/src/toolbox/transform/TransformTool.ts +9 -0
- package/src/toolbox/transform/__test__/TransformTool.test.ts +12 -0
package/package.json
CHANGED
package/src/com/Communication.ts
CHANGED
|
@@ -144,6 +144,10 @@ export default class DIVECommunication {
|
|
|
144
144
|
returnValue = this.setGizmoMode(payload as Actions['SET_GIZMO_MODE']['PAYLOAD']);
|
|
145
145
|
break;
|
|
146
146
|
}
|
|
147
|
+
case 'SET_GIZMO_VISIBILITY': {
|
|
148
|
+
returnValue = this.setGizmoVisibility(payload as Actions['SET_GIZMO_VISIBILITY']['PAYLOAD']);
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
147
151
|
case 'MODEL_LOADED': {
|
|
148
152
|
returnValue = this.modelLoaded(payload as Actions['MODEL_LOADED']['PAYLOAD']);
|
|
149
153
|
break;
|
|
@@ -380,6 +384,11 @@ export default class DIVECommunication {
|
|
|
380
384
|
return true;
|
|
381
385
|
}
|
|
382
386
|
|
|
387
|
+
private setGizmoVisibility(payload: Actions['SET_GIZMO_VISIBILITY']['PAYLOAD']): Actions['SET_GIZMO_VISIBILITY']['RETURN'] {
|
|
388
|
+
this.toolbox.SetGizmoVisibility(payload);
|
|
389
|
+
return payload;
|
|
390
|
+
}
|
|
391
|
+
|
|
383
392
|
private modelLoaded(payload: Actions['MODEL_LOADED']['PAYLOAD']): Actions['MODEL_LOADED']['RETURN'] {
|
|
384
393
|
(this.registered.get(payload.id) as COMModel).loaded = true;
|
|
385
394
|
return true;
|
|
@@ -23,6 +23,7 @@ import '../actions/scene/getallscenedata';
|
|
|
23
23
|
import '../actions/scene/setbackground';
|
|
24
24
|
import '../actions/scene/updatescene';
|
|
25
25
|
import '../actions/toolbox/select/setgizmomode';
|
|
26
|
+
import '../actions/toolbox/transform/setgizmovisible';
|
|
26
27
|
import '../actions/camera/getcameratransform';
|
|
27
28
|
import DIVEOrbitControls from '../../controls/OrbitControls';
|
|
28
29
|
import { COMLight, COMModel, COMPov } from '../types';
|
|
@@ -122,6 +123,7 @@ const mockToolBox = {
|
|
|
122
123
|
DetachGizmo: mockDetach,
|
|
123
124
|
}),
|
|
124
125
|
SetGizmoMode: jest.fn(),
|
|
126
|
+
SetGizmoVisibility: jest.fn(),
|
|
125
127
|
} as unknown as DIVEToolbox;
|
|
126
128
|
|
|
127
129
|
const mockMediaCreator = {
|
|
@@ -614,6 +616,14 @@ describe('dive/communication/DIVECommunication', () => {
|
|
|
614
616
|
expect(success).toBe(true);
|
|
615
617
|
});
|
|
616
618
|
|
|
619
|
+
it('should perform action SET_GIZMO_VISIBILITY', () => {
|
|
620
|
+
let visibility = testCom.PerformAction('SET_GIZMO_VISIBILITY', true);
|
|
621
|
+
expect(visibility).toBe(true);
|
|
622
|
+
|
|
623
|
+
visibility = testCom.PerformAction('SET_GIZMO_VISIBILITY', false);
|
|
624
|
+
expect(visibility).toBe(false);
|
|
625
|
+
});
|
|
626
|
+
|
|
617
627
|
it('should perform action MODEL_LOADED', () => {
|
|
618
628
|
const payload = {
|
|
619
629
|
entityType: "model",
|
package/src/com/actions/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import SELECT_OBJECT from "./object/selectobject.ts";
|
|
|
19
19
|
import DESELECT_OBJECT from "./object/deselectobject.ts";
|
|
20
20
|
import GET_CAMERA_TRANSFORM from "./camera/getcameratransform.ts";
|
|
21
21
|
import DROP_IT from "./object/model/dropit.ts";
|
|
22
|
+
import SET_GIZMO_VISIBILITY from "./toolbox/transform/setgizmovisible.js";
|
|
22
23
|
|
|
23
24
|
export type Actions = {
|
|
24
25
|
GET_ALL_SCENE_DATA: GET_ALL_SCENE_DATA,
|
|
@@ -39,6 +40,7 @@ export type Actions = {
|
|
|
39
40
|
SET_CAMERA_LAYER: SET_CAMERA_LAYER,
|
|
40
41
|
ZOOM_CAMERA: ZOOM_CAMERA,
|
|
41
42
|
SET_GIZMO_MODE: SET_GIZMO_MODE,
|
|
43
|
+
SET_GIZMO_VISIBILITY: SET_GIZMO_VISIBILITY,
|
|
42
44
|
MODEL_LOADED: MODEL_LOADED,
|
|
43
45
|
UPDATE_SCENE: UPDATE_SCENE,
|
|
44
46
|
GENERATE_MEDIA: GENERATE_MEDIA,
|
package/src/model/Model.ts
CHANGED
|
@@ -57,6 +57,12 @@ export default class DIVEModel extends Object3D implements DIVESelectable, DIVEM
|
|
|
57
57
|
this.scale.set(scale.x, scale.y, scale.z);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
public SetVisibility(visible: boolean): void {
|
|
61
|
+
this.traverse((child) => {
|
|
62
|
+
child.visible = visible;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
60
66
|
public SetToWorldOrigin(): void {
|
|
61
67
|
this.position.set(0, 0, 0);
|
|
62
68
|
DIVECommunication.get(this.userData.id)?.PerformAction('UPDATE_OBJECT', { id: this.userData.id, position: this.position, rotation: this.rotation, scale: this.scale });
|
|
@@ -64,6 +64,7 @@ jest.mock('three', () => {
|
|
|
64
64
|
}
|
|
65
65
|
this.add = jest.fn();
|
|
66
66
|
this.children = [{
|
|
67
|
+
visible: true,
|
|
67
68
|
material: {
|
|
68
69
|
color: {},
|
|
69
70
|
},
|
|
@@ -86,6 +87,9 @@ jest.mock('three', () => {
|
|
|
86
87
|
return vec3;
|
|
87
88
|
};
|
|
88
89
|
this.mesh = new Mesh();
|
|
90
|
+
this.traverse = jest.fn((callback) => {
|
|
91
|
+
callback(this.children[0])
|
|
92
|
+
});
|
|
89
93
|
return this;
|
|
90
94
|
}),
|
|
91
95
|
Box3: jest.fn(function () {
|
|
@@ -196,6 +200,11 @@ describe('dive/model/DIVEModel', () => {
|
|
|
196
200
|
expect(() => model.SetScale({ x: 1, y: 1, z: 1 })).not.toThrow();
|
|
197
201
|
});
|
|
198
202
|
|
|
203
|
+
it('should set visibility', () => {
|
|
204
|
+
const model = new Model();
|
|
205
|
+
expect(() => model.SetVisibility(true)).not.toThrow();
|
|
206
|
+
});
|
|
207
|
+
|
|
199
208
|
it('should set to world origin', () => {
|
|
200
209
|
const model = new Model();
|
|
201
210
|
model.userData.id = 'something';
|
|
@@ -51,7 +51,7 @@ export default class DIVEModelRoot extends Object3D {
|
|
|
51
51
|
if (object.position !== undefined) (sceneObject as Model).SetPosition(object.position);
|
|
52
52
|
if (object.rotation !== undefined) (sceneObject as Model).SetRotation(object.rotation);
|
|
53
53
|
if (object.scale !== undefined) (sceneObject as Model).SetScale(object.scale);
|
|
54
|
-
if (object.visible !== undefined) (sceneObject as Model).
|
|
54
|
+
if (object.visible !== undefined) (sceneObject as Model).SetVisibility(object.visible);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
public DeleteModel(object: Partial<COMModel>): void {
|
|
@@ -45,6 +45,7 @@ jest.mock('../../../../model/Model.ts', () => {
|
|
|
45
45
|
this.SetPosition = mock_SetPosition;
|
|
46
46
|
this.SetRotation = mock_SetRotation;
|
|
47
47
|
this.SetScale = mock_SetScale;
|
|
48
|
+
this.SetVisibility = jest.fn();
|
|
48
49
|
this.PlaceOnFloor = mock_PlaceOnFloor;
|
|
49
50
|
this.removeFromParent = jest.fn();
|
|
50
51
|
return this;
|
package/src/toolbox/BaseTool.ts
CHANGED
|
@@ -258,8 +258,8 @@ export default abstract class DIVEBaseTool {
|
|
|
258
258
|
public onWheel(e: WheelEvent): void { }
|
|
259
259
|
|
|
260
260
|
protected raycast(objects?: Object3D[]): Intersection[] {
|
|
261
|
-
if (objects !== undefined) return this._raycaster.intersectObjects(objects, true);
|
|
262
|
-
return this._raycaster.intersectObjects(this._scene.children, true);
|
|
261
|
+
if (objects !== undefined) return this._raycaster.intersectObjects(objects, true).filter(i => i.object.visible);
|
|
262
|
+
return this._raycaster.intersectObjects(this._scene.children, true).filter(i => i.object.visible);
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
private pointerWasDragged(): boolean {
|
package/src/toolbox/Toolbox.ts
CHANGED
|
@@ -69,6 +69,10 @@ export default class DIVEToolbox {
|
|
|
69
69
|
this.selectTool.SetGizmoMode(mode);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
public SetGizmoVisibility(active: boolean): void {
|
|
73
|
+
this.selectTool.SetGizmoVisibility(active);
|
|
74
|
+
}
|
|
75
|
+
|
|
72
76
|
public onPointerMove(e: PointerEvent): void {
|
|
73
77
|
this.activeTool.onPointerMove(e);
|
|
74
78
|
}
|
|
@@ -134,6 +134,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
134
134
|
object: {
|
|
135
135
|
uuid: 'uuid',
|
|
136
136
|
isHoverable: true,
|
|
137
|
+
visible: true,
|
|
137
138
|
} as Object3D & DIVEHoverable
|
|
138
139
|
}
|
|
139
140
|
]
|
|
@@ -158,6 +159,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
158
159
|
object: {
|
|
159
160
|
uuid: 'uuid',
|
|
160
161
|
isHoverable: true,
|
|
162
|
+
visible: true,
|
|
161
163
|
onPointerEnter() {
|
|
162
164
|
return;
|
|
163
165
|
},
|
|
@@ -183,6 +185,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
183
185
|
object: {
|
|
184
186
|
uuid: 'uuid',
|
|
185
187
|
isHoverable: true,
|
|
188
|
+
visible: true,
|
|
186
189
|
onPointerOver() {
|
|
187
190
|
return;
|
|
188
191
|
}
|
|
@@ -193,6 +196,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
193
196
|
|
|
194
197
|
toolBox['_hovered'] = {
|
|
195
198
|
uuid: 'uuid',
|
|
199
|
+
visible: true,
|
|
196
200
|
onPointerLeave() {
|
|
197
201
|
return;
|
|
198
202
|
},
|
|
@@ -215,6 +219,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
215
219
|
object: {
|
|
216
220
|
uuid: 'uuid2',
|
|
217
221
|
isHoverable: true,
|
|
222
|
+
visible: true,
|
|
218
223
|
onPointerEnter() {
|
|
219
224
|
return;
|
|
220
225
|
},
|
|
@@ -225,6 +230,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
|
|
|
225
230
|
|
|
226
231
|
toolBox['_hovered'] = {
|
|
227
232
|
uuid: 'uuid',
|
|
233
|
+
visible: true,
|
|
228
234
|
onPointerLeave() {
|
|
229
235
|
return;
|
|
230
236
|
},
|
|
@@ -28,6 +28,7 @@ const mock_onPointerMove = jest.fn();
|
|
|
28
28
|
const mock_onPointerUp = jest.fn();
|
|
29
29
|
const mock_onWheel = jest.fn();
|
|
30
30
|
const mock_SetGizmoMode = jest.fn();
|
|
31
|
+
const mock_SetGizmoVisibility = jest.fn();
|
|
31
32
|
|
|
32
33
|
jest.mock('../select/SelectTool.ts', () => {
|
|
33
34
|
return jest.fn(function () {
|
|
@@ -38,6 +39,7 @@ jest.mock('../select/SelectTool.ts', () => {
|
|
|
38
39
|
this.onPointerUp = mock_onPointerUp;
|
|
39
40
|
this.onWheel = mock_onWheel;
|
|
40
41
|
this.SetGizmoMode = mock_SetGizmoMode;
|
|
42
|
+
this.SetGizmoVisibility = mock_SetGizmoVisibility;
|
|
41
43
|
return this;
|
|
42
44
|
});
|
|
43
45
|
});
|
|
@@ -114,4 +116,10 @@ describe('dive/toolbox/DIVEToolBox', () => {
|
|
|
114
116
|
toolBox.SetGizmoMode('translate');
|
|
115
117
|
expect(mock_SetGizmoMode).toHaveBeenCalledTimes(1);
|
|
116
118
|
});
|
|
119
|
+
|
|
120
|
+
it('should set gizmo active', () => {
|
|
121
|
+
const toolBox = new DIVEToolbox({} as DIVEScene, mockController);
|
|
122
|
+
toolBox.SetGizmoVisibility(true);
|
|
123
|
+
expect(mock_SetGizmoVisibility).toHaveBeenCalledTimes(1);
|
|
124
|
+
});
|
|
117
125
|
});
|
|
@@ -47,13 +47,14 @@ export default class DIVESelectTool extends DIVETransformTool {
|
|
|
47
47
|
if ('isMoveable' in selectable) {
|
|
48
48
|
const movable = selectable as (Object3D & DIVESelectable & DIVEMoveable);
|
|
49
49
|
this._gizmo.attach(movable);
|
|
50
|
+
this.SetGizmoVisibility(movable.visible);
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
public onClick(e: PointerEvent): void {
|
|
54
55
|
super.onClick(e);
|
|
55
56
|
|
|
56
|
-
const first = this._raycaster.intersectObjects(this._scene.Root.children, true)[0];
|
|
57
|
+
const first = this._raycaster.intersectObjects(this._scene.Root.children, true).filter((intersect) => intersect.object.visible )[0];
|
|
57
58
|
const selectable = this.findSelectableInterface(first?.object);
|
|
58
59
|
|
|
59
60
|
// if nothing is hit
|
|
@@ -41,6 +41,7 @@ jest.mock('../../../controls/OrbitControls', () => {
|
|
|
41
41
|
jest.mock('../../../scene/Scene', () => {
|
|
42
42
|
return jest.fn(function () {
|
|
43
43
|
this.add = jest.fn();
|
|
44
|
+
this.children = [];
|
|
44
45
|
this.Root = {
|
|
45
46
|
children: [],
|
|
46
47
|
}
|
|
@@ -130,7 +131,15 @@ describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
|
130
131
|
});
|
|
131
132
|
|
|
132
133
|
it('should execute onClick with hit', () => {
|
|
133
|
-
mock_intersectObjects.mockReturnValueOnce(
|
|
134
|
+
mock_intersectObjects.mockReturnValueOnce(
|
|
135
|
+
[{
|
|
136
|
+
object: {
|
|
137
|
+
uuid: 'test',
|
|
138
|
+
visible: true,
|
|
139
|
+
parent: { name: 'this is the test scene root!!!', parent: null }
|
|
140
|
+
}
|
|
141
|
+
}]
|
|
142
|
+
);
|
|
134
143
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
135
144
|
expect(() => selectTool.onClick({ offsetX: 0, offsetY: 0 } as PointerEvent)).not.toThrow();
|
|
136
145
|
});
|
|
@@ -139,10 +148,10 @@ describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
|
139
148
|
const mock_onSelect = jest.fn();
|
|
140
149
|
|
|
141
150
|
mock_intersectObjects.mockReturnValueOnce([{
|
|
142
|
-
|
|
143
151
|
object: {
|
|
144
152
|
isSelectable: true,
|
|
145
153
|
onSelect: mock_onSelect,
|
|
154
|
+
visible: true,
|
|
146
155
|
parent: {
|
|
147
156
|
name: 'this is the test scene root!!!',
|
|
148
157
|
parent: null,
|
|
@@ -152,6 +161,7 @@ describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
|
152
161
|
}]);
|
|
153
162
|
const selectTool = new DIVESelectTool(mockScene, mockController);
|
|
154
163
|
selectTool['_gizmo'].object = {
|
|
164
|
+
visible: true,
|
|
155
165
|
isSelectable: true,
|
|
156
166
|
uuid: 'test0',
|
|
157
167
|
} as unknown as Object3D & DIVESelectable;
|
|
@@ -162,10 +172,10 @@ describe('dive/toolbox/select/DIVESelectTool', () => {
|
|
|
162
172
|
const mock_onSelect = jest.fn();
|
|
163
173
|
|
|
164
174
|
mock_intersectObjects.mockReturnValueOnce([{
|
|
165
|
-
|
|
166
175
|
object: {
|
|
167
176
|
isSelectable: true,
|
|
168
177
|
onSelect: mock_onSelect,
|
|
178
|
+
visible: true,
|
|
169
179
|
parent: {
|
|
170
180
|
name: 'this is the test scene root!!!',
|
|
171
181
|
parent: null,
|
|
@@ -50,6 +50,15 @@ export default class DIVETransformTool extends DIVEBaseTool {
|
|
|
50
50
|
this._gizmo.mode = mode;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
public SetGizmoVisibility(active: boolean): void {
|
|
54
|
+
const contains = this._scene.children.includes(this._gizmo);
|
|
55
|
+
if (active && !contains) {
|
|
56
|
+
this._scene.add(this._gizmo);
|
|
57
|
+
} else if (!active && contains) {
|
|
58
|
+
this._scene.remove(this._gizmo);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
53
62
|
// public onPointerDown(e: PointerEvent): void {
|
|
54
63
|
// super.onPointerDown(e);
|
|
55
64
|
|
|
@@ -41,9 +41,11 @@ jest.mock('../../../controls/OrbitControls', () => {
|
|
|
41
41
|
jest.mock('../../../scene/Scene', () => {
|
|
42
42
|
return jest.fn(function () {
|
|
43
43
|
this.add = jest.fn();
|
|
44
|
+
this.remove = jest.fn();
|
|
44
45
|
this.Root = {
|
|
45
46
|
children: [],
|
|
46
47
|
}
|
|
48
|
+
this.children = [];
|
|
47
49
|
return this;
|
|
48
50
|
});
|
|
49
51
|
});
|
|
@@ -129,4 +131,14 @@ describe('dive/toolbox/select/DIVETransformTool', () => {
|
|
|
129
131
|
const transformTool = new DIVETransformTool(mockScene, mockController);
|
|
130
132
|
expect(() => transformTool.SetGizmoMode('translate')).not.toThrow();
|
|
131
133
|
});
|
|
134
|
+
|
|
135
|
+
it('should set gizmo active', () => {
|
|
136
|
+
const transformTool = new DIVETransformTool(mockScene, mockController);
|
|
137
|
+
expect(() => transformTool.SetGizmoVisibility(true)).not.toThrow();
|
|
138
|
+
|
|
139
|
+
expect(mockScene.add).toBeCalled();
|
|
140
|
+
|
|
141
|
+
mockScene.children.includes = jest.fn().mockReturnValue(true);
|
|
142
|
+
expect(() => transformTool.SetGizmoVisibility(false)).not.toThrow();
|
|
143
|
+
});
|
|
132
144
|
});
|