@shopware-ag/dive 1.2.0 → 1.3.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.
Files changed (39) hide show
  1. package/build/dive.cjs +288 -60
  2. package/build/dive.cjs.map +1 -1
  3. package/build/dive.d.cts +64 -6
  4. package/build/dive.d.ts +64 -6
  5. package/build/dive.js +289 -61
  6. package/build/dive.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/__test__/DIVE.test.ts +2 -0
  9. package/src/com/Communication.ts +6 -3
  10. package/src/com/__test__/Communication.test.ts +3 -6
  11. package/src/com/actions/object/getobjects.ts +2 -2
  12. package/src/dive.ts +7 -0
  13. package/src/gizmo/Gizmo.ts +130 -0
  14. package/src/gizmo/handles/AxisHandle.ts +124 -0
  15. package/src/gizmo/handles/RadialHandle.ts +119 -0
  16. package/src/gizmo/handles/ScaleHandle.ts +152 -0
  17. package/src/gizmo/plane/GizmoPlane.ts +85 -0
  18. package/src/gizmo/rotate/RotateGizmo.ts +95 -0
  19. package/src/gizmo/scale/ScaleGizmo.ts +97 -0
  20. package/src/gizmo/translate/TranslateGizmo.ts +88 -0
  21. package/src/interface/Draggable.ts +34 -0
  22. package/src/interface/Hoverable.ts +33 -0
  23. package/src/interface/Moveable.ts +0 -2
  24. package/src/interface/Selectable.ts +6 -0
  25. package/src/interface/__test__/Interfaces.test.ts +56 -0
  26. package/src/math/index.ts +3 -0
  27. package/src/math/signedAngleTo/__test__/signedAngleTo.test.ts +14 -0
  28. package/src/math/signedAngleTo/signedAngleTo.ts +13 -0
  29. package/src/scene/root/lightroot/LightRoot.ts +17 -3
  30. package/src/scene/root/lightroot/__test__/LightRoot.test.ts +12 -3
  31. package/src/scene/root/modelroot/ModelRoot.ts +17 -3
  32. package/src/scene/root/modelroot/__test__/ModelRoot.test.ts +13 -14
  33. package/src/toolbox/BaseTool.ts +254 -4
  34. package/src/toolbox/Toolbox.ts +6 -0
  35. package/src/toolbox/__test__/BaseTool.test.ts +389 -0
  36. package/src/toolbox/__test__/Toolbox.test.ts +8 -0
  37. package/src/toolbox/select/SelectTool.ts +29 -65
  38. package/src/toolbox/select/__test__/SelectTool.test.ts +57 -25
  39. package/src/toolbox/transform/TransformTool.ts +48 -0
@@ -160,6 +160,8 @@ describe('dive/DIVE', () => {
160
160
  it('should instantiate', () => {
161
161
  const dive = new DIVE();
162
162
  expect(dive).toBeDefined();
163
+ expect((window as any).DIVE.PrintScene).toBeDefined();
164
+ expect(() => (window as any).DIVE.PrintScene()).not.toThrow();
163
165
  });
164
166
 
165
167
  it('should instantiate with settings', () => {
@@ -210,12 +210,15 @@ export default class DIVECommunication {
210
210
  }
211
211
 
212
212
  private getObjects(payload: Actions['GET_OBJECTS']['PAYLOAD']): Actions['GET_OBJECTS']['RETURN'] {
213
+ if (payload.ids.length === 0) return [];
214
+
215
+ const objects: COMEntity[] = [];
213
216
  this.registered.forEach((object) => {
214
- if (payload.ids && payload.ids.length > 0 && !payload.ids.includes(object.id)) return;
215
- payload.map.set(object.id, object);
217
+ if (!payload.ids.includes(object.id)) return;
218
+ objects.push(object);
216
219
  });
217
220
 
218
- return payload.map;
221
+ return objects;
219
222
  }
220
223
 
221
224
  private addObject(payload: Actions['ADD_OBJECT']['PAYLOAD']): Actions['ADD_OBJECT']['RETURN'] {
@@ -510,13 +510,10 @@ describe('dive/communication/DIVECommunication', () => {
510
510
  } as COMPov;
511
511
  testCom.PerformAction('ADD_OBJECT', mock1);
512
512
 
513
- let map = new Map([['test0', mock0], ['test1', mock1]]);
513
+ const successWithoutIds = testCom.PerformAction('GET_OBJECTS', { ids: [] });
514
+ expect(Array.from(successWithoutIds.values())).toStrictEqual([]);
514
515
 
515
- const successWithoutIds = testCom.PerformAction('GET_OBJECTS', { map });
516
- expect(successWithoutIds).toStrictEqual(map);
517
-
518
- map = new Map();
519
- const successWithIds = testCom.PerformAction('GET_OBJECTS', { map, ids: ['test1'] });
516
+ const successWithIds = testCom.PerformAction('GET_OBJECTS', { ids: ['test1'] });
520
517
  expect(Array.from(successWithIds.values())).toStrictEqual([{ entityType: "pov", id: "test1", position: { x: 0, y: 0, z: 0 }, target: { x: 0, y: 0, z: 0 } }]);
521
518
  });
522
519
 
@@ -1,6 +1,6 @@
1
1
  import { COMEntity } from "../../types.ts";
2
2
 
3
3
  export default interface GET_OBJECTS {
4
- 'PAYLOAD': { map: Map<string, COMEntity>, ids?: string[] },
5
- 'RETURN': Map<string, COMEntity>,
4
+ 'PAYLOAD': { ids: string[] },
5
+ 'RETURN': COMEntity[],
6
6
  };
package/src/dive.ts CHANGED
@@ -163,6 +163,13 @@ export default class DIVE {
163
163
 
164
164
  // whene everything is done, start the renderer
165
165
  this.renderer.StartRenderer(this.scene, this.perspectiveCamera);
166
+
167
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
+ (window as any).DIVE = {
169
+ PrintScene: () => {
170
+ console.log(this.scene);
171
+ },
172
+ }
166
173
  }
167
174
 
168
175
  // methods
@@ -0,0 +1,130 @@
1
+ import { Euler, Object3D, Vector3 } from "three";
2
+ import { DIVERotateGizmo } from "./rotate/RotateGizmo";
3
+ import { DIVETranslateGizmo } from "./translate/TranslateGizmo";
4
+ import DIVEOrbitControls from "../controls/OrbitControls";
5
+ import { DIVEScaleGizmo } from "./scale/ScaleGizmo";
6
+ import { DIVEGizmoPlane as DIVEGizmoPlane } from "./plane/GizmoPlane";
7
+ import { DIVESelectable } from "../interface/Selectable";
8
+
9
+ export type DIVEGizmoMode = ('translate' | 'rotate' | 'scale');
10
+
11
+ export type DIVEGizmoAxis = 'x' | 'y' | 'z';
12
+
13
+ export class DIVEGizmo extends Object3D {
14
+ private _mode: DIVEGizmoMode;
15
+ public get mode(): DIVEGizmoMode {
16
+ return this._mode;
17
+ }
18
+ public set mode(value: DIVEGizmoMode) {
19
+ this._mode = value;
20
+ this.assemble();
21
+ }
22
+
23
+ private _gizmoNode: Object3D;
24
+ public get gizmoNode(): Object3D {
25
+ return this._gizmoNode;
26
+ }
27
+ private _translateGizmo: DIVETranslateGizmo;
28
+ private _rotateGizmo: DIVERotateGizmo;
29
+ private _scaleGizmo: DIVEScaleGizmo;
30
+
31
+ private _gizmoPlane: DIVEGizmoPlane;
32
+ public get gizmoPlane(): DIVEGizmoPlane {
33
+ return this._gizmoPlane;
34
+ }
35
+
36
+ // attachment stuff
37
+ private _object: (Object3D & DIVESelectable) | null;
38
+ public get object(): (Object3D & DIVESelectable) | null {
39
+ return this._object;
40
+ }
41
+
42
+ constructor(controller: DIVEOrbitControls) {
43
+ super();
44
+ this.name = "DIVEGizmo";
45
+
46
+ controller.addEventListener('change', () => {
47
+ const size = controller.getDistance() / 2.5;
48
+ this.scale.set(size, size, size);
49
+ });
50
+
51
+ this._mode = 'translate';
52
+
53
+ this._gizmoNode = new Object3D();
54
+ this.add(this._gizmoNode);
55
+
56
+ this._translateGizmo = new DIVETranslateGizmo(controller);
57
+ this._rotateGizmo = new DIVERotateGizmo(controller);
58
+ this._scaleGizmo = new DIVEScaleGizmo(controller);
59
+
60
+ this._gizmoPlane = new DIVEGizmoPlane();
61
+ this._gizmoPlane.visible = false;
62
+
63
+ this._object = null;
64
+ }
65
+
66
+ public attach(object: (Object3D & DIVESelectable)): this {
67
+ this._object = object;
68
+ this.assemble();
69
+ return this;
70
+ }
71
+
72
+ public detach(): this {
73
+ this._object = null;
74
+ this.assemble();
75
+ return this;
76
+ }
77
+
78
+ public onHover(mode: DIVEGizmoMode, axis: DIVEGizmoAxis, value: boolean): void {
79
+ if (!value) return;
80
+ this._gizmoPlane.assemble(mode, axis);
81
+ }
82
+
83
+ public onChange(position?: Vector3, rotation?: Euler, scale?: Vector3): void {
84
+ if (this.object === null) return;
85
+
86
+ if (position) {
87
+ this.position.copy(position);
88
+ this.object.position.copy(position);
89
+ }
90
+
91
+ if (rotation) {
92
+ this.object.rotation.copy(rotation);
93
+ }
94
+
95
+ if (scale) {
96
+ this.object.scale.copy(scale);
97
+ this._scaleGizmo.update(scale);
98
+ }
99
+ }
100
+
101
+ private assemble(): void {
102
+ // clear all children
103
+ this._gizmoNode.clear();
104
+ this._gizmoPlane.clear();
105
+
106
+ // reset all gizmos
107
+ this._translateGizmo.reset();
108
+ this._rotateGizmo.reset();
109
+ this._scaleGizmo.reset();
110
+
111
+ // check for object
112
+ if (this.object === null) return;
113
+
114
+ // add gizmos
115
+ if (this._mode === 'translate') {
116
+ this._gizmoNode.add(this._translateGizmo);
117
+ }
118
+
119
+ if (this._mode === 'rotate') {
120
+ this._gizmoNode.add(this._rotateGizmo);
121
+ }
122
+
123
+ if (this._mode === 'scale') {
124
+ this._gizmoNode.add(this._scaleGizmo);
125
+ }
126
+
127
+ // add plane for raycasting properly while dragging
128
+ this.add(this._gizmoPlane);
129
+ }
130
+ }
@@ -0,0 +1,124 @@
1
+ import { Color, ColorRepresentation, CylinderGeometry, Mesh, MeshBasicMaterial, Object3D, Vector3 } from "three";
2
+ import { UI_LAYER_MASK } from "../../constant/VisibilityLayerMask";
3
+ import { DIVEHoverable } from "../../interface/Hoverable";
4
+ import { DIVETranslateGizmo } from "../translate/TranslateGizmo";
5
+ import { DIVEDraggable } from "../../interface/Draggable";
6
+ import { DraggableEvent } from "../../toolbox/BaseTool";
7
+
8
+ export class DIVEAxisHandle extends Object3D implements DIVEHoverable, DIVEDraggable {
9
+ readonly isHoverable: true = true;
10
+ readonly isDraggable: true = true;
11
+
12
+ public parent: DIVETranslateGizmo | null = null;
13
+
14
+ public axis: 'x' | 'y' | 'z';
15
+
16
+ private _color: Color = new Color(0xff00ff);
17
+ private _colorHover: Color;
18
+ private _hovered: boolean;
19
+ private _highlight: boolean;
20
+ public get highlight(): boolean {
21
+ return this._highlight;
22
+ }
23
+ public set highlight(highlight: boolean) {
24
+ this._highlight = highlight;
25
+ this._lineMaterial.color = this._highlight || this._hovered ? this._colorHover : this._color;
26
+ }
27
+
28
+ private _lineMaterial: MeshBasicMaterial;
29
+
30
+ public get forwardVector(): Vector3 {
31
+ return new Vector3(0, 0, 1).applyQuaternion(this.quaternion).normalize();
32
+ }
33
+
34
+ public get rightVector(): Vector3 {
35
+ return new Vector3(1, 0, 0).applyQuaternion(this.quaternion).normalize();
36
+ }
37
+
38
+ public get upVector(): Vector3 {
39
+ return new Vector3(0, 1, 0).applyQuaternion(this.quaternion).normalize();
40
+ }
41
+
42
+ constructor(axis: 'x' | 'y' | 'z', length: number, direction: Vector3, color: ColorRepresentation) {
43
+ super();
44
+
45
+ this.name = "DIVEAxisHandle";
46
+ this.axis = axis;
47
+
48
+ this._color.set(color);
49
+ this._colorHover = this._color.clone().multiplyScalar(2);
50
+
51
+ this._highlight = false;
52
+ this._hovered = false;
53
+
54
+ // create line
55
+ const lineGeo = new CylinderGeometry(0.01, 0.01, length, 13);
56
+ this._lineMaterial = new MeshBasicMaterial({
57
+ color: color,
58
+ depthTest: false,
59
+ depthWrite: false,
60
+ });
61
+ const lineMesh = new Mesh(lineGeo, this._lineMaterial);
62
+ lineMesh.layers.mask = UI_LAYER_MASK;
63
+ lineMesh.renderOrder = Infinity;
64
+ lineMesh.rotateX(Math.PI / 2);
65
+ lineMesh.translateY(length / 2);
66
+ this.add(lineMesh);
67
+
68
+ // create collider
69
+ const collider = new CylinderGeometry(0.1, 0.1, length, 3);
70
+ const colliderMaterial = new MeshBasicMaterial({
71
+ color: 0xff00ff,
72
+ transparent: true,
73
+ opacity: 0.15,
74
+ depthTest: false,
75
+ depthWrite: false,
76
+ });
77
+ const colliderMesh = new Mesh(collider, colliderMaterial);
78
+ colliderMesh.visible = false;
79
+ colliderMesh.layers.mask = UI_LAYER_MASK;
80
+ colliderMesh.renderOrder = Infinity;
81
+ colliderMesh.rotateX(Math.PI / 2);
82
+ colliderMesh.translateY(length / 2);
83
+ this.add(colliderMesh);
84
+
85
+ this.rotateX(direction.y * -Math.PI / 2);
86
+ this.rotateY(direction.x * Math.PI / 2);
87
+ }
88
+
89
+ public reset(): void {
90
+ this._lineMaterial.color = this._color;
91
+ }
92
+
93
+ public onPointerEnter(): void {
94
+ this._hovered = true;
95
+ if (this.parent) {
96
+ this.parent.onHandleHover(this, true);
97
+ }
98
+ }
99
+
100
+ public onPointerLeave(): void {
101
+ this._hovered = false;
102
+ if (this.parent) {
103
+ this.parent.onHandleHover(this, false);
104
+ }
105
+ }
106
+
107
+ public onDragStart(): void {
108
+ if (this.parent) {
109
+ this.parent.onHandleDragStart(this);
110
+ }
111
+ }
112
+
113
+ public onDrag(e: DraggableEvent): void {
114
+ if (this.parent) {
115
+ this.parent.onHandleDrag(this, e);
116
+ }
117
+ }
118
+
119
+ public onDragEnd(): void {
120
+ if (this.parent) {
121
+ this.parent.onHandleDragEnd(this);
122
+ }
123
+ }
124
+ }
@@ -0,0 +1,119 @@
1
+ import { Color, ColorRepresentation, Mesh, MeshBasicMaterial, Object3D, TorusGeometry, Vector3 } from "three";
2
+ import { UI_LAYER_MASK } from "../../constant/VisibilityLayerMask";
3
+ import { DIVEHoverable } from "../../interface/Hoverable";
4
+ import { DraggableEvent } from "../../toolbox/BaseTool";
5
+ import { DIVERotateGizmo } from "../rotate/RotateGizmo";
6
+ import { DIVEDraggable } from "../../interface/Draggable";
7
+
8
+ export class DIVERadialHandle extends Object3D implements DIVEHoverable, DIVEDraggable {
9
+ readonly isHoverable: true = true;
10
+ readonly isDraggable: true = true;
11
+
12
+ public parent: DIVERotateGizmo | null = null;
13
+
14
+ public axis: 'x' | 'y' | 'z';
15
+
16
+ private _color: Color = new Color(0xff00ff);
17
+ private _colorHover: Color;
18
+ private _hovered: boolean;
19
+ private _highlight: boolean;
20
+ public get highlight(): boolean {
21
+ return this._highlight;
22
+ }
23
+ public set highlight(highlight: boolean) {
24
+ this._highlight = highlight;
25
+ this._lineMaterial.color = this._highlight || this._hovered ? this._colorHover : this._color;
26
+ }
27
+
28
+ private _lineMaterial: MeshBasicMaterial;
29
+
30
+ public get forwardVector(): Vector3 {
31
+ return new Vector3(0, 0, 1).applyQuaternion(this.quaternion).normalize();
32
+ }
33
+
34
+ public get rightVector(): Vector3 {
35
+ return new Vector3(1, 0, 0).applyQuaternion(this.quaternion).normalize();
36
+ }
37
+
38
+ public get upVector(): Vector3 {
39
+ return new Vector3(0, 1, 0).applyQuaternion(this.quaternion).normalize();
40
+ }
41
+
42
+ constructor(axis: 'x' | 'y' | 'z', radius: number, arc: number, direction: Vector3, color: ColorRepresentation) {
43
+ super();
44
+
45
+ this.name = "DIVERadialHandle";
46
+ this.axis = axis;
47
+
48
+ this._color.set(color);
49
+ this._colorHover = this._color.clone().multiplyScalar(2);
50
+ this._hovered = false;
51
+ this._highlight = false;
52
+
53
+ // create line
54
+ const lineGeo = new TorusGeometry(radius, 0.01, 13, 48, arc);
55
+ this._lineMaterial = new MeshBasicMaterial({
56
+ color: color,
57
+ depthTest: false,
58
+ depthWrite: false,
59
+ });
60
+ const lineMesh = new Mesh(lineGeo, this._lineMaterial);
61
+ lineMesh.layers.mask = UI_LAYER_MASK;
62
+ lineMesh.renderOrder = Infinity;
63
+ this.add(lineMesh);
64
+
65
+ // create collider
66
+ const collider = new TorusGeometry(radius, 0.1, 3, 48, arc);
67
+ const colliderMaterial = new MeshBasicMaterial({
68
+ color: 0xff00ff,
69
+ transparent: true,
70
+ opacity: 0.15,
71
+ depthTest: false,
72
+ depthWrite: false,
73
+ });
74
+ const colliderMesh = new Mesh(collider, colliderMaterial);
75
+ colliderMesh.visible = false;
76
+ colliderMesh.layers.mask = UI_LAYER_MASK;
77
+ colliderMesh.renderOrder = Infinity;
78
+
79
+ this.add(colliderMesh);
80
+
81
+ this.lookAt(direction);
82
+ }
83
+
84
+ public reset(): void {
85
+ this._lineMaterial.color = this._color;
86
+ }
87
+
88
+ public onPointerEnter(): void {
89
+ this._hovered = true;
90
+ if (this.parent) {
91
+ this.parent.onHandleHover(this, true);
92
+ }
93
+ }
94
+
95
+ public onPointerLeave(): void {
96
+ this._hovered = false;
97
+ if (this.parent) {
98
+ this.parent.onHandleHover(this, false);
99
+ }
100
+ }
101
+
102
+ public onDragStart(): void {
103
+ if (this.parent) {
104
+ this.parent.onHandleDragStart(this);
105
+ }
106
+ }
107
+
108
+ public onDrag(e: DraggableEvent): void {
109
+ if (this.parent) {
110
+ this.parent.onHandleDrag(this, e);
111
+ }
112
+ }
113
+
114
+ public onDragEnd(): void {
115
+ if (this.parent) {
116
+ this.parent.onHandleDragEnd(this);
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,152 @@
1
+ import { BoxGeometry, Color, ColorRepresentation, CylinderGeometry, Mesh, MeshBasicMaterial, Object3D, Vector3 } from "three";
2
+ import { UI_LAYER_MASK } from "../../constant/VisibilityLayerMask";
3
+ import { DIVEHoverable } from "../../interface/Hoverable";
4
+ import { DIVEScaleGizmo } from "../scale/ScaleGizmo";
5
+ import { DIVEDraggable } from "../../interface/Draggable";
6
+ import { DraggableEvent } from "../../toolbox/BaseTool";
7
+
8
+ export class DIVEScaleHandle extends Object3D implements DIVEHoverable, DIVEDraggable {
9
+ readonly isHoverable: true = true;
10
+ readonly isDraggable: true = true;
11
+
12
+ public parent: DIVEScaleGizmo | null = null;
13
+
14
+ public axis: 'x' | 'y' | 'z';
15
+
16
+ private _color: Color = new Color(0xff00ff);
17
+ private _colorHover: Color;
18
+ private _hovered: boolean;
19
+ private _highlight: boolean;
20
+ public get highlight(): boolean {
21
+ return this._highlight;
22
+ }
23
+ public set highlight(highlight: boolean) {
24
+ this._highlight = highlight;
25
+ this._lineMaterial.color = this._highlight || this._hovered ? this._colorHover : this._color;
26
+ }
27
+
28
+ private _lineMaterial: MeshBasicMaterial;
29
+
30
+ private _box: Mesh;
31
+ private _boxSize: number;
32
+
33
+ public get forwardVector(): Vector3 {
34
+ return new Vector3(0, 0, 1).applyQuaternion(this.quaternion).normalize();
35
+ }
36
+
37
+ public get rightVector(): Vector3 {
38
+ return new Vector3(1, 0, 0).applyQuaternion(this.quaternion).normalize();
39
+ }
40
+
41
+ public get upVector(): Vector3 {
42
+ return new Vector3(0, 1, 0).applyQuaternion(this.quaternion).normalize();
43
+ }
44
+
45
+ constructor(axis: 'x' | 'y' | 'z', length: number, direction: Vector3, color: ColorRepresentation, boxSize: number = 0.05) {
46
+ super();
47
+
48
+ this.name = "DIVEScaleHandle";
49
+ this.axis = axis;
50
+
51
+ this._color.set(color);
52
+ this._colorHover = this._color.clone().multiplyScalar(2);
53
+ this._hovered = false;
54
+ this._highlight = false;
55
+
56
+ this._boxSize = boxSize;
57
+
58
+ // create line
59
+ const lineGeo = new CylinderGeometry(0.01, 0.01, length - boxSize / 2, 13);
60
+ this._lineMaterial = new MeshBasicMaterial({
61
+ color: color,
62
+ depthTest: false,
63
+ depthWrite: false,
64
+ });
65
+ const lineMesh = new Mesh(lineGeo, this._lineMaterial);
66
+ lineMesh.layers.mask = UI_LAYER_MASK;
67
+ lineMesh.renderOrder = Infinity;
68
+ lineMesh.rotateX(Math.PI / 2);
69
+ lineMesh.translateY(length / 2 - boxSize / 4);
70
+ this.add(lineMesh);
71
+
72
+ // create box
73
+ this._box = new Mesh(
74
+ new BoxGeometry(boxSize, boxSize, boxSize),
75
+ this._lineMaterial,
76
+ );
77
+ this._box.layers.mask = UI_LAYER_MASK;
78
+ this._box.renderOrder = Infinity;
79
+ this._box.rotateX(Math.PI / 2);
80
+ this._box.translateY(length - boxSize / 2);
81
+ this._box.rotateZ(direction.x * Math.PI / 2);
82
+ this._box.rotateX(direction.z * Math.PI / 2);
83
+ this.add(this._box);
84
+
85
+ // create collider
86
+ const collider = new CylinderGeometry(0.1, 0.1, length + boxSize / 2, 3);
87
+ const colliderMaterial = new MeshBasicMaterial({
88
+ color: 0xff00ff,
89
+ transparent: true,
90
+ opacity: 0.15,
91
+ depthTest: false,
92
+ depthWrite: false,
93
+ });
94
+ const colliderMesh = new Mesh(collider, colliderMaterial);
95
+ colliderMesh.visible = false;
96
+ colliderMesh.layers.mask = UI_LAYER_MASK;
97
+ colliderMesh.renderOrder = Infinity;
98
+ colliderMesh.rotateX(Math.PI / 2);
99
+ colliderMesh.translateY(length / 2);
100
+ this.add(colliderMesh);
101
+
102
+ this.rotateX(direction.y * -Math.PI / 2);
103
+ this.rotateY(direction.x * Math.PI / 2);
104
+ }
105
+
106
+ public reset(): void {
107
+ this._lineMaterial.color = this._color;
108
+ }
109
+
110
+ public update(scale: Vector3): void {
111
+ this._box.scale.copy(
112
+ new Vector3(1, 1, 1) // identity scale ...
113
+ .sub(this.forwardVector) // subtracted the forward vector ...
114
+ .add( // to then add ...
115
+ scale.clone() // the scale ...
116
+ .multiply(this.forwardVector) // that is scaled by the forward vector again to get the forward vector as the only direction
117
+ )
118
+ );
119
+ }
120
+
121
+ public onPointerEnter(): void {
122
+ this._hovered = true;
123
+ if (this.parent) {
124
+ this.parent.onHoverAxis(this, true);
125
+ }
126
+ }
127
+
128
+ public onPointerLeave(): void {
129
+ this._hovered = false;
130
+ if (this.parent) {
131
+ this.parent.onHoverAxis(this, false);
132
+ }
133
+ }
134
+
135
+ public onDragStart(): void {
136
+ if (this.parent) {
137
+ this.parent.onAxisDragStart(this);
138
+ }
139
+ }
140
+
141
+ public onDrag(e: DraggableEvent): void {
142
+ if (this.parent) {
143
+ this.parent.onAxisDrag(this, e);
144
+ }
145
+ }
146
+
147
+ public onDragEnd(): void {
148
+ if (this.parent) {
149
+ this.parent.onAxisDragEnd(this);
150
+ }
151
+ }
152
+ }
@@ -0,0 +1,85 @@
1
+ import { Mesh, MeshBasicMaterial, Object3D, PlaneGeometry } from "three";
2
+ import { UI_LAYER_MASK } from "../../constant/VisibilityLayerMask";
3
+ import { DIVEGizmoAxis, DIVEGizmoMode } from "../Gizmo";
4
+
5
+ export class DIVEGizmoPlane extends Object3D {
6
+ private _meshX: Mesh;
7
+ public get XPlane(): Mesh {
8
+ return this._meshX;
9
+ }
10
+ private _meshY: Mesh;
11
+ public get YPlane(): Mesh {
12
+ return this._meshY;
13
+ }
14
+ private _meshZ: Mesh;
15
+ public get ZPlane(): Mesh {
16
+ return this._meshZ;
17
+ }
18
+
19
+ constructor() {
20
+ super();
21
+ this.name = "DIVEGizmoPlane";
22
+
23
+ const material = new MeshBasicMaterial({
24
+ transparent: true,
25
+ opacity: 0.15,
26
+ depthTest: false,
27
+ depthWrite: false,
28
+ side: 2,
29
+ });
30
+
31
+ const geoX = new PlaneGeometry(100, 100, 2, 2);
32
+ const matX = material.clone();
33
+ matX.color.set(0xff0000);
34
+ this._meshX = new Mesh(geoX, matX);
35
+ this._meshX.layers.mask = UI_LAYER_MASK;
36
+ this._meshX.rotateY(Math.PI / 2);
37
+
38
+ const geoY = new PlaneGeometry(100, 100, 2, 2);
39
+ const matY = material.clone();
40
+ matY.color.set(0x00ff00);
41
+ this._meshY = new Mesh(geoY, matY);
42
+ this._meshY.layers.mask = UI_LAYER_MASK;
43
+ this._meshY.rotateX(-Math.PI / 2);
44
+
45
+ const geoZ = new PlaneGeometry(100, 100, 2, 2);
46
+ const matZ = material.clone();
47
+ matZ.color.set(0x0000ff);
48
+ this._meshZ = new Mesh(geoZ, matZ);
49
+ this._meshZ.layers.mask = UI_LAYER_MASK;
50
+ }
51
+
52
+ public assemble(mode: DIVEGizmoMode, axis: DIVEGizmoAxis): void {
53
+ this.clear();
54
+
55
+ if (mode === 'translate' || mode === 'scale') {
56
+ switch (axis) {
57
+ case 'x':
58
+ this.add(this._meshY);
59
+ this.add(this._meshZ);
60
+ break;
61
+ case 'y':
62
+ this.add(this._meshX);
63
+ this.add(this._meshZ);
64
+ break;
65
+ case 'z':
66
+ this.add(this._meshX);
67
+ this.add(this._meshY);
68
+ break;
69
+ }
70
+ } else if (mode === 'rotate') {
71
+ switch (axis) {
72
+ case 'x':
73
+ this.add(this._meshX);
74
+ break;
75
+ case 'y':
76
+ this.add(this._meshY);
77
+ break;
78
+ case 'z':
79
+ this.add(this._meshZ);
80
+ break;
81
+ }
82
+ }
83
+
84
+ }
85
+ }