@shapediver/viewer.features.drawing-tools 3.1.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 (209) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +161 -0
  3. package/dist/api/implementation/DrawingToolsApi.d.ts +31 -0
  4. package/dist/api/implementation/DrawingToolsApi.d.ts.map +1 -0
  5. package/dist/api/implementation/DrawingToolsApi.js +111 -0
  6. package/dist/api/implementation/DrawingToolsApi.js.map +1 -0
  7. package/dist/api/implementation/restrictions/AbstractRestrictionApi.d.ts +10 -0
  8. package/dist/api/implementation/restrictions/AbstractRestrictionApi.d.ts.map +1 -0
  9. package/dist/api/implementation/restrictions/AbstractRestrictionApi.js +38 -0
  10. package/dist/api/implementation/restrictions/AbstractRestrictionApi.js.map +1 -0
  11. package/dist/api/implementation/restrictions/AbstractSnapRestrictionApi.d.ts +11 -0
  12. package/dist/api/implementation/restrictions/AbstractSnapRestrictionApi.d.ts.map +1 -0
  13. package/dist/api/implementation/restrictions/AbstractSnapRestrictionApi.js +40 -0
  14. package/dist/api/implementation/restrictions/AbstractSnapRestrictionApi.js.map +1 -0
  15. package/dist/api/implementation/restrictions/axis/AxisRestrictionApi.d.ts +7 -0
  16. package/dist/api/implementation/restrictions/axis/AxisRestrictionApi.d.ts.map +1 -0
  17. package/dist/api/implementation/restrictions/axis/AxisRestrictionApi.js +24 -0
  18. package/dist/api/implementation/restrictions/axis/AxisRestrictionApi.js.map +1 -0
  19. package/dist/api/implementation/restrictions/geometry/GeometryRestrictionApi.d.ts +15 -0
  20. package/dist/api/implementation/restrictions/geometry/GeometryRestrictionApi.d.ts.map +1 -0
  21. package/dist/api/implementation/restrictions/geometry/GeometryRestrictionApi.js +54 -0
  22. package/dist/api/implementation/restrictions/geometry/GeometryRestrictionApi.js.map +1 -0
  23. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.d.ts +18 -0
  24. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.d.ts.map +1 -0
  25. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.js +61 -0
  26. package/dist/api/implementation/restrictions/plane/PlaneRestrictionApi.js.map +1 -0
  27. package/dist/api/implementation/restrictions/plane/snap/AngularRestrictionApi.d.ts +10 -0
  28. package/dist/api/implementation/restrictions/plane/snap/AngularRestrictionApi.d.ts.map +1 -0
  29. package/dist/api/implementation/restrictions/plane/snap/AngularRestrictionApi.js +40 -0
  30. package/dist/api/implementation/restrictions/plane/snap/AngularRestrictionApi.js.map +1 -0
  31. package/dist/api/implementation/restrictions/plane/snap/GridRestrictionApi.d.ts +10 -0
  32. package/dist/api/implementation/restrictions/plane/snap/GridRestrictionApi.d.ts.map +1 -0
  33. package/dist/api/implementation/restrictions/plane/snap/GridRestrictionApi.js +40 -0
  34. package/dist/api/implementation/restrictions/plane/snap/GridRestrictionApi.js.map +1 -0
  35. package/dist/api/interfaces/IDrawingToolsApi.d.ts +89 -0
  36. package/dist/api/interfaces/IDrawingToolsApi.d.ts.map +1 -0
  37. package/dist/api/interfaces/IDrawingToolsApi.js +3 -0
  38. package/dist/api/interfaces/IDrawingToolsApi.js.map +1 -0
  39. package/dist/api/interfaces/IRestrictionApi.d.ts +11 -0
  40. package/dist/api/interfaces/IRestrictionApi.d.ts.map +1 -0
  41. package/dist/api/interfaces/IRestrictionApi.js +3 -0
  42. package/dist/api/interfaces/IRestrictionApi.js.map +1 -0
  43. package/dist/api/interfaces/ISnapRestrictionApi.d.ts +13 -0
  44. package/dist/api/interfaces/ISnapRestrictionApi.d.ts.map +1 -0
  45. package/dist/api/interfaces/ISnapRestrictionApi.js +3 -0
  46. package/dist/api/interfaces/ISnapRestrictionApi.js.map +1 -0
  47. package/dist/business/implementation/DrawingToolsManager.d.ts +95 -0
  48. package/dist/business/implementation/DrawingToolsManager.d.ts.map +1 -0
  49. package/dist/business/implementation/DrawingToolsManager.js +544 -0
  50. package/dist/business/implementation/DrawingToolsManager.js.map +1 -0
  51. package/dist/business/implementation/managers/HistoryManager.d.ts +19 -0
  52. package/dist/business/implementation/managers/HistoryManager.d.ts.map +1 -0
  53. package/dist/business/implementation/managers/HistoryManager.js +89 -0
  54. package/dist/business/implementation/managers/HistoryManager.js.map +1 -0
  55. package/dist/business/implementation/managers/TextVisualizationManager.d.ts +14 -0
  56. package/dist/business/implementation/managers/TextVisualizationManager.d.ts.map +1 -0
  57. package/dist/business/implementation/managers/TextVisualizationManager.js +228 -0
  58. package/dist/business/implementation/managers/TextVisualizationManager.js.map +1 -0
  59. package/dist/business/implementation/managers/geometry/GeometryManager.d.ts +23 -0
  60. package/dist/business/implementation/managers/geometry/GeometryManager.d.ts.map +1 -0
  61. package/dist/business/implementation/managers/geometry/GeometryManager.js +82 -0
  62. package/dist/business/implementation/managers/geometry/GeometryManager.js.map +1 -0
  63. package/dist/business/implementation/managers/geometry/GeometryMathManager.d.ts +73 -0
  64. package/dist/business/implementation/managers/geometry/GeometryMathManager.d.ts.map +1 -0
  65. package/dist/business/implementation/managers/geometry/GeometryMathManager.js +230 -0
  66. package/dist/business/implementation/managers/geometry/GeometryMathManager.js.map +1 -0
  67. package/dist/business/implementation/managers/geometry/GeometryState.d.ts +46 -0
  68. package/dist/business/implementation/managers/geometry/GeometryState.d.ts.map +1 -0
  69. package/dist/business/implementation/managers/geometry/GeometryState.js +323 -0
  70. package/dist/business/implementation/managers/geometry/GeometryState.js.map +1 -0
  71. package/dist/business/implementation/managers/geometry/helpers/GeometryManagerHelper.d.ts +16 -0
  72. package/dist/business/implementation/managers/geometry/helpers/GeometryManagerHelper.d.ts.map +1 -0
  73. package/dist/business/implementation/managers/geometry/helpers/GeometryManagerHelper.js +157 -0
  74. package/dist/business/implementation/managers/geometry/helpers/GeometryManagerHelper.js.map +1 -0
  75. package/dist/business/implementation/managers/interaction/EventManager.d.ts +26 -0
  76. package/dist/business/implementation/managers/interaction/EventManager.d.ts.map +1 -0
  77. package/dist/business/implementation/managers/interaction/EventManager.js +63 -0
  78. package/dist/business/implementation/managers/interaction/EventManager.js.map +1 -0
  79. package/dist/business/implementation/managers/interaction/InteractionManager.d.ts +39 -0
  80. package/dist/business/implementation/managers/interaction/InteractionManager.d.ts.map +1 -0
  81. package/dist/business/implementation/managers/interaction/InteractionManager.js +237 -0
  82. package/dist/business/implementation/managers/interaction/InteractionManager.js.map +1 -0
  83. package/dist/business/implementation/managers/interaction/RestrictionManager.d.ts +19 -0
  84. package/dist/business/implementation/managers/interaction/RestrictionManager.d.ts.map +1 -0
  85. package/dist/business/implementation/managers/interaction/RestrictionManager.js +117 -0
  86. package/dist/business/implementation/managers/interaction/RestrictionManager.js.map +1 -0
  87. package/dist/business/implementation/managers/interaction/handlers/DeletionInteractionHandler.d.ts +10 -0
  88. package/dist/business/implementation/managers/interaction/handlers/DeletionInteractionHandler.d.ts.map +1 -0
  89. package/dist/business/implementation/managers/interaction/handlers/DeletionInteractionHandler.js +52 -0
  90. package/dist/business/implementation/managers/interaction/handlers/DeletionInteractionHandler.js.map +1 -0
  91. package/dist/business/implementation/managers/interaction/handlers/InsertionInteractionHandler.d.ts +14 -0
  92. package/dist/business/implementation/managers/interaction/handlers/InsertionInteractionHandler.d.ts.map +1 -0
  93. package/dist/business/implementation/managers/interaction/handlers/InsertionInteractionHandler.js +135 -0
  94. package/dist/business/implementation/managers/interaction/handlers/InsertionInteractionHandler.js.map +1 -0
  95. package/dist/business/implementation/managers/interaction/handlers/MidPointInteractionHandler.d.ts +16 -0
  96. package/dist/business/implementation/managers/interaction/handlers/MidPointInteractionHandler.d.ts.map +1 -0
  97. package/dist/business/implementation/managers/interaction/handlers/MidPointInteractionHandler.js +113 -0
  98. package/dist/business/implementation/managers/interaction/handlers/MidPointInteractionHandler.js.map +1 -0
  99. package/dist/business/implementation/managers/interaction/helpers/InteractionManagerHelper.d.ts +58 -0
  100. package/dist/business/implementation/managers/interaction/helpers/InteractionManagerHelper.d.ts.map +1 -0
  101. package/dist/business/implementation/managers/interaction/helpers/InteractionManagerHelper.js +377 -0
  102. package/dist/business/implementation/managers/interaction/helpers/InteractionManagerHelper.js.map +1 -0
  103. package/dist/business/implementation/managers/interaction/restrictions/AbstractRestriction.d.ts +19 -0
  104. package/dist/business/implementation/managers/interaction/restrictions/AbstractRestriction.d.ts.map +1 -0
  105. package/dist/business/implementation/managers/interaction/restrictions/AbstractRestriction.js +105 -0
  106. package/dist/business/implementation/managers/interaction/restrictions/AbstractRestriction.js.map +1 -0
  107. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.d.ts +22 -0
  108. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.d.ts.map +1 -0
  109. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.js +96 -0
  110. package/dist/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.js.map +1 -0
  111. package/dist/business/implementation/managers/interaction/restrictions/geometry/GeometryRestriction.d.ts +39 -0
  112. package/dist/business/implementation/managers/interaction/restrictions/geometry/GeometryRestriction.d.ts.map +1 -0
  113. package/dist/business/implementation/managers/interaction/restrictions/geometry/GeometryRestriction.js +215 -0
  114. package/dist/business/implementation/managers/interaction/restrictions/geometry/GeometryRestriction.js.map +1 -0
  115. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.d.ts +58 -0
  116. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.d.ts.map +1 -0
  117. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.js +180 -0
  118. package/dist/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.js.map +1 -0
  119. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.d.ts +38 -0
  120. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.d.ts.map +1 -0
  121. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.js +308 -0
  122. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.js.map +1 -0
  123. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.d.ts +37 -0
  124. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.d.ts.map +1 -0
  125. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.js +228 -0
  126. package/dist/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.js.map +1 -0
  127. package/dist/business/implementation/utils/numberCleaner.d.ts +2 -0
  128. package/dist/business/implementation/utils/numberCleaner.d.ts.map +1 -0
  129. package/dist/business/implementation/utils/numberCleaner.js +9 -0
  130. package/dist/business/implementation/utils/numberCleaner.js.map +1 -0
  131. package/dist/business/interfaces/IDrawingToolsManager.d.ts +270 -0
  132. package/dist/business/interfaces/IDrawingToolsManager.d.ts.map +1 -0
  133. package/dist/business/interfaces/IDrawingToolsManager.js +16 -0
  134. package/dist/business/interfaces/IDrawingToolsManager.js.map +1 -0
  135. package/dist/business/interfaces/IManager.d.ts +4 -0
  136. package/dist/business/interfaces/IManager.d.ts.map +1 -0
  137. package/dist/business/interfaces/IManager.js +3 -0
  138. package/dist/business/interfaces/IManager.js.map +1 -0
  139. package/dist/business/interfaces/IRestriction.d.ts +41 -0
  140. package/dist/business/interfaces/IRestriction.d.ts.map +1 -0
  141. package/dist/business/interfaces/IRestriction.js +13 -0
  142. package/dist/business/interfaces/IRestriction.js.map +1 -0
  143. package/dist/business/interfaces/IRestrictionBase.d.ts +19 -0
  144. package/dist/business/interfaces/IRestrictionBase.d.ts.map +1 -0
  145. package/dist/business/interfaces/IRestrictionBase.js +5 -0
  146. package/dist/business/interfaces/IRestrictionBase.js.map +1 -0
  147. package/dist/business/interfaces/ISnapRestriction.d.ts +50 -0
  148. package/dist/business/interfaces/ISnapRestriction.d.ts.map +1 -0
  149. package/dist/business/interfaces/ISnapRestriction.js +4 -0
  150. package/dist/business/interfaces/ISnapRestriction.js.map +1 -0
  151. package/dist/business/interfaces/events/EventResponseMapping.d.ts +19 -0
  152. package/dist/business/interfaces/events/EventResponseMapping.d.ts.map +1 -0
  153. package/dist/business/interfaces/events/EventResponseMapping.js +4 -0
  154. package/dist/business/interfaces/events/EventResponseMapping.js.map +1 -0
  155. package/dist/business/interfaces/events/IDrawingToolsEvent.d.ts +12 -0
  156. package/dist/business/interfaces/events/IDrawingToolsEvent.d.ts.map +1 -0
  157. package/dist/business/interfaces/events/IDrawingToolsEvent.js +3 -0
  158. package/dist/business/interfaces/events/IDrawingToolsEvent.js.map +1 -0
  159. package/dist/index.d.ts +32 -0
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +45 -0
  162. package/dist/index.js.map +1 -0
  163. package/dist/three/CSS2DRenderer.d.ts +32 -0
  164. package/dist/three/CSS2DRenderer.d.ts.map +1 -0
  165. package/dist/three/CSS2DRenderer.js +137 -0
  166. package/dist/three/CSS2DRenderer.js.map +1 -0
  167. package/package.json +55 -0
  168. package/src/api/implementation/DrawingToolsApi.ts +135 -0
  169. package/src/api/implementation/restrictions/AbstractRestrictionApi.ts +34 -0
  170. package/src/api/implementation/restrictions/AbstractSnapRestrictionApi.ts +36 -0
  171. package/src/api/implementation/restrictions/axis/AxisRestrictionApi.ts +19 -0
  172. package/src/api/implementation/restrictions/geometry/GeometryRestrictionApi.ts +56 -0
  173. package/src/api/implementation/restrictions/plane/PlaneRestrictionApi.ts +63 -0
  174. package/src/api/implementation/restrictions/plane/snap/AngularRestrictionApi.ts +35 -0
  175. package/src/api/implementation/restrictions/plane/snap/GridRestrictionApi.ts +35 -0
  176. package/src/api/interfaces/IDrawingToolsApi.ts +99 -0
  177. package/src/api/interfaces/IRestrictionApi.ts +15 -0
  178. package/src/api/interfaces/ISnapRestrictionApi.ts +18 -0
  179. package/src/business/implementation/DrawingToolsManager.ts +619 -0
  180. package/src/business/implementation/managers/HistoryManager.ts +101 -0
  181. package/src/business/implementation/managers/TextVisualizationManager.ts +245 -0
  182. package/src/business/implementation/managers/geometry/GeometryManager.ts +95 -0
  183. package/src/business/implementation/managers/geometry/GeometryMathManager.ts +273 -0
  184. package/src/business/implementation/managers/geometry/GeometryState.ts +436 -0
  185. package/src/business/implementation/managers/geometry/helpers/GeometryManagerHelper.ts +170 -0
  186. package/src/business/implementation/managers/interaction/EventManager.ts +80 -0
  187. package/src/business/implementation/managers/interaction/InteractionManager.ts +268 -0
  188. package/src/business/implementation/managers/interaction/RestrictionManager.ts +135 -0
  189. package/src/business/implementation/managers/interaction/handlers/DeletionInteractionHandler.ts +48 -0
  190. package/src/business/implementation/managers/interaction/handlers/InsertionInteractionHandler.ts +149 -0
  191. package/src/business/implementation/managers/interaction/handlers/MidPointInteractionHandler.ts +127 -0
  192. package/src/business/implementation/managers/interaction/helpers/InteractionManagerHelper.ts +411 -0
  193. package/src/business/implementation/managers/interaction/restrictions/AbstractRestriction.ts +99 -0
  194. package/src/business/implementation/managers/interaction/restrictions/axis/AxisRestriction.ts +107 -0
  195. package/src/business/implementation/managers/interaction/restrictions/geometry/GeometryRestriction.ts +237 -0
  196. package/src/business/implementation/managers/interaction/restrictions/plane/PlaneRestriction.ts +257 -0
  197. package/src/business/implementation/managers/interaction/restrictions/plane/snap/AngularRestriction.ts +384 -0
  198. package/src/business/implementation/managers/interaction/restrictions/plane/snap/GridRestriction.ts +262 -0
  199. package/src/business/implementation/utils/numberCleaner.ts +5 -0
  200. package/src/business/interfaces/IDrawingToolsManager.ts +313 -0
  201. package/src/business/interfaces/IManager.ts +7 -0
  202. package/src/business/interfaces/IRestriction.ts +64 -0
  203. package/src/business/interfaces/IRestrictionBase.ts +33 -0
  204. package/src/business/interfaces/ISnapRestriction.ts +70 -0
  205. package/src/business/interfaces/events/EventResponseMapping.ts +19 -0
  206. package/src/business/interfaces/events/IDrawingToolsEvent.ts +16 -0
  207. package/src/index.ts +72 -0
  208. package/src/three/CSS2DRenderer.ts +212 -0
  209. package/tsconfig.json +17 -0
@@ -0,0 +1,384 @@
1
+ import { AbstractRestriction } from '../../AbstractRestriction';
2
+ import { CSS2DObject } from '../../../../../../../three/CSS2DRenderer';
3
+ import { DrawingToolsManager } from '../../../../../DrawingToolsManager';
4
+ import { GeometryMathManager } from '../../../../geometry/GeometryMathManager';
5
+ import { ISnapRestriction, SnapRestrictionProperties } from '../../../../../../interfaces/ISnapRestriction';
6
+ import { numberCleaner } from '../../../../../utils/numberCleaner';
7
+ import { PlaneRestriction } from '../PlaneRestriction';
8
+ import { RestrictionMetaData } from '../../../../../../interfaces/IRestriction';
9
+ import { sceneTree } from '@shapediver/viewer';
10
+ import { Settings } from '../../../../../../interfaces/IDrawingToolsManager';
11
+ import { vec3 } from 'gl-matrix';
12
+
13
+ // #region Type aliases (1)
14
+
15
+ export type AngularRestrictionProperties = {
16
+ /**
17
+ * Step size for the angles
18
+ */
19
+ angleStep?: number;
20
+
21
+ /**
22
+ * If the angle step is editable for change to the end user.
23
+ * If it is not editable, the angle step cannot be changed from the default value.
24
+ */
25
+ angleStepEditable?: boolean;
26
+ } & SnapRestrictionProperties;
27
+
28
+ // #endregion Type aliases (1)
29
+
30
+ // #region Classes (1)
31
+
32
+ export class AngularRestriction extends AbstractRestriction implements ISnapRestriction {
33
+ // #region Properties (16)
34
+
35
+ readonly #activationKey: string;
36
+ readonly #drawingToolsManager: DrawingToolsManager;
37
+ readonly #geometryMathManager: GeometryMathManager;
38
+ readonly #planeRestriction: PlaneRestriction;
39
+ readonly #settings: Settings;
40
+
41
+ #active: boolean = false;
42
+ #activePolarGrids = {
43
+ next: false,
44
+ previous: false
45
+ };
46
+ #angleStep: number;
47
+ #angleStepEditable: boolean = true;
48
+ #angles: number[] = [];
49
+ #labelNext?: CSS2DObject;
50
+ #labelPrevious?: CSS2DObject;
51
+ #normal: vec3;
52
+ #priority: number = 0;
53
+ #vectorU: vec3;
54
+ #vectorV: vec3;
55
+
56
+ // #endregion Properties (16)
57
+
58
+ // #region Constructors (1)
59
+
60
+ constructor(drawingToolsManager: DrawingToolsManager, planeRestriction: PlaneRestriction, properties?: AngularRestrictionProperties) {
61
+ super(drawingToolsManager, 'angular');
62
+
63
+ this.#drawingToolsManager = drawingToolsManager;
64
+ this.#geometryMathManager = drawingToolsManager.geometryMathManager;
65
+ this.#settings = drawingToolsManager.settings;
66
+
67
+ this.#planeRestriction = planeRestriction;
68
+
69
+ // we store the properties of the plane restriction
70
+ // as we need them to calculate the transformation matrices
71
+ // and the offset of the grid size to the origin
72
+ this.#vectorU = planeRestriction.vectorU!;
73
+ this.#vectorV = planeRestriction.vectorV!;
74
+ this.#normal = planeRestriction.normal;
75
+
76
+ this.#activationKey = properties?.activationKey || 'a';
77
+ this.enabled = properties?.enabled ?? false;
78
+ this._enabledEditable = properties?.enabledEditable ?? true;
79
+ this.#angleStep = properties?.angleStep || Math.PI / 12;
80
+ this.#angleStepEditable = properties?.angleStepEditable ?? true;
81
+ this.#priority = properties?.priority || 0;
82
+
83
+ // calculate the angles
84
+ this.calculateAngles();
85
+ }
86
+
87
+ // #endregion Constructors (1)
88
+
89
+ // #region Public Getters And Setters (8)
90
+
91
+ public get active(): boolean {
92
+ return this.#active;
93
+ }
94
+
95
+ public set active(value: boolean) {
96
+ this.#active = value;
97
+
98
+ if (value === false) {
99
+ if (this.#labelNext) this.#labelNext.visible = false;
100
+ if (this.#labelPrevious) this.#labelPrevious.visible = false;
101
+ } else {
102
+ if (this.#labelNext && this.#activePolarGrids.next) this.#labelNext.visible = true;
103
+ if (this.#labelPrevious && this.#activePolarGrids.previous) this.#labelPrevious.visible = true;
104
+ }
105
+ }
106
+
107
+ public get angleStep(): number {
108
+ return this.#angleStep;
109
+ }
110
+
111
+ public set angleStep(value: number) {
112
+ if (this.#angleStepEditable === false) return;
113
+
114
+ this.#angleStep = value;
115
+ this.calculateAngles();
116
+ }
117
+
118
+ public get angleStepEditable(): boolean {
119
+ return this.#angleStepEditable;
120
+ }
121
+
122
+ public get enabledEditable(): boolean {
123
+ return this._enabledEditable;
124
+ }
125
+
126
+ public get priority(): number {
127
+ return this.#priority;
128
+ }
129
+
130
+ public set priority(value: number) {
131
+ this.#priority = value;
132
+ }
133
+
134
+ // #endregion Public Getters And Setters (8)
135
+
136
+ // #region Public Methods (2)
137
+
138
+ public snap(point: vec3, metaData?: RestrictionMetaData): vec3 | undefined {
139
+ // if the restriction is not enabled OR the activation key is set and the key is not pressed, return
140
+ if (this.enabled === false && this.#drawingToolsManager.keyPressed(this.#activationKey) === false) return;
141
+
142
+ if (this.#labelNext) this.#labelNext.visible = false;
143
+ if (this.#labelPrevious) this.#labelPrevious.visible = false;
144
+
145
+ this.#activePolarGrids = {
146
+ next: false,
147
+ previous: false
148
+ };
149
+
150
+ const positionArray = this.#drawingToolsManager.positionArray;
151
+
152
+ let previousIndex, nextIndex;
153
+ if (metaData !== undefined && metaData.index !== undefined) {
154
+ previousIndex = this.getPreviousIndex(metaData.index);
155
+ nextIndex = this.getNextIndex(metaData.index);
156
+ } else {
157
+ // if no index was provided, it is a new point
158
+ previousIndex = positionArray.length / 3 - 1;
159
+ nextIndex = 0;
160
+ }
161
+
162
+ const previousPreviousIndex = this.getPreviousIndex(previousIndex);
163
+ const nextNextIndex = this.getNextIndex(nextIndex);
164
+
165
+ if (positionArray.length / 3 < 2) return;
166
+
167
+ /**
168
+ * Explanation of the algorithm:
169
+ * 1. Project the point onto the XY-Plane
170
+ * 2. Find the next point and the previous point
171
+ * 3. Project the next and previous point onto the XY-Plane
172
+ * 4. Calculate the angle between the point and the next and previous point
173
+ * 5. Determine which if the angles are in the range to snap to
174
+ * a. If both are in the range, snap to the intersection of the two lines
175
+ * b. If only one is in the range, snap to the intersection of the line and the plane
176
+ * c. If none is in the range, return
177
+ * 6. Reverse the projection to the original coordinate system
178
+ */
179
+
180
+ // get the next and previous point from the position array
181
+ const nextPointFromData = vec3.fromValues(positionArray.at((nextIndex * 3))!, positionArray.at((nextIndex * 3) + 1)!, positionArray.at((nextIndex * 3) + 2)!);
182
+ const nextNextPointFromData = vec3.fromValues(positionArray.at((nextNextIndex * 3))!, positionArray.at((nextNextIndex * 3) + 1)!, positionArray.at((nextNextIndex * 3) + 2)!);
183
+ const previousPointFromData = vec3.fromValues(positionArray.at((previousIndex * 3))!, positionArray.at((previousIndex * 3) + 1)!, positionArray.at((previousIndex * 3) + 2)!);
184
+ const previousPreviousPointFromData = vec3.fromValues(positionArray.at((previousPreviousIndex * 3))!, positionArray.at((previousPreviousIndex * 3) + 1)!, positionArray.at((previousPreviousIndex * 3) + 2)!);
185
+
186
+ // project them onto the same plane as the point
187
+ const nextPointProjected = vec3.sub(vec3.create(), nextPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), nextPointFromData, point), this.#normal)));
188
+ const nextNextPointProjected = vec3.sub(vec3.create(), nextNextPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), nextNextPointFromData, point), this.#normal)));
189
+ const previousPointProjected = vec3.sub(vec3.create(), previousPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), previousPointFromData, point), this.#normal)));
190
+ const previousPreviousPointProjected = vec3.sub(vec3.create(), previousPreviousPointFromData, vec3.scale(vec3.create(), this.#normal, vec3.dot(vec3.sub(vec3.create(), previousPreviousPointFromData, point), this.#normal)));
191
+
192
+ // project the point onto the XY-Plane
193
+ const pointProjected = vec3.transformMat4(vec3.create(), point, this.#planeRestriction.transformationToXYPlaneMatrix);
194
+ vec3.transformMat4(nextPointProjected, nextPointProjected, this.#planeRestriction.transformationToXYPlaneMatrix);
195
+ vec3.transformMat4(nextNextPointProjected, nextNextPointProjected, this.#planeRestriction.transformationToXYPlaneMatrix);
196
+ vec3.transformMat4(previousPointProjected, previousPointProjected, this.#planeRestriction.transformationToXYPlaneMatrix);
197
+ vec3.transformMat4(previousPreviousPointProjected, previousPreviousPointProjected, this.#planeRestriction.transformationToXYPlaneMatrix);
198
+
199
+ // calculate the angle between the next and previous point and the point to restrict on the axis
200
+ const { angularDifference: angularDifferenceNext, crossProduct: crossProductNext, closestAngle: closestAngleNext } = this.getAngularDifference({ start: nextPointProjected, end: nextNextPointProjected }, { start: nextPointProjected, end: pointProjected });
201
+ const { angularDifference: angularDifferencePrevious, crossProduct: crossProductPrevious, closestAngle: closestAnglePrevious } = this.getAngularDifference({ start: previousPointProjected, end: previousPreviousPointProjected }, { start: previousPointProjected, end: pointProjected });
202
+
203
+ // calculate the distances in screen space so we can check how close it is
204
+ const resultPointNextAngle = vec3.rotateZ(vec3.create(), pointProjected, nextPointProjected, crossProductNext[2] < 0 ? -angularDifferenceNext : angularDifferenceNext);
205
+ const screenSpaceDistanceCheckNextAngle = this.#geometryMathManager.screenSpaceDistanceCheck(resultPointNextAngle, pointProjected, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
206
+ const resultPointPreviousAngle = vec3.rotateZ(vec3.create(), pointProjected, previousPointProjected, crossProductPrevious[2] < 0 ? -angularDifferencePrevious : angularDifferencePrevious);
207
+ const screenSpaceDistanceCheckPreviousAngle = this.#geometryMathManager.screenSpaceDistanceCheck(resultPointPreviousAngle, pointProjected, this.#settings.visualization.points.size_0! * this.#settings.visualization.distanceMultiplicationFactor);
208
+
209
+ if (screenSpaceDistanceCheckNextAngle.check === false && screenSpaceDistanceCheckPreviousAngle.check === false) return;
210
+
211
+ // snap to clear defined point if both distances are smaller than threshold
212
+ if (positionArray.length > 6 && screenSpaceDistanceCheckNextAngle.check === true && screenSpaceDistanceCheckPreviousAngle.check === true) {
213
+ const rayDirectionNext = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), resultPointNextAngle, nextPointProjected));
214
+ const rayDirectionPrevious = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), resultPointPreviousAngle, previousPointProjected));
215
+
216
+ const crossProduct = vec3.cross(vec3.create(), rayDirectionNext, rayDirectionPrevious);
217
+ const crossProductLength = vec3.length(crossProduct);
218
+
219
+ if (crossProductLength < 0.001) {
220
+ vec3.transformMat4(resultPointNextAngle, resultPointNextAngle, this.#planeRestriction.transformationFromXYPlaneMatrix);
221
+ return resultPointNextAngle;
222
+ }
223
+
224
+ const t = vec3.sub(vec3.create(), previousPointProjected, nextPointProjected);
225
+ const u = vec3.cross(vec3.create(), t, rayDirectionPrevious);
226
+ const v = vec3.cross(vec3.create(), t, rayDirectionNext);
227
+
228
+ const tValue = vec3.dot(u, crossProduct) / crossProductLength ** 2;
229
+ const uValue = vec3.dot(v, crossProduct) / crossProductLength ** 2;
230
+
231
+ if (tValue < 0 || uValue < 0) {
232
+ vec3.transformMat4(resultPointNextAngle, resultPointNextAngle, this.#planeRestriction.transformationFromXYPlaneMatrix);
233
+ return resultPointNextAngle;
234
+ }
235
+
236
+ const intersection = vec3.add(vec3.create(), nextPointProjected, vec3.scale(vec3.create(), rayDirectionNext, tValue));
237
+ this.#labelNext = this.createGrid(this.#labelNext, nextPointFromData, closestAngleNext);
238
+ this.#activePolarGrids.next = true;
239
+ this.#labelPrevious = this.createGrid(this.#labelPrevious, previousPointFromData, closestAnglePrevious);
240
+ this.#activePolarGrids.previous = true;
241
+
242
+ // reverse the projection to the original coordinate system
243
+ vec3.transformMat4(intersection, intersection, this.#planeRestriction.transformationFromXYPlaneMatrix);
244
+ return intersection;
245
+ }
246
+
247
+ // check which distance to the projection is smaller
248
+ if (screenSpaceDistanceCheckNextAngle.distanceSquared < screenSpaceDistanceCheckPreviousAngle.distanceSquared) {
249
+ this.#labelNext = this.createGrid(this.#labelNext, nextPointFromData, closestAngleNext);
250
+ this.#activePolarGrids.next = true;
251
+
252
+ // reverse the projection to the original coordinate system
253
+ vec3.transformMat4(resultPointNextAngle, resultPointNextAngle, this.#planeRestriction.transformationFromXYPlaneMatrix);
254
+ return resultPointNextAngle;
255
+ } else {
256
+ this.#labelPrevious = this.createGrid(this.#labelPrevious, previousPointFromData, closestAnglePrevious);
257
+ this.#activePolarGrids.previous = true;
258
+
259
+ // reverse the projection to the original coordinate system
260
+ vec3.transformMat4(resultPointPreviousAngle, resultPointPreviousAngle, this.#planeRestriction.transformationFromXYPlaneMatrix);
261
+ return resultPointPreviousAngle;
262
+ }
263
+ }
264
+
265
+ public updatePlaneDefinition(origin: vec3, vectorU: vec3, vectorV: vec3, normal: vec3): void {
266
+ this.#vectorU = vectorU;
267
+ this.#vectorV = vectorV;
268
+ this.#normal = normal;
269
+ }
270
+
271
+ // #endregion Public Methods (2)
272
+
273
+ // #region Protected Methods (1)
274
+
275
+ protected visibilityChanged(visible: boolean): void {
276
+ if (visible === false) {
277
+ if (this.#labelNext) this.#labelNext.visible = false;
278
+ if (this.#labelPrevious) this.#labelPrevious.visible = false;
279
+ }
280
+ }
281
+
282
+ // #endregion Protected Methods (1)
283
+
284
+ // #region Private Methods (5)
285
+
286
+ private calculateAngles() {
287
+ this.#angles = [];
288
+ for (let i = 0; i <= Math.PI + 0.0001; i += this.#angleStep) {
289
+ this.#angles.push(i);
290
+ }
291
+ }
292
+
293
+ private createGrid(label: CSS2DObject | undefined, position: vec3, angle: number): CSS2DObject {
294
+ if (label)
295
+ this._object3D.remove(label);
296
+
297
+ let radius = sceneTree.root.boundingBox.boundingSphere.radius / 100;
298
+ if (radius === Infinity)
299
+ radius = 1;
300
+
301
+ const text = document.createElement('div');
302
+ text.className = 'label';
303
+
304
+ const child = document.createElement('div');
305
+ child.className = 'angular-label';
306
+
307
+ const style = document.createElement('style');
308
+ style.textContent = `
309
+ .angular-label {
310
+ display: flex;
311
+ justify-content: center;
312
+ align-items: center;
313
+ width: 40px;
314
+ height: 40px;
315
+ color: white;
316
+ background-color: ${this.#settings.visualization.points.color_1};
317
+ border-radius: 50%;
318
+ font-size: 16px;
319
+ text-align: center;
320
+ }
321
+ `;
322
+ document.head.appendChild(style);
323
+
324
+ child.textContent = `${numberCleaner((angle / Math.PI) * 180)}°`;
325
+ text.appendChild(child);
326
+
327
+ label = new CSS2DObject(text);
328
+ label.position.set(position[0], position[1], position[2]);
329
+ label.visible = false;
330
+ this._object3D.add(label);
331
+
332
+ return label;
333
+ }
334
+
335
+ private getAngularDifference(
336
+ line: {
337
+ start: vec3, end: vec3
338
+ },
339
+ referenceLine: {
340
+ start: vec3, end: vec3
341
+ }
342
+ ): {
343
+ angularDifference: number,
344
+ crossProduct: vec3,
345
+ closestAngle: number
346
+ } {
347
+ const lineDirection = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), line.end, line.start));
348
+ const referenceLineDirection = vec3.normalize(vec3.create(), vec3.sub(vec3.create(), referenceLine.end, referenceLine.start));
349
+
350
+ // calculate the angle between the lineDirection and the referenceLineDirection
351
+ const angleReference = vec3.angle(lineDirection, referenceLineDirection);
352
+ const crossProduct = vec3.cross(vec3.create(), lineDirection, referenceLineDirection);
353
+
354
+ // find the angle that is closest to the angle of the previous point
355
+ let closestAngle = this.#angles[0];
356
+ for (let i = 0; i < this.#angles.length; i++) {
357
+ const angle = this.#angles[i];
358
+
359
+ if (Math.abs(angleReference - angle) < Math.abs(angleReference - closestAngle))
360
+ closestAngle = angle;
361
+ }
362
+
363
+ // move the point to the closest angle
364
+ const angularDifference = closestAngle - angleReference;
365
+
366
+ return {
367
+ angularDifference,
368
+ crossProduct,
369
+ closestAngle
370
+ };
371
+ }
372
+
373
+ private getNextIndex(index: number): number {
374
+ return index + 1 > this.#drawingToolsManager.positionArray.length / 3 - 1 ? 0 : index + 1;
375
+ }
376
+
377
+ private getPreviousIndex(index: number): number {
378
+ return index - 1 < 0 ? this.#drawingToolsManager.positionArray.length / 3 - 1 : index - 1;
379
+ }
380
+
381
+ // #endregion Private Methods (5)
382
+ }
383
+
384
+ // #endregion Classes (1)
@@ -0,0 +1,262 @@
1
+ import * as THREE from 'three';
2
+ import { AbstractRestriction } from '../../AbstractRestriction';
3
+ import { DrawingToolsManager } from '../../../../../DrawingToolsManager';
4
+ import { Box, sceneTree } from '@shapediver/viewer';
5
+ import { ISnapRestriction, SnapRestrictionProperties } from '../../../../../../interfaces/ISnapRestriction';
6
+ import { PlaneRestriction } from '../PlaneRestriction';
7
+ import { vec3 } from 'gl-matrix';
8
+
9
+ // #region Type aliases (1)
10
+
11
+ /**
12
+ * Properties for the grid restriction
13
+ */
14
+ export type GridRestrictionProperties = {
15
+ /**
16
+ * Size of the grid unit
17
+ */
18
+ gridUnit?: number;
19
+
20
+ /**
21
+ * If the grid unit is editable for change to the end user.
22
+ * If it is not editable, the grid unit cannot be changed from the default value.
23
+ */
24
+ gridUnitEditable?: boolean;
25
+ } & SnapRestrictionProperties;
26
+
27
+ // #endregion Type aliases (1)
28
+
29
+ // #region Classes (1)
30
+
31
+ export class GridRestriction extends AbstractRestriction implements ISnapRestriction {
32
+ // #region Properties (15)
33
+
34
+ readonly #activationKey: string;
35
+ readonly #drawingToolsManager: DrawingToolsManager;
36
+ readonly #planeRestriction: PlaneRestriction;
37
+
38
+ #active: boolean = false;
39
+ #gridHelper?: THREE.GridHelper;
40
+ #gridSize: number = 100;
41
+ #gridUnit: number;
42
+ #gridUnitEditable: boolean = true;
43
+ #normal: vec3;
44
+ #offsetFromUnit: vec3 = vec3.create();
45
+ #origin: vec3;
46
+ #priority: number = 0;
47
+ #vectorU: vec3;
48
+ #vectorV: vec3;
49
+
50
+ // #endregion Properties (15)
51
+
52
+ // #region Constructors (1)
53
+
54
+ constructor(drawingToolsManager: DrawingToolsManager, planeRestriction: PlaneRestriction, properties?: GridRestrictionProperties) {
55
+ super(drawingToolsManager, 'grid');
56
+
57
+ this.#drawingToolsManager = drawingToolsManager;
58
+ this.#planeRestriction = planeRestriction;
59
+
60
+ // we store the properties of the plane restriction
61
+ // as we need them to calculate the transformation matrices
62
+ // and the offset of the grid size to the origin
63
+ this.#vectorU = planeRestriction.vectorU!;
64
+ this.#vectorV = planeRestriction.vectorV!;
65
+ this.#normal = planeRestriction.normal;
66
+ this.#origin = planeRestriction.origin;
67
+
68
+ this.#activationKey = properties?.activationKey || 'g';
69
+ this.enabled = properties?.enabled ?? false;
70
+ this._enabledEditable = properties?.enabledEditable ?? true;
71
+ this.#gridUnit = properties?.gridUnit || 1;
72
+ this.#gridUnitEditable = properties?.gridUnitEditable ?? true;
73
+ this.#priority = properties?.priority || 0;
74
+
75
+ // create the offset of the grid size to origin
76
+ this.createOffsetFromUnit();
77
+
78
+ // calculate offset of grid size to origin
79
+ this.createGridVisualization();
80
+ }
81
+
82
+ // #endregion Constructors (1)
83
+
84
+ // #region Public Getters And Setters (8)
85
+
86
+ public get active(): boolean {
87
+ return this.#active;
88
+ }
89
+
90
+ public set active(value: boolean) {
91
+ this.#active = value;
92
+
93
+ if (this.#gridHelper) this.#gridHelper.visible = value;
94
+ }
95
+
96
+ public get enabledEditable(): boolean {
97
+ return this._enabledEditable;
98
+ }
99
+
100
+ public get gridUnit(): number {
101
+ return this.#gridUnit;
102
+ }
103
+
104
+ public set gridUnit(value: number) {
105
+ if (this.#gridUnitEditable === false) return;
106
+
107
+ this.#gridUnit = value;
108
+ this.createOffsetFromUnit();
109
+ this.createGridVisualization();
110
+ }
111
+
112
+ public get gridUnitEditable(): boolean {
113
+ return this.#gridUnitEditable;
114
+ }
115
+
116
+ public get priority(): number {
117
+ return this.#priority;
118
+ }
119
+
120
+ public set priority(value: number) {
121
+ this.#priority = value;
122
+ }
123
+
124
+ // #endregion Public Getters And Setters (8)
125
+
126
+ // #region Public Methods (2)
127
+
128
+ // public get
129
+ public snap(point: vec3): vec3 | undefined {
130
+ // if the restriction is not enabled OR the activation key is set and the key is not pressed, return
131
+ if (this.enabled === false && this.#drawingToolsManager.keyPressed(this.#activationKey) === false) return;
132
+
133
+ /**
134
+ * Explanation of the following code:
135
+ * 1. Calculate the projection of the origin onto the plane that is created by the point and the normal
136
+ * 2. Move the grid helper to the projected origin
137
+ */
138
+
139
+ // vector from the point to the origin
140
+ const v = vec3.sub(vec3.create(), this.#origin, point);
141
+
142
+ // dot product of the vector and the normal
143
+ const dot = vec3.dot(v, this.#normal);
144
+
145
+ // projection of the origin onto the plane that is created by the point and the normal
146
+ const adjustedOrigin = vec3.add(vec3.create(), this.#origin, this.#offsetFromUnit);
147
+ const projectedOrigin = vec3.sub(vec3.create(), adjustedOrigin, vec3.scale(vec3.create(), this.#normal, dot));
148
+
149
+ // we move the grid helper to the projected origin
150
+ if (this.#gridHelper) {
151
+ this.#gridHelper.position.copy(new THREE.Vector3(projectedOrigin[0], projectedOrigin[1], projectedOrigin[2]));
152
+ this.#gridHelper.visible = false;
153
+ }
154
+
155
+ /**
156
+ * Explanation of the following code:
157
+ * 1. Rotate the point so that the normal of the plane is aligned with the Z axis (with previously calculated transformation matrix)
158
+ * 2. Snap the point to the grid
159
+ * 3. Rotate the point back to the original coordinate system (with previously calculated transformation matrix)
160
+ */
161
+
162
+ // Apply the transformation to the point
163
+ const rotatedPoint = vec3.transformMat4(vec3.create(), point, this.#planeRestriction.transformationToXYPlaneMatrix);
164
+
165
+ // Snap the offset to the grid
166
+ const snappedOffset = vec3.create();
167
+ snappedOffset[0] = Math.round(rotatedPoint[0] / this.#gridUnit) * this.#gridUnit;
168
+ snappedOffset[1] = Math.round(rotatedPoint[1] / this.#gridUnit) * this.#gridUnit;
169
+ snappedOffset[2] = rotatedPoint[2];
170
+
171
+ // Move the snapped point back to the original coordinate system
172
+ const snappedPoint = vec3.transformMat4(vec3.create(), snappedOffset, this.#planeRestriction.transformationFromXYPlaneMatrix);
173
+
174
+ return snappedPoint;
175
+ }
176
+
177
+ public updatePlaneDefinition(origin: vec3, vectorU: vec3, vectorV: vec3, normal: vec3): void {
178
+ this.#origin = origin;
179
+ this.#vectorU = vectorU;
180
+ this.#vectorV = vectorV;
181
+ this.#normal = normal;
182
+
183
+ this.createOffsetFromUnit();
184
+ this.createGridVisualization();
185
+ }
186
+
187
+ // #endregion Public Methods (2)
188
+
189
+ // #region Protected Methods (1)
190
+
191
+ protected visibilityChanged(visible: boolean): void {
192
+ if (visible === false) {
193
+ if (this.#gridHelper) {
194
+ this.#gridHelper.visible = false;
195
+ }
196
+ }
197
+ }
198
+
199
+ // #endregion Protected Methods (1)
200
+
201
+ // #region Private Methods (2)
202
+
203
+ private createGridVisualization(): void {
204
+ if (this.#gridHelper) {
205
+ this._object3D.remove(this.#gridHelper);
206
+ this.#gridHelper.dispose();
207
+ }
208
+
209
+ const bb = new Box();
210
+ for(let i = 0; i < sceneTree.root.children.length; i++) {
211
+ if((sceneTree.root.children[i] as unknown as { sessionNode?: boolean }).sessionNode === true) {
212
+ bb.union(sceneTree.root.children[i].boundingBox);
213
+ }
214
+ }
215
+
216
+ const radius = bb.boundingSphere.radius;
217
+ this.#gridSize = radius * 2;
218
+ if (this.#gridSize === Infinity || this.#gridSize === -Infinity || isNaN(this.#gridSize) || this.#gridSize === 0)
219
+ this.#gridSize = 100;
220
+
221
+ // if the grid size is not divisible by the grid unit, we need to adjust the grid size
222
+ let gridSize = this.#gridUnit * Math.ceil(this.#gridSize / this.#gridUnit);
223
+ // if the number of divisions is odd, we need to add one more division
224
+ if (gridSize / this.#gridUnit % 2 === 1)
225
+ gridSize += this.#gridUnit;
226
+
227
+ // todo adjust grid size so that is divisible by grid unit
228
+ this.#gridHelper = new THREE.GridHelper(gridSize, gridSize / this.#gridUnit, 0x666666, 0x222222);
229
+ const adjustedOrigin = vec3.add(vec3.create(), this.#origin, this.#offsetFromUnit);
230
+ this.#gridHelper.position.copy(new THREE.Vector3(adjustedOrigin[0], adjustedOrigin[1], adjustedOrigin[2]));
231
+ this.#gridHelper.visible = false;
232
+
233
+ this.#gridHelper.renderOrder = 100;
234
+ (this.#gridHelper.material as THREE.LineBasicMaterial).depthTest = false;
235
+ (this.#gridHelper.material as THREE.LineBasicMaterial).transparent = true;
236
+
237
+ // three.js uses a right-handed coordinate system, so we need to rotate the grid helper
238
+ const rotationMatrix = new THREE.Matrix4().fromArray([
239
+ this.#vectorU[0], this.#vectorU[1], this.#vectorU[2], 0,
240
+ this.#vectorV[0], this.#vectorV[1], this.#vectorV[2], 0,
241
+ this.#normal[0], this.#normal[1], this.#normal[2], 0,
242
+ 0, 0, 0, 1
243
+ ]);
244
+
245
+ this.#gridHelper.rotation.setFromRotationMatrix(rotationMatrix);
246
+ // three.js grid helper is created in the XY plane, so we need to rotate it by 90 degrees around the X axis
247
+ this.#gridHelper.rotateX(Math.PI / 2);
248
+
249
+ this._object3D.add(this.#gridHelper);
250
+ }
251
+
252
+ private createOffsetFromUnit(): void {
253
+ // Calculate the offset of the rotated point from the rotated origin
254
+ this.#offsetFromUnit[0] = this.#gridUnit * Math.round(this.#origin[0] / this.#gridUnit) - this.#origin[0];
255
+ this.#offsetFromUnit[1] = this.#gridUnit * Math.round(this.#origin[1] / this.#gridUnit) - this.#origin[1];
256
+ this.#offsetFromUnit[2] = this.#gridUnit * Math.round(this.#origin[2] / this.#gridUnit) - this.#origin[2];
257
+ }
258
+
259
+ // #endregion Private Methods (2)
260
+ }
261
+
262
+ // #endregion Classes (1)
@@ -0,0 +1,5 @@
1
+
2
+ export const numberCleaner = (value: number): number => {
3
+ const roundedThreshold = 100;
4
+ return Math.round(value * roundedThreshold) / roundedThreshold;
5
+ };