@shapediver/viewer.features.drawing-tools 3.3.4 → 3.3.7

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/dist/business/implementation/managers/geometry/GeometryState.d.ts.map +1 -1
  2. package/dist/business/implementation/managers/geometry/GeometryState.js +4 -1
  3. package/dist/business/implementation/managers/geometry/GeometryState.js.map +1 -1
  4. package/package.json +12 -13
  5. package/src/api/implementation/DrawingToolsApi.ts +0 -130
  6. package/src/api/implementation/restrictions/AbstractRestrictionApi.ts +0 -34
  7. package/src/api/implementation/restrictions/AbstractSnapRestrictionApi.ts +0 -36
  8. package/src/api/implementation/restrictions/geometry/GeometryRestrictionApi.ts +0 -56
  9. package/src/api/implementation/restrictions/plane/PlaneRestrictionApi.ts +0 -70
  10. package/src/api/implementation/restrictions/plane/snap/AngularRestrictionApi.ts +0 -35
  11. package/src/api/implementation/restrictions/plane/snap/AxisRestrictionApi.ts +0 -19
  12. package/src/api/implementation/restrictions/plane/snap/GridRestrictionApi.ts +0 -35
  13. package/src/api/interfaces/IDrawingToolsApi.ts +0 -98
  14. package/src/api/interfaces/IRestrictionApi.ts +0 -15
  15. package/src/api/interfaces/ISnapRestrictionApi.ts +0 -18
  16. package/src/business/implementation/DrawingToolsManager.ts +0 -618
  17. package/src/business/implementation/managers/HistoryManager.ts +0 -101
  18. package/src/business/implementation/managers/TextVisualizationManager.ts +0 -269
  19. package/src/business/implementation/managers/geometry/GeometryManager.ts +0 -95
  20. package/src/business/implementation/managers/geometry/GeometryMathManager.ts +0 -289
  21. package/src/business/implementation/managers/geometry/GeometryState.ts +0 -436
  22. package/src/business/implementation/managers/geometry/helpers/GeometryManagerHelper.ts +0 -170
  23. package/src/business/implementation/managers/interaction/EventManager.ts +0 -80
  24. package/src/business/implementation/managers/interaction/InteractionManager.ts +0 -268
  25. package/src/business/implementation/managers/interaction/RestrictionManager.ts +0 -132
  26. package/src/business/implementation/managers/interaction/handlers/DeletionInteractionHandler.ts +0 -48
  27. package/src/business/implementation/managers/interaction/handlers/InsertionInteractionHandler.ts +0 -149
  28. package/src/business/implementation/managers/interaction/handlers/MidPointInteractionHandler.ts +0 -127
  29. package/src/business/implementation/managers/interaction/helpers/InteractionManagerHelper.ts +0 -411
  30. package/src/business/implementation/managers/interaction/restrictions/AbstractRestriction.ts +0 -99
  31. package/src/business/implementation/managers/interaction/restrictions/geometry/GeometryRestriction.ts +0 -237
  32. package/src/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.ts +0 -337
  33. package/src/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.ts +0 -394
  34. package/src/business/implementation/managers/interaction/restrictions/plane/snap/AxisRestriction.ts +0 -116
  35. package/src/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.ts +0 -246
  36. package/src/business/implementation/utils/numberCleaner.ts +0 -5
  37. package/src/business/interfaces/IDrawingToolsManager.ts +0 -312
  38. package/src/business/interfaces/IManager.ts +0 -7
  39. package/src/business/interfaces/IRestriction.ts +0 -63
  40. package/src/business/interfaces/IRestrictionBase.ts +0 -33
  41. package/src/business/interfaces/ISnapRestriction.ts +0 -70
  42. package/src/business/interfaces/events/EventResponseMapping.ts +0 -19
  43. package/src/business/interfaces/events/IDrawingToolsEvent.ts +0 -16
  44. package/src/index.ts +0 -72
  45. package/src/three/CSS2DRenderer.ts +0 -212
  46. package/tsconfig.json +0 -17
@@ -1,237 +0,0 @@
1
- import * as THREE from 'three';
2
- import { AbstractRestriction } from '../AbstractRestriction';
3
- import { DrawingToolsManager } from '../../../../DrawingToolsManager';
4
- import { GeometryMathManager } from '../../../geometry/GeometryMathManager';
5
- import { IRay, IViewportApi } from '@shapediver/viewer.features.interaction';
6
- import { IRestriction, RestrictionMetaData, RestrictionProperties } from '../../../../../interfaces/IRestriction';
7
- import { ISnapRestriction } from '../../../../../interfaces/ISnapRestriction';
8
- import { ITreeNode } from '@shapediver/viewer.shared.node-tree';
9
- import { Settings } from '../../../../../interfaces/IDrawingToolsManager';
10
- import { vec3 } from 'gl-matrix';
11
-
12
- // #region Type aliases (1)
13
-
14
- export type GeometryRestrictionProperties = {
15
- /**
16
- * The nodes to restrict the interaction to.
17
- */
18
- nodes: ITreeNode[];
19
- /**
20
- * If the geometry should be displayed as wireframe.
21
- */
22
- wireframe?: boolean;
23
- /**
24
- * The color of the wireframe.
25
- */
26
- wireframeColor?: string;
27
- } & RestrictionProperties;
28
-
29
- // #endregion Type aliases (1)
30
-
31
- // #region Classes (1)
32
-
33
- export class GeometryRestriction extends AbstractRestriction implements IRestriction {
34
- // #region Properties (10)
35
-
36
- readonly #raycaster = new THREE.Raycaster();
37
- readonly #viewport: IViewportApi;
38
-
39
- #geometryMathManager: GeometryMathManager;
40
- #nodes: ITreeNode[] = [];
41
- #settings: Settings;
42
- #snapRestrictions: { [key: string]: ISnapRestriction; } = {};
43
- #snapToEdges: boolean = true;
44
- #snapToFaces: boolean = true;
45
- #snapToVertices: boolean = true;
46
- #visualizationObject: THREE.Object3D = new THREE.Object3D();
47
- #wireframe: boolean;
48
- #wireframeColor: string;
49
-
50
- // #endregion Properties (10)
51
-
52
- // #region Constructors (1)
53
-
54
- constructor(drawingToolsManager: DrawingToolsManager, id: string, properties: GeometryRestrictionProperties) {
55
- super(drawingToolsManager, id);
56
- this.#viewport = drawingToolsManager.viewport;
57
- this.#settings = drawingToolsManager.settings;
58
- this.#geometryMathManager = drawingToolsManager.geometryMathManager;
59
- this.#wireframe = properties.wireframe ?? true;
60
- this.#wireframeColor = properties.wireframeColor ?? this.#settings.visualization.points.color_1 as string;
61
-
62
- this.updateNodes(properties.nodes);
63
- }
64
-
65
- // #endregion Constructors (1)
66
-
67
- // #region Public Getters And Setters (8)
68
-
69
- public get priority(): number {
70
- return 0;
71
- }
72
-
73
- public get snapRestrictions(): { [key: string]: ISnapRestriction; } {
74
- return this.#snapRestrictions;
75
- }
76
-
77
- public get snapToEdges(): boolean {
78
- return this.#snapToEdges;
79
- }
80
-
81
- public set snapToEdges(value: boolean) {
82
- this.#snapToEdges = value;
83
- }
84
-
85
- public get snapToFaces(): boolean {
86
- return this.#snapToFaces;
87
- }
88
-
89
- public set snapToFaces(value: boolean) {
90
- this.#snapToFaces = value;
91
- }
92
-
93
- public get snapToVertices(): boolean {
94
- return this.#snapToVertices;
95
- }
96
-
97
- public set snapToVertices(value: boolean) {
98
- this.#snapToVertices = value;
99
- }
100
-
101
- // #endregion Public Getters And Setters (8)
102
-
103
- // #region Public Methods (2)
104
-
105
- public rayTrace(ray: IRay, metaData?: RestrictionMetaData): vec3 | undefined {
106
- if (this.enabled === false) return;
107
- if (this.#snapToVertices === false && this.#snapToEdges === false && this.#snapToFaces === false) return;
108
-
109
- this.#raycaster.ray.direction.set(ray.direction[0], ray.direction[1], ray.direction[2]);
110
- this.#raycaster.ray.origin.set(ray.origin[0], ray.origin[1], ray.origin[2]);
111
-
112
- // intersect all nodes
113
- let intersections: THREE.Intersection[] = [];
114
- this.#nodes.forEach(node => {
115
- const threeJsObject = node.convertedObject[this.#viewport.id] as THREE.Object3D;
116
- if (threeJsObject) {
117
- const currentIntersections = this.#raycaster.intersectObject(threeJsObject);
118
- intersections = intersections.concat(currentIntersections);
119
- }
120
- });
121
-
122
- // sort
123
- intersections.sort((a, b) => a.distance - b.distance);
124
-
125
- // return first intersection
126
- if (intersections.length > 0) {
127
- const object = intersections[0].object as THREE.Mesh;
128
- const geometry = object.geometry;
129
- const positionAttribute = geometry.getAttribute('position');
130
- const intersectionPoint = intersections[0].point;
131
- const intersectionPointVec3 = vec3.fromValues(intersectionPoint.x, intersectionPoint.y, intersectionPoint.z);
132
-
133
- if (!intersections[0].face) return vec3.fromValues(intersectionPoint.x, intersectionPoint.y, intersectionPoint.z);
134
-
135
- if (this.#snapToVertices === true || this.#snapToEdges === true) {
136
- const vertexA = new THREE.Vector3();
137
- vertexA.fromBufferAttribute(positionAttribute, intersections[0].face!.a);
138
- object.localToWorld(vertexA);
139
- const vertexAVec3 = vec3.fromValues(vertexA.x, vertexA.y, vertexA.z);
140
-
141
- const vertexB = new THREE.Vector3();
142
- vertexB.fromBufferAttribute(positionAttribute, intersections[0].face!.b);
143
- object.localToWorld(vertexB);
144
- const vertexBVec3 = vec3.fromValues(vertexB.x, vertexB.y, vertexB.z);
145
-
146
- const vertexC = new THREE.Vector3();
147
- vertexC.fromBufferAttribute(positionAttribute, intersections[0].face!.c);
148
- object.localToWorld(vertexC);
149
- const vertexCVec3 = vec3.fromValues(vertexC.x, vertexC.y, vertexC.z);
150
-
151
- if (this.#snapToVertices === true) {
152
- const distanceA = this.#geometryMathManager.screenSpaceDistanceCheck(intersectionPointVec3, vertexAVec3, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
153
- const distanceB = this.#geometryMathManager.screenSpaceDistanceCheck(intersectionPointVec3, vertexBVec3, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
154
- const distanceC = this.#geometryMathManager.screenSpaceDistanceCheck(intersectionPointVec3, vertexCVec3, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
155
-
156
- // part 1 - check if the intersection point is close to a vertex
157
- if (distanceA.check && distanceA.distanceSquared < distanceB.distanceSquared && distanceA.distanceSquared < distanceC.distanceSquared) {
158
- return vec3.fromValues(vertexA.x, vertexA.y, vertexA.z);
159
- } else if (distanceB.check && distanceB.distanceSquared < distanceA.distanceSquared && distanceB.distanceSquared < distanceC.distanceSquared) {
160
- return vec3.fromValues(vertexB.x, vertexB.y, vertexB.z);
161
- } else if (distanceC.check && distanceC.distanceSquared < distanceA.distanceSquared && distanceC.distanceSquared < distanceB.distanceSquared) {
162
- return vec3.fromValues(vertexC.x, vertexC.y, vertexC.z);
163
- }
164
- }
165
-
166
- if (this.#snapToEdges === true) {
167
- // part 2 - check if the intersection point is close to an edge
168
-
169
- // create the closest points on the edges
170
- const closestPointOnEdgeAB = this.#geometryMathManager.closestPointOnLine(vertexAVec3, vertexBVec3, intersectionPointVec3);
171
- const closestPointOnEdgeBC = this.#geometryMathManager.closestPointOnLine(vertexBVec3, vertexCVec3, intersectionPointVec3);
172
- const closestPointOnEdgeCA = this.#geometryMathManager.closestPointOnLine(vertexCVec3, vertexAVec3, intersectionPointVec3);
173
-
174
- // create the distances
175
- const distanceAB = this.#geometryMathManager.screenSpaceDistanceCheck(intersectionPointVec3, closestPointOnEdgeAB, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
176
- const distanceBC = this.#geometryMathManager.screenSpaceDistanceCheck(intersectionPointVec3, closestPointOnEdgeBC, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
177
- const distanceCA = this.#geometryMathManager.screenSpaceDistanceCheck(intersectionPointVec3, closestPointOnEdgeCA, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
178
-
179
- // check if the intersection point is close to an edge
180
- if (distanceAB.check && distanceAB.distanceSquared < distanceBC.distanceSquared && distanceAB.distanceSquared < distanceCA.distanceSquared) {
181
- return closestPointOnEdgeAB;
182
- } else if (distanceBC.check && distanceBC.distanceSquared < distanceAB.distanceSquared && distanceBC.distanceSquared < distanceCA.distanceSquared) {
183
- return closestPointOnEdgeBC;
184
- } else if (distanceCA.check && distanceCA.distanceSquared < distanceAB.distanceSquared && distanceCA.distanceSquared < distanceBC.distanceSquared) {
185
- return closestPointOnEdgeCA;
186
- }
187
- }
188
- }
189
-
190
- if (this.#snapToFaces === true) {
191
- // part 3 - face intersection
192
- return vec3.fromValues(intersectionPoint.x, intersectionPoint.y, intersectionPoint.z);
193
- }
194
- }
195
-
196
- return;
197
- }
198
-
199
- public updateNodes(nodes: ITreeNode[]) {
200
- this.#nodes = nodes;
201
-
202
- if (this.#wireframe) {
203
- this.#visualizationObject.traverse((object) => {
204
- if (object instanceof THREE.LineSegments) {
205
- object.geometry.dispose();
206
- object.material.dispose();
207
- }
208
- });
209
- this._object3D.remove(this.#visualizationObject);
210
-
211
- this.#visualizationObject = new THREE.Object3D();
212
- this.#nodes.forEach(node => {
213
- const threeJsObject = node.convertedObject[this.#viewport.id] as THREE.Object3D;
214
- if (threeJsObject) {
215
- threeJsObject.traverse((object) => {
216
- if (object instanceof THREE.Mesh) {
217
- const wireframe = new THREE.WireframeGeometry(object.geometry);
218
- const line = new THREE.LineSegments(wireframe, new THREE.LineBasicMaterial({ color: new THREE.Color(this.#wireframeColor) }));
219
- this.#visualizationObject.add(line);
220
- }
221
- });
222
- }
223
- });
224
- this._object3D.add(this.#visualizationObject);
225
- }
226
- }
227
-
228
- // #endregion Public Methods (2)
229
-
230
- // #region Protected Methods (1)
231
-
232
- protected visibilityChanged(): void { }
233
-
234
- // #endregion Protected Methods (1)
235
- }
236
-
237
- // #endregion Classes (1)
@@ -1,337 +0,0 @@
1
- import { AbstractRestriction } from '../AbstractRestriction';
2
- import { AngularRestriction, AngularRestrictionProperties } from './snap/AngularRestriction';
3
- import { AxisRestriction, AxisRestrictionProperties } from './snap/AxisRestriction';
4
- import {
5
- CAMERA_TYPE,
6
- ICameraApi,
7
- IOrthographicCameraApi,
8
- ORTHOGRAPHIC_CAMERA_DIRECTION
9
- } from '@shapediver/viewer';
10
- import { DrawingToolsManager } from '../../../../DrawingToolsManager';
11
- import { GridRestriction, GridRestrictionProperties } from './snap/GridRestriction';
12
- import { IRay, IViewportApi } from '@shapediver/viewer.features.interaction';
13
- import { IRestriction, RestrictionMetaData, RestrictionProperties } from '../../../../../interfaces/IRestriction';
14
- import { ISnapRestriction } from '../../../../../interfaces/ISnapRestriction';
15
- import { mat4, vec3 } from 'gl-matrix';
16
- import { UuidGenerator } from '@shapediver/viewer.shared.services';
17
-
18
- // #region Type aliases (1)
19
-
20
- export type PlaneRestrictionProperties = {
21
- /**
22
- * The origin of the plane.
23
- *
24
- * @default vec3.fromValues(0, 0, 0)
25
- */
26
- origin?: vec3
27
-
28
- /**
29
- * Vector U of the plane
30
- * with the cross product of vector_u and vector_v the normal of the plane can be calculated
31
- */
32
- vector_u?: vec3;
33
-
34
- /**
35
- * Vector V of the plane
36
- * with the cross product of vector_u and vector_v the normal of the plane can be calculated
37
- */
38
- vector_v?: vec3;
39
-
40
- /**
41
- * grid snap restriction
42
- */
43
- gridSnapRestriction?: GridRestrictionProperties;
44
-
45
- /**
46
- * angular snap restriction
47
- */
48
- angularSnapRestriction?: AngularRestrictionProperties;
49
-
50
- /**
51
- * axis snap restriction
52
- */
53
- axisSnapRestriction?: AxisRestrictionProperties;
54
- } & RestrictionProperties;
55
-
56
- // #endregion Type aliases (1)
57
-
58
- // #region Classes (1)
59
-
60
- export class PlaneRestriction extends AbstractRestriction implements IRestriction {
61
- // #region Properties (14)
62
-
63
- readonly #properties: PlaneRestrictionProperties;
64
- readonly #uuidGenerator = UuidGenerator.instance;
65
- readonly #viewport: IViewportApi;
66
-
67
- #angularRestriction: AngularRestriction;
68
- #axisRestriction: AxisRestriction;
69
- #cameraId: string = '';
70
- #gridRestriction: GridRestriction;
71
- #normal: vec3 = vec3.create();
72
- #origin: vec3 = vec3.create();
73
- #snapRestrictions: { [key: string]: ISnapRestriction };
74
- #transformationFromXYPlaneMatrix: mat4 = mat4.create();
75
- #transformationToXYPlaneMatrix: mat4 = mat4.create();
76
- #vectorU: vec3 = vec3.create();
77
- #vectorV: vec3 = vec3.create();
78
-
79
- // #endregion Properties (14)
80
-
81
- // #region Constructors (1)
82
-
83
- constructor(drawingToolsManager: DrawingToolsManager, id: string, properties: PlaneRestrictionProperties) {
84
- super(drawingToolsManager, id);
85
-
86
- this.#viewport = drawingToolsManager.viewport;
87
- this.#cameraId = this.#viewport.camera!.id;
88
-
89
- this.#properties = properties;
90
-
91
- this.#gridRestriction = new GridRestriction(drawingToolsManager, this, this.#properties.gridSnapRestriction);
92
- this.#angularRestriction = new AngularRestriction(drawingToolsManager, this, this.#properties.angularSnapRestriction);
93
- this.#axisRestriction = new AxisRestriction(drawingToolsManager, this, this.#properties.axisSnapRestriction);
94
-
95
- this.updatePlaneDefinition();
96
-
97
- this.#snapRestrictions = {
98
- grid: this.#gridRestriction,
99
- angular: this.#angularRestriction,
100
- axis: this.#axisRestriction
101
- };
102
- }
103
-
104
- // #endregion Constructors (1)
105
-
106
- // #region Public Getters And Setters (14)
107
-
108
- public get angularRestriction(): AngularRestriction {
109
- return this.#angularRestriction;
110
- }
111
-
112
- public get axisRestriction(): AxisRestriction {
113
- return this.#axisRestriction;
114
- }
115
-
116
- public get gridRestriction(): GridRestriction {
117
- return this.#gridRestriction;
118
- }
119
-
120
- public get normal(): vec3 {
121
- return this.#normal;
122
- }
123
-
124
- public get origin(): vec3 {
125
- return this.#origin;
126
- }
127
-
128
- public set origin(value: vec3) {
129
- this.#origin = value;
130
- this.updatePlaneDefinition();
131
- }
132
-
133
- public get priority(): number {
134
- return -1;
135
- }
136
-
137
- public get snapRestrictions(): { [key: string]: ISnapRestriction; } {
138
- return this.#snapRestrictions;
139
- }
140
-
141
- public get transformationFromXYPlaneMatrix(): mat4 {
142
- return this.#transformationFromXYPlaneMatrix;
143
- }
144
-
145
- public get transformationToXYPlaneMatrix(): mat4 {
146
- return this.#transformationToXYPlaneMatrix;
147
- }
148
-
149
- public get vectorU(): vec3 {
150
- return this.#vectorU;
151
- }
152
-
153
- public set vectorU(value: vec3) {
154
- this.#properties.vector_u = value;
155
- this.updatePlaneDefinition();
156
- }
157
-
158
- public get vectorV(): vec3 {
159
- return this.#vectorV;
160
- }
161
-
162
- public set vectorV(value: vec3) {
163
- this.#properties.vector_v = value;
164
- this.updatePlaneDefinition();
165
- }
166
-
167
- // #endregion Public Getters And Setters (14)
168
-
169
- // #region Public Methods (1)
170
-
171
- public rayTrace(ray: IRay, metaData?: RestrictionMetaData): vec3 | undefined {
172
- if (this.enabled === false) return vec3.create();
173
-
174
- if (this.#cameraId !== this.#viewport.camera!.id) this.updatePlaneDefinition();
175
-
176
- let origin = this.#origin;
177
- if (metaData?.referencePoint)
178
- origin = vec3.sub(vec3.create(), this.#origin, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), this.#origin, metaData.referencePoint), this.#normal)));
179
-
180
- // find intersection of ray and plane
181
- const t = (vec3.dot(origin, this.#normal) - vec3.dot(ray.origin, this.#normal)) / vec3.dot(ray.direction, this.#normal);
182
- const intersection = vec3.add(vec3.create(), ray.origin, vec3.multiply(vec3.create(), ray.direction, vec3.fromValues(t, t, t)));
183
- return this.snap(ray, intersection, metaData);
184
- }
185
-
186
- // #endregion Public Methods (1)
187
-
188
- // #region Protected Methods (1)
189
-
190
- protected visibilityChanged(): void { }
191
-
192
- // #endregion Protected Methods (1)
193
-
194
- // #region Private Methods (4)
195
-
196
- private createDefaultPlane(camera: ICameraApi): void {
197
- if (camera.type === CAMERA_TYPE.PERSPECTIVE ||
198
- (camera.type === CAMERA_TYPE.ORTHOGRAPHIC && (camera as IOrthographicCameraApi).direction === ORTHOGRAPHIC_CAMERA_DIRECTION.CUSTOM)) {
199
- this.#vectorU = vec3.fromValues(1, 0, 0);
200
- this.#vectorV = vec3.fromValues(0, 1, 0);
201
- this.#normal = vec3.fromValues(0, 0, 1);
202
- this.#origin = vec3.fromValues(0, 0, 0);
203
- } else {
204
- const orthographicCamera = camera as IOrthographicCameraApi;
205
- const direction = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), orthographicCamera.target, orthographicCamera.position));
206
- const up =
207
- orthographicCamera.direction === ORTHOGRAPHIC_CAMERA_DIRECTION.TOP || orthographicCamera.direction === ORTHOGRAPHIC_CAMERA_DIRECTION.BOTTOM ?
208
- vec3.fromValues(0, 1, 0) : vec3.fromValues(0, 0, 1);
209
-
210
- this.#origin = vec3.fromValues(0, 0, 0);
211
- this.#normal = vec3.negate(vec3.create(), direction);
212
- this.#vectorU = vec3.clone(up);
213
- this.#vectorV = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), this.#normal, this.#vectorU));
214
- }
215
- }
216
-
217
- private createTransformationMatrices(): void {
218
- // Calculate the transformation matrix for the rotation
219
- const rotationMatrix = mat4.fromValues(
220
- this.#vectorU[0], this.#vectorV[0], this.#normal[0], 0,
221
- this.#vectorU[1], this.#vectorV[1], this.#normal[1], 0,
222
- this.#vectorU[2], this.#vectorV[2], this.#normal[2], 0,
223
- 0, 0, 0, 1
224
- );
225
-
226
- let rotationMatrixInverse = mat4.invert(mat4.create(), rotationMatrix);
227
- if (!rotationMatrixInverse)
228
- rotationMatrixInverse = mat4.create();
229
-
230
- const pivotMatrix = mat4.fromTranslation(mat4.create(), vec3.fromValues(this.#origin[0], this.#origin[1], this.#origin[2]));
231
- const pivotMatrixInverse = mat4.fromTranslation(mat4.create(), vec3.fromValues(-this.#origin[0], -this.#origin[1], -this.#origin[2]));
232
-
233
- mat4.multiply(this.#transformationToXYPlaneMatrix, pivotMatrix, rotationMatrix);
234
- mat4.multiply(this.#transformationToXYPlaneMatrix, this.#transformationToXYPlaneMatrix, pivotMatrixInverse);
235
-
236
- mat4.multiply(this.#transformationFromXYPlaneMatrix, pivotMatrix, rotationMatrixInverse);
237
- mat4.multiply(this.#transformationFromXYPlaneMatrix, this.#transformationFromXYPlaneMatrix, pivotMatrixInverse);
238
- }
239
-
240
- private snap(ray: IRay, point: vec3, metaData?: RestrictionMetaData): vec3 | undefined {
241
- if (this.enabled === false) return;
242
-
243
- if (this.#cameraId !== this.#viewport.camera!.id) this.updatePlaneDefinition();
244
-
245
- const sortedSnapRestrictions = Object.values(this.#snapRestrictions).sort((a, b) => b.priority - a.priority);
246
-
247
- // group snap restrictions by priority
248
- const groupedSnapRestrictions: { [key: number]: ISnapRestriction[] } = {};
249
- for (const snapRestriction of sortedSnapRestrictions) {
250
- if (!groupedSnapRestrictions[snapRestriction.priority]) groupedSnapRestrictions[snapRestriction.priority] = [];
251
- groupedSnapRestrictions[snapRestriction.priority].push(snapRestriction);
252
- }
253
-
254
- // call snap method for each group
255
- for (const snapRestrictions of Object.values(groupedSnapRestrictions)) {
256
- const results = [];
257
- for (const snapRestriction of snapRestrictions) {
258
- results.push(snapRestriction.snap(ray, point, metaData));
259
- }
260
-
261
- const indexedResults = results.map((value, index) => ({ index, value }));
262
-
263
- // find the result that is closest to the point and set the snap restriction to active
264
- indexedResults.sort((a, b) => {
265
- if (!a.value) return 1;
266
- if (!b.value) return -1;
267
- return vec3.squaredDistance(point, a.value) - vec3.squaredDistance(point, b.value);
268
- });
269
-
270
- for (const snapRestriction of snapRestrictions) {
271
- snapRestriction.active = false;
272
- }
273
-
274
- // if a snap restriction returned a result, return it
275
- if (indexedResults[0].value !== undefined) {
276
- snapRestrictions[indexedResults[0].index].active = true;
277
- return indexedResults[0].value;
278
- }
279
- }
280
-
281
- return point;
282
- }
283
-
284
- private updatePlaneDefinition(): void {
285
- const camera = this.#viewport.camera!;
286
- this.#cameraId = camera!.id;
287
-
288
- const origin = this.#properties.origin ? vec3.clone(this.#properties.origin) : undefined;
289
- const vectorU = this.#properties.vector_u ? vec3.clone(this.#properties.vector_u) : undefined;
290
- const vectorV = this.#properties.vector_v ? vec3.clone(this.#properties.vector_v) : undefined;
291
-
292
- const planeDefined = origin && vectorU && vectorV;
293
-
294
- let normal = vec3.fromValues(0, 0, 1);
295
-
296
- if (planeDefined) {
297
- vec3.normalize(vectorU, vectorU);
298
- vec3.normalize(vectorV, vectorV);
299
-
300
- normal = vec3.normalize(vec3.create(), vec3.cross(vec3.create(), vectorU, vectorV));
301
- if (vec3.dot(vectorU, vectorV) !== 0)
302
- vec3.normalize(vectorV, vec3.cross(vec3.create(), normal, vectorU));
303
-
304
- if (camera.type === CAMERA_TYPE.ORTHOGRAPHIC) {
305
- const cameraApi = camera as IOrthographicCameraApi;
306
- const cameraDirection = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), cameraApi.target, cameraApi.position));
307
-
308
- // if the dot product of the camera direction and the normal tells us that they are parallel
309
- // the plane is perpendicular to the camera direction
310
- if (Math.abs(vec3.dot(cameraDirection, normal)) < 0.0001) {
311
- this.createDefaultPlane(camera);
312
- } else {
313
- this.#vectorU = vectorU;
314
- this.#vectorV = vectorV;
315
- this.#normal = normal;
316
- this.#origin = origin;
317
- }
318
- } else {
319
- this.#vectorU = vectorU;
320
- this.#vectorV = vectorV;
321
- this.#normal = normal;
322
- this.#origin = origin;
323
- }
324
- } else {
325
- this.createDefaultPlane(camera);
326
- }
327
-
328
- this.createTransformationMatrices();
329
- this.#gridRestriction.updatePlaneDefinition();
330
- this.#angularRestriction.updatePlaneDefinition();
331
- this.#axisRestriction.updatePlaneDefinition();
332
- }
333
-
334
- // #endregion Private Methods (4)
335
- }
336
-
337
- // #endregion Classes (1)