@shopware-ag/dive 1.4.2 → 1.6.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 +38 -24
- package/build/dive.cjs +734 -492
- package/build/dive.cjs.map +1 -1
- package/build/dive.d.cts +182 -113
- package/build/dive.d.ts +182 -113
- package/build/dive.js +733 -478
- package/build/dive.js.map +1 -1
- package/package.json +1 -1
- package/src/__test__/DIVE.test.ts +66 -22
- package/src/animation/AnimationSystem.ts +16 -0
- package/src/animation/__test__/AnimationSystem.test.ts +23 -2
- package/src/axiscamera/AxisCamera.ts +40 -2
- package/src/axiscamera/__test__/AxisCamera.test.ts +178 -5
- package/src/com/Communication.ts +59 -16
- package/src/com/__test__/Communication.test.ts +83 -24
- package/src/com/actions/camera/computeencompassingview.ts +9 -0
- package/src/com/actions/index.ts +4 -0
- package/src/com/actions/scene/updatescene.ts +1 -0
- package/src/com/actions/toolbox/transform/setgizmovisible.ts +4 -0
- package/src/controls/OrbitControls.ts +14 -2
- package/src/controls/__test__/OrbitControls.test.ts +31 -4
- package/src/dive.ts +93 -33
- package/src/grid/Grid.ts +4 -0
- package/src/grid/__test__/Grid.test.ts +7 -0
- package/src/interface/Selectable.ts +17 -0
- package/src/interface/__test__/Interfaces.test.ts +18 -0
- package/src/mediacreator/MediaCreator.ts +2 -2
- package/src/mediacreator/__test__/MediaCreator.test.ts +12 -10
- package/src/model/Model.ts +6 -0
- package/src/model/__test__/Model.test.ts +9 -0
- package/src/renderer/Renderer.ts +7 -1
- package/src/renderer/__test__/Renderer.test.ts +14 -5
- package/src/scene/Scene.ts +8 -2
- package/src/scene/__test__/Scene.test.ts +6 -0
- package/src/scene/root/Root.ts +11 -1
- package/src/scene/root/__test__/Root.test.ts +68 -2
- 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 +3 -3
- package/src/toolbox/Toolbox.ts +57 -37
- package/src/toolbox/__test__/BaseTool.test.ts +49 -7
- package/src/toolbox/__test__/Toolbox.test.ts +43 -40
- package/src/toolbox/select/SelectTool.ts +18 -28
- package/src/toolbox/select/__test__/SelectTool.test.ts +27 -8
- package/src/toolbox/transform/TransformTool.ts +16 -1
- package/src/toolbox/transform/__test__/TransformTool.test.ts +34 -5
package/package.json
CHANGED
|
@@ -30,34 +30,58 @@ jest.mock('three', () => {
|
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
jest.mock('
|
|
33
|
+
jest.mock('three/src/math/MathUtils', () => {
|
|
34
|
+
return {
|
|
35
|
+
generateUUID: () => { return 'test_uuid'; },
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
jest.mock('../com/Communication.ts', () => {
|
|
34
40
|
return jest.fn(function () {
|
|
35
|
-
this.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
callback();
|
|
45
|
-
};
|
|
46
|
-
this.RemovePreRenderCallback = jest.fn();
|
|
47
|
-
this.AddPostRenderCallback = (callback: () => void) => {
|
|
48
|
-
callback();
|
|
49
|
-
};
|
|
50
|
-
this.getViewport = jest.fn();
|
|
51
|
-
this.setViewport = jest.fn();
|
|
52
|
-
this.autoClear = false;
|
|
53
|
-
this.render = jest.fn();
|
|
54
|
-
this.StartRenderer = jest.fn();
|
|
55
|
-
this.OnResize = jest.fn();
|
|
41
|
+
this.PerformAction = jest.fn().mockReturnValue({
|
|
42
|
+
position: { x: 0, y: 0, z: 0 },
|
|
43
|
+
target: { x: 0, y: 0, z: 0 },
|
|
44
|
+
});
|
|
45
|
+
this.Subscribe = jest.fn((action: string, callback: (data: { id: string }) => void) => {
|
|
46
|
+
callback({ id: 'incorrect id' });
|
|
47
|
+
callback({ id: 'test_uuid' });
|
|
48
|
+
});
|
|
49
|
+
this.DestroyInstance = jest.fn();
|
|
56
50
|
|
|
57
51
|
return this;
|
|
58
52
|
});
|
|
59
53
|
});
|
|
60
54
|
|
|
55
|
+
jest.mock('../renderer/Renderer.ts', () => {
|
|
56
|
+
return {
|
|
57
|
+
DIVERenderer: jest.fn(function () {
|
|
58
|
+
this.domElement = {
|
|
59
|
+
clientWidth: 800,
|
|
60
|
+
clientHeight: 600,
|
|
61
|
+
style: {
|
|
62
|
+
position: 'absolute',
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
this.domElement.parentElement = this.domElement;
|
|
66
|
+
this.AddPreRenderCallback = (callback: () => void) => {
|
|
67
|
+
callback();
|
|
68
|
+
};
|
|
69
|
+
this.RemovePreRenderCallback = jest.fn();
|
|
70
|
+
this.AddPostRenderCallback = (callback: () => void) => {
|
|
71
|
+
callback();
|
|
72
|
+
};
|
|
73
|
+
this.getViewport = jest.fn();
|
|
74
|
+
this.setViewport = jest.fn();
|
|
75
|
+
this.autoClear = false;
|
|
76
|
+
this.render = jest.fn();
|
|
77
|
+
this.StartRenderer = jest.fn();
|
|
78
|
+
this.OnResize = jest.fn();
|
|
79
|
+
this.Dispose = jest.fn();
|
|
80
|
+
return this;
|
|
81
|
+
}),
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
61
85
|
jest.mock('../scene/Scene.ts', () => {
|
|
62
86
|
return jest.fn(function () {
|
|
63
87
|
this.add = jest.fn();
|
|
@@ -131,6 +155,7 @@ jest.mock('../toolbox/Toolbox.ts', () => {
|
|
|
131
155
|
this.userData = {
|
|
132
156
|
id: undefined,
|
|
133
157
|
}
|
|
158
|
+
this.Dispose = jest.fn();
|
|
134
159
|
this.removeFromParent = jest.fn();
|
|
135
160
|
return this;
|
|
136
161
|
});
|
|
@@ -152,11 +177,17 @@ jest.mock('../axiscamera/AxisCamera.ts', () => {
|
|
|
152
177
|
}
|
|
153
178
|
this.removeFromParent = jest.fn();
|
|
154
179
|
this.SetFromCameraMatrix = jest.fn();
|
|
180
|
+
this.Dispose = jest.fn();
|
|
155
181
|
return this;
|
|
156
182
|
});
|
|
157
183
|
});
|
|
158
184
|
|
|
159
185
|
describe('dive/DIVE', () => {
|
|
186
|
+
it('should QuickView', () => {
|
|
187
|
+
const dive = DIVE.QuickView('test_uri');
|
|
188
|
+
expect(dive).toBeDefined();
|
|
189
|
+
});
|
|
190
|
+
|
|
160
191
|
it('should instantiate', () => {
|
|
161
192
|
const dive = new DIVE();
|
|
162
193
|
expect(dive).toBeDefined();
|
|
@@ -165,9 +196,21 @@ describe('dive/DIVE', () => {
|
|
|
165
196
|
expect(() => (window as any).DIVE.PrintScene()).not.toThrow();
|
|
166
197
|
});
|
|
167
198
|
|
|
199
|
+
it('should dispose', () => {
|
|
200
|
+
let dive = new DIVE();
|
|
201
|
+
expect(() => dive.Dispose()).not.toThrow();
|
|
202
|
+
|
|
203
|
+
const settings = {
|
|
204
|
+
displayAxes: true,
|
|
205
|
+
}
|
|
206
|
+
dive = new DIVE(settings);
|
|
207
|
+
expect(() => dive.Dispose()).not.toThrow();
|
|
208
|
+
});
|
|
209
|
+
|
|
168
210
|
it('should instantiate with settings', () => {
|
|
169
211
|
const settings = {
|
|
170
212
|
autoResize: false,
|
|
213
|
+
displayAxes: true,
|
|
171
214
|
renderer: {
|
|
172
215
|
antialias: false,
|
|
173
216
|
alpha: false,
|
|
@@ -209,6 +252,7 @@ describe('dive/DIVE', () => {
|
|
|
209
252
|
const dive = new DIVE();
|
|
210
253
|
dive.Settings = {
|
|
211
254
|
autoResize: false,
|
|
255
|
+
displayAxes: true,
|
|
212
256
|
renderer: {
|
|
213
257
|
antialias: false,
|
|
214
258
|
alpha: false,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { update as updateTween } from "@tweenjs/tween.js";
|
|
2
|
+
import { DIVERenderer } from "../renderer/Renderer";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Updates all animations.
|
|
@@ -8,6 +9,21 @@ import { update as updateTween } from "@tweenjs/tween.js";
|
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
export default class DIVEAnimationSystem {
|
|
12
|
+
private _renderer: DIVERenderer;
|
|
13
|
+
private _rendererCallbackId: string;
|
|
14
|
+
|
|
15
|
+
constructor(renderer: DIVERenderer) {
|
|
16
|
+
this._renderer = renderer;
|
|
17
|
+
|
|
18
|
+
this._rendererCallbackId = this._renderer.AddPreRenderCallback(() => {
|
|
19
|
+
this.update();
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public Dispose(): void {
|
|
24
|
+
this._renderer.RemovePreRenderCallback(this._rendererCallbackId);
|
|
25
|
+
}
|
|
26
|
+
|
|
11
27
|
public update(): void {
|
|
12
28
|
updateTween();
|
|
13
29
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DIVERenderer } from '../../renderer/Renderer';
|
|
1
2
|
import DIVEAnimationSystem from '../AnimationSystem';
|
|
2
3
|
|
|
3
4
|
jest.mock('@tweenjs/tween.js', () => {
|
|
@@ -6,14 +7,34 @@ jest.mock('@tweenjs/tween.js', () => {
|
|
|
6
7
|
}
|
|
7
8
|
});
|
|
8
9
|
|
|
10
|
+
const mockRenderer = {
|
|
11
|
+
render: jest.fn(),
|
|
12
|
+
OnResize: jest.fn(),
|
|
13
|
+
getViewport: jest.fn(),
|
|
14
|
+
setViewport: jest.fn(),
|
|
15
|
+
AddPreRenderCallback: jest.fn((callback) => {
|
|
16
|
+
callback();
|
|
17
|
+
}),
|
|
18
|
+
AddPostRenderCallback: jest.fn((callback) => {
|
|
19
|
+
callback();
|
|
20
|
+
}),
|
|
21
|
+
RemovePreRenderCallback: jest.fn(),
|
|
22
|
+
RemovePostRenderCallback: jest.fn(),
|
|
23
|
+
} as unknown as DIVERenderer;
|
|
24
|
+
|
|
9
25
|
describe('dive/animation/DIVEAnimationSystem', () => {
|
|
10
26
|
it('should instantiate', () => {
|
|
11
|
-
const anim = new DIVEAnimationSystem();
|
|
27
|
+
const anim = new DIVEAnimationSystem(mockRenderer);
|
|
12
28
|
expect(anim).toBeDefined();
|
|
13
29
|
});
|
|
14
30
|
|
|
15
31
|
it('should update', () => {
|
|
16
|
-
const anim = new DIVEAnimationSystem();
|
|
32
|
+
const anim = new DIVEAnimationSystem(mockRenderer);
|
|
17
33
|
expect(() => anim.update()).not.toThrow();
|
|
18
34
|
});
|
|
35
|
+
|
|
36
|
+
it('should dispose', () => {
|
|
37
|
+
const anim = new DIVEAnimationSystem(mockRenderer);
|
|
38
|
+
expect(() => anim.Dispose()).not.toThrow();
|
|
39
|
+
});
|
|
19
40
|
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { AxesHelper, Color, Material, Matrix4, OrthographicCamera } from "three";
|
|
1
|
+
import { AxesHelper, Color, Material, Matrix4, OrthographicCamera, Vector4 } from "three";
|
|
2
2
|
import SpriteText from "three-spritetext";
|
|
3
3
|
import { COORDINATE_LAYER_MASK } from "../constant/VisibilityLayerMask.ts";
|
|
4
4
|
import { AxesColorRed, AxesColorGreen, AxesColorBlue, AxesColorRedLetter, AxesColorGreenLetter, AxesColorBlueLetter } from "../constant/AxisHelperColors.ts";
|
|
5
|
+
import { DIVERenderer } from "../renderer/Renderer.ts";
|
|
6
|
+
import DIVEScene from "../scene/Scene.ts";
|
|
7
|
+
import DIVEOrbitControls from "../controls/OrbitControls.ts";
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* Shows the scene axes in the bottom left corner of the screen.
|
|
@@ -12,7 +15,12 @@ import { AxesColorRed, AxesColorGreen, AxesColorBlue, AxesColorRedLetter, AxesCo
|
|
|
12
15
|
export default class DIVEAxisCamera extends OrthographicCamera {
|
|
13
16
|
private axesHelper: AxesHelper;
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
private _renderer: DIVERenderer;
|
|
19
|
+
private _scene: DIVEScene;
|
|
20
|
+
|
|
21
|
+
private _renderCallbackId: string;
|
|
22
|
+
|
|
23
|
+
constructor(renderer: DIVERenderer, scene: DIVEScene, controls: DIVEOrbitControls) {
|
|
16
24
|
super(-1, 1, 1, -1, 0.1, 100);
|
|
17
25
|
|
|
18
26
|
this.layers.mask = COORDINATE_LAYER_MASK;
|
|
@@ -42,6 +50,36 @@ export default class DIVEAxisCamera extends OrthographicCamera {
|
|
|
42
50
|
this.axesHelper.add(z);
|
|
43
51
|
|
|
44
52
|
this.add(this.axesHelper);
|
|
53
|
+
|
|
54
|
+
// attach everything to current scene and render cycle
|
|
55
|
+
this._renderer = renderer;
|
|
56
|
+
this._scene = scene;
|
|
57
|
+
this._scene.add(this);
|
|
58
|
+
|
|
59
|
+
const restoreViewport = new Vector4();
|
|
60
|
+
|
|
61
|
+
this._renderCallbackId = renderer.AddPostRenderCallback(() => {
|
|
62
|
+
const restoreBackground = scene.background;
|
|
63
|
+
scene.background = null;
|
|
64
|
+
|
|
65
|
+
renderer.getViewport(restoreViewport);
|
|
66
|
+
renderer.setViewport(0, 0, 150, 150);
|
|
67
|
+
renderer.autoClear = false;
|
|
68
|
+
|
|
69
|
+
this.SetFromCameraMatrix(controls.object.matrix);
|
|
70
|
+
|
|
71
|
+
renderer.render(scene, this);
|
|
72
|
+
|
|
73
|
+
renderer.setViewport(restoreViewport);
|
|
74
|
+
renderer.autoClear = true;
|
|
75
|
+
|
|
76
|
+
scene.background = restoreBackground;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public Dispose(): void {
|
|
81
|
+
this._renderer.RemovePostRenderCallback(this._renderCallbackId);
|
|
82
|
+
this._scene.remove(this);
|
|
45
83
|
}
|
|
46
84
|
|
|
47
85
|
public SetFromCameraMatrix(matrix: Matrix4): void {
|
|
@@ -1,5 +1,63 @@
|
|
|
1
|
-
import { Matrix4 } from 'three';
|
|
1
|
+
import { AxesHelper, Matrix4, OrthographicCamera, Vector4 } from 'three';
|
|
2
2
|
import DIVEAxisCamera from '../AxisCamera';
|
|
3
|
+
import { DIVERenderer } from '../../renderer/Renderer';
|
|
4
|
+
import DIVEScene from '../../scene/Scene';
|
|
5
|
+
import DIVEOrbitControls from '../../controls/OrbitControls';
|
|
6
|
+
|
|
7
|
+
jest.mock('three', () => {
|
|
8
|
+
return {
|
|
9
|
+
Vector4: jest.fn(),
|
|
10
|
+
Color: jest.fn(function () {
|
|
11
|
+
this.getHexString = jest.fn().mockReturnValue('ffffff');
|
|
12
|
+
return this;
|
|
13
|
+
}),
|
|
14
|
+
Matrix4: jest.fn(function () {
|
|
15
|
+
this.extractRotation = jest.fn(() => { return this; });
|
|
16
|
+
this.invert = jest.fn(() => { return this; });
|
|
17
|
+
this.elements = [
|
|
18
|
+
1, 0, 0, 0,
|
|
19
|
+
0, 1, 0, 0,
|
|
20
|
+
0, 0, 1, 0,
|
|
21
|
+
0, 0, 0, 1,
|
|
22
|
+
];
|
|
23
|
+
return this;
|
|
24
|
+
}),
|
|
25
|
+
OrthographicCamera: jest.fn(function () {
|
|
26
|
+
|
|
27
|
+
this.isObject3D = true;
|
|
28
|
+
this.parent = null;
|
|
29
|
+
this.dispatchEvent = jest.fn();
|
|
30
|
+
this.layers = {
|
|
31
|
+
mask: 0,
|
|
32
|
+
};
|
|
33
|
+
this.position = {
|
|
34
|
+
set: jest.fn(),
|
|
35
|
+
};
|
|
36
|
+
this.add = jest.fn();
|
|
37
|
+
return this;
|
|
38
|
+
}),
|
|
39
|
+
AxesHelper: jest.fn(function () {
|
|
40
|
+
this.isObject3D = true;
|
|
41
|
+
this.parent = null;
|
|
42
|
+
this.dispatchEvent = jest.fn();
|
|
43
|
+
this.layers = {
|
|
44
|
+
mask: 0,
|
|
45
|
+
};
|
|
46
|
+
this.position = {
|
|
47
|
+
set: jest.fn(),
|
|
48
|
+
};
|
|
49
|
+
this.add = jest.fn();
|
|
50
|
+
this.material = {
|
|
51
|
+
depthTest: false,
|
|
52
|
+
};
|
|
53
|
+
this.setColors = jest.fn();
|
|
54
|
+
this.rotation = {
|
|
55
|
+
setFromRotationMatrix: jest.fn(),
|
|
56
|
+
}
|
|
57
|
+
return this;
|
|
58
|
+
}),
|
|
59
|
+
}
|
|
60
|
+
});
|
|
3
61
|
|
|
4
62
|
jest.mock('three-spritetext', () => {
|
|
5
63
|
return jest.fn(() => {
|
|
@@ -19,10 +77,122 @@ jest.mock('three-spritetext', () => {
|
|
|
19
77
|
)
|
|
20
78
|
});
|
|
21
79
|
|
|
80
|
+
const mockRenderer = {
|
|
81
|
+
render: jest.fn(),
|
|
82
|
+
OnResize: jest.fn(),
|
|
83
|
+
getViewport: jest.fn(),
|
|
84
|
+
setViewport: jest.fn(),
|
|
85
|
+
AddPostRenderCallback: jest.fn((callback) => {
|
|
86
|
+
callback();
|
|
87
|
+
}),
|
|
88
|
+
RemovePostRenderCallback: jest.fn(),
|
|
89
|
+
} as unknown as DIVERenderer;
|
|
90
|
+
|
|
91
|
+
const mockScene = {
|
|
92
|
+
add: jest.fn(),
|
|
93
|
+
remove: jest.fn(),
|
|
94
|
+
SetBackground: jest.fn(),
|
|
95
|
+
AddSceneObject: jest.fn(),
|
|
96
|
+
UpdateSceneObject: jest.fn(),
|
|
97
|
+
DeleteSceneObject: jest.fn(),
|
|
98
|
+
PlaceOnFloor: jest.fn(),
|
|
99
|
+
GetSceneObject: jest.fn(),
|
|
100
|
+
background: {
|
|
101
|
+
getHexString: jest.fn().mockReturnValue('ffffff'),
|
|
102
|
+
},
|
|
103
|
+
Root: {
|
|
104
|
+
Floor: {
|
|
105
|
+
isFloor: true,
|
|
106
|
+
visible: true,
|
|
107
|
+
material: {
|
|
108
|
+
color: {
|
|
109
|
+
getHexString: jest.fn().mockReturnValue('ffffff'),
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
SetVisibility: jest.fn(),
|
|
113
|
+
SetColor: jest.fn(),
|
|
114
|
+
},
|
|
115
|
+
Grid: {
|
|
116
|
+
SetVisibility: jest.fn(),
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
} as unknown as DIVEScene;
|
|
120
|
+
|
|
121
|
+
const mockController = {
|
|
122
|
+
enableDamping: true,
|
|
123
|
+
dampingFactor: 0.25,
|
|
124
|
+
enableZoom: true,
|
|
125
|
+
enablePan: true,
|
|
126
|
+
minPolarAngle: 0,
|
|
127
|
+
maxPolarAngle: Math.PI,
|
|
128
|
+
minDistance: 0,
|
|
129
|
+
maxDistance: Infinity,
|
|
130
|
+
rotateSpeed: 0.5,
|
|
131
|
+
panSpeed: 0.5,
|
|
132
|
+
zoomSpeed: 0.5,
|
|
133
|
+
keyPanSpeed: 0.5,
|
|
134
|
+
screenSpacePanning: true,
|
|
135
|
+
autoRotate: false,
|
|
136
|
+
autoRotateSpeed: 2.0,
|
|
137
|
+
enableKeys: true,
|
|
138
|
+
keys: {
|
|
139
|
+
LEFT: 37,
|
|
140
|
+
UP: 38,
|
|
141
|
+
RIGHT: 39,
|
|
142
|
+
BOTTOM: 40,
|
|
143
|
+
},
|
|
144
|
+
mouseButtons: {
|
|
145
|
+
LEFT: 0,
|
|
146
|
+
MIDDLE: 1,
|
|
147
|
+
RIGHT: 2,
|
|
148
|
+
},
|
|
149
|
+
target: {
|
|
150
|
+
x: 4,
|
|
151
|
+
y: 5,
|
|
152
|
+
z: 6,
|
|
153
|
+
set: jest.fn(),
|
|
154
|
+
clone: jest.fn().mockReturnValue({ x: 4, y: 5, z: 6 }),
|
|
155
|
+
copy: jest.fn(),
|
|
156
|
+
},
|
|
157
|
+
update: jest.fn(),
|
|
158
|
+
dispose: jest.fn(),
|
|
159
|
+
ZoomIn: jest.fn(),
|
|
160
|
+
ZoomOut: jest.fn(),
|
|
161
|
+
object: {
|
|
162
|
+
position: {
|
|
163
|
+
x: 1,
|
|
164
|
+
y: 2,
|
|
165
|
+
z: 3,
|
|
166
|
+
clone: jest.fn().mockReturnValue({ x: 1, y: 2, z: 3 }),
|
|
167
|
+
copy: jest.fn(),
|
|
168
|
+
},
|
|
169
|
+
quaternion: {
|
|
170
|
+
x: 1,
|
|
171
|
+
y: 2,
|
|
172
|
+
z: 3,
|
|
173
|
+
w: 4,
|
|
174
|
+
clone: jest.fn().mockReturnValue({ x: 1, y: 2, z: 3, w: 4 }),
|
|
175
|
+
copy: jest.fn(),
|
|
176
|
+
},
|
|
177
|
+
SetCameraLayer: jest.fn(),
|
|
178
|
+
OnResize: jest.fn(),
|
|
179
|
+
layers: {
|
|
180
|
+
mask: 1,
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
MoveTo: jest.fn(),
|
|
184
|
+
RevertLast: jest.fn(),
|
|
185
|
+
} as unknown as DIVEOrbitControls;
|
|
186
|
+
|
|
187
|
+
let textAxisCamera: DIVEAxisCamera;
|
|
188
|
+
|
|
22
189
|
describe('dive/axiscamera/DIVEAxisCamera', () => {
|
|
190
|
+
beforeEach(() => {
|
|
191
|
+
textAxisCamera = new DIVEAxisCamera(mockRenderer, mockScene, mockController);
|
|
192
|
+
});
|
|
193
|
+
|
|
23
194
|
it('should instantiate', () => {
|
|
24
|
-
|
|
25
|
-
expect(cam).toBeDefined();
|
|
195
|
+
expect(textAxisCamera).toBeDefined();
|
|
26
196
|
});
|
|
27
197
|
|
|
28
198
|
it('should set rotation from Matrix4', () => {
|
|
@@ -35,7 +205,10 @@ describe('dive/axiscamera/DIVEAxisCamera', () => {
|
|
|
35
205
|
0, 0, 0, 1,
|
|
36
206
|
],
|
|
37
207
|
} as Matrix4;
|
|
38
|
-
|
|
39
|
-
|
|
208
|
+
textAxisCamera.SetFromCameraMatrix(matrix);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should dispose', () => {
|
|
212
|
+
textAxisCamera.Dispose();
|
|
40
213
|
});
|
|
41
214
|
});
|
package/src/com/Communication.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { Color, MeshStandardMaterial, MathUtils } from "three";
|
|
2
|
-
import DIVEScene from "../scene/Scene.ts";
|
|
3
1
|
import { Actions } from "./actions/index.ts";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
2
|
+
import { generateUUID } from 'three/src/math/MathUtils';
|
|
3
|
+
|
|
4
|
+
// type imports
|
|
5
|
+
import { type Color, type MeshStandardMaterial } from "three";
|
|
6
|
+
import { type COMLight, type COMModel, type COMEntity, type COMPov } from "./types.ts";
|
|
7
|
+
import type DIVEScene from "../scene/Scene.ts";
|
|
8
|
+
import type DIVEToolbox from "../toolbox/Toolbox.ts";
|
|
9
|
+
import type DIVEOrbitControls from "../controls/OrbitControls.ts";
|
|
10
10
|
import type DIVEModel from "../model/Model.ts";
|
|
11
|
+
import { type DIVEMediaCreator } from "../mediacreator/MediaCreator.ts";
|
|
12
|
+
import { type DIVERenderer } from "../renderer/Renderer.ts";
|
|
13
|
+
import { type DIVESelectable } from "../interface/Selectable.ts";
|
|
14
|
+
import { isSelectTool } from "../toolbox/select/SelectTool.ts";
|
|
11
15
|
|
|
12
16
|
type EventListener<Action extends keyof Actions> = (payload: Actions[Action]['PAYLOAD']) => void;
|
|
13
17
|
|
|
@@ -41,22 +45,32 @@ export default class DIVECommunication {
|
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
private id: string;
|
|
48
|
+
private renderer: DIVERenderer;
|
|
44
49
|
private scene: DIVEScene;
|
|
45
50
|
private controller: DIVEOrbitControls;
|
|
46
51
|
private toolbox: DIVEToolbox;
|
|
47
|
-
|
|
52
|
+
|
|
53
|
+
private _mediaGenerator: DIVEMediaCreator | null;
|
|
54
|
+
private get mediaGenerator(): DIVEMediaCreator {
|
|
55
|
+
if (!this._mediaGenerator) {
|
|
56
|
+
const DIVEMediaCreator = require('../mediacreator/MediaCreator.ts').default as typeof import('../mediacreator/MediaCreator.ts').DIVEMediaCreator;
|
|
57
|
+
this._mediaGenerator = new DIVEMediaCreator(this.renderer, this.scene, this.controller);
|
|
58
|
+
}
|
|
59
|
+
return this._mediaGenerator;
|
|
60
|
+
}
|
|
48
61
|
|
|
49
62
|
private registered: Map<string, COMEntity> = new Map();
|
|
50
63
|
|
|
51
64
|
// private listeners: { [key: string]: EventListener[] } = {};
|
|
52
65
|
private listeners: Map<keyof Actions, EventListener<keyof Actions>[]> = new Map();
|
|
53
66
|
|
|
54
|
-
constructor(scene: DIVEScene, controls: DIVEOrbitControls, toolbox: DIVEToolbox
|
|
55
|
-
this.id =
|
|
67
|
+
constructor(renderer: DIVERenderer, scene: DIVEScene, controls: DIVEOrbitControls, toolbox: DIVEToolbox) {
|
|
68
|
+
this.id = generateUUID();
|
|
69
|
+
this.renderer = renderer;
|
|
56
70
|
this.scene = scene;
|
|
57
71
|
this.controller = controls;
|
|
58
72
|
this.toolbox = toolbox;
|
|
59
|
-
this.
|
|
73
|
+
this._mediaGenerator = null;
|
|
60
74
|
|
|
61
75
|
DIVECommunication.__instances.push(this);
|
|
62
76
|
}
|
|
@@ -132,6 +146,10 @@ export default class DIVECommunication {
|
|
|
132
146
|
returnValue = this.resetCamera(payload as Actions['RESET_CAMERA']['PAYLOAD']);
|
|
133
147
|
break;
|
|
134
148
|
}
|
|
149
|
+
case 'COMPUTE_ENCOMPASSING_VIEW': {
|
|
150
|
+
returnValue = this.computeEncompassingView(payload as Actions['COMPUTE_ENCOMPASSING_VIEW']['PAYLOAD']);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
135
153
|
case 'SET_CAMERA_LAYER': {
|
|
136
154
|
returnValue = this.setCameraLayer(payload as Actions['SET_CAMERA_LAYER']['PAYLOAD']);
|
|
137
155
|
break;
|
|
@@ -144,6 +162,10 @@ export default class DIVECommunication {
|
|
|
144
162
|
returnValue = this.setGizmoMode(payload as Actions['SET_GIZMO_MODE']['PAYLOAD']);
|
|
145
163
|
break;
|
|
146
164
|
}
|
|
165
|
+
case 'SET_GIZMO_VISIBILITY': {
|
|
166
|
+
returnValue = this.setGizmoVisibility(payload as Actions['SET_GIZMO_VISIBILITY']['PAYLOAD']);
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
147
169
|
case 'MODEL_LOADED': {
|
|
148
170
|
returnValue = this.modelLoaded(payload as Actions['MODEL_LOADED']['PAYLOAD']);
|
|
149
171
|
break;
|
|
@@ -272,8 +294,10 @@ export default class DIVECommunication {
|
|
|
272
294
|
|
|
273
295
|
if (!('isSelectable' in sceneObject)) return false;
|
|
274
296
|
|
|
275
|
-
this.toolbox.
|
|
276
|
-
(
|
|
297
|
+
const activeTool = this.toolbox.GetActiveTool();
|
|
298
|
+
if (activeTool && isSelectTool(activeTool)) {
|
|
299
|
+
activeTool.AttachGizmo(sceneObject as DIVESelectable);
|
|
300
|
+
}
|
|
277
301
|
|
|
278
302
|
// copy object to payload to use later
|
|
279
303
|
Object.assign(payload, object);
|
|
@@ -290,8 +314,10 @@ export default class DIVECommunication {
|
|
|
290
314
|
|
|
291
315
|
if (!('isSelectable' in sceneObject)) return false;
|
|
292
316
|
|
|
293
|
-
this.toolbox.
|
|
294
|
-
(
|
|
317
|
+
const activeTool = this.toolbox.GetActiveTool();
|
|
318
|
+
if (activeTool && isSelectTool(activeTool)) {
|
|
319
|
+
activeTool.DetachGizmo();
|
|
320
|
+
}
|
|
295
321
|
|
|
296
322
|
// copy object to payload to use later
|
|
297
323
|
Object.assign(payload, object);
|
|
@@ -368,6 +394,15 @@ export default class DIVECommunication {
|
|
|
368
394
|
return true;
|
|
369
395
|
}
|
|
370
396
|
|
|
397
|
+
private computeEncompassingView(payload: Actions['COMPUTE_ENCOMPASSING_VIEW']['PAYLOAD']): Actions['COMPUTE_ENCOMPASSING_VIEW']['RETURN'] {
|
|
398
|
+
const sceneBB = this.scene.ComputeSceneBB();
|
|
399
|
+
|
|
400
|
+
const transform = this.controller.ComputeEncompassingView(sceneBB);
|
|
401
|
+
Object.assign(payload, transform);
|
|
402
|
+
|
|
403
|
+
return transform;
|
|
404
|
+
}
|
|
405
|
+
|
|
371
406
|
private zoomCamera(payload: Actions['ZOOM_CAMERA']['PAYLOAD']): Actions['ZOOM_CAMERA']['RETURN'] {
|
|
372
407
|
if (payload.direction === 'IN') this.controller.ZoomIn(payload.by);
|
|
373
408
|
if (payload.direction === 'OUT') this.controller.ZoomOut(payload.by);
|
|
@@ -380,6 +415,11 @@ export default class DIVECommunication {
|
|
|
380
415
|
return true;
|
|
381
416
|
}
|
|
382
417
|
|
|
418
|
+
private setGizmoVisibility(payload: Actions['SET_GIZMO_VISIBILITY']['PAYLOAD']): Actions['SET_GIZMO_VISIBILITY']['RETURN'] {
|
|
419
|
+
this.toolbox.SetGizmoVisibility(payload);
|
|
420
|
+
return payload;
|
|
421
|
+
}
|
|
422
|
+
|
|
383
423
|
private modelLoaded(payload: Actions['MODEL_LOADED']['PAYLOAD']): Actions['MODEL_LOADED']['RETURN'] {
|
|
384
424
|
(this.registered.get(payload.id) as COMModel).loaded = true;
|
|
385
425
|
return true;
|
|
@@ -389,6 +429,8 @@ export default class DIVECommunication {
|
|
|
389
429
|
if (payload.name !== undefined) this.scene.name = payload.name;
|
|
390
430
|
if (payload.backgroundColor !== undefined) this.scene.SetBackground(payload.backgroundColor);
|
|
391
431
|
|
|
432
|
+
if (payload.gridEnabled !== undefined) this.scene.Root.Grid.SetVisibility(payload.gridEnabled);
|
|
433
|
+
|
|
392
434
|
if (payload.floorEnabled !== undefined) this.scene.Root.Floor.SetVisibility(payload.floorEnabled);
|
|
393
435
|
if (payload.floorColor !== undefined) this.scene.Root.Floor.SetColor(payload.floorColor);
|
|
394
436
|
|
|
@@ -397,6 +439,7 @@ export default class DIVECommunication {
|
|
|
397
439
|
// TODO optmize this
|
|
398
440
|
payload.name = this.scene.name;
|
|
399
441
|
payload.backgroundColor = '#' + (this.scene.background as Color).getHexString();
|
|
442
|
+
payload.gridEnabled = this.scene.Root.Grid.visible;
|
|
400
443
|
payload.floorEnabled = this.scene.Root.Floor.visible;
|
|
401
444
|
payload.floorColor = '#' + (this.scene.Root.Floor.material as MeshStandardMaterial).color.getHexString();
|
|
402
445
|
|