@shopware-ag/dive 1.5.0 → 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 -25
- package/build/dive.cjs +717 -500
- package/build/dive.cjs.map +1 -1
- package/build/dive.d.cts +174 -113
- package/build/dive.d.ts +174 -113
- package/build/dive.js +716 -486
- 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 +50 -16
- package/src/com/__test__/Communication.test.ts +73 -24
- package/src/com/actions/camera/computeencompassingview.ts +9 -0
- package/src/com/actions/index.ts +2 -0
- package/src/com/actions/scene/updatescene.ts +1 -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/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/toolbox/BaseTool.ts +1 -1
- package/src/toolbox/Toolbox.ts +53 -37
- package/src/toolbox/__test__/BaseTool.test.ts +43 -7
- package/src/toolbox/__test__/Toolbox.test.ts +39 -44
- package/src/toolbox/select/SelectTool.ts +17 -28
- package/src/toolbox/select/__test__/SelectTool.test.ts +21 -12
- package/src/toolbox/transform/TransformTool.ts +7 -1
- package/src/toolbox/transform/__test__/TransformTool.test.ts +22 -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;
|
|
@@ -276,8 +294,10 @@ export default class DIVECommunication {
|
|
|
276
294
|
|
|
277
295
|
if (!('isSelectable' in sceneObject)) return false;
|
|
278
296
|
|
|
279
|
-
this.toolbox.
|
|
280
|
-
(
|
|
297
|
+
const activeTool = this.toolbox.GetActiveTool();
|
|
298
|
+
if (activeTool && isSelectTool(activeTool)) {
|
|
299
|
+
activeTool.AttachGizmo(sceneObject as DIVESelectable);
|
|
300
|
+
}
|
|
281
301
|
|
|
282
302
|
// copy object to payload to use later
|
|
283
303
|
Object.assign(payload, object);
|
|
@@ -294,8 +314,10 @@ export default class DIVECommunication {
|
|
|
294
314
|
|
|
295
315
|
if (!('isSelectable' in sceneObject)) return false;
|
|
296
316
|
|
|
297
|
-
this.toolbox.
|
|
298
|
-
(
|
|
317
|
+
const activeTool = this.toolbox.GetActiveTool();
|
|
318
|
+
if (activeTool && isSelectTool(activeTool)) {
|
|
319
|
+
activeTool.DetachGizmo();
|
|
320
|
+
}
|
|
299
321
|
|
|
300
322
|
// copy object to payload to use later
|
|
301
323
|
Object.assign(payload, object);
|
|
@@ -372,6 +394,15 @@ export default class DIVECommunication {
|
|
|
372
394
|
return true;
|
|
373
395
|
}
|
|
374
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
|
+
|
|
375
406
|
private zoomCamera(payload: Actions['ZOOM_CAMERA']['PAYLOAD']): Actions['ZOOM_CAMERA']['RETURN'] {
|
|
376
407
|
if (payload.direction === 'IN') this.controller.ZoomIn(payload.by);
|
|
377
408
|
if (payload.direction === 'OUT') this.controller.ZoomOut(payload.by);
|
|
@@ -398,6 +429,8 @@ export default class DIVECommunication {
|
|
|
398
429
|
if (payload.name !== undefined) this.scene.name = payload.name;
|
|
399
430
|
if (payload.backgroundColor !== undefined) this.scene.SetBackground(payload.backgroundColor);
|
|
400
431
|
|
|
432
|
+
if (payload.gridEnabled !== undefined) this.scene.Root.Grid.SetVisibility(payload.gridEnabled);
|
|
433
|
+
|
|
401
434
|
if (payload.floorEnabled !== undefined) this.scene.Root.Floor.SetVisibility(payload.floorEnabled);
|
|
402
435
|
if (payload.floorColor !== undefined) this.scene.Root.Floor.SetColor(payload.floorColor);
|
|
403
436
|
|
|
@@ -406,6 +439,7 @@ export default class DIVECommunication {
|
|
|
406
439
|
// TODO optmize this
|
|
407
440
|
payload.name = this.scene.name;
|
|
408
441
|
payload.backgroundColor = '#' + (this.scene.background as Color).getHexString();
|
|
442
|
+
payload.gridEnabled = this.scene.Root.Grid.visible;
|
|
409
443
|
payload.floorEnabled = this.scene.Root.Floor.visible;
|
|
410
444
|
payload.floorColor = '#' + (this.scene.Root.Floor.material as MeshStandardMaterial).color.getHexString();
|
|
411
445
|
|