@shopware-ag/dive 1.0.7 → 1.0.8

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.
Files changed (97) hide show
  1. package/package.json +6 -3
  2. package/src/__test__/DIVE.test.ts +244 -0
  3. package/src/animation/AnimationSystem.ts +14 -0
  4. package/src/animation/__test__/AnimationSystem.test.ts +19 -0
  5. package/src/axiscamera/AxisCamera.ts +50 -0
  6. package/src/axiscamera/__test__/AxisCamera.test.ts +41 -0
  7. package/src/camera/PerspectiveCamera.ts +43 -0
  8. package/src/camera/__test__/PerspectiveCamera.test.ts +27 -0
  9. package/src/com/Communication.ts +382 -0
  10. package/src/com/__test__/Communication.test.ts +612 -0
  11. package/src/com/actions/camera/getcameratransform.ts +9 -0
  12. package/src/com/actions/camera/movecamera.ts +15 -0
  13. package/src/com/actions/camera/resetcamera.ts +4 -0
  14. package/src/com/actions/camera/setcameralayer.ts +4 -0
  15. package/src/com/actions/camera/setcameratransform.ts +9 -0
  16. package/src/com/actions/camera/zoomcamera.ts +4 -0
  17. package/src/com/actions/index.ts +41 -0
  18. package/src/com/actions/media/generatemedia.ts +15 -0
  19. package/src/com/actions/object/addobject.ts +6 -0
  20. package/src/com/actions/object/deleteobject.ts +6 -0
  21. package/src/com/actions/object/getallobjects.ts +6 -0
  22. package/src/com/actions/object/getobjects.ts +6 -0
  23. package/src/com/actions/object/model/modelloaded.ts +4 -0
  24. package/src/com/actions/object/model/placeonfloor.ts +4 -0
  25. package/src/com/actions/object/selectobject.ts +6 -0
  26. package/src/com/actions/object/updateobject.ts +6 -0
  27. package/src/com/actions/scene/getallscenedata.ts +23 -0
  28. package/src/com/actions/scene/setbackground.ts +4 -0
  29. package/src/com/actions/scene/updatescene.ts +9 -0
  30. package/src/com/actions/toolbox/select/setgizmomode.ts +4 -0
  31. package/src/com/index.ts +4 -0
  32. package/src/com/types.ts +30 -0
  33. package/src/constant/AxisHelperColors.ts +7 -0
  34. package/src/constant/GridColors.ts +2 -0
  35. package/src/constant/VisibilityLayerMask.ts +5 -0
  36. package/src/controls/OrbitControls.ts +145 -0
  37. package/src/controls/__test__/OrbitControls.test.ts +181 -0
  38. package/src/grid/Grid.ts +22 -0
  39. package/src/grid/__test__/Grid.test.ts +19 -0
  40. package/src/helper/applyMixins/__test__/applyMixins.test.ts +27 -0
  41. package/src/helper/applyMixins/applyMixins.ts +15 -0
  42. package/src/helper/getObjectDelta/__test__/getObjectDelta.spec.ts +152 -0
  43. package/src/helper/getObjectDelta/getObjectDelta.ts +101 -0
  44. package/src/interface/Moveable.ts +13 -0
  45. package/src/interface/Rotatable.ts +10 -0
  46. package/src/interface/Scalable.ts +10 -0
  47. package/src/interface/Selectable.ts +11 -0
  48. package/src/interface/__test__/Interfaces.test.ts +13 -0
  49. package/src/light/AmbientLight.ts +29 -0
  50. package/src/light/PointLight.ts +63 -0
  51. package/src/light/SceneLight.ts +60 -0
  52. package/src/light/__test__/AmbientLight.test.ts +44 -0
  53. package/src/light/__test__/PointLight.test.ts +98 -0
  54. package/src/light/__test__/SceneLight.test.ts +122 -0
  55. package/src/loadingmanager/LoadingManager.ts +44 -0
  56. package/src/loadingmanager/__test__/LoadingManager.test.ts +52 -0
  57. package/src/math/__test__/DIVEMath.test.ts +12 -0
  58. package/src/math/ceil/__test__/ceilExp.test.ts +12 -0
  59. package/src/math/ceil/ceilExp.ts +6 -0
  60. package/src/math/floor/__test__/floorExp.test.ts +14 -0
  61. package/src/math/floor/floorExp.ts +6 -0
  62. package/src/math/helper/__test__/shift.test.ts +12 -0
  63. package/src/math/helper/shift.ts +4 -0
  64. package/src/math/index.ts +19 -0
  65. package/src/math/round/__test__/roundExp.test.ts +14 -0
  66. package/src/math/round/roundExp.ts +7 -0
  67. package/src/math/toFixed/__test__/toFixedExp.test.ts +14 -0
  68. package/src/math/toFixed/toFixedExp.ts +6 -0
  69. package/src/math/truncate/__test__/truncateExp.test.ts +14 -0
  70. package/src/math/truncate/truncateExp.ts +6 -0
  71. package/src/mediacreator/MediaCreator.ts +65 -0
  72. package/src/mediacreator/__test__/MediaCreator.test.ts +113 -0
  73. package/src/model/Model.ts +72 -0
  74. package/src/model/__test__/Model.test.ts +163 -0
  75. package/src/primitive/floor/Floor.ts +34 -0
  76. package/src/primitive/floor/__test__/Floor.test.ts +21 -0
  77. package/src/renderer/Renderer.ts +165 -0
  78. package/src/renderer/__test__/Renderer.test.ts +169 -0
  79. package/src/scene/Scene.ts +49 -0
  80. package/src/scene/__test__/Scene.test.ts +70 -0
  81. package/src/scene/root/Root.ts +107 -0
  82. package/src/scene/root/__test__/Root.test.ts +129 -0
  83. package/src/scene/root/lightroot/LightRoot.ts +84 -0
  84. package/src/scene/root/lightroot/__test__/LightRoot.test.ts +137 -0
  85. package/src/scene/root/modelroot/ModelRoot.ts +82 -0
  86. package/src/scene/root/modelroot/__test__/ModelRoot.test.ts +185 -0
  87. package/src/toolbox/BaseTool.ts +18 -0
  88. package/src/toolbox/Toolbox.ts +76 -0
  89. package/src/toolbox/__test__/Toolbox.test.ts +109 -0
  90. package/src/toolbox/select/SelectTool.ts +123 -0
  91. package/src/toolbox/select/__test__/SelectTool.test.ts +190 -0
  92. package/build/dive.cjs +0 -1551
  93. package/build/dive.cjs.map +0 -1
  94. package/build/dive.d.cts +0 -558
  95. package/build/dive.d.ts +0 -558
  96. package/build/dive.js +0 -1516
  97. package/build/dive.js.map +0 -1
@@ -0,0 +1,41 @@
1
+ import SET_BACKGROUND from "./scene/setbackground.ts";
2
+ import RESET_CAMERA from "./camera/resetcamera.ts";
3
+ import SET_CAMERA_LAYER from "./camera/setcameralayer.ts";
4
+ import ZOOM_CAMERA from "./camera/zoomcamera.ts";
5
+ import SET_GIZMO_MODE from "./toolbox/select/setgizmomode.ts";
6
+ import SET_CAMERA_TRANSFORM from "./camera/setcameratransform.ts";
7
+ import MOVE_CAMERA from "./camera/movecamera.ts";
8
+ import PLACE_ON_FLOOR from "./object/model/placeonfloor.ts";
9
+ import GET_ALL_OBJECTS from "./object/getallobjects.ts";
10
+ import GET_OBJECTS from "./object/getobjects.ts";
11
+ import ADD_OBJECT from "./object/addobject.ts";
12
+ import DELETE_OBJECT from "./object/deleteobject.ts";
13
+ import UPDATE_OBJECT from "./object/updateobject.ts";
14
+ import MODEL_LOADED from "./object/model/modelloaded.ts";
15
+ import UPDATE_SCENE from "./scene/updatescene.ts";
16
+ import GENERATE_MEDIA from "./media/generatemedia.ts";
17
+ import GET_ALL_SCENE_DATA from "./scene/getallscenedata.ts";
18
+ import SELECT_OBJECT from "./object/selectobject.ts";
19
+ import GET_CAMERA_TRANSFORM from "./camera/getcameratransform.ts";
20
+
21
+ export type Actions = {
22
+ GET_ALL_SCENE_DATA: GET_ALL_SCENE_DATA,
23
+ GET_ALL_OBJECTS: GET_ALL_OBJECTS,
24
+ GET_OBJECTS: GET_OBJECTS,
25
+ ADD_OBJECT: ADD_OBJECT,
26
+ UPDATE_OBJECT: UPDATE_OBJECT,
27
+ DELETE_OBJECT: DELETE_OBJECT,
28
+ SELECT_OBJECT: SELECT_OBJECT,
29
+ SET_BACKGROUND: SET_BACKGROUND,
30
+ PLACE_ON_FLOOR: PLACE_ON_FLOOR,
31
+ SET_CAMERA_TRANSFORM: SET_CAMERA_TRANSFORM,
32
+ GET_CAMERA_TRANSFORM: GET_CAMERA_TRANSFORM,
33
+ MOVE_CAMERA: MOVE_CAMERA,
34
+ RESET_CAMERA: RESET_CAMERA,
35
+ SET_CAMERA_LAYER: SET_CAMERA_LAYER,
36
+ ZOOM_CAMERA: ZOOM_CAMERA,
37
+ SET_GIZMO_MODE: SET_GIZMO_MODE,
38
+ MODEL_LOADED: MODEL_LOADED,
39
+ UPDATE_SCENE: UPDATE_SCENE,
40
+ GENERATE_MEDIA: GENERATE_MEDIA,
41
+ };
@@ -0,0 +1,15 @@
1
+ import { Vector3Like } from "three";
2
+
3
+ export default interface GENERATE_MEDIA {
4
+ 'PAYLOAD': ({
5
+ position: Vector3Like,
6
+ target: Vector3Like,
7
+ } | {
8
+ id: string,
9
+ }) & {
10
+ width: number, // image width in pixels
11
+ height: number, // image height in pixels
12
+ dataUri: string
13
+ },
14
+ 'RETURN': boolean,
15
+ }
@@ -0,0 +1,6 @@
1
+ import { COMEntity } from "../../types.ts";
2
+
3
+ export default interface ADD_OBJECT {
4
+ 'PAYLOAD': COMEntity,
5
+ 'RETURN': boolean,
6
+ };
@@ -0,0 +1,6 @@
1
+ import { COMEntity } from "../../types.ts";
2
+
3
+ export default interface DELETE_OBJECT {
4
+ 'PAYLOAD': Partial<COMEntity> & { id: string },
5
+ 'RETURN': boolean,
6
+ }
@@ -0,0 +1,6 @@
1
+ import { COMEntity } from "../../types.ts";
2
+
3
+ export default interface GET_ALL_OBJECTS {
4
+ 'PAYLOAD': Map<string, COMEntity>,
5
+ 'RETURN': Map<string, COMEntity>,
6
+ };
@@ -0,0 +1,6 @@
1
+ import { COMEntity } from "../../types.ts";
2
+
3
+ export default interface GET_OBJECTS {
4
+ 'PAYLOAD': { map: Map<string, COMEntity>, ids?: string[] },
5
+ 'RETURN': Map<string, COMEntity>,
6
+ };
@@ -0,0 +1,4 @@
1
+ export default interface MODEL_LOADED {
2
+ 'PAYLOAD': { id: string },
3
+ 'RETURN': boolean,
4
+ };
@@ -0,0 +1,4 @@
1
+ export default interface PLACE_ON_FLOOR {
2
+ 'PAYLOAD': { id: string },
3
+ 'RETURN': boolean,
4
+ };
@@ -0,0 +1,6 @@
1
+ import { COMEntity } from "../../types.ts";
2
+
3
+ export default interface SELECT_OBJECT {
4
+ 'PAYLOAD': Partial<COMEntity> & { id: string },
5
+ 'RETURN': boolean,
6
+ };
@@ -0,0 +1,6 @@
1
+ import { COMEntity } from "../../types.ts";
2
+
3
+ export default interface UPDATE_OBJECT {
4
+ 'PAYLOAD': Partial<COMEntity> & { id: string },
5
+ 'RETURN': boolean,
6
+ };
@@ -0,0 +1,23 @@
1
+ import { Vector3Like } from "three";
2
+ import { COMLight, COMModel, COMPov } from "../../types.ts";
3
+
4
+ type SceneData = {
5
+ name: string,
6
+ mediaItem: null,
7
+ backgroundColor: string,
8
+ floorEnabled: boolean,
9
+ floorColor: string,
10
+ userCamera: {
11
+ position: Vector3Like,
12
+ target: Vector3Like,
13
+ },
14
+ spotmarks: object[],
15
+ lights: COMLight[],
16
+ objects: COMModel[],
17
+ cameras: COMPov[],
18
+ };
19
+
20
+ export default interface GET_ALL_SCENE_DATA {
21
+ 'PAYLOAD': object,
22
+ 'RETURN': SceneData,
23
+ };
@@ -0,0 +1,4 @@
1
+ export default interface SET_BACKGROUND {
2
+ 'PAYLOAD': { color: string | number },
3
+ 'RETURN': boolean,
4
+ };
@@ -0,0 +1,9 @@
1
+ export default interface UPDATE_SCENE {
2
+ 'PAYLOAD': {
3
+ name?: string,
4
+ backgroundColor?: string | number,
5
+ floorEnabled?: boolean,
6
+ floorColor?: string | number
7
+ },
8
+ 'RETURN': boolean,
9
+ };
@@ -0,0 +1,4 @@
1
+ export default interface SET_GIZMO_MODE {
2
+ 'PAYLOAD': { mode: 'translate' | 'rotate' | 'scale' },
3
+ 'RETURN': boolean,
4
+ };
@@ -0,0 +1,4 @@
1
+ import DIVECommunication from './Communication.ts';
2
+ export type { Actions } from './actions/index.ts';
3
+ export type { COMLight, COMModel, COMPov, COMEntity } from './types.ts';
4
+ export default DIVECommunication;
@@ -0,0 +1,30 @@
1
+ import { Vector3Like } from "three";
2
+
3
+ type COMBaseEntity = {
4
+ id: string;
5
+ name: string;
6
+ entityType: 'pov' | 'light' | 'model';
7
+ }
8
+ export type COMPov = COMBaseEntity & {
9
+ position: Vector3Like;
10
+ target: Vector3Like;
11
+ locked?: boolean;
12
+ };
13
+
14
+ export type COMLight = COMBaseEntity & {
15
+ type: 'ambient' | 'point' | 'scene';
16
+ intensity: number;
17
+ color: string | number;
18
+ enabled: boolean;
19
+ position?: Vector3Like;
20
+ };
21
+
22
+ export type COMModel = COMBaseEntity & {
23
+ uri: string;
24
+ position: Vector3Like;
25
+ rotation: Vector3Like;
26
+ scale: Vector3Like;
27
+ loaded: boolean;
28
+ };
29
+
30
+ export type COMEntity = COMPov | COMLight | COMModel;
@@ -0,0 +1,7 @@
1
+ export const AxesColorRedLetter = '#c20017';
2
+ export const AxesColorGreenLetter = '#00ab26';
3
+ export const AxesColorBlueLetter = '#0081d4';
4
+
5
+ export const AxesColorRed = AxesColorRedLetter;
6
+ export const AxesColorGreen = AxesColorGreenLetter;
7
+ export const AxesColorBlue = AxesColorBlueLetter;
@@ -0,0 +1,2 @@
1
+ export const GRID_CENTER_LINE_COLOR = '#888888';
2
+ export const GRID_SIDE_LINE_COLOR = '#dddddd';
@@ -0,0 +1,5 @@
1
+ export const DEFAULT_LAYER_MASK = 0b00000001; // 1
2
+ export const COORDINATE_LAYER_MASK = 0b00000010; // 2
3
+ export const UI_LAYER_MASK = 0b00000100; // 4
4
+ export const HELPER_LAYER_MASK = 0b00001000; // 8
5
+ export const PRODUCT_LAYER_MASK = 0b00010000; // 16
@@ -0,0 +1,145 @@
1
+ import { OrbitControls } from "three/examples/jsm/Addons.js";
2
+ import DIVEPerspectiveCamera from "../camera/PerspectiveCamera.ts";
3
+ import DIVERenderer from "../renderer/Renderer.ts";
4
+ import { MathUtils, Vector3Like } from "three";
5
+ import { Easing, Tween } from "@tweenjs/tween.js";
6
+
7
+ export type DIVEOrbitControlsSettings = {
8
+ enableDamping: boolean;
9
+ dampingFactor: number;
10
+ }
11
+
12
+ export const DIVEOrbitControlsDefaultSettings: DIVEOrbitControlsSettings = {
13
+ enableDamping: true,
14
+ dampingFactor: 0.04,
15
+ }
16
+
17
+ /**
18
+ * Orbit Controls. Basic functionality to orbit around a given target point in the scene.
19
+ *
20
+ * @module
21
+ */
22
+
23
+ export default class DIVEOrbitControls extends OrbitControls {
24
+ public static readonly DEFAULT_ZOOM_FACTOR = 1;
25
+
26
+ private last: { pos: Vector3Like, target: Vector3Like } | null = null;
27
+
28
+ private animating: boolean = false;
29
+ private locked: boolean = false;
30
+
31
+ private stopMoveTo: () => void = () => { };
32
+ private stopRevertLast: () => void = () => { };
33
+
34
+ public object: DIVEPerspectiveCamera;
35
+ public domElement: HTMLCanvasElement;
36
+
37
+ constructor(camera: DIVEPerspectiveCamera, renderer: DIVERenderer, settings: DIVEOrbitControlsSettings = DIVEOrbitControlsDefaultSettings) {
38
+ super(camera, renderer.domElement);
39
+
40
+ this.domElement = renderer.domElement;
41
+
42
+ this.object = camera;
43
+
44
+ renderer.AddPreRenderCallback(() => {
45
+ this.preRenderCallback();
46
+ });
47
+
48
+ this.enableDamping = settings.enableDamping;
49
+ this.dampingFactor = settings.dampingFactor;
50
+ }
51
+
52
+ public ZoomIn(by?: number): void {
53
+ const zoomBy = by || DIVEOrbitControls.DEFAULT_ZOOM_FACTOR;
54
+ const { minDistance, maxDistance } = this;
55
+ this.minDistance = this.maxDistance = MathUtils.clamp(this.getDistance() - zoomBy, minDistance + zoomBy, maxDistance - zoomBy);
56
+ this.update();
57
+ this.minDistance = minDistance;
58
+ this.maxDistance = maxDistance;
59
+ }
60
+
61
+ public ZoomOut(by?: number): void {
62
+ const zoomBy = by || DIVEOrbitControls.DEFAULT_ZOOM_FACTOR;
63
+ const { minDistance, maxDistance } = this;
64
+ this.minDistance = this.maxDistance = MathUtils.clamp(this.getDistance() + zoomBy, minDistance + zoomBy, maxDistance - zoomBy);
65
+ this.update();
66
+ this.minDistance = minDistance;
67
+ this.maxDistance = maxDistance;
68
+ }
69
+
70
+ public MoveTo(pos: Vector3Like | undefined, target: Vector3Like | undefined, duration: number, lock: boolean): void {
71
+ if (this.animating) return;
72
+
73
+ const toPosition = pos || this.object.position.clone();
74
+ const toTarget = target || this.target.clone();
75
+
76
+ this.stopRevertLast();
77
+
78
+ if (!this.locked) this.last = { pos: this.object.position.clone(), target: this.target.clone() };
79
+
80
+ this.animating = duration > 0;
81
+ this.locked = lock;
82
+ this.enabled = false;
83
+
84
+ const tweenPos = new Tween(this.object.position)
85
+ .to(toPosition, duration)
86
+ .easing(Easing.Quadratic.Out)
87
+ .start();
88
+
89
+ const tweenQuat = new Tween(this.target)
90
+ .to(toTarget, duration)
91
+ .easing(Easing.Quadratic.Out)
92
+ .onUpdate(() => {
93
+ this.object.lookAt(this.target);
94
+ })
95
+ .onComplete(() => {
96
+ this.animating = false;
97
+ this.enabled = !lock;
98
+ })
99
+ .start();
100
+
101
+ this.stopMoveTo = () => {
102
+ tweenPos.stop();
103
+ tweenQuat.stop();
104
+ }
105
+ }
106
+
107
+ public RevertLast(duration: number): void {
108
+ if (this.animating || !this.locked) return;
109
+
110
+ this.stopMoveTo();
111
+
112
+ this.animating = duration > 0;
113
+ this.enabled = false;
114
+
115
+ const { pos, target } = this.last!;
116
+
117
+ const tweenPos = new Tween(this.object.position)
118
+ .to(pos, duration)
119
+ .easing(Easing.Quadratic.Out)
120
+ .start();
121
+
122
+ const tweenQuat = new Tween(this.target)
123
+ .to(target, duration)
124
+ .easing(Easing.Quadratic.Out)
125
+ .onUpdate(() => {
126
+ this.object.lookAt(this.target);
127
+ })
128
+ .onComplete(() => {
129
+ this.animating = false;
130
+ this.locked = false;
131
+ this.enabled = true;
132
+ })
133
+ .start();
134
+
135
+ this.stopRevertLast = () => {
136
+ tweenPos.stop();
137
+ tweenQuat.stop();
138
+ }
139
+ }
140
+
141
+ private preRenderCallback = (): void => {
142
+ if (this.locked) return;
143
+ this.update();
144
+ }
145
+ }
@@ -0,0 +1,181 @@
1
+ import DIVEOrbitControls from '../OrbitControls';
2
+ import DIVEPerspectiveCamera from '../../camera/PerspectiveCamera';
3
+ import DIVERenderer, { DIVERendererDefaultSettings } from '../../renderer/Renderer';
4
+
5
+ jest.mock('three/examples/jsm/Addons.js', () => {
6
+ return {
7
+ OrbitControls: jest.fn(function () {
8
+ this.enableDamping = true;
9
+ this.dampingFactor = 0.25;
10
+ this.enableZoom = true;
11
+ this.enablePan = true;
12
+ this.minPolarAngle = 0;
13
+ this.maxPolarAngle = Math.PI;
14
+ this.minDistance = 0;
15
+ this.maxDistance = Infinity;
16
+ this.rotateSpeed = 0.5;
17
+ this.panSpeed = 0.5;
18
+ this.zoomSpeed = 0.5;
19
+ this.keyPanSpeed = 0.5;
20
+ this.screenSpacePanning = true;
21
+ this.autoRotate = false;
22
+ this.autoRotateSpeed = 2.0;
23
+ this.enableKeys = true;
24
+ this.keys = {
25
+ LEFT: 37,
26
+ UP: 38,
27
+ RIGHT: 39,
28
+ BOTTOM: 40,
29
+ };
30
+ this.mouseButtons = {
31
+ LEFT: 0,
32
+ MIDDLE: 1,
33
+ RIGHT: 2,
34
+ };
35
+ this.target = {
36
+ set: jest.fn(),
37
+ };
38
+ this.update = jest.fn();
39
+ this.dispose = jest.fn();
40
+ this.getDistance = jest.fn();
41
+ this.target = {
42
+ clone: jest.fn(),
43
+ };
44
+ return this;
45
+ }),
46
+ }
47
+ });
48
+
49
+ jest.mock('../../renderer/Renderer', () => {
50
+ return jest.fn(function () {
51
+ this.domElement = {
52
+ style: {},
53
+ };
54
+ this.AddPreRenderCallback = (callback: () => void) => {
55
+ callback();
56
+ };
57
+
58
+ return this;
59
+ });
60
+ });
61
+
62
+ jest.mock('@tweenjs/tween.js', () => {
63
+ return {
64
+ Easing: {
65
+ Quadratic: {
66
+ In: jest.fn(),
67
+ Out: jest.fn(),
68
+ InOut: jest.fn(),
69
+ },
70
+ },
71
+ Tween: jest.fn(() => {
72
+ const instance: object = {
73
+ easing: () => { return instance; },
74
+ to: () => { return instance; },
75
+ start: () => { return instance; },
76
+ stop: () => { return instance; },
77
+ onComplete: (callback: () => typeof instance) => { callback(); return instance; },
78
+ onUpdate: (callback: () => typeof instance) => { callback(); return instance; },
79
+ }
80
+ return instance;
81
+ }),
82
+ }
83
+ });
84
+
85
+ const moveToPos = { x: 10, y: 0, z: 0 };
86
+ const moveToQuat = { x: 0, y: 0, z: 0 };
87
+ const moveToDuration = 1000;
88
+
89
+ const mockCamera = {
90
+ position: {
91
+ clone: jest.fn(),
92
+ },
93
+ lookAt: jest.fn(),
94
+ } as unknown as DIVEPerspectiveCamera;
95
+ const mockRenderer: DIVERenderer = new DIVERenderer(DIVERendererDefaultSettings);
96
+
97
+ describe('dive/controls/DIVEOrbitControls', () => {
98
+ afterEach(() => {
99
+ jest.clearAllMocks();
100
+ });
101
+
102
+ it('should instantiate', () => {
103
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
104
+ expect(controller).toBeDefined();
105
+ });
106
+
107
+ it('should zoom in with default value', () => {
108
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
109
+ expect(() => controller.ZoomIn()).not.toThrow();
110
+ });
111
+
112
+ it('should zoom in with custom value', () => {
113
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
114
+ expect(() => controller.ZoomIn(10)).not.toThrow();
115
+ });
116
+
117
+ it('should zoom out with default value', () => {
118
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
119
+ expect(() => controller.ZoomOut()).not.toThrow();
120
+ });
121
+
122
+ it('should zoom out with custom value', () => {
123
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
124
+ expect(() => controller.ZoomOut(10)).not.toThrow();
125
+ });
126
+
127
+ it('should move to', () => {
128
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
129
+ expect(() => controller.MoveTo(moveToPos, moveToQuat, moveToDuration, false)).not.toThrow();
130
+ });
131
+
132
+ it('should revert move to', () => {
133
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
134
+ controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true);
135
+ expect(() => controller.RevertLast(moveToDuration)).not.toThrow();
136
+ });
137
+
138
+ it('should revert move to without values', () => {
139
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
140
+ expect(() => controller.MoveTo(undefined, undefined, moveToDuration, true)).not.toThrow();
141
+ });
142
+
143
+ it('should revert move to with lock', async () => {
144
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
145
+ controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true);
146
+ expect(() => controller.RevertLast(moveToDuration)).not.toThrow();
147
+ });
148
+
149
+ it('should move after revert with lock', async () => {
150
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
151
+ controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true);
152
+ controller.RevertLast(moveToDuration);
153
+ expect(() => controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true)).not.toThrow();
154
+ });
155
+
156
+ it('should catch multiple move tos', () => {
157
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
158
+ controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true);
159
+ controller.RevertLast(moveToDuration);
160
+ expect(() => controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true)).not.toThrow();
161
+ controller['animating'] = true;
162
+ expect(() => controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true)).not.toThrow();
163
+ expect(() => controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true)).not.toThrow();
164
+ });
165
+
166
+ it('should catch multiple reverts', () => {
167
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
168
+ controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true);
169
+ expect(() => controller.RevertLast(moveToDuration)).not.toThrow();
170
+ expect(() => controller.RevertLast(moveToDuration)).not.toThrow();
171
+ expect(() => controller.RevertLast(moveToDuration)).not.toThrow();
172
+ });
173
+
174
+ it('should execute preRenderCallback', () => {
175
+ const controller = new DIVEOrbitControls(mockCamera, mockRenderer);
176
+ controller.MoveTo(moveToPos, moveToQuat, moveToDuration, true);
177
+ expect(() => controller['preRenderCallback']()).not.toThrow();
178
+ controller['locked'] = true;
179
+ expect(() => controller['preRenderCallback']()).not.toThrow();
180
+ });
181
+ });
@@ -0,0 +1,22 @@
1
+ import { GRID_SIDE_LINE_COLOR, GRID_CENTER_LINE_COLOR } from "../constant/GridColors.ts";
2
+ import { HELPER_LAYER_MASK } from "../constant/VisibilityLayerMask.ts";
3
+ import { GridHelper, Object3D } from "three";
4
+
5
+ /**
6
+ * A basic grid for the scene.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ export default class DIVEGrid extends Object3D {
12
+ constructor() {
13
+ super();
14
+ this.name = 'Grid';
15
+
16
+ const grid = new GridHelper(100, 100, GRID_CENTER_LINE_COLOR, GRID_SIDE_LINE_COLOR);
17
+ grid.material.depthTest = false;
18
+ grid.layers.mask = HELPER_LAYER_MASK;
19
+
20
+ this.add(grid);
21
+ }
22
+ }
@@ -0,0 +1,19 @@
1
+ import DIVEGrid from '../Grid.ts';
2
+ import { HELPER_LAYER_MASK } from "../../constant/VisibilityLayerMask.ts";
3
+ import { GridHelper } from 'three';
4
+
5
+ let grid: DIVEGrid;
6
+
7
+ describe('dive/grid/DIVEGrid', () => {
8
+ beforeEach(() => {
9
+ grid = new DIVEGrid();
10
+ });
11
+
12
+ it('should instantiate', () => {
13
+ expect(grid).toBeDefined();
14
+ expect(grid.name).toBeTruthy();
15
+ expect(grid.children.length).toBeGreaterThanOrEqual(1);
16
+ expect((grid.children[0] as GridHelper).material.depthTest).toBe(false);
17
+ expect((grid.children[0] as GridHelper).layers.mask).toBe(HELPER_LAYER_MASK);
18
+ });
19
+ });
@@ -0,0 +1,27 @@
1
+ import { applyMixins } from '../applyMixins.ts';
2
+
3
+ class Moveable {
4
+ move() { }
5
+ }
6
+
7
+ class Selectable {
8
+ select() { }
9
+ }
10
+
11
+ describe('dive/helper/applyMixins', () => {
12
+ it('should apply mixins', () => {
13
+ class Product {
14
+ doProductThings() { }
15
+ }
16
+
17
+ interface Product extends Moveable, Selectable { }
18
+
19
+ applyMixins(Product, [Moveable, Selectable]);
20
+
21
+ const instance = new Product();
22
+ expect(instance).toBeDefined();
23
+ expect(instance.move).toBeDefined();
24
+ expect(instance.select).toBeDefined();
25
+ expect(instance.doProductThings).toBeDefined();
26
+ });
27
+ });
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Merges two class prototypes to a new one.
3
+ */
4
+
5
+ export const applyMixins = (derivedCtor: { prototype: object }, constructors: { prototype: object }[]): void => {
6
+ constructors.forEach((baseCtor) => {
7
+ Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
8
+ Object.defineProperty(
9
+ derivedCtor.prototype,
10
+ name,
11
+ Object.getOwnPropertyDescriptor(baseCtor.prototype, name)!
12
+ );
13
+ });
14
+ });
15
+ }