@shopware-ag/dive 1.7.0 → 1.9.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 +1 -1
- package/build/dive.cjs +344 -45
- package/build/dive.cjs.map +1 -1
- package/build/dive.d.cts +33 -11
- package/build/dive.d.ts +33 -11
- package/build/dive.js +335 -36
- package/build/dive.js.map +1 -1
- package/package.json +1 -1
- package/src/__test__/DIVE.test.ts +2 -1
- package/src/camera/PerspectiveCamera.ts +7 -2
- package/src/camera/__test__/PerspectiveCamera.test.ts +11 -2
- package/src/com/index.ts +0 -1
- package/src/com/types.ts +26 -3
- package/src/controls/OrbitControls.ts +9 -4
- package/src/controls/__test__/OrbitControls.test.ts +15 -5
- package/src/dive.ts +10 -8
- package/src/mediacreator/__test__/MediaCreator.test.ts +1 -1
- package/src/primitive/Primitive.ts +210 -0
- package/src/primitive/__test__/Primitive.test.ts +434 -0
- package/src/renderer/Renderer.ts +10 -7
- package/src/renderer/__test__/Renderer.test.ts +11 -0
- package/src/scene/__test__/Scene.test.ts +2 -2
- package/src/scene/root/Root.ts +44 -3
- package/src/scene/root/__test__/Root.test.ts +71 -27
- package/src/scene/root/lightroot/__test__/LightRoot.test.ts +2 -3
- package/src/scene/root/primitiveroot/PrimitiveRoot.ts +88 -0
- package/src/scene/root/primitiveroot/__test__/PrimitiveRoot.test.ts +181 -0
package/package.json
CHANGED
|
@@ -183,6 +183,8 @@ jest.mock('../axiscamera/AxisCamera.ts', () => {
|
|
|
183
183
|
});
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
+
console.log = jest.fn();
|
|
187
|
+
|
|
186
188
|
describe('dive/DIVE', () => {
|
|
187
189
|
it('should QuickView', () => {
|
|
188
190
|
const dive = DIVE.QuickView('test_uri');
|
|
@@ -193,7 +195,6 @@ describe('dive/DIVE', () => {
|
|
|
193
195
|
const dive = new DIVE();
|
|
194
196
|
expect(dive).toBeDefined();
|
|
195
197
|
expect((window as any).DIVE.PrintScene).toBeDefined();
|
|
196
|
-
console.log = jest.fn();
|
|
197
198
|
expect(() => (window as any).DIVE.PrintScene()).not.toThrow();
|
|
198
199
|
});
|
|
199
200
|
|
|
@@ -25,8 +25,13 @@ export default class DIVEPerspectiveCamera extends PerspectiveCamera {
|
|
|
25
25
|
|
|
26
26
|
public onSetCameraLayer: (mask: number) => void = () => { };
|
|
27
27
|
|
|
28
|
-
constructor(settings: DIVEPerspectiveCameraSettings = DIVEPerspectiveCameraDefaultSettings) {
|
|
29
|
-
super(
|
|
28
|
+
constructor(settings: Partial<DIVEPerspectiveCameraSettings> = DIVEPerspectiveCameraDefaultSettings) {
|
|
29
|
+
super(
|
|
30
|
+
settings.fov || DIVEPerspectiveCameraDefaultSettings.fov,
|
|
31
|
+
1,
|
|
32
|
+
settings.near || DIVEPerspectiveCameraDefaultSettings.near,
|
|
33
|
+
settings.far || DIVEPerspectiveCameraDefaultSettings.far
|
|
34
|
+
);
|
|
30
35
|
|
|
31
36
|
this.layers.mask = DIVEPerspectiveCamera.EDITOR_VIEW_LAYER_MASK;
|
|
32
37
|
}
|
|
@@ -5,11 +5,20 @@ let cam: DIVEPerspectiveCamera;
|
|
|
5
5
|
describe('dive/camera/DIVEPerspectiveCamera', () => {
|
|
6
6
|
beforeEach(() => {
|
|
7
7
|
jest.clearAllMocks();
|
|
8
|
-
cam = new DIVEPerspectiveCamera(
|
|
8
|
+
cam = new DIVEPerspectiveCamera();
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
it('should instantiate', () => {
|
|
12
|
-
cam = new DIVEPerspectiveCamera();
|
|
12
|
+
cam = new DIVEPerspectiveCamera({});
|
|
13
|
+
expect(cam).toBeDefined();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('should instantiate with settings', () => {
|
|
17
|
+
cam = new DIVEPerspectiveCamera({
|
|
18
|
+
fov: 45,
|
|
19
|
+
near: 0.1,
|
|
20
|
+
far: 100,
|
|
21
|
+
});
|
|
13
22
|
expect(cam).toBeDefined();
|
|
14
23
|
});
|
|
15
24
|
|
package/src/com/index.ts
CHANGED
package/src/com/types.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Vector3Like } from "three";
|
|
1
|
+
import { type Texture, type Vector3Like } from "three";
|
|
2
2
|
|
|
3
3
|
type COMBaseEntity = {
|
|
4
4
|
id: string;
|
|
5
5
|
name: string;
|
|
6
|
-
entityType: 'pov' | 'light' | 'model';
|
|
6
|
+
entityType: 'pov' | 'light' | 'model' | 'primitive';
|
|
7
7
|
visible: boolean;
|
|
8
8
|
}
|
|
9
9
|
export type COMPov = COMBaseEntity & {
|
|
@@ -28,4 +28,27 @@ export type COMModel = COMBaseEntity & {
|
|
|
28
28
|
loaded: boolean;
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
export type
|
|
31
|
+
export type COMGeometry = {
|
|
32
|
+
name: string
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
depth: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type COMMaterial = {
|
|
39
|
+
color: string | number;
|
|
40
|
+
roughness: number;
|
|
41
|
+
roughnessMap: Texture | null;
|
|
42
|
+
metalness: number;
|
|
43
|
+
metalnessMap: Texture | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type COMPrimitive = COMBaseEntity & {
|
|
47
|
+
position: Vector3Like;
|
|
48
|
+
rotation: Vector3Like;
|
|
49
|
+
scale: Vector3Like;
|
|
50
|
+
geometry: COMGeometry;
|
|
51
|
+
material: COMMaterial;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type COMEntity = COMPov | COMLight | COMModel | COMPrimitive;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OrbitControls } from "three/examples/jsm/
|
|
1
|
+
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
|
2
2
|
import DIVEPerspectiveCamera from "../camera/PerspectiveCamera.ts";
|
|
3
3
|
import { DIVERenderer } from "../renderer/Renderer.ts";
|
|
4
4
|
import { type Box3, MathUtils, Vector3, Vector3Like } from "three";
|
|
@@ -39,7 +39,7 @@ export default class DIVEOrbitControls extends OrbitControls {
|
|
|
39
39
|
|
|
40
40
|
private _removePreRenderCallback: () => void = () => { };
|
|
41
41
|
|
|
42
|
-
constructor(camera: DIVEPerspectiveCamera, renderer: DIVERenderer, animationSystem: DIVEAnimationSystem, settings: DIVEOrbitControlsSettings = DIVEOrbitControlsDefaultSettings) {
|
|
42
|
+
constructor(camera: DIVEPerspectiveCamera, renderer: DIVERenderer, animationSystem: DIVEAnimationSystem, settings: Partial<DIVEOrbitControlsSettings> = DIVEOrbitControlsDefaultSettings) {
|
|
43
43
|
super(camera, renderer.domElement);
|
|
44
44
|
|
|
45
45
|
this._animationSystem = animationSystem;
|
|
@@ -56,8 +56,13 @@ export default class DIVEOrbitControls extends OrbitControls {
|
|
|
56
56
|
renderer.RemovePreRenderCallback(id);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
this.enableDamping = settings.enableDamping;
|
|
60
|
-
this.dampingFactor = settings.dampingFactor;
|
|
59
|
+
this.enableDamping = settings.enableDamping || DIVEOrbitControlsDefaultSettings.enableDamping;
|
|
60
|
+
this.dampingFactor = settings.dampingFactor || DIVEOrbitControlsDefaultSettings.dampingFactor;
|
|
61
|
+
|
|
62
|
+
// initialize camera transformation
|
|
63
|
+
this.object.position.set(0, 2, 2);
|
|
64
|
+
this.target.copy({ x: 0, y: 0.5, z: 0 });
|
|
65
|
+
this.update();
|
|
61
66
|
}
|
|
62
67
|
|
|
63
68
|
public Dispose(): void {
|
|
@@ -12,7 +12,7 @@ jest.mock('@tweenjs/tween.js', () => {
|
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
|
|
15
|
-
jest.mock('three/examples/jsm/
|
|
15
|
+
jest.mock('three/examples/jsm/controls/OrbitControls', () => {
|
|
16
16
|
return {
|
|
17
17
|
OrbitControls: jest.fn(function () {
|
|
18
18
|
this.enableDamping = true;
|
|
@@ -42,14 +42,13 @@ jest.mock('three/examples/jsm/Addons.js', () => {
|
|
|
42
42
|
MIDDLE: 1,
|
|
43
43
|
RIGHT: 2,
|
|
44
44
|
};
|
|
45
|
-
this.target = {
|
|
46
|
-
set: jest.fn(),
|
|
47
|
-
};
|
|
48
45
|
this.update = jest.fn();
|
|
49
46
|
this.dispose = jest.fn();
|
|
50
47
|
this.getDistance = jest.fn();
|
|
51
48
|
this.target = {
|
|
52
49
|
clone: jest.fn(),
|
|
50
|
+
set: jest.fn(),
|
|
51
|
+
copy: jest.fn(),
|
|
53
52
|
};
|
|
54
53
|
return this;
|
|
55
54
|
}),
|
|
@@ -122,6 +121,9 @@ const mockCamera = {
|
|
|
122
121
|
multiplyScalar: jest.fn(() => {
|
|
123
122
|
return mockCamera.position;
|
|
124
123
|
}),
|
|
124
|
+
set: jest.fn(() => {
|
|
125
|
+
return mockCamera.position;
|
|
126
|
+
}),
|
|
125
127
|
},
|
|
126
128
|
lookAt: jest.fn(),
|
|
127
129
|
} as unknown as DIVEPerspectiveCamera;
|
|
@@ -148,7 +150,15 @@ describe('dive/controls/DIVEOrbitControls', () => {
|
|
|
148
150
|
});
|
|
149
151
|
|
|
150
152
|
it('should instantiate', () => {
|
|
151
|
-
const controller = new DIVEOrbitControls(mockCamera, mockRenderer, mockAnimSystem);
|
|
153
|
+
const controller = new DIVEOrbitControls(mockCamera, mockRenderer, mockAnimSystem, {});
|
|
154
|
+
expect(controller).toBeDefined();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should instantiate with settings', () => {
|
|
158
|
+
const controller = new DIVEOrbitControls(mockCamera, mockRenderer, mockAnimSystem, {
|
|
159
|
+
enableDamping: false,
|
|
160
|
+
dampingFactor: 0.5,
|
|
161
|
+
});
|
|
152
162
|
expect(controller).toBeDefined();
|
|
153
163
|
});
|
|
154
164
|
|
package/src/dive.ts
CHANGED
|
@@ -17,9 +17,9 @@ import { DIVEInfo } from "./info/Info.ts";
|
|
|
17
17
|
export type DIVESettings = {
|
|
18
18
|
autoResize: boolean;
|
|
19
19
|
displayAxes: boolean;
|
|
20
|
-
renderer: DIVERendererSettings
|
|
21
|
-
perspectiveCamera: DIVEPerspectiveCameraSettings
|
|
22
|
-
orbitControls: DIVEOrbitControlsSettings
|
|
20
|
+
renderer: Partial<DIVERendererSettings>;
|
|
21
|
+
perspectiveCamera: Partial<DIVEPerspectiveCameraSettings>;
|
|
22
|
+
orbitControls: Partial<DIVEOrbitControlsSettings>;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export const DIVEDefaultSettings: DIVESettings = {
|
|
@@ -159,15 +159,15 @@ export default class DIVE {
|
|
|
159
159
|
|
|
160
160
|
// apply perspective camera settings
|
|
161
161
|
if (settingsDelta.perspectiveCamera) {
|
|
162
|
-
this.perspectiveCamera.fov = settingsDelta.perspectiveCamera.fov;
|
|
163
|
-
this.perspectiveCamera.near = settingsDelta.perspectiveCamera.near;
|
|
164
|
-
this.perspectiveCamera.far = settingsDelta.perspectiveCamera.far;
|
|
162
|
+
if (settingsDelta.perspectiveCamera.fov !== undefined) this.perspectiveCamera.fov = settingsDelta.perspectiveCamera.fov;
|
|
163
|
+
if (settingsDelta.perspectiveCamera.near !== undefined) this.perspectiveCamera.near = settingsDelta.perspectiveCamera.near;
|
|
164
|
+
if (settingsDelta.perspectiveCamera.far !== undefined) this.perspectiveCamera.far = settingsDelta.perspectiveCamera.far;
|
|
165
165
|
this.perspectiveCamera.OnResize(this.renderer.domElement.width, this.renderer.domElement.height);
|
|
166
166
|
}
|
|
167
167
|
// apply orbit controls settings
|
|
168
168
|
if (settingsDelta.orbitControls) {
|
|
169
|
-
this.orbitControls.enableDamping = settingsDelta.orbitControls.enableDamping;
|
|
170
|
-
this.orbitControls.dampingFactor = settingsDelta.orbitControls.dampingFactor;
|
|
169
|
+
if (settingsDelta.orbitControls.enableDamping !== undefined) this.orbitControls.enableDamping = settingsDelta.orbitControls.enableDamping;
|
|
170
|
+
if (settingsDelta.orbitControls.dampingFactor !== undefined) this.orbitControls.dampingFactor = settingsDelta.orbitControls.dampingFactor;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
if (settingsDelta.autoResize !== this._settings.autoResize) {
|
|
@@ -229,6 +229,8 @@ export default class DIVE {
|
|
|
229
229
|
console.log(this.scene);
|
|
230
230
|
},
|
|
231
231
|
}
|
|
232
|
+
|
|
233
|
+
console.log('DIVE initialized');
|
|
232
234
|
}
|
|
233
235
|
|
|
234
236
|
public Dispose(): void {
|
|
@@ -2,7 +2,7 @@ import { DIVEMediaCreator } from '../MediaCreator';
|
|
|
2
2
|
import { DIVERenderer } from '../../renderer/Renderer';
|
|
3
3
|
import DIVEScene from '../../scene/Scene';
|
|
4
4
|
import DIVEPerspectiveCamera, { DIVEPerspectiveCameraDefaultSettings } from '../../camera/PerspectiveCamera';
|
|
5
|
-
import { COMPov } from '../../com';
|
|
5
|
+
import { type COMPov } from '../../com/types';
|
|
6
6
|
import DIVEOrbitControls from '../../controls/OrbitControls';
|
|
7
7
|
import { DIVEAnimationSystem } from '../../animation/AnimationSystem';
|
|
8
8
|
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { Box3, BoxGeometry, BufferGeometry, Color, CylinderGeometry, Float32BufferAttribute, Mesh, MeshStandardMaterial, Object3D, Raycaster, SphereGeometry, Uint32BufferAttribute, Vector3, Vector3Like } from 'three';
|
|
2
|
+
import DIVECommunication from '../com/Communication';
|
|
3
|
+
import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
|
|
4
|
+
import { findSceneRecursive } from '../helper/findSceneRecursive/findSceneRecursive';
|
|
5
|
+
import { type DIVESelectable } from '../interface/Selectable';
|
|
6
|
+
import { type DIVEMoveable } from '../interface/Moveable';
|
|
7
|
+
import { type TransformControls } from 'three/examples/jsm/controls/TransformControls';
|
|
8
|
+
import { type COMGeometry, type COMMaterial } from '../com/types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A basic model class.
|
|
12
|
+
*
|
|
13
|
+
* It does calculate it's own bounding box which is used for positioning on the floor.
|
|
14
|
+
*
|
|
15
|
+
* Can be moved and selected.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
export class DIVEPrimitive extends Object3D implements DIVESelectable, DIVEMoveable {
|
|
21
|
+
public isSelectable: true = true;
|
|
22
|
+
public isMoveable: true = true;
|
|
23
|
+
|
|
24
|
+
public gizmo: TransformControls | null = null;
|
|
25
|
+
|
|
26
|
+
private _mesh: Mesh;
|
|
27
|
+
private _boundingBox: Box3;
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
super();
|
|
31
|
+
|
|
32
|
+
this.layers.mask = PRODUCT_LAYER_MASK;
|
|
33
|
+
|
|
34
|
+
this._mesh = new Mesh();
|
|
35
|
+
this._mesh.layers.mask = PRODUCT_LAYER_MASK;
|
|
36
|
+
this._mesh.castShadow = true;
|
|
37
|
+
this._mesh.receiveShadow = true;
|
|
38
|
+
this.add(this._mesh);
|
|
39
|
+
|
|
40
|
+
this._boundingBox = new Box3();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public SetGeometry(geometry: COMGeometry): void {
|
|
44
|
+
this.clear();
|
|
45
|
+
|
|
46
|
+
this._mesh.geometry = this.assembleGeometry(geometry);
|
|
47
|
+
this._boundingBox.setFromObject(this._mesh);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public SetPosition(position: Vector3Like): void {
|
|
51
|
+
this.position.set(position.x, position.y, position.z);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public SetRotation(rotation: Vector3Like): void {
|
|
55
|
+
this.rotation.setFromVector3(new Vector3(rotation.x, rotation.y, rotation.z));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
public SetScale(scale: Vector3Like): void {
|
|
59
|
+
this.scale.set(scale.x, scale.y, scale.z);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public SetVisibility(visible: boolean): void {
|
|
63
|
+
this.traverse((child) => {
|
|
64
|
+
child.visible = visible;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public SetMaterial(material: COMMaterial): void {
|
|
69
|
+
const primitiveMaterial = this._mesh.material as MeshStandardMaterial;
|
|
70
|
+
|
|
71
|
+
primitiveMaterial.color = new Color(material.color);
|
|
72
|
+
|
|
73
|
+
// if there is a roughness map, use it, otherwise use the roughness value
|
|
74
|
+
if (material.roughnessMap) {
|
|
75
|
+
primitiveMaterial.roughnessMap = material.roughnessMap;
|
|
76
|
+
primitiveMaterial.roughness = 1.0;
|
|
77
|
+
} else {
|
|
78
|
+
primitiveMaterial.roughness = material.roughness;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// if there is a metalness map, use it, otherwise use the metalness value
|
|
82
|
+
if (material.metalnessMap) {
|
|
83
|
+
primitiveMaterial.metalnessMap = material.metalnessMap;
|
|
84
|
+
primitiveMaterial.metalness = 0.0;
|
|
85
|
+
} else {
|
|
86
|
+
primitiveMaterial.metalness = material.metalness;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public SetToWorldOrigin(): void {
|
|
91
|
+
this.position.set(0, 0, 0);
|
|
92
|
+
DIVECommunication.get(this.userData.id)?.PerformAction('UPDATE_OBJECT', { id: this.userData.id, position: this.position, rotation: this.rotation, scale: this.scale });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public PlaceOnFloor(): void {
|
|
96
|
+
this.position.y = -this._boundingBox.min.y * this.scale.y;
|
|
97
|
+
DIVECommunication.get(this.userData.id)?.PerformAction('UPDATE_OBJECT', { id: this.userData.id, position: this.position, rotation: this.rotation, scale: this.scale });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public DropIt(): void {
|
|
101
|
+
if (!this.parent) {
|
|
102
|
+
console.warn('DIVEModel: DropIt() called on a model that is not in the scene.', this);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// calculate the bottom center of the bounding box
|
|
107
|
+
const bottomY = this._boundingBox.min.y * this.scale.y;
|
|
108
|
+
const bbBottomCenter = this.localToWorld(this._boundingBox.getCenter(new Vector3()).multiply(this.scale));
|
|
109
|
+
bbBottomCenter.y = bottomY + this.position.y;
|
|
110
|
+
|
|
111
|
+
// set up raycaster and raycast all scene objects (product layer)
|
|
112
|
+
const raycaster = new Raycaster(bbBottomCenter, new Vector3(0, -1, 0));
|
|
113
|
+
raycaster.layers.mask = PRODUCT_LAYER_MASK;
|
|
114
|
+
const intersections = raycaster.intersectObjects(findSceneRecursive(this).Root.children, true);
|
|
115
|
+
|
|
116
|
+
// if we hit something, move the model to the top on the hit object's bounding box
|
|
117
|
+
if (intersections.length > 0) {
|
|
118
|
+
const mesh = intersections[0].object as Mesh;
|
|
119
|
+
mesh.geometry.computeBoundingBox();
|
|
120
|
+
const meshBB = mesh.geometry.boundingBox!;
|
|
121
|
+
const worldPos = mesh.localToWorld(meshBB.max.clone());
|
|
122
|
+
|
|
123
|
+
const oldPos = this.position.clone();
|
|
124
|
+
const newPos = this.position.clone().setY(worldPos.y).sub(new Vector3(0, bottomY, 0));
|
|
125
|
+
this.position.copy(newPos);
|
|
126
|
+
|
|
127
|
+
// if the position changed, update the object in communication
|
|
128
|
+
if (this.position.y === oldPos.y) return;
|
|
129
|
+
DIVECommunication.get(this.userData.id)?.PerformAction('UPDATE_OBJECT', { id: this.userData.id, position: this.position, rotation: this.rotation, scale: this.scale });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public onMove(): void {
|
|
134
|
+
DIVECommunication.get(this.userData.id)?.PerformAction('UPDATE_OBJECT', { id: this.userData.id, position: this.position, rotation: this.rotation, scale: this.scale });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public onSelect(): void {
|
|
138
|
+
DIVECommunication.get(this.userData.id)?.PerformAction('SELECT_OBJECT', { id: this.userData.id });
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public onDeselect(): void {
|
|
142
|
+
DIVECommunication.get(this.userData.id)?.PerformAction('DESELECT_OBJECT', { id: this.userData.id });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private assembleGeometry(geometry: COMGeometry): BufferGeometry {
|
|
146
|
+
switch (geometry.name) {
|
|
147
|
+
case 'cylinder':
|
|
148
|
+
return this.createCylinderGeometry(geometry);
|
|
149
|
+
case 'sphere':
|
|
150
|
+
return this.createSphereGeometry(geometry);
|
|
151
|
+
case 'pyramid':
|
|
152
|
+
return this.createPyramidGeometry(geometry);
|
|
153
|
+
case 'box':
|
|
154
|
+
return this.createBoxGeometry(geometry);
|
|
155
|
+
case 'cone':
|
|
156
|
+
return this.createConeGeometry(geometry);
|
|
157
|
+
case 'wall':
|
|
158
|
+
return this.createWallGeometry(geometry);
|
|
159
|
+
case 'plane':
|
|
160
|
+
return this.createPlaneGeometry(geometry);
|
|
161
|
+
default:
|
|
162
|
+
return new BufferGeometry();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
private createCylinderGeometry(geometry: COMGeometry): BufferGeometry {
|
|
167
|
+
return new CylinderGeometry(geometry.width * 2, geometry.width * 2, geometry.height, 64);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private createSphereGeometry(geometry: COMGeometry): BufferGeometry {
|
|
171
|
+
return new SphereGeometry(geometry.width * 2, 64);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
private createPyramidGeometry(geometry: COMGeometry): BufferGeometry {
|
|
175
|
+
const geo = new BufferGeometry();
|
|
176
|
+
const { width, height, depth } = geometry;
|
|
177
|
+
geo.setAttribute('position', new Float32BufferAttribute([
|
|
178
|
+
width / 2, 0, depth / 2, // right back
|
|
179
|
+
width / 2, 0, -depth / 2, // right front
|
|
180
|
+
-width / 2, 0, -depth / 2, // left front
|
|
181
|
+
-width / 2, 0, depth / 2, // left back
|
|
182
|
+
0, height, 0, // top
|
|
183
|
+
], 3));
|
|
184
|
+
geo.setIndex(new Uint32BufferAttribute([
|
|
185
|
+
1, 0, 4,
|
|
186
|
+
2, 1, 4,
|
|
187
|
+
3, 2, 4,
|
|
188
|
+
3, 0, 4,
|
|
189
|
+
0, 1, 2,
|
|
190
|
+
0, 2, 3,
|
|
191
|
+
], 1));
|
|
192
|
+
return geo;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private createBoxGeometry(geometry: COMGeometry): BufferGeometry {
|
|
196
|
+
return new BoxGeometry(geometry.width, geometry.height, geometry.depth);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private createConeGeometry(geometry: COMGeometry): BufferGeometry {
|
|
200
|
+
return new CylinderGeometry(0, geometry.width * 2, geometry.height, 64);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private createWallGeometry(geometry: COMGeometry): BufferGeometry {
|
|
204
|
+
return new BoxGeometry(geometry.width, geometry.height, geometry.depth, 16);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private createPlaneGeometry(geometry: COMGeometry): BufferGeometry {
|
|
208
|
+
return new BoxGeometry(geometry.width, geometry.height, geometry.depth);
|
|
209
|
+
}
|
|
210
|
+
}
|