@aura3d/math 4.0.2 → 4.0.4

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 (165) hide show
  1. package/dist/Box3.d.ts +50 -0
  2. package/dist/Box3.d.ts.map +1 -1
  3. package/dist/Box3.js +177 -6
  4. package/dist/Box3.js.map +1 -1
  5. package/dist/Capsule.d.ts +25 -0
  6. package/dist/Capsule.d.ts.map +1 -0
  7. package/dist/Capsule.js +54 -0
  8. package/dist/Capsule.js.map +1 -0
  9. package/dist/Color.d.ts +27 -0
  10. package/dist/Color.d.ts.map +1 -1
  11. package/dist/Color.js +87 -0
  12. package/dist/Color.js.map +1 -1
  13. package/dist/ConvexHull.d.ts +100 -0
  14. package/dist/ConvexHull.d.ts.map +1 -0
  15. package/dist/ConvexHull.js +578 -0
  16. package/dist/ConvexHull.js.map +1 -0
  17. package/dist/Curves.d.ts +59 -18
  18. package/dist/Curves.d.ts.map +1 -1
  19. package/dist/Curves.js +15 -73
  20. package/dist/Curves.js.map +1 -1
  21. package/dist/Cylindrical.d.ts +19 -0
  22. package/dist/Cylindrical.d.ts.map +1 -0
  23. package/dist/Cylindrical.js +40 -0
  24. package/dist/Cylindrical.js.map +1 -0
  25. package/dist/Euler.d.ts +24 -0
  26. package/dist/Euler.d.ts.map +1 -1
  27. package/dist/Euler.js +126 -2
  28. package/dist/Euler.js.map +1 -1
  29. package/dist/Frustum.d.ts +18 -0
  30. package/dist/Frustum.d.ts.map +1 -1
  31. package/dist/Frustum.js +62 -12
  32. package/dist/Frustum.js.map +1 -1
  33. package/dist/Line3.d.ts +38 -0
  34. package/dist/Line3.d.ts.map +1 -0
  35. package/dist/Line3.js +122 -0
  36. package/dist/Line3.js.map +1 -0
  37. package/dist/MathUtils.d.ts +37 -0
  38. package/dist/MathUtils.d.ts.map +1 -0
  39. package/dist/MathUtils.js +105 -0
  40. package/dist/MathUtils.js.map +1 -0
  41. package/dist/Matrix3.d.ts +23 -2
  42. package/dist/Matrix3.d.ts.map +1 -1
  43. package/dist/Matrix3.js +90 -0
  44. package/dist/Matrix3.js.map +1 -1
  45. package/dist/Matrix4.d.ts +3 -0
  46. package/dist/Matrix4.d.ts.map +1 -1
  47. package/dist/Matrix4.js +17 -0
  48. package/dist/Matrix4.js.map +1 -1
  49. package/dist/OBB.d.ts +44 -0
  50. package/dist/OBB.d.ts.map +1 -0
  51. package/dist/OBB.js +214 -0
  52. package/dist/OBB.js.map +1 -0
  53. package/dist/Octree.d.ts +72 -0
  54. package/dist/Octree.d.ts.map +1 -0
  55. package/dist/Octree.js +385 -0
  56. package/dist/Octree.js.map +1 -0
  57. package/dist/Plane.d.ts +42 -0
  58. package/dist/Plane.d.ts.map +1 -1
  59. package/dist/Plane.js +79 -3
  60. package/dist/Plane.js.map +1 -1
  61. package/dist/Quaternion.d.ts +6 -1
  62. package/dist/Quaternion.d.ts.map +1 -1
  63. package/dist/Quaternion.js +28 -3
  64. package/dist/Quaternion.js.map +1 -1
  65. package/dist/Ray.d.ts +42 -2
  66. package/dist/Ray.d.ts.map +1 -1
  67. package/dist/Ray.js +202 -9
  68. package/dist/Ray.js.map +1 -1
  69. package/dist/ShapeUtils.d.ts +28 -0
  70. package/dist/ShapeUtils.d.ts.map +1 -0
  71. package/dist/ShapeUtils.js +551 -0
  72. package/dist/ShapeUtils.js.map +1 -0
  73. package/dist/Sphere.d.ts +32 -0
  74. package/dist/Sphere.d.ts.map +1 -1
  75. package/dist/Sphere.js +122 -4
  76. package/dist/Sphere.js.map +1 -1
  77. package/dist/Spherical.d.ts +21 -0
  78. package/dist/Spherical.d.ts.map +1 -0
  79. package/dist/Spherical.js +50 -0
  80. package/dist/Spherical.js.map +1 -0
  81. package/dist/SphericalHarmonics3.d.ts +35 -0
  82. package/dist/SphericalHarmonics3.d.ts.map +1 -0
  83. package/dist/SphericalHarmonics3.js +115 -0
  84. package/dist/SphericalHarmonics3.js.map +1 -0
  85. package/dist/Triangle.d.ts +45 -0
  86. package/dist/Triangle.d.ts.map +1 -0
  87. package/dist/Triangle.js +160 -0
  88. package/dist/Triangle.js.map +1 -0
  89. package/dist/Vector2.d.ts +7 -0
  90. package/dist/Vector2.d.ts.map +1 -1
  91. package/dist/Vector2.js +17 -0
  92. package/dist/Vector2.js.map +1 -1
  93. package/dist/Vector3.d.ts +16 -0
  94. package/dist/Vector3.d.ts.map +1 -1
  95. package/dist/Vector3.js +35 -0
  96. package/dist/Vector3.js.map +1 -1
  97. package/dist/curves/ArcCurve.d.ts +7 -0
  98. package/dist/curves/ArcCurve.d.ts.map +1 -0
  99. package/dist/curves/ArcCurve.js +9 -0
  100. package/dist/curves/ArcCurve.js.map +1 -0
  101. package/dist/curves/CatmullRomCurve3.d.ts +39 -0
  102. package/dist/curves/CatmullRomCurve3.d.ts.map +1 -0
  103. package/dist/curves/CatmullRomCurve3.js +176 -0
  104. package/dist/curves/CatmullRomCurve3.js.map +1 -0
  105. package/dist/curves/ClampedCatmullRomCurve3.d.ts +26 -0
  106. package/dist/curves/ClampedCatmullRomCurve3.d.ts.map +1 -0
  107. package/dist/curves/ClampedCatmullRomCurve3.js +48 -0
  108. package/dist/curves/ClampedCatmullRomCurve3.js.map +1 -0
  109. package/dist/curves/CubicBezierCurve.d.ts +14 -0
  110. package/dist/curves/CubicBezierCurve.d.ts.map +1 -0
  111. package/dist/curves/CubicBezierCurve.js +25 -0
  112. package/dist/curves/CubicBezierCurve.js.map +1 -0
  113. package/dist/curves/CubicBezierCurve3.d.ts +14 -0
  114. package/dist/curves/CubicBezierCurve3.d.ts.map +1 -0
  115. package/dist/curves/CubicBezierCurve3.js +25 -0
  116. package/dist/curves/CubicBezierCurve3.js.map +1 -0
  117. package/dist/curves/CurveBase.d.ts +49 -0
  118. package/dist/curves/CurveBase.d.ts.map +1 -0
  119. package/dist/curves/CurveBase.js +199 -0
  120. package/dist/curves/CurveBase.js.map +1 -0
  121. package/dist/curves/CurvePath.d.ts +34 -0
  122. package/dist/curves/CurvePath.d.ts.map +1 -0
  123. package/dist/curves/CurvePath.js +135 -0
  124. package/dist/curves/CurvePath.js.map +1 -0
  125. package/dist/curves/EllipseCurve.d.ts +18 -0
  126. package/dist/curves/EllipseCurve.d.ts.map +1 -0
  127. package/dist/curves/EllipseCurve.js +67 -0
  128. package/dist/curves/EllipseCurve.js.map +1 -0
  129. package/dist/curves/Interpolations.d.ts +9 -0
  130. package/dist/curves/Interpolations.d.ts.map +1 -0
  131. package/dist/curves/Interpolations.js +21 -0
  132. package/dist/curves/Interpolations.js.map +1 -0
  133. package/dist/curves/LineCurve.d.ts +16 -0
  134. package/dist/curves/LineCurve.d.ts.map +1 -0
  135. package/dist/curves/LineCurve.js +32 -0
  136. package/dist/curves/LineCurve.js.map +1 -0
  137. package/dist/curves/LineCurve3.d.ts +16 -0
  138. package/dist/curves/LineCurve3.d.ts.map +1 -0
  139. package/dist/curves/LineCurve3.js +32 -0
  140. package/dist/curves/LineCurve3.js.map +1 -0
  141. package/dist/curves/Path.d.ts +23 -0
  142. package/dist/curves/Path.d.ts.map +1 -0
  143. package/dist/curves/Path.js +94 -0
  144. package/dist/curves/Path.js.map +1 -0
  145. package/dist/curves/QuadraticBezierCurve.d.ts +13 -0
  146. package/dist/curves/QuadraticBezierCurve.d.ts.map +1 -0
  147. package/dist/curves/QuadraticBezierCurve.js +23 -0
  148. package/dist/curves/QuadraticBezierCurve.js.map +1 -0
  149. package/dist/curves/QuadraticBezierCurve3.d.ts +13 -0
  150. package/dist/curves/QuadraticBezierCurve3.d.ts.map +1 -0
  151. package/dist/curves/QuadraticBezierCurve3.js +23 -0
  152. package/dist/curves/QuadraticBezierCurve3.js.map +1 -0
  153. package/dist/curves/Shape.d.ts +15 -0
  154. package/dist/curves/Shape.d.ts.map +1 -0
  155. package/dist/curves/Shape.js +26 -0
  156. package/dist/curves/Shape.js.map +1 -0
  157. package/dist/curves/SplineCurve.d.ts +11 -0
  158. package/dist/curves/SplineCurve.d.ts.map +1 -0
  159. package/dist/curves/SplineCurve.js +27 -0
  160. package/dist/curves/SplineCurve.js.map +1 -0
  161. package/dist/index.d.ts +12 -0
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +16 -0
  164. package/dist/index.js.map +1 -1
  165. package/package.json +1 -1
@@ -0,0 +1,100 @@
1
+ import { Vector3 } from "./Vector3.js";
2
+ import type { Ray } from "./Ray.js";
3
+ /**
4
+ * QuickHull convex hull — three.js `examples/jsm/math/ConvexHull.js` parity.
5
+ * The internal face/half-edge/vertex-list topology is mutable by design
6
+ * (QuickHull is a mutating algorithm); hull point data stays immutable.
7
+ */
8
+ export declare class ConvexHull {
9
+ tolerance: number;
10
+ /** The generated faces of the convex hull. */
11
+ faces: ConvexHullFace[];
12
+ /** Faces generated within a single iteration. */
13
+ newFaces: ConvexHullFace[];
14
+ /** Vertices assigned to faces they can "see". */
15
+ readonly assigned: VertexList;
16
+ /** Vertices not (yet) assigned to any face. */
17
+ readonly unassigned: VertexList;
18
+ /** All hull vertices (internal representation). */
19
+ vertices: VertexNode[];
20
+ /** three.js `ConvexHull.setFromPoints` — needs ≥ 4 points. */
21
+ setFromPoints(points: readonly Vector3[]): this;
22
+ /** three.js `ConvexHull.setFromObject`-equivalent over flat points. */
23
+ static fromPoints(points: readonly Vector3[]): ConvexHull;
24
+ /** `true` when `point` is inside the hull (within `tolerance`). */
25
+ containsPoint(point: Vector3): boolean;
26
+ /**
27
+ * Ray–hull intersection — "Fast Ray-Convex Polyhedron Intersection"
28
+ * (Haines, Graphics Gems II). Returns the nearer hit point or `undefined`.
29
+ */
30
+ intersectRay(ray: Ray): Vector3 | undefined;
31
+ intersectsRay(ray: Ray): boolean;
32
+ makeEmpty(): this;
33
+ private addVertexToFace;
34
+ private removeVertexFromFace;
35
+ private removeAllVerticesFromFace;
36
+ private deleteFaceVertices;
37
+ private resolveUnassignedPoints;
38
+ private computeExtremes;
39
+ private computeInitialHull;
40
+ private reindexFaces;
41
+ private nextVertexToAdd;
42
+ private computeHorizon;
43
+ private addAdjoiningFace;
44
+ private addNewFaces;
45
+ private addVertexToHull;
46
+ private cleanup;
47
+ compute(): this;
48
+ }
49
+ /** Hull face — holds a half-edge loop plus plane data. */
50
+ export declare class ConvexHullFace {
51
+ normal: Vector3;
52
+ midpoint: Vector3;
53
+ area: number;
54
+ constant: number;
55
+ outside: VertexNode | null;
56
+ mark: number;
57
+ edge: HalfEdge | null;
58
+ static create(a: VertexNode, b: VertexNode, c: VertexNode): ConvexHullFace;
59
+ getEdge(i: number): HalfEdge;
60
+ compute(): this;
61
+ distanceToPoint(point: Vector3): number;
62
+ }
63
+ /** Doubly-linked half-edge (three `HalfEdge`). */
64
+ export declare class HalfEdge {
65
+ readonly vertex: VertexNode;
66
+ readonly face: ConvexHullFace;
67
+ prev: HalfEdge | null;
68
+ next: HalfEdge | null;
69
+ twin: HalfEdge | null;
70
+ constructor(vertex: VertexNode, face: ConvexHullFace);
71
+ head(): VertexNode;
72
+ tail(): VertexNode | null;
73
+ length(): number;
74
+ lengthSquared(): number;
75
+ setTwin(edge: HalfEdge): this;
76
+ }
77
+ /** Doubly-linked vertex node (three `VertexNode`). */
78
+ export declare class VertexNode {
79
+ readonly point: Vector3;
80
+ prev: VertexNode | null;
81
+ next: VertexNode | null;
82
+ face: ConvexHullFace | null;
83
+ constructor(point: Vector3);
84
+ }
85
+ /** Doubly-linked vertex list (three `VertexList`). */
86
+ export declare class VertexList {
87
+ head: VertexNode | null;
88
+ tail: VertexNode | null;
89
+ first(): VertexNode | null;
90
+ last(): VertexNode | null;
91
+ clear(): this;
92
+ insertBefore(target: VertexNode, vertex: VertexNode): this;
93
+ insertAfter(target: VertexNode, vertex: VertexNode): this;
94
+ append(vertex: VertexNode): this;
95
+ appendChain(vertex: VertexNode): this;
96
+ remove(vertex: VertexNode): this;
97
+ removeSubList(a: VertexNode, b: VertexNode): this;
98
+ isEmpty(): boolean;
99
+ }
100
+ //# sourceMappingURL=ConvexHull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConvexHull.d.ts","sourceRoot":"","sources":["../../../../packages/math/src/ConvexHull.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,578 @@
1
+ import { Line3 } from "./Line3.js";
2
+ import { Plane } from "./Plane.js";
3
+ import { Triangle } from "./Triangle.js";
4
+ import { Vector3 } from "./Vector3.js";
5
+ const Visible = 0;
6
+ const Deleted = 1;
7
+ /**
8
+ * QuickHull convex hull — three.js `examples/jsm/math/ConvexHull.js` parity.
9
+ * The internal face/half-edge/vertex-list topology is mutable by design
10
+ * (QuickHull is a mutating algorithm); hull point data stays immutable.
11
+ */
12
+ export class ConvexHull {
13
+ tolerance = -1;
14
+ /** The generated faces of the convex hull. */
15
+ faces = [];
16
+ /** Faces generated within a single iteration. */
17
+ newFaces = [];
18
+ /** Vertices assigned to faces they can "see". */
19
+ assigned = new VertexList();
20
+ /** Vertices not (yet) assigned to any face. */
21
+ unassigned = new VertexList();
22
+ /** All hull vertices (internal representation). */
23
+ vertices = [];
24
+ /** three.js `ConvexHull.setFromPoints` — needs ≥ 4 points. */
25
+ setFromPoints(points) {
26
+ if (points.length >= 4) {
27
+ this.makeEmpty();
28
+ for (const point of points) {
29
+ this.vertices.push(new VertexNode(point));
30
+ }
31
+ this.compute();
32
+ }
33
+ return this;
34
+ }
35
+ /** three.js `ConvexHull.setFromObject`-equivalent over flat points. */
36
+ static fromPoints(points) {
37
+ return new ConvexHull().setFromPoints(points);
38
+ }
39
+ /** `true` when `point` is inside the hull (within `tolerance`). */
40
+ containsPoint(point) {
41
+ for (const face of this.faces) {
42
+ if (face.distanceToPoint(point) > this.tolerance)
43
+ return false;
44
+ }
45
+ return true;
46
+ }
47
+ /**
48
+ * Ray–hull intersection — "Fast Ray-Convex Polyhedron Intersection"
49
+ * (Haines, Graphics Gems II). Returns the nearer hit point or `undefined`.
50
+ */
51
+ intersectRay(ray) {
52
+ const faces = this.faces;
53
+ let tNear = -Infinity;
54
+ let tFar = Infinity;
55
+ for (const face of faces) {
56
+ const vN = face.distanceToPoint(ray.origin);
57
+ const vD = face.normal.dot(ray.direction);
58
+ // plane can "see" the origin and ray points away/parallel → no hit
59
+ if (vN > 0 && vD >= 0)
60
+ return undefined;
61
+ const t = vD !== 0 ? -vN / vD : 0;
62
+ if (t <= 0)
63
+ continue;
64
+ if (vD > 0) {
65
+ tFar = Math.min(t, tFar);
66
+ }
67
+ else {
68
+ tNear = Math.max(t, tNear);
69
+ }
70
+ if (tNear > tFar)
71
+ return undefined;
72
+ }
73
+ if (tNear !== -Infinity) {
74
+ return ray.at(tNear);
75
+ }
76
+ return ray.at(tFar);
77
+ }
78
+ intersectsRay(ray) {
79
+ return this.intersectRay(ray) !== undefined;
80
+ }
81
+ makeEmpty() {
82
+ this.faces = [];
83
+ this.vertices = [];
84
+ return this;
85
+ }
86
+ // ---- internals (verbatim QuickHull port) ----
87
+ addVertexToFace(vertex, face) {
88
+ vertex.face = face;
89
+ if (face.outside === null) {
90
+ this.assigned.append(vertex);
91
+ }
92
+ else {
93
+ this.assigned.insertBefore(face.outside, vertex);
94
+ }
95
+ face.outside = vertex;
96
+ }
97
+ removeVertexFromFace(vertex, face) {
98
+ if (vertex === face.outside) {
99
+ if (vertex.next !== null && vertex.next.face === face) {
100
+ face.outside = vertex.next;
101
+ }
102
+ else {
103
+ face.outside = null;
104
+ }
105
+ }
106
+ this.assigned.remove(vertex);
107
+ }
108
+ removeAllVerticesFromFace(face) {
109
+ if (face.outside !== null) {
110
+ const start = face.outside;
111
+ let end = face.outside;
112
+ while (end.next !== null && end.next.face === face) {
113
+ end = end.next;
114
+ }
115
+ this.assigned.removeSubList(start, end);
116
+ start.prev = null;
117
+ end.next = null;
118
+ face.outside = null;
119
+ return start;
120
+ }
121
+ return undefined;
122
+ }
123
+ deleteFaceVertices(face, absorbingFace) {
124
+ const faceVertices = this.removeAllVerticesFromFace(face);
125
+ if (faceVertices !== undefined) {
126
+ if (absorbingFace === undefined) {
127
+ this.unassigned.appendChain(faceVertices);
128
+ }
129
+ else {
130
+ let vertex = faceVertices;
131
+ do {
132
+ const nextVertex = vertex.next;
133
+ const distance = absorbingFace.distanceToPoint(vertex.point);
134
+ if (distance > this.tolerance) {
135
+ this.addVertexToFace(vertex, absorbingFace);
136
+ }
137
+ else {
138
+ this.unassigned.append(vertex);
139
+ }
140
+ vertex = nextVertex;
141
+ } while (vertex !== null);
142
+ }
143
+ }
144
+ }
145
+ resolveUnassignedPoints(newFaces) {
146
+ if (!this.unassigned.isEmpty()) {
147
+ let vertex = this.unassigned.first();
148
+ do {
149
+ const nextVertex = vertex.next;
150
+ let maxDistance = this.tolerance;
151
+ let maxFace = null;
152
+ for (const face of newFaces) {
153
+ if (face.mark === Visible) {
154
+ const distance = face.distanceToPoint(vertex.point);
155
+ if (distance > maxDistance) {
156
+ maxDistance = distance;
157
+ maxFace = face;
158
+ }
159
+ if (maxDistance > 1000 * this.tolerance)
160
+ break;
161
+ }
162
+ }
163
+ if (maxFace !== null) {
164
+ this.addVertexToFace(vertex, maxFace);
165
+ }
166
+ vertex = nextVertex;
167
+ } while (vertex !== null);
168
+ }
169
+ }
170
+ computeExtremes() {
171
+ const minVertices = [];
172
+ const maxVertices = [];
173
+ const min = this.vertices[0].point.toArray();
174
+ const max = this.vertices[0].point.toArray();
175
+ for (let i = 0; i < 3; i += 1) {
176
+ minVertices[i] = this.vertices[0];
177
+ maxVertices[i] = this.vertices[0];
178
+ }
179
+ for (const vertex of this.vertices) {
180
+ const point = vertex.point;
181
+ for (let j = 0; j < 3; j += 1) {
182
+ if (point.getComponent(j) < min[j]) {
183
+ min[j] = point.getComponent(j);
184
+ minVertices[j] = vertex;
185
+ }
186
+ }
187
+ for (let j = 0; j < 3; j += 1) {
188
+ if (point.getComponent(j) > max[j]) {
189
+ max[j] = point.getComponent(j);
190
+ maxVertices[j] = vertex;
191
+ }
192
+ }
193
+ }
194
+ this.tolerance =
195
+ 3 * Number.EPSILON *
196
+ (Math.max(Math.abs(min[0]), Math.abs(max[0])) +
197
+ Math.max(Math.abs(min[1]), Math.abs(max[1])) +
198
+ Math.max(Math.abs(min[2]), Math.abs(max[2])));
199
+ return { min: minVertices, max: maxVertices };
200
+ }
201
+ computeInitialHull() {
202
+ const vertices = this.vertices;
203
+ const extremes = this.computeExtremes();
204
+ const min = extremes.min;
205
+ const max = extremes.max;
206
+ // 1. v0/v1: greatest 1D separation
207
+ let maxDistance = 0;
208
+ let index = 0;
209
+ for (let i = 0; i < 3; i += 1) {
210
+ const distance = max[i].point.getComponent(i) - min[i].point.getComponent(i);
211
+ if (distance > maxDistance) {
212
+ maxDistance = distance;
213
+ index = i;
214
+ }
215
+ }
216
+ const v0 = min[index];
217
+ const v1 = max[index];
218
+ let v2;
219
+ let v3;
220
+ // 2. v2: farthest from line v0–v1
221
+ maxDistance = 0;
222
+ const line3 = new Line3(v0.point, v1.point);
223
+ for (const vertex of vertices) {
224
+ if (vertex !== v0 && vertex !== v1) {
225
+ const closest = line3.closestPointToPoint(vertex.point, true);
226
+ const distance = closest.distanceToSquared(vertex.point);
227
+ if (distance > maxDistance) {
228
+ maxDistance = distance;
229
+ v2 = vertex;
230
+ }
231
+ }
232
+ }
233
+ // 3. v3: farthest from plane v0,v1,v2
234
+ maxDistance = -1;
235
+ const plane = Plane.fromCoplanarPoints(v0.point, v1.point, v2.point);
236
+ for (const vertex of vertices) {
237
+ if (vertex !== v0 && vertex !== v1 && vertex !== v2) {
238
+ const distance = Math.abs(plane.distanceToPoint(vertex.point));
239
+ if (distance > maxDistance) {
240
+ maxDistance = distance;
241
+ v3 = vertex;
242
+ }
243
+ }
244
+ }
245
+ const faces = [];
246
+ if (plane.distanceToPoint(v3.point) < 0) {
247
+ faces.push(ConvexHullFace.create(v0, v1, v2), ConvexHullFace.create(v3, v1, v0), ConvexHullFace.create(v3, v2, v1), ConvexHullFace.create(v3, v0, v2));
248
+ for (let i = 0; i < 3; i += 1) {
249
+ const j = (i + 1) % 3;
250
+ faces[i + 1].getEdge(2).setTwin(faces[0].getEdge(j));
251
+ faces[i + 1].getEdge(1).setTwin(faces[j + 1].getEdge(0));
252
+ }
253
+ }
254
+ else {
255
+ faces.push(ConvexHullFace.create(v0, v2, v1), ConvexHullFace.create(v3, v0, v1), ConvexHullFace.create(v3, v1, v2), ConvexHullFace.create(v3, v2, v0));
256
+ for (let i = 0; i < 3; i += 1) {
257
+ const j = (i + 1) % 3;
258
+ faces[i + 1].getEdge(2).setTwin(faces[0].getEdge((3 - i) % 3));
259
+ faces[i + 1].getEdge(0).setTwin(faces[j + 1].getEdge(1));
260
+ }
261
+ }
262
+ for (const face of faces) {
263
+ this.faces.push(face);
264
+ }
265
+ // initial assignment of vertices to the tetrahedron faces
266
+ for (const vertex of vertices) {
267
+ if (vertex !== v0 && vertex !== v1 && vertex !== v2 && vertex !== v3) {
268
+ maxDistance = this.tolerance;
269
+ let maxFace = null;
270
+ for (let j = 0; j < 4; j += 1) {
271
+ const distance = this.faces[j].distanceToPoint(vertex.point);
272
+ if (distance > maxDistance) {
273
+ maxDistance = distance;
274
+ maxFace = this.faces[j];
275
+ }
276
+ }
277
+ if (maxFace !== null) {
278
+ this.addVertexToFace(vertex, maxFace);
279
+ }
280
+ }
281
+ }
282
+ }
283
+ reindexFaces() {
284
+ const activeFaces = [];
285
+ for (const face of this.faces) {
286
+ if (face.mark === Visible) {
287
+ activeFaces.push(face);
288
+ }
289
+ }
290
+ this.faces = activeFaces;
291
+ }
292
+ nextVertexToAdd() {
293
+ if (!this.assigned.isEmpty()) {
294
+ let eyeVertex;
295
+ let maxDistance = 0;
296
+ const eyeFace = this.assigned.first().face;
297
+ let vertex = eyeFace.outside;
298
+ do {
299
+ const distance = eyeFace.distanceToPoint(vertex.point);
300
+ if (distance > maxDistance) {
301
+ maxDistance = distance;
302
+ eyeVertex = vertex;
303
+ }
304
+ vertex = vertex.next;
305
+ } while (vertex !== null && vertex.face === eyeFace);
306
+ return eyeVertex;
307
+ }
308
+ return undefined;
309
+ }
310
+ computeHorizon(eyePoint, crossEdge, face, horizon) {
311
+ this.deleteFaceVertices(face);
312
+ face.mark = Deleted;
313
+ let edge;
314
+ let cross = crossEdge;
315
+ if (cross === null) {
316
+ cross = face.getEdge(0);
317
+ edge = cross;
318
+ }
319
+ else {
320
+ edge = cross.next;
321
+ }
322
+ do {
323
+ const twinEdge = edge.twin;
324
+ const oppositeFace = twinEdge.face;
325
+ if (oppositeFace.mark === Visible) {
326
+ if (oppositeFace.distanceToPoint(eyePoint) > this.tolerance) {
327
+ this.computeHorizon(eyePoint, twinEdge, oppositeFace, horizon);
328
+ }
329
+ else {
330
+ horizon.push(edge);
331
+ }
332
+ }
333
+ edge = edge.next;
334
+ } while (edge !== cross);
335
+ }
336
+ addAdjoiningFace(eyeVertex, horizonEdge) {
337
+ const face = ConvexHullFace.create(eyeVertex, horizonEdge.tail(), horizonEdge.head());
338
+ this.faces.push(face);
339
+ face.getEdge(-1).setTwin(horizonEdge.twin);
340
+ return face.getEdge(0);
341
+ }
342
+ addNewFaces(eyeVertex, horizon) {
343
+ this.newFaces = [];
344
+ let firstSideEdge = null;
345
+ let previousSideEdge = null;
346
+ for (const horizonEdge of horizon) {
347
+ const sideEdge = this.addAdjoiningFace(eyeVertex, horizonEdge);
348
+ if (firstSideEdge === null) {
349
+ firstSideEdge = sideEdge;
350
+ }
351
+ else {
352
+ sideEdge.next.setTwin(previousSideEdge);
353
+ }
354
+ this.newFaces.push(sideEdge.face);
355
+ previousSideEdge = sideEdge;
356
+ }
357
+ firstSideEdge.next.setTwin(previousSideEdge);
358
+ }
359
+ addVertexToHull(eyeVertex) {
360
+ const horizon = [];
361
+ this.unassigned.clear();
362
+ this.removeVertexFromFace(eyeVertex, eyeVertex.face);
363
+ this.computeHorizon(eyeVertex.point, null, eyeVertex.face, horizon);
364
+ this.addNewFaces(eyeVertex, horizon);
365
+ this.resolveUnassignedPoints(this.newFaces);
366
+ }
367
+ cleanup() {
368
+ this.assigned.clear();
369
+ this.unassigned.clear();
370
+ this.newFaces = [];
371
+ }
372
+ compute() {
373
+ this.computeInitialHull();
374
+ let vertex;
375
+ while ((vertex = this.nextVertexToAdd()) !== undefined) {
376
+ this.addVertexToHull(vertex);
377
+ }
378
+ this.reindexFaces();
379
+ this.cleanup();
380
+ return this;
381
+ }
382
+ }
383
+ /** Hull face — holds a half-edge loop plus plane data. */
384
+ export class ConvexHullFace {
385
+ normal = new Vector3(0, 0, 0);
386
+ midpoint = new Vector3(0, 0, 0);
387
+ area = 0;
388
+ constant = 0;
389
+ outside = null;
390
+ mark = Visible;
391
+ edge = null;
392
+ static create(a, b, c) {
393
+ const face = new ConvexHullFace();
394
+ const e0 = new HalfEdge(a, face);
395
+ const e1 = new HalfEdge(b, face);
396
+ const e2 = new HalfEdge(c, face);
397
+ e0.next = e2.prev = e1;
398
+ e1.next = e0.prev = e2;
399
+ e2.next = e1.prev = e0;
400
+ face.edge = e0;
401
+ return face.compute();
402
+ }
403
+ getEdge(i) {
404
+ let edge = this.edge;
405
+ while (i > 0) {
406
+ edge = edge.next;
407
+ i -= 1;
408
+ }
409
+ while (i < 0) {
410
+ edge = edge.prev;
411
+ i += 1;
412
+ }
413
+ return edge;
414
+ }
415
+ compute() {
416
+ const a = this.edge.tail();
417
+ const b = this.edge.head();
418
+ const c = this.edge.next.head();
419
+ const triangle = new Triangle(a.point, b.point, c.point);
420
+ this.normal = triangle.getNormal();
421
+ this.midpoint = triangle.getMidpoint();
422
+ this.area = triangle.getArea();
423
+ this.constant = this.normal.dot(this.midpoint);
424
+ return this;
425
+ }
426
+ distanceToPoint(point) {
427
+ return this.normal.dot(point) - this.constant;
428
+ }
429
+ }
430
+ /** Doubly-linked half-edge (three `HalfEdge`). */
431
+ export class HalfEdge {
432
+ vertex;
433
+ face;
434
+ prev = null;
435
+ next = null;
436
+ twin = null;
437
+ constructor(vertex, face) {
438
+ this.vertex = vertex;
439
+ this.face = face;
440
+ }
441
+ head() {
442
+ return this.vertex;
443
+ }
444
+ tail() {
445
+ return this.prev ? this.prev.vertex : null;
446
+ }
447
+ length() {
448
+ const head = this.head();
449
+ const tail = this.tail();
450
+ if (tail !== null) {
451
+ return tail.point.distanceTo(head.point);
452
+ }
453
+ return -1;
454
+ }
455
+ lengthSquared() {
456
+ const head = this.head();
457
+ const tail = this.tail();
458
+ if (tail !== null) {
459
+ return tail.point.distanceToSquared(head.point);
460
+ }
461
+ return -1;
462
+ }
463
+ setTwin(edge) {
464
+ this.twin = edge;
465
+ edge.twin = this;
466
+ return this;
467
+ }
468
+ }
469
+ /** Doubly-linked vertex node (three `VertexNode`). */
470
+ export class VertexNode {
471
+ point;
472
+ prev = null;
473
+ next = null;
474
+ face = null;
475
+ constructor(point) {
476
+ this.point = point;
477
+ }
478
+ }
479
+ /** Doubly-linked vertex list (three `VertexList`). */
480
+ export class VertexList {
481
+ head = null;
482
+ tail = null;
483
+ first() {
484
+ return this.head;
485
+ }
486
+ last() {
487
+ return this.tail;
488
+ }
489
+ clear() {
490
+ this.head = this.tail = null;
491
+ return this;
492
+ }
493
+ insertBefore(target, vertex) {
494
+ vertex.prev = target.prev;
495
+ vertex.next = target;
496
+ if (vertex.prev === null) {
497
+ this.head = vertex;
498
+ }
499
+ else {
500
+ vertex.prev.next = vertex;
501
+ }
502
+ target.prev = vertex;
503
+ return this;
504
+ }
505
+ insertAfter(target, vertex) {
506
+ vertex.prev = target;
507
+ vertex.next = target.next;
508
+ if (vertex.next === null) {
509
+ this.tail = vertex;
510
+ }
511
+ else {
512
+ vertex.next.prev = vertex;
513
+ }
514
+ target.next = vertex;
515
+ return this;
516
+ }
517
+ append(vertex) {
518
+ if (this.head === null) {
519
+ this.head = vertex;
520
+ }
521
+ else {
522
+ this.tail.next = vertex;
523
+ }
524
+ vertex.prev = this.tail;
525
+ vertex.next = null;
526
+ this.tail = vertex;
527
+ return this;
528
+ }
529
+ appendChain(vertex) {
530
+ if (this.head === null) {
531
+ this.head = vertex;
532
+ }
533
+ else {
534
+ this.tail.next = vertex;
535
+ }
536
+ vertex.prev = this.tail;
537
+ let v = vertex;
538
+ while (v.next !== null) {
539
+ v = v.next;
540
+ }
541
+ this.tail = v;
542
+ return this;
543
+ }
544
+ remove(vertex) {
545
+ if (vertex.prev === null) {
546
+ this.head = vertex.next;
547
+ }
548
+ else {
549
+ vertex.prev.next = vertex.next;
550
+ }
551
+ if (vertex.next === null) {
552
+ this.tail = vertex.prev;
553
+ }
554
+ else {
555
+ vertex.next.prev = vertex.prev;
556
+ }
557
+ return this;
558
+ }
559
+ removeSubList(a, b) {
560
+ if (a.prev === null) {
561
+ this.head = b.next;
562
+ }
563
+ else {
564
+ a.prev.next = b.next;
565
+ }
566
+ if (b.next === null) {
567
+ this.tail = a.prev;
568
+ }
569
+ else {
570
+ b.next.prev = a.prev;
571
+ }
572
+ return this;
573
+ }
574
+ isEmpty() {
575
+ return this.head === null;
576
+ }
577
+ }
578
+ //# sourceMappingURL=ConvexHull.js.map