@shopware-ag/dive 1.19.0 → 1.19.1-beta.1
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/build/dive.cjs +388 -220
- package/build/dive.cjs.map +1 -1
- package/build/dive.js +395 -21946
- package/build/dive.js.map +1 -1
- package/build/dive.mjs +28206 -0
- package/build/dive.mjs.map +1 -0
- package/build/src/ar/AR.d.ts +37 -14
- package/build/src/ar/arquicklook/ARQuickLook.d.ts +5 -6
- package/build/src/ar/sceneviewer/SceneViewer.d.ts +42 -6
- package/build/src/com/actions/scene/launchar.d.ts +5 -2
- package/build/src/converter/Converter.d.ts +21 -0
- package/build/src/dive.d.ts +3 -2
- package/build/src/exporter/Exporter.d.ts +11 -0
- package/build/src/helper/applyMixins/applyMixins.d.ts +22 -6
- package/build/src/info/Info.d.ts +37 -13
- package/build/src/interface/Movable.d.ts +5 -5
- package/build/src/interface/Selectable.d.ts +4 -4
- package/build/src/loader/Loader.d.ts +11 -0
- package/build/src/model/Model.d.ts +2 -2
- package/build/src/node/Node.d.ts +3 -3
- package/build/src/scene/root/Root.d.ts +1 -1
- package/build/src/types/ExporterOptions.d.ts +15 -0
- package/build/src/types/FileTypes.d.ts +27 -0
- package/build/src/types/index.d.ts +4 -0
- package/build/src/types/info/index.d.ts +66 -0
- package/package.json +17 -3
- package/build/src/exporters/usdz/USDZExporter.d.ts +0 -15
- package/build/src/loadingmanager/LoadingManager.d.ts +0 -14
- package/src/__test__/DIVE.test.ts +0 -274
- package/src/animation/AnimationSystem.ts +0 -34
- package/src/animation/__test__/AnimationSystem.test.ts +0 -40
- package/src/ar/AR.ts +0 -98
- package/src/ar/__test__/AR.test.ts +0 -187
- package/src/ar/arquicklook/ARQuickLook.ts +0 -93
- package/src/ar/arquicklook/__test__/ARQuickLook.test.ts +0 -93
- package/src/ar/sceneviewer/SceneViewer.ts +0 -74
- package/src/ar/sceneviewer/__test__/SceneViewer.test.ts +0 -93
- package/src/ar/webxr/WebXR.ts +0 -176
- package/src/ar/webxr/controller/WebXRController.ts +0 -340
- package/src/ar/webxr/crosshair/WebXRCrosshair.ts +0 -35
- package/src/ar/webxr/origin/WebXROrigin.ts +0 -192
- package/src/ar/webxr/overlay/Overlay.ts +0 -50
- package/src/ar/webxr/raycaster/WebXRRaycaster.ts +0 -131
- package/src/ar/webxr/raycaster/ar/WebXRRaycasterAR.ts +0 -102
- package/src/ar/webxr/raycaster/three/WebXRRaycasterTHREE.ts +0 -49
- package/src/ar/webxr/touchscreencontrols/WebXRTouchscreenControls.ts +0 -356
- package/src/axiscamera/AxisCamera.ts +0 -108
- package/src/axiscamera/__test__/AxisCamera.test.ts +0 -150
- package/src/camera/PerspectiveCamera.ts +0 -63
- package/src/camera/__test__/PerspectiveCamera.test.ts +0 -36
- package/src/com/Communication.ts +0 -808
- package/src/com/__test__/Communication.test.ts +0 -1024
- package/src/com/actions/camera/computeencompassingview.ts +0 -10
- package/src/com/actions/camera/getcameratransform.ts +0 -10
- package/src/com/actions/camera/movecamera.ts +0 -18
- package/src/com/actions/camera/resetcamera.ts +0 -5
- package/src/com/actions/camera/setcameralayer.ts +0 -5
- package/src/com/actions/camera/setcameratransform.ts +0 -10
- package/src/com/actions/camera/zoomcamera.ts +0 -5
- package/src/com/actions/index.ts +0 -61
- package/src/com/actions/media/generatemedia.ts +0 -18
- package/src/com/actions/object/addobject.ts +0 -7
- package/src/com/actions/object/deleteobject.ts +0 -7
- package/src/com/actions/object/deselectobject.ts +0 -7
- package/src/com/actions/object/getallobjects.ts +0 -7
- package/src/com/actions/object/getobjects.ts +0 -7
- package/src/com/actions/object/model/dropit.ts +0 -5
- package/src/com/actions/object/model/modelloaded.ts +0 -5
- package/src/com/actions/object/model/placeonfloor.ts +0 -5
- package/src/com/actions/object/selectobject.ts +0 -7
- package/src/com/actions/object/setparent.ts +0 -10
- package/src/com/actions/object/updateobject.ts +0 -7
- package/src/com/actions/renderer/startrender.ts +0 -5
- package/src/com/actions/scene/exportscene.ts +0 -7
- package/src/com/actions/scene/getallscenedata.ts +0 -7
- package/src/com/actions/scene/launchar.ts +0 -7
- package/src/com/actions/scene/setbackground.ts +0 -5
- package/src/com/actions/scene/updatescene.ts +0 -11
- package/src/com/actions/toolbox/select/setgizmomode.ts +0 -5
- package/src/com/actions/toolbox/transform/setgizmoscalelinked.ts +0 -5
- package/src/com/actions/toolbox/transform/setgizmovisible.ts +0 -5
- package/src/com/actions/toolbox/usetool.ts +0 -7
- package/src/com/types/COMBaseEntity.ts +0 -9
- package/src/com/types/COMEntity.ts +0 -7
- package/src/com/types/COMEntityType.ts +0 -1
- package/src/com/types/COMGeometry.ts +0 -8
- package/src/com/types/COMGeometryType.ts +0 -9
- package/src/com/types/COMGroup.ts +0 -9
- package/src/com/types/COMLight.ts +0 -11
- package/src/com/types/COMMaterial.ts +0 -12
- package/src/com/types/COMModel.ts +0 -12
- package/src/com/types/COMPov.ts +0 -8
- package/src/com/types/COMPrimitive.ts +0 -12
- package/src/com/types/index.ts +0 -23
- package/src/constant/AxisHelperColors.ts +0 -7
- package/src/constant/GridColors.ts +0 -2
- package/src/constant/VisibilityLayerMask.ts +0 -5
- package/src/controls/OrbitControls.ts +0 -211
- package/src/controls/__test__/OrbitControls.test.ts +0 -256
- package/src/dive.ts +0 -363
- package/src/events/EventExecutor.ts +0 -35
- package/src/exporters/usdz/USDZExporter.ts +0 -21
- package/src/exporters/usdz/__test__/USDZExporter.test.ts +0 -57
- package/src/gizmo/Gizmo.ts +0 -144
- package/src/gizmo/handles/AxisHandle.ts +0 -153
- package/src/gizmo/handles/RadialHandle.ts +0 -149
- package/src/gizmo/handles/ScaleHandle.ts +0 -195
- package/src/gizmo/plane/GizmoPlane.ts +0 -84
- package/src/gizmo/rotate/RotateGizmo.ts +0 -143
- package/src/gizmo/scale/ScaleGizmo.ts +0 -125
- package/src/gizmo/translate/TranslateGizmo.ts +0 -114
- package/src/grid/Grid.ts +0 -34
- package/src/grid/__test__/Grid.test.ts +0 -28
- package/src/group/Group.ts +0 -184
- package/src/group/__test__/Group.test.ts +0 -212
- package/src/helper/applyMixins/__test__/applyMixins.test.ts +0 -30
- package/src/helper/applyMixins/applyMixins.ts +0 -18
- package/src/helper/findInterface/__test__/findInterface.test.ts +0 -63
- package/src/helper/findInterface/findInterface.ts +0 -13
- package/src/helper/findSceneRecursive/__test__/findSceneRecursive.test.ts +0 -40
- package/src/helper/findSceneRecursive/findSceneRecursive.ts +0 -16
- package/src/helper/getObjectDelta/__test__/getObjectDelta.test.ts +0 -186
- package/src/helper/getObjectDelta/getObjectDelta.ts +0 -105
- package/src/helper/isInterface/__test__/implementsInterface.test.ts +0 -19
- package/src/helper/isInterface/implementsInterface.ts +0 -9
- package/src/info/Info.ts +0 -154
- package/src/info/__test__/Info.test.ts +0 -338
- package/src/interface/Draggable.ts +0 -14
- package/src/interface/Hoverable.ts +0 -14
- package/src/interface/Movable.ts +0 -12
- package/src/interface/Rotatable.ts +0 -10
- package/src/interface/Scalable.ts +0 -10
- package/src/interface/Selectable.ts +0 -11
- package/src/io/IO.ts +0 -62
- package/src/io/__test__/IO.test.ts +0 -116
- package/src/io/gltf/GLTFIO.ts +0 -56
- package/src/io/gltf/__test__/GLTFIO.test.ts +0 -108
- package/src/light/AmbientLight.ts +0 -39
- package/src/light/PointLight.ts +0 -115
- package/src/light/SceneLight.ts +0 -63
- package/src/light/__test__/AmbientLight.test.ts +0 -29
- package/src/light/__test__/PointLight.test.ts +0 -74
- package/src/light/__test__/SceneLight.test.ts +0 -47
- package/src/loadingmanager/LoadingManager.ts +0 -50
- package/src/loadingmanager/__test__/LoadingManager.test.ts +0 -27
- package/src/math/__test__/DIVEMath.test.ts +0 -12
- package/src/math/ceil/__test__/ceilExp.test.ts +0 -12
- package/src/math/ceil/ceilExp.ts +0 -6
- package/src/math/degToRad/__test__/degToRad.test.ts +0 -172
- package/src/math/degToRad/degToRad.ts +0 -5
- package/src/math/floor/__test__/floorExp.test.ts +0 -14
- package/src/math/floor/floorExp.ts +0 -6
- package/src/math/helper/__test__/shift.test.ts +0 -12
- package/src/math/helper/shift.ts +0 -4
- package/src/math/index.ts +0 -28
- package/src/math/radToDeg/__test__/radToDeg.test.ts +0 -155
- package/src/math/radToDeg/radToDeg.ts +0 -5
- package/src/math/round/__test__/roundExp.test.ts +0 -14
- package/src/math/round/roundExp.ts +0 -10
- package/src/math/signedAngleTo/__test__/signedAngleTo.test.ts +0 -20
- package/src/math/signedAngleTo/signedAngleTo.ts +0 -20
- package/src/math/toFixed/__test__/toFixedExp.test.ts +0 -14
- package/src/math/toFixed/toFixedExp.ts +0 -9
- package/src/math/truncate/__test__/truncateExp.test.ts +0 -14
- package/src/math/truncate/truncateExp.ts +0 -9
- package/src/mediacreator/MediaCreator.ts +0 -75
- package/src/mediacreator/__test__/MediaCreator.test.ts +0 -155
- package/src/model/Model.ts +0 -185
- package/src/model/__test__/Model.test.ts +0 -222
- package/src/module/Module.ts +0 -45
- package/src/module/__test__/Module.test.ts +0 -54
- package/src/node/Node.ts +0 -98
- package/src/node/__test__/Node.test.ts +0 -120
- package/src/primitive/Primitive.ts +0 -299
- package/src/primitive/__test__/Primitive.test.ts +0 -281
- package/src/primitive/floor/Floor.ts +0 -45
- package/src/primitive/floor/__test__/Floor.test.ts +0 -24
- package/src/renderer/Renderer.ts +0 -215
- package/src/renderer/__test__/Renderer.test.ts +0 -228
- package/src/scene/Scene.ts +0 -106
- package/src/scene/__test__/Scene.test.ts +0 -124
- package/src/scene/root/Root.ts +0 -426
- package/src/scene/root/__test__/Root.test.ts +0 -903
- package/src/scene/xrroot/XRRoot.ts +0 -56
- package/src/scene/xrroot/xrlightroot/XRLightRoot.ts +0 -80
- package/src/toolbox/BaseTool.ts +0 -319
- package/src/toolbox/Toolbox.ts +0 -129
- package/src/toolbox/__test__/BaseTool.test.ts +0 -627
- package/src/toolbox/__test__/Toolbox.test.ts +0 -143
- package/src/toolbox/select/SelectTool.ts +0 -92
- package/src/toolbox/select/__test__/SelectTool.test.ts +0 -237
- package/src/toolbox/transform/TransformTool.ts +0 -166
- package/src/toolbox/transform/__test__/TransformTool.test.ts +0 -147
- package/src/types/SceneData.ts +0 -26
- package/src/types/SceneObjects.ts +0 -14
- package/src/types/SceneType.ts +0 -14
- package/src/types/index.ts +0 -5
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { DIVEMediaCreator } from '../MediaCreator';
|
|
2
|
-
import { DIVERenderer } from '../../renderer/Renderer';
|
|
3
|
-
import { DIVEScene } from '../../scene/Scene';
|
|
4
|
-
import DIVEPerspectiveCamera, {
|
|
5
|
-
DIVEPerspectiveCameraDefaultSettings,
|
|
6
|
-
} from '../../camera/PerspectiveCamera';
|
|
7
|
-
import { type COMPov } from '../../com/types';
|
|
8
|
-
import DIVEOrbitControls from '../../controls/OrbitControls';
|
|
9
|
-
import { DIVEAnimationSystem } from '../../animation/AnimationSystem';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @jest-environment jsdom
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const mock_render = jest.fn();
|
|
16
|
-
const mock_toDataURL = jest.fn();
|
|
17
|
-
|
|
18
|
-
jest.mock('../../scene/Scene', () => {
|
|
19
|
-
return {
|
|
20
|
-
DIVEScene: jest.fn(function () {
|
|
21
|
-
this.add = jest.fn();
|
|
22
|
-
this.children = [];
|
|
23
|
-
this.Root = {
|
|
24
|
-
children: [],
|
|
25
|
-
};
|
|
26
|
-
return this;
|
|
27
|
-
}),
|
|
28
|
-
};
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
jest.mock('../../camera/PerspectiveCamera', () => {
|
|
32
|
-
return jest.fn(function () {
|
|
33
|
-
this.position = {
|
|
34
|
-
clone: jest.fn(),
|
|
35
|
-
copy: jest.fn(),
|
|
36
|
-
};
|
|
37
|
-
this.quaternion = {
|
|
38
|
-
clone: jest.fn(),
|
|
39
|
-
copy: jest.fn(),
|
|
40
|
-
};
|
|
41
|
-
this.orbitControls = {
|
|
42
|
-
target: {
|
|
43
|
-
clone: jest.fn(),
|
|
44
|
-
copy: jest.fn(),
|
|
45
|
-
},
|
|
46
|
-
update: jest.fn(),
|
|
47
|
-
};
|
|
48
|
-
this.layers = {
|
|
49
|
-
mask: 0,
|
|
50
|
-
};
|
|
51
|
-
return this;
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
jest.mock('../../controls/OrbitControls', () => {
|
|
56
|
-
return jest.fn(function () {
|
|
57
|
-
this.object = {
|
|
58
|
-
position: {
|
|
59
|
-
clone: jest.fn(),
|
|
60
|
-
copy: jest.fn(),
|
|
61
|
-
},
|
|
62
|
-
quaternion: {
|
|
63
|
-
clone: jest.fn(),
|
|
64
|
-
copy: jest.fn(),
|
|
65
|
-
},
|
|
66
|
-
layers: {
|
|
67
|
-
mask: 0,
|
|
68
|
-
},
|
|
69
|
-
OnResize: jest.fn(),
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
this.target = {
|
|
73
|
-
clone: jest.fn(),
|
|
74
|
-
copy: jest.fn(),
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
this.update = jest.fn();
|
|
78
|
-
|
|
79
|
-
return this;
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
jest.mock('../../renderer/Renderer', () => {
|
|
84
|
-
return {
|
|
85
|
-
DIVERenderer: jest.fn(function () {
|
|
86
|
-
this.domElement = {
|
|
87
|
-
toDataURL: mock_toDataURL,
|
|
88
|
-
};
|
|
89
|
-
this.render = mock_render;
|
|
90
|
-
this.OnResize = jest.fn();
|
|
91
|
-
return this;
|
|
92
|
-
}),
|
|
93
|
-
};
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
jest.mock('../../animation/AnimationSystem', () => {
|
|
97
|
-
return {
|
|
98
|
-
DIVEAnimationSystem: jest.fn(function () {
|
|
99
|
-
this.domElement = {
|
|
100
|
-
toDataURL: mock_toDataURL,
|
|
101
|
-
};
|
|
102
|
-
this.render = mock_render;
|
|
103
|
-
this.OnResize = jest.fn();
|
|
104
|
-
this.AddPreRenderCallback = jest.fn((callback) => {
|
|
105
|
-
callback();
|
|
106
|
-
return 'id';
|
|
107
|
-
});
|
|
108
|
-
return this;
|
|
109
|
-
}),
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
let mediaCreator: DIVEMediaCreator;
|
|
114
|
-
|
|
115
|
-
describe('dive/mediacreator/DIVEMediaCreator', () => {
|
|
116
|
-
beforeEach(() => {
|
|
117
|
-
jest.clearAllMocks();
|
|
118
|
-
mediaCreator = new DIVEMediaCreator(
|
|
119
|
-
new DIVERenderer(),
|
|
120
|
-
new DIVEScene(),
|
|
121
|
-
new DIVEOrbitControls(
|
|
122
|
-
new DIVEPerspectiveCamera(DIVEPerspectiveCameraDefaultSettings),
|
|
123
|
-
new DIVERenderer(),
|
|
124
|
-
new DIVEAnimationSystem(new DIVERenderer()),
|
|
125
|
-
),
|
|
126
|
-
);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should instantiate', () => {
|
|
130
|
-
expect(mediaCreator).toBeDefined();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('should generate media', () => {
|
|
134
|
-
const mock_POV = {
|
|
135
|
-
position: { x: 0, y: 0, z: 0 },
|
|
136
|
-
target: { x: 0, y: 0, z: 0 },
|
|
137
|
-
} as COMPov;
|
|
138
|
-
expect(() => {
|
|
139
|
-
mediaCreator.GenerateMedia(
|
|
140
|
-
mock_POV.position,
|
|
141
|
-
mock_POV.target,
|
|
142
|
-
800,
|
|
143
|
-
600,
|
|
144
|
-
);
|
|
145
|
-
}).not.toThrow();
|
|
146
|
-
expect(mock_render).toHaveBeenCalledTimes(1);
|
|
147
|
-
expect(mock_toDataURL).toHaveBeenCalledTimes(1);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
it('should draw canvas with custom canvas', () => {
|
|
151
|
-
const canvas = document.createElement('canvas');
|
|
152
|
-
mediaCreator.DrawCanvas(canvas);
|
|
153
|
-
expect(mock_render).toHaveBeenCalledTimes(1);
|
|
154
|
-
});
|
|
155
|
-
});
|
package/src/model/Model.ts
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { Mesh, MeshStandardMaterial, Raycaster, Vector3 } from 'three';
|
|
2
|
-
import { PRODUCT_LAYER_MASK } from '../constant/VisibilityLayerMask';
|
|
3
|
-
import type { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
4
|
-
import { findSceneRecursive } from '../helper/findSceneRecursive/findSceneRecursive';
|
|
5
|
-
import { type COMMaterial } from '../com/types';
|
|
6
|
-
import { DIVENode } from '../node/Node';
|
|
7
|
-
import { DIVECommunication } from '../com/Communication';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A basic model class.
|
|
11
|
-
*
|
|
12
|
-
* It does calculate it's own bounding box which is used for positioning on the floor.
|
|
13
|
-
*
|
|
14
|
-
* Can be moved and selected.
|
|
15
|
-
*
|
|
16
|
-
* @module
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
export class DIVEModel extends DIVENode {
|
|
20
|
-
readonly isDIVEModel: true = true;
|
|
21
|
-
|
|
22
|
-
private _mesh: Mesh | null = null;
|
|
23
|
-
private _material: MeshStandardMaterial | null = null;
|
|
24
|
-
|
|
25
|
-
public SetModel(gltf: GLTF): void {
|
|
26
|
-
this.clear();
|
|
27
|
-
this._boundingBox.makeEmpty();
|
|
28
|
-
|
|
29
|
-
gltf.scene.traverse((child) => {
|
|
30
|
-
child.castShadow = true;
|
|
31
|
-
child.receiveShadow = true;
|
|
32
|
-
|
|
33
|
-
child.layers.mask = this.layers.mask;
|
|
34
|
-
this._boundingBox.expandByObject(child);
|
|
35
|
-
|
|
36
|
-
// only search for first mesh for now
|
|
37
|
-
if (!this._mesh && 'isMesh' in child) {
|
|
38
|
-
this._mesh = child as Mesh;
|
|
39
|
-
|
|
40
|
-
// if the material is already set, use it, otherwise set it from the model's material
|
|
41
|
-
if (this._material) {
|
|
42
|
-
this._mesh.material = this._material;
|
|
43
|
-
} else {
|
|
44
|
-
this._material = (child as Mesh)
|
|
45
|
-
.material as MeshStandardMaterial;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
this.add(gltf.scene);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public SetMaterial(material: Partial<COMMaterial>): void {
|
|
54
|
-
// if there is no material, create a new one
|
|
55
|
-
if (!this._material) {
|
|
56
|
-
this._material = new MeshStandardMaterial();
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (material.vertexColors !== undefined) {
|
|
60
|
-
this._material.vertexColors = material.vertexColors;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// apply color if supplied
|
|
64
|
-
if (material.color !== undefined) {
|
|
65
|
-
this._material.color.set(material.color);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// apply albedo map if supplied
|
|
69
|
-
if (material.map !== undefined) {
|
|
70
|
-
this._material.map = material.map;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// apply normal map
|
|
74
|
-
if (material.normalMap !== undefined) {
|
|
75
|
-
this._material.normalMap = material.normalMap;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// set roughness value
|
|
79
|
-
// if supplied, apply roughness map
|
|
80
|
-
// if we applied a roughness map, set roughness to 1.0
|
|
81
|
-
if (material.roughness !== undefined) {
|
|
82
|
-
this._material.roughness = material.roughness;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (material.roughnessMap !== undefined) {
|
|
86
|
-
this._material.roughnessMap = material.roughnessMap;
|
|
87
|
-
|
|
88
|
-
if (this._material.roughnessMap) {
|
|
89
|
-
this._material.roughness = 1.0;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// set metalness value
|
|
94
|
-
// if supplied, apply metalness map
|
|
95
|
-
// if we applied a metalness map, set metalness to 1.0
|
|
96
|
-
if (material.metalness !== undefined) {
|
|
97
|
-
this._material.metalness = material.metalness;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (material.metalnessMap !== undefined) {
|
|
101
|
-
this._material.metalnessMap = material.metalnessMap;
|
|
102
|
-
|
|
103
|
-
if (this._material.metalnessMap) {
|
|
104
|
-
this._material.metalness = 1.0;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// if the mesh is already set, update the material
|
|
109
|
-
if (this._mesh) {
|
|
110
|
-
this._mesh.material = this._material;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
public PlaceOnFloor(): void {
|
|
115
|
-
// calculate and temporary save world position
|
|
116
|
-
const worldPos = this.getWorldPosition(this._positionWorldBuffer);
|
|
117
|
-
const oldWorldPos = worldPos.clone();
|
|
118
|
-
|
|
119
|
-
// compute the bounding box
|
|
120
|
-
this._mesh?.geometry?.computeBoundingBox();
|
|
121
|
-
const meshBB = this._mesh?.geometry?.boundingBox;
|
|
122
|
-
|
|
123
|
-
// subtract the bounding box min y axis value from the world position y value
|
|
124
|
-
if (!meshBB || !this._mesh) return;
|
|
125
|
-
worldPos.y = worldPos.y - this._mesh.localToWorld(meshBB.min.clone()).y;
|
|
126
|
-
|
|
127
|
-
// skip any action when the position did not change
|
|
128
|
-
if (worldPos.y === oldWorldPos.y) return;
|
|
129
|
-
|
|
130
|
-
DIVECommunication.get(this.userData.id)?.PerformAction(
|
|
131
|
-
'UPDATE_OBJECT',
|
|
132
|
-
{
|
|
133
|
-
id: this.userData.id,
|
|
134
|
-
position: worldPos,
|
|
135
|
-
rotation: this.rotation,
|
|
136
|
-
scale: this.scale,
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
public DropIt(): void {
|
|
142
|
-
if (!this.parent) {
|
|
143
|
-
console.warn(
|
|
144
|
-
'DIVEModel: DropIt() called on a model that is not in the scene.',
|
|
145
|
-
this,
|
|
146
|
-
);
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// calculate the bottom center of the bounding box
|
|
151
|
-
const bottomY = this._boundingBox.min.y * this.scale.y;
|
|
152
|
-
const bbBottomCenter = this.localToWorld(
|
|
153
|
-
this._boundingBox.getCenter(new Vector3()).multiply(this.scale),
|
|
154
|
-
);
|
|
155
|
-
bbBottomCenter.y = bottomY + this.position.y;
|
|
156
|
-
|
|
157
|
-
// set up raycaster and raycast all scene objects (product layer)
|
|
158
|
-
const raycaster = new Raycaster(bbBottomCenter, new Vector3(0, -1, 0));
|
|
159
|
-
raycaster.layers.mask = PRODUCT_LAYER_MASK;
|
|
160
|
-
const intersections = raycaster.intersectObjects(
|
|
161
|
-
findSceneRecursive(this).Root.children,
|
|
162
|
-
true,
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
// if we hit something, move the model to the top on the hit object's bounding box
|
|
166
|
-
if (intersections.length > 0) {
|
|
167
|
-
const mesh = intersections[0].object as Mesh;
|
|
168
|
-
mesh.geometry.computeBoundingBox();
|
|
169
|
-
const meshBB = mesh.geometry.boundingBox!;
|
|
170
|
-
const worldPos = mesh.localToWorld(meshBB.max.clone());
|
|
171
|
-
|
|
172
|
-
const oldPos = this.position.clone();
|
|
173
|
-
const newPos = this.position
|
|
174
|
-
.clone()
|
|
175
|
-
.setY(worldPos.y)
|
|
176
|
-
.sub(new Vector3(0, bottomY, 0));
|
|
177
|
-
this.position.copy(newPos);
|
|
178
|
-
|
|
179
|
-
// if the position changed, update the object in communication
|
|
180
|
-
if (this.position.y === oldPos.y) return;
|
|
181
|
-
|
|
182
|
-
this.onMove();
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { RaycasterIntersectObjectMock } from '../../../__mocks__/three';
|
|
2
|
-
|
|
3
|
-
import { DIVEModel } from '../Model';
|
|
4
|
-
import { DIVECommunication } from '../../com/Communication';
|
|
5
|
-
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
6
|
-
import { DIVEScene } from '../../scene/Scene';
|
|
7
|
-
import {
|
|
8
|
-
Vector3,
|
|
9
|
-
Box3,
|
|
10
|
-
Mesh,
|
|
11
|
-
MeshStandardMaterial,
|
|
12
|
-
type Texture,
|
|
13
|
-
Object3D,
|
|
14
|
-
} from 'three';
|
|
15
|
-
import { type COMMaterial } from '../../com/types';
|
|
16
|
-
|
|
17
|
-
jest.mock('../../com/Communication.ts', () => {
|
|
18
|
-
return {
|
|
19
|
-
DIVECommunication: {
|
|
20
|
-
get: jest.fn(() => {
|
|
21
|
-
return {
|
|
22
|
-
PerformAction: jest.fn(),
|
|
23
|
-
};
|
|
24
|
-
}),
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
const object = new Object3D();
|
|
30
|
-
object.children.push(new Mesh());
|
|
31
|
-
|
|
32
|
-
const gltf = {
|
|
33
|
-
scene: {
|
|
34
|
-
...object,
|
|
35
|
-
},
|
|
36
|
-
} as unknown as GLTF;
|
|
37
|
-
|
|
38
|
-
jest.spyOn(DIVECommunication, 'get').mockReturnValue({
|
|
39
|
-
PerformAction: jest.fn(),
|
|
40
|
-
} as unknown as DIVECommunication);
|
|
41
|
-
|
|
42
|
-
let model: DIVEModel;
|
|
43
|
-
|
|
44
|
-
describe('dive/model/DIVEModel', () => {
|
|
45
|
-
beforeEach(() => {
|
|
46
|
-
jest.clearAllMocks();
|
|
47
|
-
RaycasterIntersectObjectMock.mockClear();
|
|
48
|
-
model = new DIVEModel();
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
afterEach(() => {
|
|
52
|
-
jest.clearAllMocks();
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should instantiate', () => {
|
|
56
|
-
expect(model).toBeDefined();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should set model', () => {
|
|
60
|
-
expect(() => model.SetModel(gltf)).not.toThrow();
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should place on floor', () => {
|
|
64
|
-
model.SetModel(gltf);
|
|
65
|
-
|
|
66
|
-
const com = DIVECommunication.get('id')!;
|
|
67
|
-
const spyPerformAction = jest.spyOn(com, 'PerformAction');
|
|
68
|
-
|
|
69
|
-
model.userData.id = 'something';
|
|
70
|
-
model.position.set(0, 4, 0);
|
|
71
|
-
|
|
72
|
-
jest.spyOn(model['_mesh']!, 'localToWorld').mockReturnValueOnce(
|
|
73
|
-
new Vector3(0, 2, 0),
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
const scene = {
|
|
77
|
-
parent: null,
|
|
78
|
-
Root: {
|
|
79
|
-
children: [
|
|
80
|
-
model,
|
|
81
|
-
],
|
|
82
|
-
},
|
|
83
|
-
} as unknown as DIVEScene;
|
|
84
|
-
scene.Root.parent = scene;
|
|
85
|
-
model.parent = scene.Root;
|
|
86
|
-
|
|
87
|
-
expect(() => model.PlaceOnFloor()).not.toThrow();
|
|
88
|
-
expect(spyPerformAction).toHaveBeenCalledWith(
|
|
89
|
-
'UPDATE_OBJECT',
|
|
90
|
-
expect.objectContaining({
|
|
91
|
-
position: expect.objectContaining({
|
|
92
|
-
y: 2,
|
|
93
|
-
}),
|
|
94
|
-
}),
|
|
95
|
-
);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should drop it', () => {
|
|
99
|
-
const comMock = {
|
|
100
|
-
PerformAction: jest.fn(),
|
|
101
|
-
} as unknown as DIVECommunication;
|
|
102
|
-
jest.spyOn(DIVECommunication, 'get').mockReturnValue(comMock);
|
|
103
|
-
|
|
104
|
-
const spy = jest.spyOn(model, 'onMove').mockImplementation(() => {});
|
|
105
|
-
|
|
106
|
-
const size = {
|
|
107
|
-
x: 1,
|
|
108
|
-
y: 1,
|
|
109
|
-
z: 1,
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
model.userData.id = 'something';
|
|
113
|
-
model.position.set(0, 4, 0);
|
|
114
|
-
model['_boundingBox'] = {
|
|
115
|
-
min: new Vector3(-size.x / 2, -size.y / 2, -size.z / 2),
|
|
116
|
-
max: new Vector3(size.x / 2, size.y / 2, size.z / 2),
|
|
117
|
-
getCenter: jest.fn(() => {
|
|
118
|
-
return new Vector3(0, 0, 0);
|
|
119
|
-
}),
|
|
120
|
-
} as unknown as Box3;
|
|
121
|
-
|
|
122
|
-
const hitObject = new Mesh();
|
|
123
|
-
hitObject.geometry.boundingBox = new Box3();
|
|
124
|
-
hitObject.geometry.boundingBox.max = new Vector3(0, 2, 0);
|
|
125
|
-
RaycasterIntersectObjectMock.mockReturnValue([
|
|
126
|
-
{
|
|
127
|
-
object: hitObject,
|
|
128
|
-
},
|
|
129
|
-
]);
|
|
130
|
-
|
|
131
|
-
const scene = {
|
|
132
|
-
parent: null,
|
|
133
|
-
Root: {
|
|
134
|
-
children: [
|
|
135
|
-
model,
|
|
136
|
-
],
|
|
137
|
-
},
|
|
138
|
-
} as unknown as DIVEScene;
|
|
139
|
-
scene.Root.parent = scene;
|
|
140
|
-
|
|
141
|
-
// test when parent is not set
|
|
142
|
-
console.warn = jest.fn();
|
|
143
|
-
expect(() => model.DropIt()).not.toThrow();
|
|
144
|
-
expect(console.warn).toHaveBeenCalledTimes(1);
|
|
145
|
-
|
|
146
|
-
model.parent = scene.Root;
|
|
147
|
-
|
|
148
|
-
expect(() => model.DropIt()).not.toThrow();
|
|
149
|
-
expect(model.position.y).toBe(2.5);
|
|
150
|
-
expect(spy).toHaveBeenCalledTimes(1);
|
|
151
|
-
|
|
152
|
-
expect(() => model.DropIt()).not.toThrow();
|
|
153
|
-
expect(spy).toHaveBeenCalledTimes(1);
|
|
154
|
-
|
|
155
|
-
// alter position so onMove will be called again
|
|
156
|
-
model.position.y = 2;
|
|
157
|
-
jest.spyOn(DIVECommunication, 'get').mockReturnValueOnce(undefined);
|
|
158
|
-
expect(() => model.DropIt()).not.toThrow();
|
|
159
|
-
expect(spy).toHaveBeenCalledTimes(2);
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('should set material', () => {
|
|
163
|
-
// apply invalid material should not crash
|
|
164
|
-
expect(() => model.SetMaterial({} as COMMaterial)).not.toThrow();
|
|
165
|
-
expect(model['_material']).not.toBeNull();
|
|
166
|
-
|
|
167
|
-
expect(() =>
|
|
168
|
-
model.SetMaterial({
|
|
169
|
-
color: 0xffffff,
|
|
170
|
-
roughness: 0,
|
|
171
|
-
metalness: 1,
|
|
172
|
-
} as COMMaterial),
|
|
173
|
-
).not.toThrow();
|
|
174
|
-
expect((model['_material'] as MeshStandardMaterial).roughness).toBe(0);
|
|
175
|
-
expect(
|
|
176
|
-
(model['_material'] as MeshStandardMaterial).roughnessMap,
|
|
177
|
-
).toBeUndefined();
|
|
178
|
-
expect((model['_material'] as MeshStandardMaterial).metalness).toBe(1);
|
|
179
|
-
expect(
|
|
180
|
-
(model['_material'] as MeshStandardMaterial).metalnessMap,
|
|
181
|
-
).toBeUndefined();
|
|
182
|
-
|
|
183
|
-
expect(() =>
|
|
184
|
-
model.SetMaterial({
|
|
185
|
-
color: 0xff00ff,
|
|
186
|
-
vertexColors: true,
|
|
187
|
-
map: 'This_Is_A_Texture' as unknown as Texture,
|
|
188
|
-
normalMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
189
|
-
roughness: 0,
|
|
190
|
-
roughnessMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
191
|
-
metalness: 1,
|
|
192
|
-
metalnessMap: 'This_Is_A_Texture' as unknown as Texture,
|
|
193
|
-
} as COMMaterial),
|
|
194
|
-
).not.toThrow();
|
|
195
|
-
expect((model['_material'] as MeshStandardMaterial).roughness).toBe(1);
|
|
196
|
-
expect(
|
|
197
|
-
(model['_material'] as MeshStandardMaterial).roughnessMap,
|
|
198
|
-
).toBeDefined();
|
|
199
|
-
expect((model['_material'] as MeshStandardMaterial).metalness).toBe(1);
|
|
200
|
-
expect(
|
|
201
|
-
(model['_material'] as MeshStandardMaterial).metalnessMap,
|
|
202
|
-
).toBeDefined();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('should set model material when material already set before', () => {
|
|
206
|
-
model.SetMaterial({ roughness: 0.5 } as COMMaterial);
|
|
207
|
-
expect(() => model.SetModel(gltf)).not.toThrow();
|
|
208
|
-
expect(
|
|
209
|
-
(model['_mesh']?.material as MeshStandardMaterial).roughness,
|
|
210
|
-
).toBe(0.5);
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
it('should set material to model when model already set before', () => {
|
|
214
|
-
model.SetModel(gltf);
|
|
215
|
-
expect(() =>
|
|
216
|
-
model.SetMaterial({ roughness: 0.5 } as COMMaterial),
|
|
217
|
-
).not.toThrow();
|
|
218
|
-
expect(
|
|
219
|
-
(model['_mesh']?.material as MeshStandardMaterial).roughness,
|
|
220
|
-
).toBe(0.5);
|
|
221
|
-
});
|
|
222
|
-
});
|
package/src/module/Module.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
export class DIVEModule<T> {
|
|
2
|
-
constructor(
|
|
3
|
-
private _path: string,
|
|
4
|
-
private _ctor: string,
|
|
5
|
-
) {}
|
|
6
|
-
|
|
7
|
-
private _promise: Promise<T> | null = null;
|
|
8
|
-
private _instance: T | null = null;
|
|
9
|
-
|
|
10
|
-
public async get(): Promise<T> {
|
|
11
|
-
// if we already have an instance, return it
|
|
12
|
-
if (this._instance) {
|
|
13
|
-
return Promise.resolve(this._instance);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// if we already have a loading process ongoing, return the already created promise
|
|
17
|
-
if (this._promise) {
|
|
18
|
-
return this._promise;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// if we don't have a promise yet, it means that we are not already loading the module
|
|
22
|
-
this._promise = (async () => {
|
|
23
|
-
const module = await import(this._path);
|
|
24
|
-
|
|
25
|
-
const ModuleConstructor = module[this._ctor];
|
|
26
|
-
|
|
27
|
-
if (!ModuleConstructor) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`DIVE: Module class ${this._ctor} not found in ${this._path}`,
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (typeof ModuleConstructor !== 'function') {
|
|
34
|
-
throw new Error(
|
|
35
|
-
`DIVE: Module at ${this._path} does not export a valid constructor (${this._ctor} wanted)`,
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
this._instance = new ModuleConstructor() as T;
|
|
40
|
-
return this._instance;
|
|
41
|
-
})();
|
|
42
|
-
|
|
43
|
-
return this._promise;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { DIVEModule } from '../Module';
|
|
2
|
-
|
|
3
|
-
jest.mock('/mock/path', () => mockModule, { virtual: true });
|
|
4
|
-
|
|
5
|
-
const mockModule: Record<string, any> = {};
|
|
6
|
-
|
|
7
|
-
describe('dive/module/DIVEModule', () => {
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
// Reset the mock module before each test
|
|
10
|
-
Object.keys(mockModule).forEach((key) => delete mockModule[key]);
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it('should return the same instance on multiple calls to get()', async () => {
|
|
14
|
-
mockModule.TestClass = class TestClass {};
|
|
15
|
-
const diveModule = new DIVEModule('/mock/path', 'TestClass');
|
|
16
|
-
|
|
17
|
-
const instance1 = await diveModule.get();
|
|
18
|
-
const instance2 = await diveModule.get();
|
|
19
|
-
|
|
20
|
-
expect(instance1).toBe(instance2);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('should throw an error if the constructor is not found', async () => {
|
|
24
|
-
const diveModule = new DIVEModule('/mock/path', 'NonExistentClass');
|
|
25
|
-
|
|
26
|
-
await expect(diveModule.get()).rejects.toThrow(
|
|
27
|
-
'DIVE: Module class NonExistentClass not found in /mock/path',
|
|
28
|
-
);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should throw an error if the constructor is not a function', async () => {
|
|
32
|
-
mockModule.InvalidClass = {};
|
|
33
|
-
const diveModule = new DIVEModule('/mock/path', 'InvalidClass');
|
|
34
|
-
|
|
35
|
-
await expect(diveModule.get()).rejects.toThrow(
|
|
36
|
-
'DIVE: Module at /mock/path does not export a valid constructor (InvalidClass wanted)',
|
|
37
|
-
);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should only load the module once even with concurrent calls to get()', async () => {
|
|
41
|
-
mockModule.TestClass = class TestClass {};
|
|
42
|
-
const diveModule = new DIVEModule('/mock/path', 'TestClass');
|
|
43
|
-
|
|
44
|
-
const [
|
|
45
|
-
instance1,
|
|
46
|
-
instance2,
|
|
47
|
-
] = await Promise.all([
|
|
48
|
-
diveModule.get(),
|
|
49
|
-
diveModule.get(),
|
|
50
|
-
]);
|
|
51
|
-
|
|
52
|
-
expect(instance1).toBe(instance2);
|
|
53
|
-
});
|
|
54
|
-
});
|