@math.gl/culling 3.6.2 → 4.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/{esm/constants.js → constants.js} +0 -0
  2. package/dist/constants.js.map +1 -0
  3. package/dist/index.cjs +1049 -0
  4. package/dist/index.js +12 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/{esm/lib → lib}/algorithms/bounding-box-from-points.js +3 -3
  7. package/dist/lib/algorithms/bounding-box-from-points.js.map +1 -0
  8. package/dist/{esm/lib → lib}/algorithms/bounding-sphere-from-points.js +1 -2
  9. package/dist/lib/algorithms/bounding-sphere-from-points.js.map +1 -0
  10. package/dist/lib/algorithms/compute-eigen-decomposition.d.ts +1 -1
  11. package/dist/lib/algorithms/compute-eigen-decomposition.d.ts.map +1 -1
  12. package/dist/{esm/lib → lib}/algorithms/compute-eigen-decomposition.js +0 -0
  13. package/dist/lib/algorithms/compute-eigen-decomposition.js.map +1 -0
  14. package/dist/{esm/lib → lib}/bounding-volumes/axis-aligned-bounding-box.js +1 -1
  15. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -0
  16. package/dist/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -1
  17. package/dist/{esm/lib → lib}/bounding-volumes/bounding-sphere.js +1 -1
  18. package/dist/lib/bounding-volumes/bounding-sphere.js.map +1 -0
  19. package/dist/{esm/lib → lib}/bounding-volumes/bounding-volume.js +0 -0
  20. package/dist/{es5/lib → lib}/bounding-volumes/bounding-volume.js.map +0 -0
  21. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +2 -2
  22. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -1
  23. package/dist/{esm/lib → lib}/bounding-volumes/oriented-bounding-box.js +2 -2
  24. package/dist/lib/bounding-volumes/oriented-bounding-box.js.map +1 -0
  25. package/dist/{esm/lib → lib}/culling-volume.js +2 -5
  26. package/dist/lib/culling-volume.js.map +1 -0
  27. package/dist/lib/perspective-frustum.d.ts +1 -1
  28. package/dist/lib/perspective-frustum.d.ts.map +1 -1
  29. package/dist/{esm/lib → lib}/perspective-frustum.js +1 -1
  30. package/dist/lib/perspective-frustum.js.map +1 -0
  31. package/dist/lib/perspective-off-center-frustum.d.ts +1 -1
  32. package/dist/lib/perspective-off-center-frustum.d.ts.map +1 -1
  33. package/dist/{esm/lib → lib}/perspective-off-center-frustum.js +2 -2
  34. package/dist/lib/perspective-off-center-frustum.js.map +1 -0
  35. package/dist/{esm/lib → lib}/plane.js +3 -3
  36. package/dist/lib/plane.js.map +1 -0
  37. package/package.json +7 -6
  38. package/src/lib/algorithms/bounding-sphere-from-points.ts +1 -1
  39. package/src/lib/bounding-volumes/bounding-sphere.ts +2 -0
  40. package/src/lib/bounding-volumes/bounding-volume.ts +1 -1
  41. package/src/lib/bounding-volumes/oriented-bounding-box.ts +5 -2
  42. package/src/lib/culling-volume.ts +3 -3
  43. package/src/lib/perspective-frustum.ts +1 -1
  44. package/src/lib/plane.ts +4 -4
  45. package/dist/es5/constants.js +0 -13
  46. package/dist/es5/constants.js.map +0 -1
  47. package/dist/es5/index.js +0 -102
  48. package/dist/es5/index.js.map +0 -1
  49. package/dist/es5/lib/algorithms/bounding-box-from-points.js +0 -198
  50. package/dist/es5/lib/algorithms/bounding-box-from-points.js.map +0 -1
  51. package/dist/es5/lib/algorithms/bounding-sphere-from-points.js +0 -167
  52. package/dist/es5/lib/algorithms/bounding-sphere-from-points.js.map +0 -1
  53. package/dist/es5/lib/algorithms/compute-eigen-decomposition.js +0 -114
  54. package/dist/es5/lib/algorithms/compute-eigen-decomposition.js.map +0 -1
  55. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js +0 -114
  56. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js.map +0 -1
  57. package/dist/es5/lib/bounding-volumes/bounding-sphere.js +0 -148
  58. package/dist/es5/lib/bounding-volumes/bounding-sphere.js.map +0 -1
  59. package/dist/es5/lib/bounding-volumes/bounding-volume.js +0 -2
  60. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js +0 -253
  61. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js.map +0 -1
  62. package/dist/es5/lib/culling-volume.js +0 -154
  63. package/dist/es5/lib/culling-volume.js.map +0 -1
  64. package/dist/es5/lib/perspective-frustum.js +0 -161
  65. package/dist/es5/lib/perspective-frustum.js.map +0 -1
  66. package/dist/es5/lib/perspective-off-center-frustum.js +0 -183
  67. package/dist/es5/lib/perspective-off-center-frustum.js.map +0 -1
  68. package/dist/es5/lib/plane.js +0 -94
  69. package/dist/es5/lib/plane.js.map +0 -1
  70. package/dist/esm/constants.js.map +0 -1
  71. package/dist/esm/index.js +0 -12
  72. package/dist/esm/index.js.map +0 -1
  73. package/dist/esm/lib/algorithms/bounding-box-from-points.js.map +0 -1
  74. package/dist/esm/lib/algorithms/bounding-sphere-from-points.js.map +0 -1
  75. package/dist/esm/lib/algorithms/compute-eigen-decomposition.js.map +0 -1
  76. package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js.map +0 -1
  77. package/dist/esm/lib/bounding-volumes/bounding-sphere.js.map +0 -1
  78. package/dist/esm/lib/bounding-volumes/bounding-volume.js.map +0 -1
  79. package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js.map +0 -1
  80. package/dist/esm/lib/culling-volume.js.map +0 -1
  81. package/dist/esm/lib/perspective-frustum.js.map +0 -1
  82. package/dist/esm/lib/perspective-off-center-frustum.js.map +0 -1
  83. package/dist/esm/lib/plane.js.map +0 -1
package/dist/index.cjs ADDED
@@ -0,0 +1,1049 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
+ mod
22
+ ));
23
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
+
25
+ // src/index.ts
26
+ var src_exports = {};
27
+ __export(src_exports, {
28
+ AxisAlignedBoundingBox: () => AxisAlignedBoundingBox,
29
+ BoundingSphere: () => BoundingSphere,
30
+ CullingVolume: () => CullingVolume,
31
+ INTERSECTION: () => INTERSECTION,
32
+ OrientedBoundingBox: () => OrientedBoundingBox,
33
+ Plane: () => Plane,
34
+ _PerspectiveFrustum: () => PerspectiveFrustum,
35
+ _PerspectiveOffCenterFrustum: () => PerspectiveOffCenterFrustum,
36
+ computeEigenDecomposition: () => computeEigenDecomposition,
37
+ makeAxisAlignedBoundingBoxFromPoints: () => makeAxisAlignedBoundingBoxFromPoints,
38
+ makeBoundingSphereFromPoints: () => makeBoundingSphereFromPoints,
39
+ makeOrientedBoundingBoxFromPoints: () => makeOrientedBoundingBoxFromPoints
40
+ });
41
+ module.exports = __toCommonJS(src_exports);
42
+
43
+ // src/constants.ts
44
+ var INTERSECTION = {
45
+ OUTSIDE: -1,
46
+ INTERSECTING: 0,
47
+ INSIDE: 1
48
+ };
49
+
50
+ // src/lib/bounding-volumes/axis-aligned-bounding-box.ts
51
+ var import_core = require("@math.gl/core");
52
+ var scratchVector = new import_core.Vector3();
53
+ var scratchNormal = new import_core.Vector3();
54
+ var AxisAlignedBoundingBox = class {
55
+ constructor(minimum = [0, 0, 0], maximum = [0, 0, 0], center) {
56
+ center = center || scratchVector.copy(minimum).add(maximum).scale(0.5);
57
+ this.center = new import_core.Vector3(center);
58
+ this.halfDiagonal = new import_core.Vector3(maximum).subtract(this.center);
59
+ this.minimum = new import_core.Vector3(minimum);
60
+ this.maximum = new import_core.Vector3(maximum);
61
+ }
62
+ clone() {
63
+ return new AxisAlignedBoundingBox(this.minimum, this.maximum, this.center);
64
+ }
65
+ equals(right) {
66
+ return this === right || Boolean(right) && this.minimum.equals(right.minimum) && this.maximum.equals(right.maximum);
67
+ }
68
+ transform(transform) {
69
+ this.center.transformAsPoint(transform);
70
+ this.halfDiagonal.transform(transform);
71
+ this.minimum.transform(transform);
72
+ this.maximum.transform(transform);
73
+ return this;
74
+ }
75
+ intersectPlane(plane) {
76
+ const { halfDiagonal } = this;
77
+ const normal = scratchNormal.from(plane.normal);
78
+ const e = halfDiagonal.x * Math.abs(normal.x) + halfDiagonal.y * Math.abs(normal.y) + halfDiagonal.z * Math.abs(normal.z);
79
+ const s = this.center.dot(normal) + plane.distance;
80
+ if (s - e > 0) {
81
+ return INTERSECTION.INSIDE;
82
+ }
83
+ if (s + e < 0) {
84
+ return INTERSECTION.OUTSIDE;
85
+ }
86
+ return INTERSECTION.INTERSECTING;
87
+ }
88
+ distanceTo(point) {
89
+ return Math.sqrt(this.distanceSquaredTo(point));
90
+ }
91
+ distanceSquaredTo(point) {
92
+ const offset = scratchVector.from(point).subtract(this.center);
93
+ const { halfDiagonal } = this;
94
+ let distanceSquared = 0;
95
+ let d;
96
+ d = Math.abs(offset.x) - halfDiagonal.x;
97
+ if (d > 0) {
98
+ distanceSquared += d * d;
99
+ }
100
+ d = Math.abs(offset.y) - halfDiagonal.y;
101
+ if (d > 0) {
102
+ distanceSquared += d * d;
103
+ }
104
+ d = Math.abs(offset.z) - halfDiagonal.z;
105
+ if (d > 0) {
106
+ distanceSquared += d * d;
107
+ }
108
+ return distanceSquared;
109
+ }
110
+ };
111
+
112
+ // src/lib/bounding-volumes/bounding-sphere.ts
113
+ var import_core2 = require("@math.gl/core");
114
+ var mat4 = __toESM(require("gl-matrix/mat4"), 1);
115
+ var scratchVector2 = new import_core2.Vector3();
116
+ var scratchVector22 = new import_core2.Vector3();
117
+ var BoundingSphere = class {
118
+ constructor(center = [0, 0, 0], radius = 0) {
119
+ this.radius = -0;
120
+ this.center = new import_core2.Vector3();
121
+ this.fromCenterRadius(center, radius);
122
+ }
123
+ fromCenterRadius(center, radius) {
124
+ this.center.from(center);
125
+ this.radius = radius;
126
+ return this;
127
+ }
128
+ fromCornerPoints(corner, oppositeCorner) {
129
+ oppositeCorner = scratchVector2.from(oppositeCorner);
130
+ this.center = new import_core2.Vector3().from(corner).add(oppositeCorner).scale(0.5);
131
+ this.radius = this.center.distance(oppositeCorner);
132
+ return this;
133
+ }
134
+ equals(right) {
135
+ return this === right || Boolean(right) && this.center.equals(right.center) && this.radius === right.radius;
136
+ }
137
+ clone() {
138
+ return new BoundingSphere(this.center, this.radius);
139
+ }
140
+ union(boundingSphere) {
141
+ const leftCenter = this.center;
142
+ const leftRadius = this.radius;
143
+ const rightCenter = boundingSphere.center;
144
+ const rightRadius = boundingSphere.radius;
145
+ const toRightCenter = scratchVector2.copy(rightCenter).subtract(leftCenter);
146
+ const centerSeparation = toRightCenter.magnitude();
147
+ if (leftRadius >= centerSeparation + rightRadius) {
148
+ return this.clone();
149
+ }
150
+ if (rightRadius >= centerSeparation + leftRadius) {
151
+ return boundingSphere.clone();
152
+ }
153
+ const halfDistanceBetweenTangentPoints = (leftRadius + centerSeparation + rightRadius) * 0.5;
154
+ scratchVector22.copy(toRightCenter).scale((-leftRadius + halfDistanceBetweenTangentPoints) / centerSeparation).add(leftCenter);
155
+ this.center.copy(scratchVector22);
156
+ this.radius = halfDistanceBetweenTangentPoints;
157
+ return this;
158
+ }
159
+ expand(point) {
160
+ const scratchPoint = scratchVector2.from(point);
161
+ const radius = scratchPoint.subtract(this.center).magnitude();
162
+ if (radius > this.radius) {
163
+ this.radius = radius;
164
+ }
165
+ return this;
166
+ }
167
+ transform(transform) {
168
+ this.center.transform(transform);
169
+ const scale = mat4.getScaling(scratchVector2, transform);
170
+ this.radius = Math.max(scale[0], Math.max(scale[1], scale[2])) * this.radius;
171
+ return this;
172
+ }
173
+ distanceSquaredTo(point) {
174
+ const d = this.distanceTo(point);
175
+ return d * d;
176
+ }
177
+ distanceTo(point) {
178
+ const scratchPoint = scratchVector2.from(point);
179
+ const delta = scratchPoint.subtract(this.center);
180
+ return Math.max(0, delta.len() - this.radius);
181
+ }
182
+ intersectPlane(plane) {
183
+ const center = this.center;
184
+ const radius = this.radius;
185
+ const normal = plane.normal;
186
+ const distanceToPlane = normal.dot(center) + plane.distance;
187
+ if (distanceToPlane < -radius) {
188
+ return INTERSECTION.OUTSIDE;
189
+ }
190
+ if (distanceToPlane < radius) {
191
+ return INTERSECTION.INTERSECTING;
192
+ }
193
+ return INTERSECTION.INSIDE;
194
+ }
195
+ };
196
+
197
+ // src/lib/bounding-volumes/oriented-bounding-box.ts
198
+ var import_core3 = require("@math.gl/core");
199
+ var scratchVector3 = new import_core3.Vector3();
200
+ var scratchOffset = new import_core3.Vector3();
201
+ var scratchVectorU = new import_core3.Vector3();
202
+ var scratchVectorV = new import_core3.Vector3();
203
+ var scratchVectorW = new import_core3.Vector3();
204
+ var scratchCorner = new import_core3.Vector3();
205
+ var scratchToCenter = new import_core3.Vector3();
206
+ var MATRIX3 = {
207
+ COLUMN0ROW0: 0,
208
+ COLUMN0ROW1: 1,
209
+ COLUMN0ROW2: 2,
210
+ COLUMN1ROW0: 3,
211
+ COLUMN1ROW1: 4,
212
+ COLUMN1ROW2: 5,
213
+ COLUMN2ROW0: 6,
214
+ COLUMN2ROW1: 7,
215
+ COLUMN2ROW2: 8
216
+ };
217
+ var OrientedBoundingBox = class {
218
+ constructor(center = [0, 0, 0], halfAxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]) {
219
+ this.center = new import_core3.Vector3().from(center);
220
+ this.halfAxes = new import_core3.Matrix3(halfAxes);
221
+ }
222
+ get halfSize() {
223
+ const xAxis = this.halfAxes.getColumn(0);
224
+ const yAxis = this.halfAxes.getColumn(1);
225
+ const zAxis = this.halfAxes.getColumn(2);
226
+ return [new import_core3.Vector3(xAxis).len(), new import_core3.Vector3(yAxis).len(), new import_core3.Vector3(zAxis).len()];
227
+ }
228
+ get quaternion() {
229
+ const xAxis = this.halfAxes.getColumn(0);
230
+ const yAxis = this.halfAxes.getColumn(1);
231
+ const zAxis = this.halfAxes.getColumn(2);
232
+ const normXAxis = new import_core3.Vector3(xAxis).normalize();
233
+ const normYAxis = new import_core3.Vector3(yAxis).normalize();
234
+ const normZAxis = new import_core3.Vector3(zAxis).normalize();
235
+ return new import_core3.Quaternion().fromMatrix3(new import_core3.Matrix3([...normXAxis, ...normYAxis, ...normZAxis]));
236
+ }
237
+ fromCenterHalfSizeQuaternion(center, halfSize, quaternion) {
238
+ const quaternionObject = new import_core3.Quaternion(quaternion);
239
+ const directionsMatrix = new import_core3.Matrix3().fromQuaternion(quaternionObject);
240
+ directionsMatrix[0] = directionsMatrix[0] * halfSize[0];
241
+ directionsMatrix[1] = directionsMatrix[1] * halfSize[0];
242
+ directionsMatrix[2] = directionsMatrix[2] * halfSize[0];
243
+ directionsMatrix[3] = directionsMatrix[3] * halfSize[1];
244
+ directionsMatrix[4] = directionsMatrix[4] * halfSize[1];
245
+ directionsMatrix[5] = directionsMatrix[5] * halfSize[1];
246
+ directionsMatrix[6] = directionsMatrix[6] * halfSize[2];
247
+ directionsMatrix[7] = directionsMatrix[7] * halfSize[2];
248
+ directionsMatrix[8] = directionsMatrix[8] * halfSize[2];
249
+ this.center = new import_core3.Vector3().from(center);
250
+ this.halfAxes = directionsMatrix;
251
+ return this;
252
+ }
253
+ clone() {
254
+ return new OrientedBoundingBox(this.center, this.halfAxes);
255
+ }
256
+ equals(right) {
257
+ return this === right || Boolean(right) && this.center.equals(right.center) && this.halfAxes.equals(right.halfAxes);
258
+ }
259
+ getBoundingSphere(result = new BoundingSphere()) {
260
+ const halfAxes = this.halfAxes;
261
+ const u = halfAxes.getColumn(0, scratchVectorU);
262
+ const v = halfAxes.getColumn(1, scratchVectorV);
263
+ const w = halfAxes.getColumn(2, scratchVectorW);
264
+ const cornerVector = scratchVector3.copy(u).add(v).add(w);
265
+ result.center.copy(this.center);
266
+ result.radius = cornerVector.magnitude();
267
+ return result;
268
+ }
269
+ intersectPlane(plane) {
270
+ const center = this.center;
271
+ const normal = plane.normal;
272
+ const halfAxes = this.halfAxes;
273
+ const normalX = normal.x;
274
+ const normalY = normal.y;
275
+ const normalZ = normal.z;
276
+ const radEffective = Math.abs(
277
+ normalX * halfAxes[MATRIX3.COLUMN0ROW0] + normalY * halfAxes[MATRIX3.COLUMN0ROW1] + normalZ * halfAxes[MATRIX3.COLUMN0ROW2]
278
+ ) + Math.abs(
279
+ normalX * halfAxes[MATRIX3.COLUMN1ROW0] + normalY * halfAxes[MATRIX3.COLUMN1ROW1] + normalZ * halfAxes[MATRIX3.COLUMN1ROW2]
280
+ ) + Math.abs(
281
+ normalX * halfAxes[MATRIX3.COLUMN2ROW0] + normalY * halfAxes[MATRIX3.COLUMN2ROW1] + normalZ * halfAxes[MATRIX3.COLUMN2ROW2]
282
+ );
283
+ const distanceToPlane = normal.dot(center) + plane.distance;
284
+ if (distanceToPlane <= -radEffective) {
285
+ return INTERSECTION.OUTSIDE;
286
+ } else if (distanceToPlane >= radEffective) {
287
+ return INTERSECTION.INSIDE;
288
+ }
289
+ return INTERSECTION.INTERSECTING;
290
+ }
291
+ distanceTo(point) {
292
+ return Math.sqrt(this.distanceSquaredTo(point));
293
+ }
294
+ distanceSquaredTo(point) {
295
+ const offset = scratchOffset.from(point).subtract(this.center);
296
+ const halfAxes = this.halfAxes;
297
+ const u = halfAxes.getColumn(0, scratchVectorU);
298
+ const v = halfAxes.getColumn(1, scratchVectorV);
299
+ const w = halfAxes.getColumn(2, scratchVectorW);
300
+ const uHalf = u.magnitude();
301
+ const vHalf = v.magnitude();
302
+ const wHalf = w.magnitude();
303
+ u.normalize();
304
+ v.normalize();
305
+ w.normalize();
306
+ let distanceSquared = 0;
307
+ let d;
308
+ d = Math.abs(offset.dot(u)) - uHalf;
309
+ if (d > 0) {
310
+ distanceSquared += d * d;
311
+ }
312
+ d = Math.abs(offset.dot(v)) - vHalf;
313
+ if (d > 0) {
314
+ distanceSquared += d * d;
315
+ }
316
+ d = Math.abs(offset.dot(w)) - wHalf;
317
+ if (d > 0) {
318
+ distanceSquared += d * d;
319
+ }
320
+ return distanceSquared;
321
+ }
322
+ computePlaneDistances(position, direction, result = [-0, -0]) {
323
+ let minDist = Number.POSITIVE_INFINITY;
324
+ let maxDist = Number.NEGATIVE_INFINITY;
325
+ const center = this.center;
326
+ const halfAxes = this.halfAxes;
327
+ const u = halfAxes.getColumn(0, scratchVectorU);
328
+ const v = halfAxes.getColumn(1, scratchVectorV);
329
+ const w = halfAxes.getColumn(2, scratchVectorW);
330
+ const corner = scratchCorner.copy(u).add(v).add(w).add(center);
331
+ const toCenter = scratchToCenter.copy(corner).subtract(position);
332
+ let mag = direction.dot(toCenter);
333
+ minDist = Math.min(mag, minDist);
334
+ maxDist = Math.max(mag, maxDist);
335
+ corner.copy(center).add(u).add(v).subtract(w);
336
+ toCenter.copy(corner).subtract(position);
337
+ mag = direction.dot(toCenter);
338
+ minDist = Math.min(mag, minDist);
339
+ maxDist = Math.max(mag, maxDist);
340
+ corner.copy(center).add(u).subtract(v).add(w);
341
+ toCenter.copy(corner).subtract(position);
342
+ mag = direction.dot(toCenter);
343
+ minDist = Math.min(mag, minDist);
344
+ maxDist = Math.max(mag, maxDist);
345
+ corner.copy(center).add(u).subtract(v).subtract(w);
346
+ toCenter.copy(corner).subtract(position);
347
+ mag = direction.dot(toCenter);
348
+ minDist = Math.min(mag, minDist);
349
+ maxDist = Math.max(mag, maxDist);
350
+ center.copy(corner).subtract(u).add(v).add(w);
351
+ toCenter.copy(corner).subtract(position);
352
+ mag = direction.dot(toCenter);
353
+ minDist = Math.min(mag, minDist);
354
+ maxDist = Math.max(mag, maxDist);
355
+ center.copy(corner).subtract(u).add(v).subtract(w);
356
+ toCenter.copy(corner).subtract(position);
357
+ mag = direction.dot(toCenter);
358
+ minDist = Math.min(mag, minDist);
359
+ maxDist = Math.max(mag, maxDist);
360
+ center.copy(corner).subtract(u).subtract(v).add(w);
361
+ toCenter.copy(corner).subtract(position);
362
+ mag = direction.dot(toCenter);
363
+ minDist = Math.min(mag, minDist);
364
+ maxDist = Math.max(mag, maxDist);
365
+ center.copy(corner).subtract(u).subtract(v).subtract(w);
366
+ toCenter.copy(corner).subtract(position);
367
+ mag = direction.dot(toCenter);
368
+ minDist = Math.min(mag, minDist);
369
+ maxDist = Math.max(mag, maxDist);
370
+ result[0] = minDist;
371
+ result[1] = maxDist;
372
+ return result;
373
+ }
374
+ transform(transformation) {
375
+ this.center.transformAsPoint(transformation);
376
+ const xAxis = this.halfAxes.getColumn(0, scratchVectorU);
377
+ xAxis.transformAsPoint(transformation);
378
+ const yAxis = this.halfAxes.getColumn(1, scratchVectorV);
379
+ yAxis.transformAsPoint(transformation);
380
+ const zAxis = this.halfAxes.getColumn(2, scratchVectorW);
381
+ zAxis.transformAsPoint(transformation);
382
+ this.halfAxes = new import_core3.Matrix3([...xAxis, ...yAxis, ...zAxis]);
383
+ return this;
384
+ }
385
+ getTransform() {
386
+ throw new Error("not implemented");
387
+ }
388
+ };
389
+
390
+ // src/lib/culling-volume.ts
391
+ var import_core5 = require("@math.gl/core");
392
+
393
+ // src/lib/plane.ts
394
+ var import_core4 = require("@math.gl/core");
395
+ var scratchPosition = new import_core4.Vector3();
396
+ var scratchNormal2 = new import_core4.Vector3();
397
+ var Plane = class {
398
+ constructor(normal = [0, 0, 1], distance = 0) {
399
+ this.normal = new import_core4.Vector3();
400
+ this.distance = -0;
401
+ this.fromNormalDistance(normal, distance);
402
+ }
403
+ fromNormalDistance(normal, distance) {
404
+ (0, import_core4.assert)(Number.isFinite(distance));
405
+ this.normal.from(normal).normalize();
406
+ this.distance = distance;
407
+ return this;
408
+ }
409
+ fromPointNormal(point, normal) {
410
+ point = scratchPosition.from(point);
411
+ this.normal.from(normal).normalize();
412
+ const distance = -this.normal.dot(point);
413
+ this.distance = distance;
414
+ return this;
415
+ }
416
+ fromCoefficients(a, b, c, d) {
417
+ this.normal.set(a, b, c);
418
+ (0, import_core4.assert)((0, import_core4.equals)(this.normal.len(), 1));
419
+ this.distance = d;
420
+ return this;
421
+ }
422
+ clone() {
423
+ return new Plane(this.normal, this.distance);
424
+ }
425
+ equals(right) {
426
+ return (0, import_core4.equals)(this.distance, right.distance) && (0, import_core4.equals)(this.normal, right.normal);
427
+ }
428
+ getPointDistance(point) {
429
+ return this.normal.dot(point) + this.distance;
430
+ }
431
+ transform(matrix4) {
432
+ const normal = scratchNormal2.copy(this.normal).transformAsVector(matrix4).normalize();
433
+ const point = this.normal.scale(-this.distance).transform(matrix4);
434
+ return this.fromPointNormal(point, normal);
435
+ }
436
+ projectPointOntoPlane(point, result = [0, 0, 0]) {
437
+ const scratchPoint = scratchPosition.from(point);
438
+ const pointDistance = this.getPointDistance(scratchPoint);
439
+ const scaledNormal = scratchNormal2.copy(this.normal).scale(pointDistance);
440
+ return scratchPoint.subtract(scaledNormal).to(result);
441
+ }
442
+ };
443
+
444
+ // src/lib/culling-volume.ts
445
+ var faces = [new import_core5.Vector3([1, 0, 0]), new import_core5.Vector3([0, 1, 0]), new import_core5.Vector3([0, 0, 1])];
446
+ var scratchPlaneCenter = new import_core5.Vector3();
447
+ var scratchPlaneNormal = new import_core5.Vector3();
448
+ var _CullingVolume = class {
449
+ constructor(planes = []) {
450
+ this.planes = planes;
451
+ }
452
+ fromBoundingSphere(boundingSphere) {
453
+ this.planes.length = 2 * faces.length;
454
+ const center = boundingSphere.center;
455
+ const radius = boundingSphere.radius;
456
+ let planeIndex = 0;
457
+ for (const faceNormal of faces) {
458
+ let plane0 = this.planes[planeIndex];
459
+ let plane1 = this.planes[planeIndex + 1];
460
+ if (!plane0) {
461
+ plane0 = this.planes[planeIndex] = new Plane();
462
+ }
463
+ if (!plane1) {
464
+ plane1 = this.planes[planeIndex + 1] = new Plane();
465
+ }
466
+ const plane0Center = scratchPlaneCenter.copy(faceNormal).scale(-radius).add(center);
467
+ plane0.fromPointNormal(plane0Center, faceNormal);
468
+ const plane1Center = scratchPlaneCenter.copy(faceNormal).scale(radius).add(center);
469
+ const negatedFaceNormal = scratchPlaneNormal.copy(faceNormal).negate();
470
+ plane1.fromPointNormal(plane1Center, negatedFaceNormal);
471
+ planeIndex += 2;
472
+ }
473
+ return this;
474
+ }
475
+ computeVisibility(boundingVolume) {
476
+ let intersect = INTERSECTION.INSIDE;
477
+ for (const plane of this.planes) {
478
+ const result = boundingVolume.intersectPlane(plane);
479
+ switch (result) {
480
+ case INTERSECTION.OUTSIDE:
481
+ return INTERSECTION.OUTSIDE;
482
+ case INTERSECTION.INTERSECTING:
483
+ intersect = INTERSECTION.INTERSECTING;
484
+ break;
485
+ default:
486
+ }
487
+ }
488
+ return intersect;
489
+ }
490
+ computeVisibilityWithPlaneMask(boundingVolume, parentPlaneMask) {
491
+ (0, import_core5.assert)(Number.isFinite(parentPlaneMask), "parentPlaneMask is required.");
492
+ if (parentPlaneMask === _CullingVolume.MASK_OUTSIDE || parentPlaneMask === _CullingVolume.MASK_INSIDE) {
493
+ return parentPlaneMask;
494
+ }
495
+ let mask = _CullingVolume.MASK_INSIDE;
496
+ const planes = this.planes;
497
+ for (let k = 0; k < this.planes.length; ++k) {
498
+ const flag = k < 31 ? 1 << k : 0;
499
+ if (k < 31 && (parentPlaneMask & flag) === 0) {
500
+ continue;
501
+ }
502
+ const plane = planes[k];
503
+ const result = boundingVolume.intersectPlane(plane);
504
+ if (result === INTERSECTION.OUTSIDE) {
505
+ return _CullingVolume.MASK_OUTSIDE;
506
+ } else if (result === INTERSECTION.INTERSECTING) {
507
+ mask |= flag;
508
+ }
509
+ }
510
+ return mask;
511
+ }
512
+ };
513
+ var CullingVolume = _CullingVolume;
514
+ CullingVolume.MASK_OUTSIDE = 4294967295;
515
+ CullingVolume.MASK_INSIDE = 0;
516
+ CullingVolume.MASK_INDETERMINATE = 2147483647;
517
+
518
+ // src/lib/perspective-off-center-frustum.ts
519
+ var import_core6 = require("@math.gl/core");
520
+ var scratchPlaneUpVector = new import_core6.Vector3();
521
+ var scratchPlaneRightVector = new import_core6.Vector3();
522
+ var scratchPlaneNearCenter = new import_core6.Vector3();
523
+ var scratchPlaneFarCenter = new import_core6.Vector3();
524
+ var scratchPlaneNormal2 = new import_core6.Vector3();
525
+ var PerspectiveOffCenterFrustum = class {
526
+ constructor(options = {}) {
527
+ this._cullingVolume = new CullingVolume([
528
+ new Plane(),
529
+ new Plane(),
530
+ new Plane(),
531
+ new Plane(),
532
+ new Plane(),
533
+ new Plane()
534
+ ]);
535
+ this._perspectiveMatrix = new import_core6.Matrix4();
536
+ this._infinitePerspective = new import_core6.Matrix4();
537
+ const { near = 1, far = 5e8 } = options;
538
+ this.left = options.left;
539
+ this._left = void 0;
540
+ this.right = options.right;
541
+ this._right = void 0;
542
+ this.top = options.top;
543
+ this._top = void 0;
544
+ this.bottom = options.bottom;
545
+ this._bottom = void 0;
546
+ this.near = near;
547
+ this._near = near;
548
+ this.far = far;
549
+ this._far = far;
550
+ }
551
+ clone() {
552
+ return new PerspectiveOffCenterFrustum({
553
+ right: this.right,
554
+ left: this.left,
555
+ top: this.top,
556
+ bottom: this.bottom,
557
+ near: this.near,
558
+ far: this.far
559
+ });
560
+ }
561
+ equals(other) {
562
+ return other && other instanceof PerspectiveOffCenterFrustum && this.right === other.right && this.left === other.left && this.top === other.top && this.bottom === other.bottom && this.near === other.near && this.far === other.far;
563
+ }
564
+ get projectionMatrix() {
565
+ this._update();
566
+ return this._perspectiveMatrix;
567
+ }
568
+ get infiniteProjectionMatrix() {
569
+ this._update();
570
+ return this._infinitePerspective;
571
+ }
572
+ computeCullingVolume(position, direction, up) {
573
+ (0, import_core6.assert)(position, "position is required.");
574
+ (0, import_core6.assert)(direction, "direction is required.");
575
+ (0, import_core6.assert)(up, "up is required.");
576
+ const planes = this._cullingVolume.planes;
577
+ up = scratchPlaneUpVector.copy(up).normalize();
578
+ const right = scratchPlaneRightVector.copy(direction).cross(up).normalize();
579
+ const nearCenter = scratchPlaneNearCenter.copy(direction).multiplyByScalar(this.near).add(position);
580
+ const farCenter = scratchPlaneFarCenter.copy(direction).multiplyByScalar(this.far).add(position);
581
+ let normal = scratchPlaneNormal2;
582
+ normal.copy(right).multiplyByScalar(this.left).add(nearCenter).subtract(position).cross(up);
583
+ planes[0].fromPointNormal(position, normal);
584
+ normal.copy(right).multiplyByScalar(this.right).add(nearCenter).subtract(position).cross(up).negate();
585
+ planes[1].fromPointNormal(position, normal);
586
+ normal.copy(up).multiplyByScalar(this.bottom).add(nearCenter).subtract(position).cross(right).negate();
587
+ planes[2].fromPointNormal(position, normal);
588
+ normal.copy(up).multiplyByScalar(this.top).add(nearCenter).subtract(position).cross(right);
589
+ planes[3].fromPointNormal(position, normal);
590
+ normal = new import_core6.Vector3().copy(direction);
591
+ planes[4].fromPointNormal(nearCenter, normal);
592
+ normal.negate();
593
+ planes[5].fromPointNormal(farCenter, normal);
594
+ return this._cullingVolume;
595
+ }
596
+ getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result) {
597
+ this._update();
598
+ (0, import_core6.assert)(Number.isFinite(drawingBufferWidth) && Number.isFinite(drawingBufferHeight));
599
+ (0, import_core6.assert)(drawingBufferWidth > 0);
600
+ (0, import_core6.assert)(drawingBufferHeight > 0);
601
+ (0, import_core6.assert)(distance > 0);
602
+ (0, import_core6.assert)(result);
603
+ const inverseNear = 1 / this.near;
604
+ let tanTheta = this.top * inverseNear;
605
+ const pixelHeight = 2 * distance * tanTheta / drawingBufferHeight;
606
+ tanTheta = this.right * inverseNear;
607
+ const pixelWidth = 2 * distance * tanTheta / drawingBufferWidth;
608
+ result.x = pixelWidth;
609
+ result.y = pixelHeight;
610
+ return result;
611
+ }
612
+ _update() {
613
+ (0, import_core6.assert)(
614
+ Number.isFinite(this.right) && Number.isFinite(this.left) && Number.isFinite(this.top) && Number.isFinite(this.bottom) && Number.isFinite(this.near) && Number.isFinite(this.far)
615
+ );
616
+ const { top, bottom, right, left, near, far } = this;
617
+ if (top !== this._top || bottom !== this._bottom || left !== this._left || right !== this._right || near !== this._near || far !== this._far) {
618
+ (0, import_core6.assert)(
619
+ this.near > 0 && this.near < this.far,
620
+ "near must be greater than zero and less than far."
621
+ );
622
+ this._left = left;
623
+ this._right = right;
624
+ this._top = top;
625
+ this._bottom = bottom;
626
+ this._near = near;
627
+ this._far = far;
628
+ this._perspectiveMatrix = new import_core6.Matrix4().frustum({
629
+ left,
630
+ right,
631
+ bottom,
632
+ top,
633
+ near,
634
+ far
635
+ });
636
+ this._infinitePerspective = new import_core6.Matrix4().frustum({
637
+ left,
638
+ right,
639
+ bottom,
640
+ top,
641
+ near,
642
+ far: Infinity
643
+ });
644
+ }
645
+ }
646
+ };
647
+
648
+ // src/lib/perspective-frustum.ts
649
+ var import_core7 = require("@math.gl/core");
650
+ var defined = (val) => val !== null && typeof val !== "undefined";
651
+ var PerspectiveFrustum = class {
652
+ constructor(options = {}) {
653
+ this._offCenterFrustum = new PerspectiveOffCenterFrustum();
654
+ const { fov, aspectRatio, near = 1, far = 5e8, xOffset = 0, yOffset = 0 } = options;
655
+ this.fov = fov;
656
+ this.aspectRatio = aspectRatio;
657
+ this.near = near;
658
+ this.far = far;
659
+ this.xOffset = xOffset;
660
+ this.yOffset = yOffset;
661
+ }
662
+ clone() {
663
+ return new PerspectiveFrustum({
664
+ aspectRatio: this.aspectRatio,
665
+ fov: this.fov,
666
+ near: this.near,
667
+ far: this.far
668
+ });
669
+ }
670
+ equals(other) {
671
+ if (!defined(other) || !(other instanceof PerspectiveFrustum)) {
672
+ return false;
673
+ }
674
+ this._update();
675
+ other._update();
676
+ return this.fov === other.fov && this.aspectRatio === other.aspectRatio && this.near === other.near && this.far === other.far && this._offCenterFrustum.equals(other._offCenterFrustum);
677
+ }
678
+ get projectionMatrix() {
679
+ this._update();
680
+ return this._offCenterFrustum.projectionMatrix;
681
+ }
682
+ get infiniteProjectionMatrix() {
683
+ this._update();
684
+ return this._offCenterFrustum.infiniteProjectionMatrix;
685
+ }
686
+ get fovy() {
687
+ this._update();
688
+ return this._fovy;
689
+ }
690
+ get sseDenominator() {
691
+ this._update();
692
+ return this._sseDenominator;
693
+ }
694
+ computeCullingVolume(position, direction, up) {
695
+ this._update();
696
+ return this._offCenterFrustum.computeCullingVolume(position, direction, up);
697
+ }
698
+ getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result) {
699
+ this._update();
700
+ return this._offCenterFrustum.getPixelDimensions(
701
+ drawingBufferWidth,
702
+ drawingBufferHeight,
703
+ distance,
704
+ result || new import_core7.Vector2()
705
+ );
706
+ }
707
+ _update() {
708
+ (0, import_core7.assert)(
709
+ Number.isFinite(this.fov) && Number.isFinite(this.aspectRatio) && Number.isFinite(this.near) && Number.isFinite(this.far)
710
+ );
711
+ const f = this._offCenterFrustum;
712
+ if (this.fov !== this._fov || this.aspectRatio !== this._aspectRatio || this.near !== this._near || this.far !== this._far || this.xOffset !== this._xOffset || this.yOffset !== this._yOffset) {
713
+ (0, import_core7.assert)(this.fov >= 0 && this.fov < Math.PI);
714
+ (0, import_core7.assert)(this.aspectRatio > 0);
715
+ (0, import_core7.assert)(this.near >= 0 && this.near < this.far);
716
+ this._aspectRatio = this.aspectRatio;
717
+ this._fov = this.fov;
718
+ this._fovy = this.aspectRatio <= 1 ? this.fov : Math.atan(Math.tan(this.fov * 0.5) / this.aspectRatio) * 2;
719
+ this._near = this.near;
720
+ this._far = this.far;
721
+ this._sseDenominator = 2 * Math.tan(0.5 * this._fovy);
722
+ this._xOffset = this.xOffset;
723
+ this._yOffset = this.yOffset;
724
+ f.top = this.near * Math.tan(0.5 * this._fovy);
725
+ f.bottom = -f.top;
726
+ f.right = this.aspectRatio * f.top;
727
+ f.left = -f.right;
728
+ f.near = this.near;
729
+ f.far = this.far;
730
+ f.right += this.xOffset;
731
+ f.left += this.xOffset;
732
+ f.top += this.yOffset;
733
+ f.bottom += this.yOffset;
734
+ }
735
+ }
736
+ };
737
+
738
+ // src/lib/algorithms/bounding-sphere-from-points.ts
739
+ var import_core8 = require("@math.gl/core");
740
+ var fromPointsXMin = new import_core8.Vector3();
741
+ var fromPointsYMin = new import_core8.Vector3();
742
+ var fromPointsZMin = new import_core8.Vector3();
743
+ var fromPointsXMax = new import_core8.Vector3();
744
+ var fromPointsYMax = new import_core8.Vector3();
745
+ var fromPointsZMax = new import_core8.Vector3();
746
+ var fromPointsCurrentPos = new import_core8.Vector3();
747
+ var fromPointsScratch = new import_core8.Vector3();
748
+ var fromPointsRitterCenter = new import_core8.Vector3();
749
+ var fromPointsMinBoxPt = new import_core8.Vector3();
750
+ var fromPointsMaxBoxPt = new import_core8.Vector3();
751
+ var fromPointsNaiveCenterScratch = new import_core8.Vector3();
752
+ function makeBoundingSphereFromPoints(positions, result = new BoundingSphere()) {
753
+ if (!positions || positions.length === 0) {
754
+ return result.fromCenterRadius([0, 0, 0], 0);
755
+ }
756
+ const currentPos = fromPointsCurrentPos.copy(positions[0]);
757
+ const xMin = fromPointsXMin.copy(currentPos);
758
+ const yMin = fromPointsYMin.copy(currentPos);
759
+ const zMin = fromPointsZMin.copy(currentPos);
760
+ const xMax = fromPointsXMax.copy(currentPos);
761
+ const yMax = fromPointsYMax.copy(currentPos);
762
+ const zMax = fromPointsZMax.copy(currentPos);
763
+ for (const position of positions) {
764
+ currentPos.copy(position);
765
+ const x = currentPos.x;
766
+ const y = currentPos.y;
767
+ const z = currentPos.z;
768
+ if (x < xMin.x) {
769
+ xMin.copy(currentPos);
770
+ }
771
+ if (x > xMax.x) {
772
+ xMax.copy(currentPos);
773
+ }
774
+ if (y < yMin.y) {
775
+ yMin.copy(currentPos);
776
+ }
777
+ if (y > yMax.y) {
778
+ yMax.copy(currentPos);
779
+ }
780
+ if (z < zMin.z) {
781
+ zMin.copy(currentPos);
782
+ }
783
+ if (z > zMax.z) {
784
+ zMax.copy(currentPos);
785
+ }
786
+ }
787
+ const xSpan = fromPointsScratch.copy(xMax).subtract(xMin).magnitudeSquared();
788
+ const ySpan = fromPointsScratch.copy(yMax).subtract(yMin).magnitudeSquared();
789
+ const zSpan = fromPointsScratch.copy(zMax).subtract(zMin).magnitudeSquared();
790
+ let diameter1 = xMin;
791
+ let diameter2 = xMax;
792
+ let maxSpan = xSpan;
793
+ if (ySpan > maxSpan) {
794
+ maxSpan = ySpan;
795
+ diameter1 = yMin;
796
+ diameter2 = yMax;
797
+ }
798
+ if (zSpan > maxSpan) {
799
+ maxSpan = zSpan;
800
+ diameter1 = zMin;
801
+ diameter2 = zMax;
802
+ }
803
+ const ritterCenter = fromPointsRitterCenter;
804
+ ritterCenter.x = (diameter1.x + diameter2.x) * 0.5;
805
+ ritterCenter.y = (diameter1.y + diameter2.y) * 0.5;
806
+ ritterCenter.z = (diameter1.z + diameter2.z) * 0.5;
807
+ let radiusSquared = fromPointsScratch.copy(diameter2).subtract(ritterCenter).magnitudeSquared();
808
+ let ritterRadius = Math.sqrt(radiusSquared);
809
+ const minBoxPt = fromPointsMinBoxPt;
810
+ minBoxPt.x = xMin.x;
811
+ minBoxPt.y = yMin.y;
812
+ minBoxPt.z = zMin.z;
813
+ const maxBoxPt = fromPointsMaxBoxPt;
814
+ maxBoxPt.x = xMax.x;
815
+ maxBoxPt.y = yMax.y;
816
+ maxBoxPt.z = zMax.z;
817
+ const naiveCenter = fromPointsNaiveCenterScratch.copy(minBoxPt).add(maxBoxPt).multiplyByScalar(0.5);
818
+ let naiveRadius = 0;
819
+ for (const position of positions) {
820
+ currentPos.copy(position);
821
+ const r = fromPointsScratch.copy(currentPos).subtract(naiveCenter).magnitude();
822
+ if (r > naiveRadius) {
823
+ naiveRadius = r;
824
+ }
825
+ const oldCenterToPointSquared = fromPointsScratch.copy(currentPos).subtract(ritterCenter).magnitudeSquared();
826
+ if (oldCenterToPointSquared > radiusSquared) {
827
+ const oldCenterToPoint = Math.sqrt(oldCenterToPointSquared);
828
+ ritterRadius = (ritterRadius + oldCenterToPoint) * 0.5;
829
+ radiusSquared = ritterRadius * ritterRadius;
830
+ const oldToNew = oldCenterToPoint - ritterRadius;
831
+ ritterCenter.x = (ritterRadius * ritterCenter.x + oldToNew * currentPos.x) / oldCenterToPoint;
832
+ ritterCenter.y = (ritterRadius * ritterCenter.y + oldToNew * currentPos.y) / oldCenterToPoint;
833
+ ritterCenter.z = (ritterRadius * ritterCenter.z + oldToNew * currentPos.z) / oldCenterToPoint;
834
+ }
835
+ }
836
+ if (ritterRadius < naiveRadius) {
837
+ ritterCenter.to(result.center);
838
+ result.radius = ritterRadius;
839
+ } else {
840
+ naiveCenter.to(result.center);
841
+ result.radius = naiveRadius;
842
+ }
843
+ return result;
844
+ }
845
+
846
+ // src/lib/algorithms/bounding-box-from-points.ts
847
+ var import_core10 = require("@math.gl/core");
848
+
849
+ // src/lib/algorithms/compute-eigen-decomposition.ts
850
+ var import_core9 = require("@math.gl/core");
851
+ var scratchMatrix = new import_core9.Matrix3();
852
+ var scratchUnitary = new import_core9.Matrix3();
853
+ var scratchDiagonal = new import_core9.Matrix3();
854
+ var jMatrix = new import_core9.Matrix3();
855
+ var jMatrixTranspose = new import_core9.Matrix3();
856
+ function computeEigenDecomposition(matrix, result = {}) {
857
+ const EIGEN_TOLERANCE = import_core9._MathUtils.EPSILON20;
858
+ const EIGEN_MAX_SWEEPS = 10;
859
+ let count = 0;
860
+ let sweep = 0;
861
+ const unitaryMatrix = scratchUnitary;
862
+ const diagonalMatrix = scratchDiagonal;
863
+ unitaryMatrix.identity();
864
+ diagonalMatrix.copy(matrix);
865
+ const epsilon = EIGEN_TOLERANCE * computeFrobeniusNorm(diagonalMatrix);
866
+ while (sweep < EIGEN_MAX_SWEEPS && offDiagonalFrobeniusNorm(diagonalMatrix) > epsilon) {
867
+ shurDecomposition(diagonalMatrix, jMatrix);
868
+ jMatrixTranspose.copy(jMatrix).transpose();
869
+ diagonalMatrix.multiplyRight(jMatrix);
870
+ diagonalMatrix.multiplyLeft(jMatrixTranspose);
871
+ unitaryMatrix.multiplyRight(jMatrix);
872
+ if (++count > 2) {
873
+ ++sweep;
874
+ count = 0;
875
+ }
876
+ }
877
+ result.unitary = unitaryMatrix.toTarget(result.unitary);
878
+ result.diagonal = diagonalMatrix.toTarget(result.diagonal);
879
+ return result;
880
+ }
881
+ function computeFrobeniusNorm(matrix) {
882
+ let norm = 0;
883
+ for (let i = 0; i < 9; ++i) {
884
+ const temp = matrix[i];
885
+ norm += temp * temp;
886
+ }
887
+ return Math.sqrt(norm);
888
+ }
889
+ var rowVal = [1, 0, 0];
890
+ var colVal = [2, 2, 1];
891
+ function offDiagonalFrobeniusNorm(matrix) {
892
+ let norm = 0;
893
+ for (let i = 0; i < 3; ++i) {
894
+ const temp = matrix[scratchMatrix.getElementIndex(colVal[i], rowVal[i])];
895
+ norm += 2 * temp * temp;
896
+ }
897
+ return Math.sqrt(norm);
898
+ }
899
+ function shurDecomposition(matrix, result) {
900
+ const tolerance = import_core9._MathUtils.EPSILON15;
901
+ let maxDiagonal = 0;
902
+ let rotAxis = 1;
903
+ for (let i = 0; i < 3; ++i) {
904
+ const temp = Math.abs(matrix[scratchMatrix.getElementIndex(colVal[i], rowVal[i])]);
905
+ if (temp > maxDiagonal) {
906
+ rotAxis = i;
907
+ maxDiagonal = temp;
908
+ }
909
+ }
910
+ const p = rowVal[rotAxis];
911
+ const q = colVal[rotAxis];
912
+ let c = 1;
913
+ let s = 0;
914
+ if (Math.abs(matrix[scratchMatrix.getElementIndex(q, p)]) > tolerance) {
915
+ const qq = matrix[scratchMatrix.getElementIndex(q, q)];
916
+ const pp = matrix[scratchMatrix.getElementIndex(p, p)];
917
+ const qp = matrix[scratchMatrix.getElementIndex(q, p)];
918
+ const tau = (qq - pp) / 2 / qp;
919
+ let t;
920
+ if (tau < 0) {
921
+ t = -1 / (-tau + Math.sqrt(1 + tau * tau));
922
+ } else {
923
+ t = 1 / (tau + Math.sqrt(1 + tau * tau));
924
+ }
925
+ c = 1 / Math.sqrt(1 + t * t);
926
+ s = t * c;
927
+ }
928
+ import_core9.Matrix3.IDENTITY.to(result);
929
+ result[scratchMatrix.getElementIndex(p, p)] = result[scratchMatrix.getElementIndex(q, q)] = c;
930
+ result[scratchMatrix.getElementIndex(q, p)] = s;
931
+ result[scratchMatrix.getElementIndex(p, q)] = -s;
932
+ return result;
933
+ }
934
+
935
+ // src/lib/algorithms/bounding-box-from-points.ts
936
+ var scratchVector23 = new import_core10.Vector3();
937
+ var scratchVector32 = new import_core10.Vector3();
938
+ var scratchVector4 = new import_core10.Vector3();
939
+ var scratchVector5 = new import_core10.Vector3();
940
+ var scratchVector6 = new import_core10.Vector3();
941
+ var scratchCovarianceResult = new import_core10.Matrix3();
942
+ var scratchEigenResult = {
943
+ diagonal: new import_core10.Matrix3(),
944
+ unitary: new import_core10.Matrix3()
945
+ };
946
+ function makeOrientedBoundingBoxFromPoints(positions, result = new OrientedBoundingBox()) {
947
+ if (!positions || positions.length === 0) {
948
+ result.halfAxes = new import_core10.Matrix3([0, 0, 0, 0, 0, 0, 0, 0, 0]);
949
+ result.center = new import_core10.Vector3();
950
+ return result;
951
+ }
952
+ const length = positions.length;
953
+ const meanPoint = new import_core10.Vector3(0, 0, 0);
954
+ for (const position of positions) {
955
+ meanPoint.add(position);
956
+ }
957
+ const invLength = 1 / length;
958
+ meanPoint.multiplyByScalar(invLength);
959
+ let exx = 0;
960
+ let exy = 0;
961
+ let exz = 0;
962
+ let eyy = 0;
963
+ let eyz = 0;
964
+ let ezz = 0;
965
+ for (const position of positions) {
966
+ const p = scratchVector23.copy(position).subtract(meanPoint);
967
+ exx += p.x * p.x;
968
+ exy += p.x * p.y;
969
+ exz += p.x * p.z;
970
+ eyy += p.y * p.y;
971
+ eyz += p.y * p.z;
972
+ ezz += p.z * p.z;
973
+ }
974
+ exx *= invLength;
975
+ exy *= invLength;
976
+ exz *= invLength;
977
+ eyy *= invLength;
978
+ eyz *= invLength;
979
+ ezz *= invLength;
980
+ const covarianceMatrix = scratchCovarianceResult;
981
+ covarianceMatrix[0] = exx;
982
+ covarianceMatrix[1] = exy;
983
+ covarianceMatrix[2] = exz;
984
+ covarianceMatrix[3] = exy;
985
+ covarianceMatrix[4] = eyy;
986
+ covarianceMatrix[5] = eyz;
987
+ covarianceMatrix[6] = exz;
988
+ covarianceMatrix[7] = eyz;
989
+ covarianceMatrix[8] = ezz;
990
+ const { unitary } = computeEigenDecomposition(covarianceMatrix, scratchEigenResult);
991
+ const rotation = result.halfAxes.copy(unitary);
992
+ let v1 = rotation.getColumn(0, scratchVector4);
993
+ let v2 = rotation.getColumn(1, scratchVector5);
994
+ let v3 = rotation.getColumn(2, scratchVector6);
995
+ let u1 = -Number.MAX_VALUE;
996
+ let u2 = -Number.MAX_VALUE;
997
+ let u3 = -Number.MAX_VALUE;
998
+ let l1 = Number.MAX_VALUE;
999
+ let l2 = Number.MAX_VALUE;
1000
+ let l3 = Number.MAX_VALUE;
1001
+ for (const position of positions) {
1002
+ scratchVector23.copy(position);
1003
+ u1 = Math.max(scratchVector23.dot(v1), u1);
1004
+ u2 = Math.max(scratchVector23.dot(v2), u2);
1005
+ u3 = Math.max(scratchVector23.dot(v3), u3);
1006
+ l1 = Math.min(scratchVector23.dot(v1), l1);
1007
+ l2 = Math.min(scratchVector23.dot(v2), l2);
1008
+ l3 = Math.min(scratchVector23.dot(v3), l3);
1009
+ }
1010
+ v1 = v1.multiplyByScalar(0.5 * (l1 + u1));
1011
+ v2 = v2.multiplyByScalar(0.5 * (l2 + u2));
1012
+ v3 = v3.multiplyByScalar(0.5 * (l3 + u3));
1013
+ result.center.copy(v1).add(v2).add(v3);
1014
+ const scale = scratchVector32.set(u1 - l1, u2 - l2, u3 - l3).multiplyByScalar(0.5);
1015
+ const scaleMatrix = new import_core10.Matrix3([scale[0], 0, 0, 0, scale[1], 0, 0, 0, scale[2]]);
1016
+ result.halfAxes.multiplyRight(scaleMatrix);
1017
+ return result;
1018
+ }
1019
+ function makeAxisAlignedBoundingBoxFromPoints(positions, result = new AxisAlignedBoundingBox()) {
1020
+ if (!positions || positions.length === 0) {
1021
+ result.minimum.set(0, 0, 0);
1022
+ result.maximum.set(0, 0, 0);
1023
+ result.center.set(0, 0, 0);
1024
+ result.halfDiagonal.set(0, 0, 0);
1025
+ return result;
1026
+ }
1027
+ let minimumX = positions[0][0];
1028
+ let minimumY = positions[0][1];
1029
+ let minimumZ = positions[0][2];
1030
+ let maximumX = positions[0][0];
1031
+ let maximumY = positions[0][1];
1032
+ let maximumZ = positions[0][2];
1033
+ for (const p of positions) {
1034
+ const x = p[0];
1035
+ const y = p[1];
1036
+ const z = p[2];
1037
+ minimumX = Math.min(x, minimumX);
1038
+ maximumX = Math.max(x, maximumX);
1039
+ minimumY = Math.min(y, minimumY);
1040
+ maximumY = Math.max(y, maximumY);
1041
+ minimumZ = Math.min(z, minimumZ);
1042
+ maximumZ = Math.max(z, maximumZ);
1043
+ }
1044
+ result.minimum.set(minimumX, minimumY, minimumZ);
1045
+ result.maximum.set(maximumX, maximumY, maximumZ);
1046
+ result.center.copy(result.minimum).add(result.maximum).scale(0.5);
1047
+ result.halfDiagonal.copy(result.maximum).subtract(result.center);
1048
+ return result;
1049
+ }