@shopware-ag/dive 1.4.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +38 -24
  2. package/build/dive.cjs +734 -492
  3. package/build/dive.cjs.map +1 -1
  4. package/build/dive.d.cts +182 -113
  5. package/build/dive.d.ts +182 -113
  6. package/build/dive.js +733 -478
  7. package/build/dive.js.map +1 -1
  8. package/package.json +1 -1
  9. package/src/__test__/DIVE.test.ts +66 -22
  10. package/src/animation/AnimationSystem.ts +16 -0
  11. package/src/animation/__test__/AnimationSystem.test.ts +23 -2
  12. package/src/axiscamera/AxisCamera.ts +40 -2
  13. package/src/axiscamera/__test__/AxisCamera.test.ts +178 -5
  14. package/src/com/Communication.ts +59 -16
  15. package/src/com/__test__/Communication.test.ts +83 -24
  16. package/src/com/actions/camera/computeencompassingview.ts +9 -0
  17. package/src/com/actions/index.ts +4 -0
  18. package/src/com/actions/scene/updatescene.ts +1 -0
  19. package/src/com/actions/toolbox/transform/setgizmovisible.ts +4 -0
  20. package/src/controls/OrbitControls.ts +14 -2
  21. package/src/controls/__test__/OrbitControls.test.ts +31 -4
  22. package/src/dive.ts +93 -33
  23. package/src/grid/Grid.ts +4 -0
  24. package/src/grid/__test__/Grid.test.ts +7 -0
  25. package/src/interface/Selectable.ts +17 -0
  26. package/src/interface/__test__/Interfaces.test.ts +18 -0
  27. package/src/mediacreator/MediaCreator.ts +2 -2
  28. package/src/mediacreator/__test__/MediaCreator.test.ts +12 -10
  29. package/src/model/Model.ts +6 -0
  30. package/src/model/__test__/Model.test.ts +9 -0
  31. package/src/renderer/Renderer.ts +7 -1
  32. package/src/renderer/__test__/Renderer.test.ts +14 -5
  33. package/src/scene/Scene.ts +8 -2
  34. package/src/scene/__test__/Scene.test.ts +6 -0
  35. package/src/scene/root/Root.ts +11 -1
  36. package/src/scene/root/__test__/Root.test.ts +68 -2
  37. package/src/scene/root/modelroot/ModelRoot.ts +1 -1
  38. package/src/scene/root/modelroot/__test__/ModelRoot.test.ts +1 -0
  39. package/src/toolbox/BaseTool.ts +3 -3
  40. package/src/toolbox/Toolbox.ts +57 -37
  41. package/src/toolbox/__test__/BaseTool.test.ts +49 -7
  42. package/src/toolbox/__test__/Toolbox.test.ts +43 -40
  43. package/src/toolbox/select/SelectTool.ts +18 -28
  44. package/src/toolbox/select/__test__/SelectTool.test.ts +27 -8
  45. package/src/toolbox/transform/TransformTool.ts +16 -1
  46. package/src/toolbox/transform/__test__/TransformTool.test.ts +34 -5
@@ -64,6 +64,7 @@ jest.mock('three', () => {
64
64
  }
65
65
  this.add = jest.fn();
66
66
  this.children = [{
67
+ visible: true,
67
68
  material: {
68
69
  color: {},
69
70
  },
@@ -86,6 +87,9 @@ jest.mock('three', () => {
86
87
  return vec3;
87
88
  };
88
89
  this.mesh = new Mesh();
90
+ this.traverse = jest.fn((callback) => {
91
+ callback(this.children[0])
92
+ });
89
93
  return this;
90
94
  }),
91
95
  Box3: jest.fn(function () {
@@ -196,6 +200,11 @@ describe('dive/model/DIVEModel', () => {
196
200
  expect(() => model.SetScale({ x: 1, y: 1, z: 1 })).not.toThrow();
197
201
  });
198
202
 
203
+ it('should set visibility', () => {
204
+ const model = new Model();
205
+ expect(() => model.SetVisibility(true)).not.toThrow();
206
+ });
207
+
199
208
  it('should set to world origin', () => {
200
209
  const model = new Model();
201
210
  model.userData.id = 'something';
@@ -26,7 +26,7 @@ export const DIVERendererDefaultSettings: DIVERendererSettings = {
26
26
  * @module
27
27
  */
28
28
 
29
- export default class DIVERenderer extends WebGLRenderer {
29
+ export class DIVERenderer extends WebGLRenderer {
30
30
  // basic functionality members
31
31
  private paused: boolean = false;
32
32
  private running: boolean = false;
@@ -52,6 +52,12 @@ export default class DIVERenderer extends WebGLRenderer {
52
52
  this.debug.checkShaderErrors = false;
53
53
  }
54
54
 
55
+ // Stops renderings and disposes the renderer.
56
+ public Dispose(): void {
57
+ this.StopRenderer();
58
+ this.dispose();
59
+ }
60
+
55
61
  // Starts the renderer with the given scene and camera.
56
62
  public StartRenderer(scene: Scene, cam: Camera): void {
57
63
  this.setAnimationLoop(() => { this.internal_render(scene, cam) });
@@ -1,6 +1,6 @@
1
- import DIVEPerspectiveCamera from '../../camera/PerspectiveCamera';
2
- import DIVEScene from '../../scene/Scene';
3
- import DIVERenderer, { DIVERendererDefaultSettings } from '../Renderer';
1
+ import type DIVEPerspectiveCamera from '../../camera/PerspectiveCamera';
2
+ import type DIVEScene from '../../scene/Scene';
3
+ import { DIVERenderer, DIVERendererDefaultSettings } from '../Renderer';
4
4
 
5
5
  /**
6
6
  * @jest-environment jsdom
@@ -20,6 +20,7 @@ jest.mock('three', () => {
20
20
  position: 'absolute',
21
21
  },
22
22
  };
23
+ this.dispose = jest.fn();
23
24
  this.debug = {
24
25
  checkShaderErrors: true,
25
26
  };
@@ -43,12 +44,20 @@ let renderer: DIVERenderer;
43
44
  describe('dive/renderer/DIVERenderer', () => {
44
45
  beforeEach(() => {
45
46
  jest.clearAllMocks();
46
- renderer = new DIVERenderer(DIVERendererDefaultSettings);
47
+ renderer = new DIVERenderer();
47
48
  });
48
49
 
49
50
  it('should instantiate', () => {
50
51
  expect(renderer).toBeDefined();
51
- renderer = new DIVERenderer();
52
+ });
53
+
54
+ it('should instantiate with settings parameter', () => {
55
+ renderer = new DIVERenderer(DIVERendererDefaultSettings);
56
+ expect(renderer).toBeDefined();
57
+ });
58
+
59
+ it('should dispose', () => {
60
+ renderer.Dispose();
52
61
  });
53
62
 
54
63
  it('should start render', () => {
@@ -1,5 +1,5 @@
1
- import { Color, ColorRepresentation, Object3D, Scene } from 'three';
2
- import { COMModel, COMEntity } from '../com/types';
1
+ import { Color, Scene, type Box3, type ColorRepresentation, type Object3D } from 'three';
2
+ import { type COMModel, type COMEntity } from '../com/types';
3
3
  import DIVERoot from './root/Root';
4
4
 
5
5
  /**
@@ -19,6 +19,8 @@ export default class DIVEScene extends Scene {
19
19
  constructor() {
20
20
  super();
21
21
 
22
+ this.background = new Color(0xffffff);
23
+
22
24
  this.root = new DIVERoot();
23
25
  this.add(this.root);
24
26
  }
@@ -27,6 +29,10 @@ export default class DIVEScene extends Scene {
27
29
  this.background = new Color(color);
28
30
  }
29
31
 
32
+ public ComputeSceneBB(): Box3 {
33
+ return this.Root.ComputeSceneBB();
34
+ }
35
+
30
36
  public GetSceneObject(object: Partial<COMEntity>): Object3D | undefined {
31
37
  return this.Root.GetSceneObject(object);
32
38
  }
@@ -17,6 +17,7 @@ jest.mock('../root/Root', () => {
17
17
  this.PlaceOnFloor = mock_PlaceOnFloor;
18
18
  this.GetSceneObject = mock_GetSceneObject;
19
19
  this.removeFromParent = jest.fn();
20
+ this.ComputeSceneBB = jest.fn();
20
21
  return this;
21
22
  });
22
23
  });
@@ -38,6 +39,11 @@ describe('dive/scene/DIVEScene', () => {
38
39
  expect((scene.background as Color).getHex()).toBe(0x123456);
39
40
  });
40
41
 
42
+ it('should ComputeSceneBB', () => {
43
+ const scene = new DIVEScene();
44
+ expect(() => scene.ComputeSceneBB()).not.toThrow();
45
+ });
46
+
41
47
  it('should add object', () => {
42
48
  const scene = new DIVEScene();
43
49
  scene.AddSceneObject({} as COMEntity);
@@ -1,4 +1,4 @@
1
- import { Object3D } from "three";
1
+ import { Box3, Object3D } from "three";
2
2
  import DIVELightRoot from "./lightroot/LightRoot.ts";
3
3
  import DIVEModelRoot from "./modelroot/ModelRoot.ts";
4
4
  import { COMLight, COMModel, COMEntity } from "../../com/types.ts";
@@ -39,6 +39,16 @@ export default class DIVERoot extends Object3D {
39
39
  this.add(this.grid);
40
40
  }
41
41
 
42
+ public ComputeSceneBB(): Box3 {
43
+ const bb = new Box3();
44
+ this.modelRoot.traverse((object: Object3D) => {
45
+ if ('isObject3D' in object) {
46
+ bb.expandByObject(object);
47
+ }
48
+ });
49
+ return bb;
50
+ }
51
+
42
52
  public GetSceneObject(object: Partial<COMEntity>): Object3D | undefined {
43
53
  switch (object.entityType) {
44
54
  case "pov": {
@@ -1,5 +1,6 @@
1
- import { COMLight, COMModel, COMPov } from '../../../com';
2
1
  import DIVERoot from '../Root';
2
+ import { type Vector3, type Object3D } from 'three';
3
+ import { type COMLight, type COMModel, type COMPov } from '../../../com';
3
4
 
4
5
  const mock_UpdateLight = jest.fn();
5
6
  const mock_UpdateModel = jest.fn();
@@ -9,6 +10,62 @@ const mock_DeleteLight = jest.fn();
9
10
  const mock_DeleteModel = jest.fn();
10
11
  const mock_PlaceOnFloor = jest.fn();
11
12
 
13
+ jest.mock('three', () => {
14
+ return {
15
+ Box3: jest.fn(() => {
16
+ return {
17
+ expandByObject: jest.fn(),
18
+ setFromObject: jest.fn(),
19
+ applyMatrix4: jest.fn(),
20
+ union: jest.fn(),
21
+ isEmpty: jest.fn(),
22
+ getCenter: jest.fn(),
23
+ getSize: jest.fn(),
24
+ getBoundingSphere: jest.fn(),
25
+ };
26
+ }),
27
+ Object3D: jest.fn(function () {
28
+ this.clear = jest.fn();
29
+ this.color = {};
30
+ this.intensity = 0;
31
+ this.layers = {
32
+ mask: 0,
33
+ };
34
+ this.shadow = {
35
+ radius: 0,
36
+ mapSize: { width: 0, height: 0 },
37
+ bias: 0,
38
+ camera: {
39
+ near: 0,
40
+ far: 0,
41
+ fov: 0,
42
+ },
43
+ }
44
+ this.add = jest.fn();
45
+ this.userData = {};
46
+ this.rotation = {
47
+ x: 0,
48
+ y: 0,
49
+ z: 0,
50
+ setFromVector3: jest.fn(),
51
+ };
52
+ this.scale = {
53
+ x: 1,
54
+ y: 1,
55
+ z: 1,
56
+ set: jest.fn(),
57
+ };
58
+ this.localToWorld = (vec3: Vector3) => {
59
+ return vec3;
60
+ };
61
+ this.traverse = jest.fn((callback) => {
62
+ callback(this.children[0])
63
+ });
64
+ return this;
65
+ }),
66
+ }
67
+ });
68
+
12
69
  jest.mock('../../../primitive/floor/Floor', () => {
13
70
  return jest.fn(function () {
14
71
  this.isObject3D = true;
@@ -52,6 +109,9 @@ jest.mock('../modelroot/ModelRoot', () => {
52
109
  this.PlaceOnFloor = mock_PlaceOnFloor;
53
110
  this.GetModel = mock_GetModel;
54
111
  this.removeFromParent = jest.fn();
112
+ this.traverse = jest.fn((callback: (object: Object3D) => void) => {
113
+ callback(this);
114
+ });
55
115
  return this;
56
116
  });
57
117
  });
@@ -64,7 +124,7 @@ describe('DIVE/scene/root/DIVERoot', () => {
64
124
  it('should instantiate', () => {
65
125
  const root = new DIVERoot();
66
126
  expect(root).toBeDefined();
67
- expect(root.children).toHaveLength(4);
127
+ expect(root.add).toHaveBeenCalledTimes(4);
68
128
  });
69
129
 
70
130
  it('should have Floor', () => {
@@ -77,6 +137,12 @@ describe('DIVE/scene/root/DIVERoot', () => {
77
137
  expect(root.Grid).toBeDefined();
78
138
  });
79
139
 
140
+ it('should ComputeSceneBB', () => {
141
+ const root = new DIVERoot();
142
+ const bb = root.ComputeSceneBB();
143
+ expect(bb).toBeDefined();
144
+ });
145
+
80
146
  it('should add object', () => {
81
147
  const root = new DIVERoot();
82
148
  root.AddSceneObject({ entityType: 'light' } as COMLight);
@@ -51,7 +51,7 @@ export default class DIVEModelRoot extends Object3D {
51
51
  if (object.position !== undefined) (sceneObject as Model).SetPosition(object.position);
52
52
  if (object.rotation !== undefined) (sceneObject as Model).SetRotation(object.rotation);
53
53
  if (object.scale !== undefined) (sceneObject as Model).SetScale(object.scale);
54
- if (object.visible !== undefined) (sceneObject as Model).visible = object.visible;
54
+ if (object.visible !== undefined) (sceneObject as Model).SetVisibility(object.visible);
55
55
  }
56
56
 
57
57
  public DeleteModel(object: Partial<COMModel>): void {
@@ -45,6 +45,7 @@ jest.mock('../../../../model/Model.ts', () => {
45
45
  this.SetPosition = mock_SetPosition;
46
46
  this.SetRotation = mock_SetRotation;
47
47
  this.SetScale = mock_SetScale;
48
+ this.SetVisibility = jest.fn();
48
49
  this.PlaceOnFloor = mock_PlaceOnFloor;
49
50
  this.removeFromParent = jest.fn();
50
51
  return this;
@@ -13,7 +13,7 @@ export type DraggableEvent = {
13
13
  }
14
14
 
15
15
  /* eslint-disable @typescript-eslint/no-unused-vars */
16
- export default abstract class DIVEBaseTool {
16
+ export abstract class DIVEBaseTool {
17
17
  readonly POINTER_DRAG_THRESHOLD: number = 0.001;
18
18
 
19
19
  public name: string;
@@ -258,8 +258,8 @@ export default abstract class DIVEBaseTool {
258
258
  public onWheel(e: WheelEvent): void { }
259
259
 
260
260
  protected raycast(objects?: Object3D[]): Intersection[] {
261
- if (objects !== undefined) return this._raycaster.intersectObjects(objects, true);
262
- return this._raycaster.intersectObjects(this._scene.children, true);
261
+ if (objects !== undefined) return this._raycaster.intersectObjects(objects, true).filter(i => i.object.visible);
262
+ return this._raycaster.intersectObjects(this._scene.children, true).filter(i => i.object.visible);
263
263
  }
264
264
 
265
265
  private pointerWasDragged(): boolean {
@@ -1,7 +1,9 @@
1
- import DIVEOrbitControls from "../controls/OrbitControls.ts";
2
- import DIVEScene from "../scene/Scene.ts";
3
- import DIVEBaseTool from "./BaseTool.ts";
4
- import DIVESelectTool from "./select/SelectTool.ts";
1
+ import type DIVEOrbitControls from "../controls/OrbitControls.ts";
2
+ import type DIVEScene from "../scene/Scene.ts";
3
+ import { type DIVEBaseTool } from "./BaseTool.ts";
4
+ import { type DIVESelectTool } from "./select/SelectTool.ts";
5
+
6
+ export type ToolType = 'select' | 'none';
5
7
 
6
8
  /**
7
9
  * A Toolbox to activate and deactivate tools to use with the pointer.
@@ -12,51 +14,51 @@ import DIVESelectTool from "./select/SelectTool.ts";
12
14
  export default class DIVEToolbox {
13
15
  public static readonly DefaultTool = 'select';
14
16
 
15
- private activeTool: DIVEBaseTool;
17
+ private _scene: DIVEScene;
18
+ private _controller: DIVEOrbitControls;
16
19
 
17
- private selectTool: DIVESelectTool;
20
+ private _activeTool: DIVEBaseTool | null;
18
21
 
19
- private removeListenersCallback: () => void = () => { };
22
+ private _selectTool: DIVESelectTool | null;
23
+ public get selectTool(): DIVESelectTool {
24
+ if (!this._selectTool) {
25
+ const DIVESelectTool = require('./select/SelectTool.ts').DIVESelectTool as typeof import('./select/SelectTool.ts').DIVESelectTool;
26
+ this._selectTool = new DIVESelectTool(this._scene, this._controller);
27
+ }
28
+ return this._selectTool;
29
+ }
20
30
 
21
31
  constructor(scene: DIVEScene, controller: DIVEOrbitControls) {
22
- this.selectTool = new DIVESelectTool(scene, controller);
23
-
24
- const pointerMove = this.onPointerMove.bind(this);
25
- const pointerDown = this.onPointerDown.bind(this);
26
- const pointerUp = this.onPointerUp.bind(this);
27
- const wheel = this.onWheel.bind(this);
32
+ this._scene = scene;
33
+ this._controller = controller;
28
34
 
29
- controller.domElement.addEventListener('pointermove', pointerMove);
30
- controller.domElement.addEventListener('pointerdown', pointerDown);
31
- controller.domElement.addEventListener('pointerup', pointerUp);
32
- controller.domElement.addEventListener('wheel', wheel);
33
-
34
- this.removeListenersCallback = () => {
35
- controller.domElement.removeEventListener('pointermove', pointerMove);
36
- controller.domElement.removeEventListener('pointerdown', pointerDown);
37
- controller.domElement.removeEventListener('pointerup', pointerUp);
38
- controller.domElement.removeEventListener('wheel', wheel);
39
- };
35
+ // toolset
36
+ this._selectTool = null;
40
37
 
41
38
  // default tool
42
- this.activeTool = this.selectTool;
43
- this.activeTool.Activate();
39
+ this._activeTool = null;
44
40
  }
45
41
 
46
- public dispose(): void {
47
- this.removeListenersCallback();
42
+ public Dispose(): void {
43
+ this.removeEventListeners();
48
44
  }
49
45
 
50
- public GetActiveTool(): DIVEBaseTool {
51
- return this.activeTool;
46
+ public GetActiveTool(): DIVEBaseTool | null {
47
+ return this._activeTool;
52
48
  }
53
49
 
54
- public UseTool(tool: string): void {
55
- this.activeTool.Deactivate();
50
+ public UseTool(tool: ToolType): void {
51
+ this._activeTool?.Deactivate();
56
52
  switch (tool) {
57
53
  case "select": {
54
+ this.addEventListeners();
58
55
  this.selectTool.Activate();
59
- this.activeTool = this.selectTool;
56
+ this._activeTool = this.selectTool;
57
+ break;
58
+ }
59
+ case "none": {
60
+ this.removeEventListeners();
61
+ this._activeTool = null;
60
62
  break;
61
63
  }
62
64
  default: {
@@ -69,19 +71,37 @@ export default class DIVEToolbox {
69
71
  this.selectTool.SetGizmoMode(mode);
70
72
  }
71
73
 
74
+ public SetGizmoVisibility(active: boolean): void {
75
+ this.selectTool.SetGizmoVisibility(active);
76
+ }
77
+
72
78
  public onPointerMove(e: PointerEvent): void {
73
- this.activeTool.onPointerMove(e);
79
+ this._activeTool?.onPointerMove(e);
74
80
  }
75
81
 
76
82
  public onPointerDown(e: PointerEvent): void {
77
- this.activeTool.onPointerDown(e);
83
+ this._activeTool?.onPointerDown(e);
78
84
  }
79
85
 
80
86
  public onPointerUp(e: PointerEvent): void {
81
- this.activeTool.onPointerUp(e);
87
+ this._activeTool?.onPointerUp(e);
82
88
  }
83
89
 
84
90
  public onWheel(e: WheelEvent): void {
85
- this.activeTool.onWheel(e);
91
+ this._activeTool?.onWheel(e);
92
+ }
93
+
94
+ private addEventListeners(): void {
95
+ this._controller.domElement.addEventListener('pointermove', (e) => this.onPointerMove(e));
96
+ this._controller.domElement.addEventListener('pointerdown', (e) => this.onPointerDown(e));
97
+ this._controller.domElement.addEventListener('pointerup', (e) => this.onPointerUp(e));
98
+ this._controller.domElement.addEventListener('wheel', (e) => this.onWheel(e));
99
+ }
100
+
101
+ private removeEventListeners(): void {
102
+ this._controller.domElement.removeEventListener('pointermove', (e) => this.onPointerMove(e));
103
+ this._controller.domElement.removeEventListener('pointerdown', (e) => this.onPointerDown(e));
104
+ this._controller.domElement.removeEventListener('pointerup', (e) => this.onPointerUp(e));
105
+ this._controller.domElement.removeEventListener('wheel', (e) => this.onWheel(e));
86
106
  }
87
107
  }
@@ -1,11 +1,10 @@
1
1
 
2
+ import { DIVEBaseTool } from '../BaseTool';
3
+ import type DIVEOrbitControls from '../../controls/OrbitControls';
4
+ import type DIVEScene from '../../scene/Scene';
2
5
  import { type Object3D, type Vector3 } from 'three';
3
- import DIVEOrbitControls from '../../controls/OrbitControls';
4
- import DIVEScene from '../../scene/Scene';
5
- import DIVEBaseTool from '../BaseTool';
6
- import DIVEToolbox from '../Toolbox';
7
6
  import { type DIVEHoverable } from '../../interface/Hoverable';
8
- import { DIVEDraggable } from '../../interface/Draggable';
7
+ import { type DIVEDraggable } from '../../interface/Draggable';
9
8
 
10
9
  /**
11
10
  * @jest-environment jsdom
@@ -47,8 +46,18 @@ describe('dive/toolbox/DIVEBaseTool', () => {
47
46
  });
48
47
 
49
48
  it('should instantiate', () => {
50
- const toolBox = new abstractWrapper(mockScene, mockController);
51
- expect(toolBox).toBeDefined();
49
+ const baseTool = new abstractWrapper(mockScene, mockController);
50
+ expect(baseTool).toBeDefined();
51
+ });
52
+
53
+ it('should Activate', () => {
54
+ const baseTool = new abstractWrapper(mockScene, mockController);
55
+ expect(() => baseTool.Activate()).not.toThrow();
56
+ });
57
+
58
+ it('should Deactivate', () => {
59
+ const baseTool = new abstractWrapper(mockScene, mockController);
60
+ expect(() => baseTool.Deactivate()).not.toThrow();
52
61
  });
53
62
 
54
63
  it('should raycast', () => {
@@ -63,7 +72,24 @@ describe('dive/toolbox/DIVEBaseTool', () => {
63
72
  expect(toolBox['_pointerAnyDown']).toBeDefined();
64
73
  expect(toolBox['_pointerAnyDown']).toBe(false);
65
74
 
75
+ toolBox['_pointerPrimaryDown'] = false;
76
+ toolBox['_pointerMiddleDown'] = false;
77
+ toolBox['_pointerSecondaryDown'] = false;
78
+ expect(toolBox['_pointerAnyDown']).toBe(false);
79
+
66
80
  toolBox['_pointerPrimaryDown'] = true;
81
+ toolBox['_pointerMiddleDown'] = false;
82
+ toolBox['_pointerSecondaryDown'] = false;
83
+ expect(toolBox['_pointerAnyDown']).toBe(true);
84
+
85
+ toolBox['_pointerPrimaryDown'] = false;
86
+ toolBox['_pointerMiddleDown'] = true;
87
+ toolBox['_pointerSecondaryDown'] = false;
88
+ expect(toolBox['_pointerAnyDown']).toBe(true);
89
+
90
+ toolBox['_pointerPrimaryDown'] = false;
91
+ toolBox['_pointerMiddleDown'] = false;
92
+ toolBox['_pointerSecondaryDown'] = true;
67
93
  expect(toolBox['_pointerAnyDown']).toBe(true);
68
94
  });
69
95
 
@@ -134,6 +160,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
134
160
  object: {
135
161
  uuid: 'uuid',
136
162
  isHoverable: true,
163
+ visible: true,
137
164
  } as Object3D & DIVEHoverable
138
165
  }
139
166
  ]
@@ -158,6 +185,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
158
185
  object: {
159
186
  uuid: 'uuid',
160
187
  isHoverable: true,
188
+ visible: true,
161
189
  onPointerEnter() {
162
190
  return;
163
191
  },
@@ -183,6 +211,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
183
211
  object: {
184
212
  uuid: 'uuid',
185
213
  isHoverable: true,
214
+ visible: true,
186
215
  onPointerOver() {
187
216
  return;
188
217
  }
@@ -193,6 +222,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
193
222
 
194
223
  toolBox['_hovered'] = {
195
224
  uuid: 'uuid',
225
+ visible: true,
196
226
  onPointerLeave() {
197
227
  return;
198
228
  },
@@ -215,6 +245,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
215
245
  object: {
216
246
  uuid: 'uuid2',
217
247
  isHoverable: true,
248
+ visible: true,
218
249
  onPointerEnter() {
219
250
  return;
220
251
  },
@@ -225,6 +256,7 @@ describe('dive/toolbox/DIVEBaseTool', () => {
225
256
 
226
257
  toolBox['_hovered'] = {
227
258
  uuid: 'uuid',
259
+ visible: true,
228
260
  onPointerLeave() {
229
261
  return;
230
262
  },
@@ -382,8 +414,18 @@ describe('dive/toolbox/DIVEBaseTool', () => {
382
414
  expect(() => toolBox.onDrag({} as PointerEvent)).not.toThrow();
383
415
  });
384
416
 
417
+ it('should execute onCLick correctly', () => {
418
+ const toolBox = new abstractWrapper(mockScene, mockController);
419
+ expect(() => toolBox.onClick({} as PointerEvent)).not.toThrow();
420
+ });
421
+
385
422
  it('should execute onDragEnd correctly', () => {
386
423
  const toolBox = new abstractWrapper(mockScene, mockController);
387
424
  expect(() => toolBox.onDragEnd({} as PointerEvent)).not.toThrow();
388
425
  });
426
+
427
+ it('should execute onWheel correctly', () => {
428
+ const toolBox = new abstractWrapper(mockScene, mockController);
429
+ expect(() => toolBox.onWheel({} as WheelEvent)).not.toThrow();
430
+ });
389
431
  });