@math.gl/culling 4.2.0-alpha.3 → 4.2.0-alpha.6
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.
- package/LICENSE +51 -0
- package/README.md +8 -1
- package/dist/constants.d.ts +10 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +9 -5
- package/dist/constants.js.map +1 -1
- package/dist/index.cjs +640 -113
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +2 -1
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -1
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js +3 -4
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
- package/dist/lib/bounding-volumes/bounding-sphere.d.ts +2 -1
- package/dist/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -1
- package/dist/lib/bounding-volumes/bounding-sphere.js +3 -4
- package/dist/lib/bounding-volumes/bounding-sphere.js.map +1 -1
- package/dist/lib/bounding-volumes/bounding-volume.d.ts +5 -4
- package/dist/lib/bounding-volumes/bounding-volume.d.ts.map +1 -1
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +2 -1
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -1
- package/dist/lib/bounding-volumes/oriented-bounding-box.js +3 -4
- package/dist/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
- package/dist/lib/culling-volume.d.ts +2 -1
- package/dist/lib/culling-volume.d.ts.map +1 -1
- package/dist/lib/culling-volume.js +7 -8
- package/dist/lib/culling-volume.js.map +1 -1
- package/dist/lib/plane.d.ts +2 -2
- package/dist/lib/plane.d.ts.map +1 -1
- package/dist/lib/plane.js +3 -6
- package/dist/lib/plane.js.map +1 -1
- package/dist/lib/shapes/box-shape.d.ts +19 -0
- package/dist/lib/shapes/box-shape.d.ts.map +1 -0
- package/dist/lib/shapes/box-shape.js +69 -0
- package/dist/lib/shapes/box-shape.js.map +1 -0
- package/dist/lib/shapes/capsule-shape.d.ts +23 -0
- package/dist/lib/shapes/capsule-shape.d.ts.map +1 -0
- package/dist/lib/shapes/capsule-shape.js +151 -0
- package/dist/lib/shapes/capsule-shape.js.map +1 -0
- package/dist/lib/shapes/cylinder-shape.d.ts +22 -0
- package/dist/lib/shapes/cylinder-shape.d.ts.map +1 -0
- package/dist/lib/shapes/cylinder-shape.js +99 -0
- package/dist/lib/shapes/cylinder-shape.js.map +1 -0
- package/dist/lib/shapes/implicit-shape.d.ts +56 -0
- package/dist/lib/shapes/implicit-shape.d.ts.map +1 -0
- package/dist/lib/shapes/implicit-shape.js +142 -0
- package/dist/lib/shapes/implicit-shape.js.map +1 -0
- package/dist/lib/shapes/plane-shape.d.ts +27 -0
- package/dist/lib/shapes/plane-shape.d.ts.map +1 -0
- package/dist/lib/shapes/plane-shape.js +71 -0
- package/dist/lib/shapes/plane-shape.js.map +1 -0
- package/dist/lib/shapes/sphere-shape.d.ts +18 -0
- package/dist/lib/shapes/sphere-shape.d.ts.map +1 -0
- package/dist/lib/shapes/sphere-shape.js +43 -0
- package/dist/lib/shapes/sphere-shape.js.map +1 -0
- package/package.json +4 -4
- package/src/constants.ts +11 -5
- package/src/index.ts +13 -0
- package/src/lib/bounding-volumes/axis-aligned-bounding-box.ts +5 -5
- package/src/lib/bounding-volumes/bounding-sphere.ts +5 -5
- package/src/lib/bounding-volumes/bounding-volume.ts +5 -4
- package/src/lib/bounding-volumes/oriented-bounding-box.ts +5 -5
- package/src/lib/culling-volume.ts +9 -9
- package/src/lib/plane.ts +3 -6
- package/src/lib/shapes/box-shape.ts +78 -0
- package/src/lib/shapes/capsule-shape.ts +232 -0
- package/src/lib/shapes/cylinder-shape.ts +133 -0
- package/src/lib/shapes/implicit-shape.ts +209 -0
- package/src/lib/shapes/plane-shape.ts +78 -0
- package/src/lib/shapes/sphere-shape.ts +60 -0
package/dist/index.cjs
CHANGED
|
@@ -17,15 +17,20 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
18
|
|
|
19
19
|
// dist/index.js
|
|
20
|
-
var
|
|
21
|
-
__export(
|
|
20
|
+
var index_exports = {};
|
|
21
|
+
__export(index_exports, {
|
|
22
22
|
AxisAlignedBoundingBox: () => AxisAlignedBoundingBox,
|
|
23
23
|
BoundingSphere: () => BoundingSphere,
|
|
24
|
+
BoxShape: () => BoxShape,
|
|
25
|
+
CapsuleShape: () => CapsuleShape,
|
|
24
26
|
CullingVolume: () => CullingVolume,
|
|
27
|
+
CylinderShape: () => CylinderShape,
|
|
25
28
|
INTERSECTION: () => INTERSECTION,
|
|
26
29
|
OrientedBoundingBox: () => OrientedBoundingBox,
|
|
27
30
|
Plane: () => Plane,
|
|
31
|
+
PlaneShape: () => PlaneShape,
|
|
28
32
|
Ray: () => Ray,
|
|
33
|
+
SphereShape: () => SphereShape,
|
|
29
34
|
_PerspectiveFrustum: () => PerspectiveFrustum,
|
|
30
35
|
_PerspectiveOffCenterFrustum: () => PerspectiveOffCenterFrustum,
|
|
31
36
|
computeEigenDecomposition: () => computeEigenDecomposition,
|
|
@@ -33,23 +38,21 @@ __export(dist_exports, {
|
|
|
33
38
|
makeBoundingSphereFromPoints: () => makeBoundingSphereFromPoints,
|
|
34
39
|
makeOrientedBoundingBoxFromPoints: () => makeOrientedBoundingBoxFromPoints
|
|
35
40
|
});
|
|
36
|
-
module.exports = __toCommonJS(
|
|
41
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
42
|
|
|
38
43
|
// dist/constants.js
|
|
39
|
-
var INTERSECTION
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
INTERSECTING
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
// Represents that an object is fully within the frustum.
|
|
46
|
-
};
|
|
44
|
+
var INTERSECTION;
|
|
45
|
+
(function(INTERSECTION2) {
|
|
46
|
+
INTERSECTION2["OUTSIDE"] = "outside";
|
|
47
|
+
INTERSECTION2["INTERSECTING"] = "intersecting";
|
|
48
|
+
INTERSECTION2["INSIDE"] = "inside";
|
|
49
|
+
})(INTERSECTION || (INTERSECTION = {}));
|
|
47
50
|
|
|
48
51
|
// dist/lib/bounding-volumes/axis-aligned-bounding-box.js
|
|
49
52
|
var import_core = require("@math.gl/core");
|
|
50
53
|
var scratchVector = new import_core.Vector3();
|
|
51
54
|
var scratchNormal = new import_core.Vector3();
|
|
52
|
-
var AxisAlignedBoundingBox = class {
|
|
55
|
+
var AxisAlignedBoundingBox = class _AxisAlignedBoundingBox {
|
|
53
56
|
/**
|
|
54
57
|
* Creates an instance of an AxisAlignedBoundingBox from the minimum and maximum points along the x, y, and z axes.
|
|
55
58
|
* @param minimum=[0, 0, 0] The minimum point along the x, y, and z axes.
|
|
@@ -69,7 +72,7 @@ var AxisAlignedBoundingBox = class {
|
|
|
69
72
|
* @returns {AxisAlignedBoundingBox} A new AxisAlignedBoundingBox instance.
|
|
70
73
|
*/
|
|
71
74
|
clone() {
|
|
72
|
-
return new
|
|
75
|
+
return new _AxisAlignedBoundingBox(this.minimum, this.maximum, this.center);
|
|
73
76
|
}
|
|
74
77
|
/**
|
|
75
78
|
* Compares the provided AxisAlignedBoundingBox componentwise and returns
|
|
@@ -102,12 +105,12 @@ var AxisAlignedBoundingBox = class {
|
|
|
102
105
|
const e = halfDiagonal.x * Math.abs(normal.x) + halfDiagonal.y * Math.abs(normal.y) + halfDiagonal.z * Math.abs(normal.z);
|
|
103
106
|
const s = this.center.dot(normal) + plane.distance;
|
|
104
107
|
if (s - e > 0) {
|
|
105
|
-
return
|
|
108
|
+
return "inside";
|
|
106
109
|
}
|
|
107
110
|
if (s + e < 0) {
|
|
108
|
-
return
|
|
111
|
+
return "outside";
|
|
109
112
|
}
|
|
110
|
-
return
|
|
113
|
+
return "intersecting";
|
|
111
114
|
}
|
|
112
115
|
/** Computes the estimated distance from the closest point on a bounding box to a point. */
|
|
113
116
|
distanceTo(point) {
|
|
@@ -139,7 +142,7 @@ var AxisAlignedBoundingBox = class {
|
|
|
139
142
|
var import_core2 = require("@math.gl/core");
|
|
140
143
|
var scratchVector2 = new import_core2.Vector3();
|
|
141
144
|
var scratchVector22 = new import_core2.Vector3();
|
|
142
|
-
var BoundingSphere = class {
|
|
145
|
+
var BoundingSphere = class _BoundingSphere {
|
|
143
146
|
/** Creates a bounding sphere */
|
|
144
147
|
constructor(center = [0, 0, 0], radius = 0) {
|
|
145
148
|
this.radius = -0;
|
|
@@ -168,7 +171,7 @@ var BoundingSphere = class {
|
|
|
168
171
|
}
|
|
169
172
|
/** Duplicates a BoundingSphere instance. */
|
|
170
173
|
clone() {
|
|
171
|
-
return new
|
|
174
|
+
return new _BoundingSphere(this.center, this.radius);
|
|
172
175
|
}
|
|
173
176
|
/** Computes a bounding sphere that contains both the left and right bounding spheres. */
|
|
174
177
|
union(boundingSphere) {
|
|
@@ -230,12 +233,12 @@ var BoundingSphere = class {
|
|
|
230
233
|
const normal = plane.normal;
|
|
231
234
|
const distanceToPlane = normal.dot(center) + plane.distance;
|
|
232
235
|
if (distanceToPlane < -radius) {
|
|
233
|
-
return
|
|
236
|
+
return "outside";
|
|
234
237
|
}
|
|
235
238
|
if (distanceToPlane < radius) {
|
|
236
|
-
return
|
|
239
|
+
return "intersecting";
|
|
237
240
|
}
|
|
238
|
-
return
|
|
241
|
+
return "inside";
|
|
239
242
|
}
|
|
240
243
|
};
|
|
241
244
|
|
|
@@ -259,7 +262,7 @@ var MATRIX3 = {
|
|
|
259
262
|
COLUMN2ROW1: 7,
|
|
260
263
|
COLUMN2ROW2: 8
|
|
261
264
|
};
|
|
262
|
-
var OrientedBoundingBox = class {
|
|
265
|
+
var OrientedBoundingBox = class _OrientedBoundingBox {
|
|
263
266
|
constructor(center = [0, 0, 0], halfAxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]) {
|
|
264
267
|
this.center = new import_core3.Vector3().from(center);
|
|
265
268
|
this.halfAxes = new import_core3.Matrix3(halfAxes);
|
|
@@ -302,7 +305,7 @@ var OrientedBoundingBox = class {
|
|
|
302
305
|
}
|
|
303
306
|
/** Duplicates a OrientedBoundingBox instance. */
|
|
304
307
|
clone() {
|
|
305
|
-
return new
|
|
308
|
+
return new _OrientedBoundingBox(this.center, this.halfAxes);
|
|
306
309
|
}
|
|
307
310
|
/** Compares the provided OrientedBoundingBox component wise and returns */
|
|
308
311
|
equals(right) {
|
|
@@ -330,11 +333,11 @@ var OrientedBoundingBox = class {
|
|
|
330
333
|
const radEffective = Math.abs(normalX * halfAxes[MATRIX3.COLUMN0ROW0] + normalY * halfAxes[MATRIX3.COLUMN0ROW1] + normalZ * halfAxes[MATRIX3.COLUMN0ROW2]) + Math.abs(normalX * halfAxes[MATRIX3.COLUMN1ROW0] + normalY * halfAxes[MATRIX3.COLUMN1ROW1] + normalZ * halfAxes[MATRIX3.COLUMN1ROW2]) + Math.abs(normalX * halfAxes[MATRIX3.COLUMN2ROW0] + normalY * halfAxes[MATRIX3.COLUMN2ROW1] + normalZ * halfAxes[MATRIX3.COLUMN2ROW2]);
|
|
331
334
|
const distanceToPlane = normal.dot(center) + plane.distance;
|
|
332
335
|
if (distanceToPlane <= -radEffective) {
|
|
333
|
-
return
|
|
336
|
+
return "outside";
|
|
334
337
|
} else if (distanceToPlane >= radEffective) {
|
|
335
|
-
return
|
|
338
|
+
return "inside";
|
|
336
339
|
}
|
|
337
|
-
return
|
|
340
|
+
return "intersecting";
|
|
338
341
|
}
|
|
339
342
|
/** Computes the estimated distance from the closest point on a bounding box to a point. */
|
|
340
343
|
distanceTo(point) {
|
|
@@ -468,7 +471,7 @@ var import_core5 = require("@math.gl/core");
|
|
|
468
471
|
var import_core4 = require("@math.gl/core");
|
|
469
472
|
var scratchPosition = new import_core4.Vector3();
|
|
470
473
|
var scratchNormal2 = new import_core4.Vector3();
|
|
471
|
-
var Plane = class {
|
|
474
|
+
var Plane = class _Plane {
|
|
472
475
|
constructor(normal = [0, 0, 1], distance = 0) {
|
|
473
476
|
this.normal = new import_core4.Vector3();
|
|
474
477
|
this.distance = -0;
|
|
@@ -498,7 +501,7 @@ var Plane = class {
|
|
|
498
501
|
}
|
|
499
502
|
/** Duplicates a Plane instance. */
|
|
500
503
|
clone() {
|
|
501
|
-
return new
|
|
504
|
+
return new _Plane(this.normal, this.distance);
|
|
502
505
|
}
|
|
503
506
|
/** Compares the provided Planes by normal and distance */
|
|
504
507
|
equals(right) {
|
|
@@ -527,11 +530,9 @@ var Plane = class {
|
|
|
527
530
|
*
|
|
528
531
|
* @param {Ray} ray The ray.
|
|
529
532
|
* @param {Vector3} [result] The object onto which to store the result.
|
|
530
|
-
* @returns {Vector3} The intersection point or undefined if there is no
|
|
533
|
+
* @returns {Vector3} The intersection point or undefined if there is no intersection.
|
|
531
534
|
*/
|
|
532
|
-
intersectWithRay(ray, result) {
|
|
533
|
-
if (!result)
|
|
534
|
-
result = new import_core4.Vector3();
|
|
535
|
+
intersectWithRay(ray, result = new import_core4.Vector3()) {
|
|
535
536
|
const origin = ray.origin;
|
|
536
537
|
const direction = ray.direction;
|
|
537
538
|
const normal = this.normal;
|
|
@@ -543,8 +544,7 @@ var Plane = class {
|
|
|
543
544
|
if (t < 0) {
|
|
544
545
|
return void 0;
|
|
545
546
|
}
|
|
546
|
-
|
|
547
|
-
return origin.add(result);
|
|
547
|
+
return result.copy(direction).multiplyByScalar(t).add(origin);
|
|
548
548
|
}
|
|
549
549
|
};
|
|
550
550
|
|
|
@@ -552,7 +552,7 @@ var Plane = class {
|
|
|
552
552
|
var faces = [new import_core5.Vector3([1, 0, 0]), new import_core5.Vector3([0, 1, 0]), new import_core5.Vector3([0, 0, 1])];
|
|
553
553
|
var scratchPlaneCenter = new import_core5.Vector3();
|
|
554
554
|
var scratchPlaneNormal = new import_core5.Vector3();
|
|
555
|
-
var CullingVolume = class {
|
|
555
|
+
var CullingVolume = class _CullingVolume {
|
|
556
556
|
/**
|
|
557
557
|
* Create a new `CullingVolume` bounded by an array of clipping planed
|
|
558
558
|
* @param planes Array of clipping planes.
|
|
@@ -589,14 +589,14 @@ var CullingVolume = class {
|
|
|
589
589
|
}
|
|
590
590
|
/** Determines whether a bounding volume intersects the culling volume. */
|
|
591
591
|
computeVisibility(boundingVolume) {
|
|
592
|
-
let intersect =
|
|
592
|
+
let intersect = "inside";
|
|
593
593
|
for (const plane of this.planes) {
|
|
594
594
|
const result = boundingVolume.intersectPlane(plane);
|
|
595
595
|
switch (result) {
|
|
596
|
-
case
|
|
597
|
-
return
|
|
598
|
-
case
|
|
599
|
-
intersect =
|
|
596
|
+
case "outside":
|
|
597
|
+
return "outside";
|
|
598
|
+
case "intersecting":
|
|
599
|
+
intersect = "intersecting";
|
|
600
600
|
break;
|
|
601
601
|
default:
|
|
602
602
|
}
|
|
@@ -613,10 +613,10 @@ var CullingVolume = class {
|
|
|
613
613
|
*/
|
|
614
614
|
computeVisibilityWithPlaneMask(boundingVolume, parentPlaneMask) {
|
|
615
615
|
(0, import_core5.assert)(Number.isFinite(parentPlaneMask), "parentPlaneMask is required.");
|
|
616
|
-
if (parentPlaneMask ===
|
|
616
|
+
if (parentPlaneMask === _CullingVolume.MASK_OUTSIDE || parentPlaneMask === _CullingVolume.MASK_INSIDE) {
|
|
617
617
|
return parentPlaneMask;
|
|
618
618
|
}
|
|
619
|
-
let mask =
|
|
619
|
+
let mask = _CullingVolume.MASK_INSIDE;
|
|
620
620
|
const planes = this.planes;
|
|
621
621
|
for (let k = 0; k < this.planes.length; ++k) {
|
|
622
622
|
const flag = k < 31 ? 1 << k : 0;
|
|
@@ -625,9 +625,9 @@ var CullingVolume = class {
|
|
|
625
625
|
}
|
|
626
626
|
const plane = planes[k];
|
|
627
627
|
const result = boundingVolume.intersectPlane(plane);
|
|
628
|
-
if (result ===
|
|
629
|
-
return
|
|
630
|
-
} else if (result ===
|
|
628
|
+
if (result === "outside") {
|
|
629
|
+
return _CullingVolume.MASK_OUTSIDE;
|
|
630
|
+
} else if (result === "intersecting") {
|
|
631
631
|
mask |= flag;
|
|
632
632
|
}
|
|
633
633
|
}
|
|
@@ -661,14 +661,541 @@ var Ray = class {
|
|
|
661
661
|
}
|
|
662
662
|
};
|
|
663
663
|
|
|
664
|
-
// dist/lib/
|
|
664
|
+
// dist/lib/shapes/implicit-shape.js
|
|
665
665
|
var import_core7 = require("@math.gl/core");
|
|
666
|
-
var
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
666
|
+
var ImplicitShapeBase = class {
|
|
667
|
+
constructor(matrix) {
|
|
668
|
+
this.matrix = new import_core7.Matrix4();
|
|
669
|
+
if (matrix)
|
|
670
|
+
this.matrix.copy(matrix);
|
|
671
|
+
validateAffineMatrix(this.matrix);
|
|
672
|
+
this.inverseMatrix = this.matrix.clone().invert();
|
|
673
|
+
}
|
|
674
|
+
equals(shape) {
|
|
675
|
+
if (this.type !== shape.type)
|
|
676
|
+
return false;
|
|
677
|
+
for (let i = 0; i < 16; i++)
|
|
678
|
+
if (this.matrix[i] !== shape.matrix[i])
|
|
679
|
+
return false;
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
transform(transform) {
|
|
683
|
+
const next = new import_core7.Matrix4().copy(transform);
|
|
684
|
+
validateAffineMatrix(next);
|
|
685
|
+
this.matrix.multiplyLeft(next);
|
|
686
|
+
validateAffineMatrix(this.matrix);
|
|
687
|
+
this.inverseMatrix.copy(this.matrix).invert();
|
|
688
|
+
return this;
|
|
689
|
+
}
|
|
690
|
+
containsPoint(point) {
|
|
691
|
+
return this.containsLocalPoint(this.inverseMatrix.transformAsPoint(point));
|
|
692
|
+
}
|
|
693
|
+
distanceSquaredTo(point) {
|
|
694
|
+
const distance = this.distanceTo(point);
|
|
695
|
+
return distance * distance;
|
|
696
|
+
}
|
|
697
|
+
/** Exact for rigid/uniform transforms; conservative estimate for non-uniform scale or shear. */
|
|
698
|
+
distanceTo(point) {
|
|
699
|
+
const localPoint = this.inverseMatrix.transformAsPoint(point);
|
|
700
|
+
const localDistance = this.distanceToLocalPoint(localPoint);
|
|
701
|
+
const scales = this.matrix.getScale();
|
|
702
|
+
return localDistance * Math.min(scales[0], scales[1], scales[2]);
|
|
703
|
+
}
|
|
704
|
+
intersectPlane(plane) {
|
|
705
|
+
const maximum = this.getSupportPoint(plane.normal);
|
|
706
|
+
const minimum = this.getSupportPoint([-plane.normal[0], -plane.normal[1], -plane.normal[2]]);
|
|
707
|
+
const maxDistance = plane.getPointDistance(maximum);
|
|
708
|
+
const minDistance = plane.getPointDistance(minimum);
|
|
709
|
+
if (minDistance > 0)
|
|
710
|
+
return "inside";
|
|
711
|
+
if (maxDistance < 0)
|
|
712
|
+
return "outside";
|
|
713
|
+
return "intersecting";
|
|
714
|
+
}
|
|
715
|
+
intersectRay(ray) {
|
|
716
|
+
const localOrigin = this.inverseMatrix.transformAsPoint(ray.origin);
|
|
717
|
+
const localDirection = this.inverseMatrix.transformAsVector(ray.direction);
|
|
718
|
+
const hit = this.intersectLocalRay(localOrigin, localDirection);
|
|
719
|
+
if (!hit || hit.distance < 0)
|
|
720
|
+
return void 0;
|
|
721
|
+
const point = new import_core7.Vector3(ray.direction).scale(hit.distance).add(ray.origin);
|
|
722
|
+
const inverse = this.inverseMatrix;
|
|
723
|
+
const normal = new import_core7.Vector3(inverse[0] * hit.normal[0] + inverse[1] * hit.normal[1] + inverse[2] * hit.normal[2], inverse[4] * hit.normal[0] + inverse[5] * hit.normal[1] + inverse[6] * hit.normal[2], inverse[8] * hit.normal[0] + inverse[9] * hit.normal[1] + inverse[10] * hit.normal[2]).normalize();
|
|
724
|
+
return { distance: hit.distance, point, normal, entering: ray.direction.dot(normal) < 0 };
|
|
725
|
+
}
|
|
726
|
+
getAxisAlignedBoundingBox() {
|
|
727
|
+
const minimum = new import_core7.Vector3();
|
|
728
|
+
const maximum = new import_core7.Vector3();
|
|
729
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
730
|
+
const direction = [0, 0, 0];
|
|
731
|
+
direction[axis] = 1;
|
|
732
|
+
maximum[axis] = this.getSupportPoint(direction)[axis];
|
|
733
|
+
direction[axis] = -1;
|
|
734
|
+
minimum[axis] = this.getSupportPoint(direction)[axis];
|
|
735
|
+
}
|
|
736
|
+
return new AxisAlignedBoundingBox(minimum, maximum);
|
|
737
|
+
}
|
|
738
|
+
getBoundingSphere() {
|
|
739
|
+
const box = this.getAxisAlignedBoundingBox();
|
|
740
|
+
if (!box)
|
|
741
|
+
return void 0;
|
|
742
|
+
return new BoundingSphere().fromCornerPoints(box.minimum, box.maximum);
|
|
743
|
+
}
|
|
744
|
+
getSupportPoint(worldDirection) {
|
|
745
|
+
const matrix = this.matrix;
|
|
746
|
+
const localDirection = [
|
|
747
|
+
matrix[0] * worldDirection[0] + matrix[1] * worldDirection[1] + matrix[2] * worldDirection[2],
|
|
748
|
+
matrix[4] * worldDirection[0] + matrix[5] * worldDirection[1] + matrix[6] * worldDirection[2],
|
|
749
|
+
matrix[8] * worldDirection[0] + matrix[9] * worldDirection[1] + matrix[10] * worldDirection[2]
|
|
750
|
+
];
|
|
751
|
+
return new import_core7.Vector3(this.supportLocal(localDirection)).transform(this.matrix);
|
|
752
|
+
}
|
|
753
|
+
};
|
|
754
|
+
function validateAffineMatrix(matrix) {
|
|
755
|
+
if (matrix.length !== 16 || matrix.some((value) => !Number.isFinite(value))) {
|
|
756
|
+
throw new Error("Shape matrix must contain 16 finite values");
|
|
757
|
+
}
|
|
758
|
+
if (Math.abs(matrix[3]) > 1e-12 || Math.abs(matrix[7]) > 1e-12 || Math.abs(matrix[11]) > 1e-12 || Math.abs(matrix[15] - 1) > 1e-12) {
|
|
759
|
+
throw new Error("Shape matrix must be affine");
|
|
760
|
+
}
|
|
761
|
+
if (Math.abs(new import_core7.Matrix4().copy(matrix).determinant()) < 1e-15)
|
|
762
|
+
throw new Error("Shape matrix must be invertible");
|
|
763
|
+
}
|
|
764
|
+
function solveQuadratic(a, b, c) {
|
|
765
|
+
if (Math.abs(a) < 1e-15)
|
|
766
|
+
return Math.abs(b) < 1e-15 ? [] : [-c / b];
|
|
767
|
+
const discriminant = b * b - 4 * a * c;
|
|
768
|
+
if (discriminant < 0)
|
|
769
|
+
return [];
|
|
770
|
+
const root = Math.sqrt(Math.max(0, discriminant));
|
|
771
|
+
return [(-b - root) / (2 * a), (-b + root) / (2 * a)].sort((left, right) => left - right);
|
|
772
|
+
}
|
|
773
|
+
function closestDistanceToSegment2D(px, py, ax, ay, bx, by) {
|
|
774
|
+
const dx = bx - ax;
|
|
775
|
+
const dy = by - ay;
|
|
776
|
+
const denominator = dx * dx + dy * dy;
|
|
777
|
+
const t = denominator ? Math.max(0, Math.min(1, ((px - ax) * dx + (py - ay) * dy) / denominator)) : 0;
|
|
778
|
+
return Math.hypot(px - (ax + t * dx), py - (ay + t * dy));
|
|
779
|
+
}
|
|
780
|
+
function closestDistanceToCircleArc2D(px, py, centerY, radius, minimumNormalY, maximumNormalY) {
|
|
781
|
+
if (radius === 0)
|
|
782
|
+
return Math.hypot(px, py - centerY);
|
|
783
|
+
const dx = px;
|
|
784
|
+
const dy = py - centerY;
|
|
785
|
+
const length = Math.hypot(dx, dy);
|
|
786
|
+
const normalY = length ? dy / length : 0;
|
|
787
|
+
if (normalY >= minimumNormalY && normalY <= maximumNormalY) {
|
|
788
|
+
return Math.abs(length - radius);
|
|
789
|
+
}
|
|
790
|
+
const minimumRadius = radius * Math.sqrt(Math.max(0, 1 - minimumNormalY ** 2));
|
|
791
|
+
const maximumRadius = radius * Math.sqrt(Math.max(0, 1 - maximumNormalY ** 2));
|
|
792
|
+
return Math.min(Math.hypot(px - minimumRadius, py - (centerY + radius * minimumNormalY)), Math.hypot(px - maximumRadius, py - (centerY + radius * maximumNormalY)));
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
// dist/lib/shapes/box-shape.js
|
|
796
|
+
var EPSILON = 1e-6;
|
|
797
|
+
var BoxShape = class _BoxShape extends ImplicitShapeBase {
|
|
798
|
+
constructor(props = {}) {
|
|
799
|
+
super(props.matrix);
|
|
800
|
+
this.type = "box";
|
|
801
|
+
this.size = props.size ? [...props.size] : [1, 1, 1];
|
|
802
|
+
if (this.size.some((value) => !Number.isFinite(value) || value <= 0))
|
|
803
|
+
throw new Error("Box size values must be greater than zero");
|
|
804
|
+
this.halfSize = [this.size[0] / 2, this.size[1] / 2, this.size[2] / 2];
|
|
805
|
+
}
|
|
806
|
+
clone() {
|
|
807
|
+
return new _BoxShape({ size: this.size, matrix: this.matrix });
|
|
808
|
+
}
|
|
809
|
+
equals(shape) {
|
|
810
|
+
return shape instanceof _BoxShape && super.equals(shape) && this.size.every((value, i) => value === shape.size[i]);
|
|
811
|
+
}
|
|
812
|
+
containsLocalPoint(point) {
|
|
813
|
+
return point.every((value, i) => Math.abs(value) <= this.halfSize[i] + EPSILON);
|
|
814
|
+
}
|
|
815
|
+
distanceToLocalPoint(point) {
|
|
816
|
+
return Math.hypot(...point.map((value, i) => Math.max(0, Math.abs(value) - this.halfSize[i])));
|
|
817
|
+
}
|
|
818
|
+
supportLocal(direction) {
|
|
819
|
+
return direction.map((value, i) => value < 0 ? -this.halfSize[i] : this.halfSize[i]);
|
|
820
|
+
}
|
|
821
|
+
intersectLocalRay(origin, direction) {
|
|
822
|
+
let near = -Infinity;
|
|
823
|
+
let far = Infinity;
|
|
824
|
+
let nearAxis = 0;
|
|
825
|
+
let farAxis = 0;
|
|
826
|
+
for (let axis2 = 0; axis2 < 3; axis2++) {
|
|
827
|
+
if (Math.abs(direction[axis2]) < 1e-15) {
|
|
828
|
+
if (Math.abs(origin[axis2]) > this.halfSize[axis2])
|
|
829
|
+
return void 0;
|
|
830
|
+
continue;
|
|
831
|
+
}
|
|
832
|
+
let t1 = (-this.halfSize[axis2] - origin[axis2]) / direction[axis2];
|
|
833
|
+
let t2 = (this.halfSize[axis2] - origin[axis2]) / direction[axis2];
|
|
834
|
+
if (t1 > t2)
|
|
835
|
+
[t1, t2] = [t2, t1];
|
|
836
|
+
if (t1 > near) {
|
|
837
|
+
near = t1;
|
|
838
|
+
nearAxis = axis2;
|
|
839
|
+
}
|
|
840
|
+
if (t2 < far) {
|
|
841
|
+
far = t2;
|
|
842
|
+
farAxis = axis2;
|
|
843
|
+
}
|
|
844
|
+
if (near > far)
|
|
845
|
+
return void 0;
|
|
846
|
+
}
|
|
847
|
+
const distance = near >= 0 ? near : far;
|
|
848
|
+
if (distance < 0 || !Number.isFinite(distance))
|
|
849
|
+
return void 0;
|
|
850
|
+
const axis = near >= 0 ? nearAxis : farAxis;
|
|
851
|
+
const pointCoordinate = origin[axis] + distance * direction[axis];
|
|
852
|
+
const normal = [0, 0, 0];
|
|
853
|
+
normal[axis] = pointCoordinate < 0 ? -1 : 1;
|
|
854
|
+
return { distance, normal };
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
// dist/lib/shapes/capsule-shape.js
|
|
859
|
+
var EPSILON2 = 1e-6;
|
|
860
|
+
var CapsuleShape = class _CapsuleShape extends ImplicitShapeBase {
|
|
861
|
+
constructor(props = {}) {
|
|
862
|
+
super(props.matrix);
|
|
863
|
+
this.type = "capsule";
|
|
864
|
+
this.height = props.height ?? 1;
|
|
865
|
+
this.radiusBottom = props.radiusBottom ?? 0.5;
|
|
866
|
+
this.radiusTop = props.radiusTop ?? 0.5;
|
|
867
|
+
if (!Number.isFinite(this.height) || this.height <= 0)
|
|
868
|
+
throw new Error("Capsule height must be greater than zero");
|
|
869
|
+
if (![this.radiusBottom, this.radiusTop].every((value) => Number.isFinite(value) && value >= 0))
|
|
870
|
+
throw new Error("Capsule radii must be non-negative");
|
|
871
|
+
if (this.radiusBottom === 0 && this.radiusTop === 0)
|
|
872
|
+
throw new Error("At least one capsule radius must be greater than zero");
|
|
873
|
+
}
|
|
874
|
+
clone() {
|
|
875
|
+
return new _CapsuleShape({
|
|
876
|
+
height: this.height,
|
|
877
|
+
radiusBottom: this.radiusBottom,
|
|
878
|
+
radiusTop: this.radiusTop,
|
|
879
|
+
matrix: this.matrix
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
equals(shape) {
|
|
883
|
+
return shape instanceof _CapsuleShape && super.equals(shape) && this.height === shape.height && this.radiusBottom === shape.radiusBottom && this.radiusTop === shape.radiusTop;
|
|
884
|
+
}
|
|
885
|
+
containsLocalPoint(point) {
|
|
886
|
+
const profile = this.getProfile();
|
|
887
|
+
const radial = Math.hypot(point[0], point[2]);
|
|
888
|
+
if (profile.sphere)
|
|
889
|
+
return Math.hypot(radial, point[1] - profile.sphere.center) <= profile.sphere.radius + EPSILON2;
|
|
890
|
+
if (point[1] < profile.bottom.y)
|
|
891
|
+
return Math.hypot(radial, point[1] + this.height / 2) <= this.radiusBottom + EPSILON2;
|
|
892
|
+
if (point[1] > profile.top.y)
|
|
893
|
+
return Math.hypot(radial, point[1] - this.height / 2) <= this.radiusTop + EPSILON2;
|
|
894
|
+
const t = (point[1] - profile.bottom.y) / (profile.top.y - profile.bottom.y);
|
|
895
|
+
return radial <= profile.bottom.radius + (profile.top.radius - profile.bottom.radius) * t + EPSILON2;
|
|
896
|
+
}
|
|
897
|
+
distanceToLocalPoint(point) {
|
|
898
|
+
if (this.containsLocalPoint(point))
|
|
899
|
+
return 0;
|
|
900
|
+
const profile = this.getProfile();
|
|
901
|
+
const radial = Math.hypot(point[0], point[2]);
|
|
902
|
+
if (profile.sphere)
|
|
903
|
+
return Math.max(0, Math.hypot(radial, point[1] - profile.sphere.center) - profile.sphere.radius);
|
|
904
|
+
const delta = this.radiusTop - this.radiusBottom;
|
|
905
|
+
const sideNormalY = -delta / this.height;
|
|
906
|
+
const bottomArc = closestDistanceToCircleArc2D(radial, point[1], -this.height / 2, this.radiusBottom, -1, sideNormalY);
|
|
907
|
+
const topArc = closestDistanceToCircleArc2D(radial, point[1], this.height / 2, this.radiusTop, sideNormalY, 1);
|
|
908
|
+
const side = closestDistanceToSegment2D(radial, point[1], profile.bottom.radius, profile.bottom.y, profile.top.radius, profile.top.y);
|
|
909
|
+
return Math.min(bottomArc, topArc, side);
|
|
910
|
+
}
|
|
911
|
+
supportLocal(direction) {
|
|
912
|
+
const length = Math.hypot(...direction);
|
|
913
|
+
const unit = length ? direction.map((value) => value / length) : [1, 0, 0];
|
|
914
|
+
const bottom = [
|
|
915
|
+
unit[0] * this.radiusBottom,
|
|
916
|
+
-this.height / 2 + unit[1] * this.radiusBottom,
|
|
917
|
+
unit[2] * this.radiusBottom
|
|
918
|
+
];
|
|
919
|
+
const top = [
|
|
920
|
+
unit[0] * this.radiusTop,
|
|
921
|
+
this.height / 2 + unit[1] * this.radiusTop,
|
|
922
|
+
unit[2] * this.radiusTop
|
|
923
|
+
];
|
|
924
|
+
return dot(top, direction) >= dot(bottom, direction) ? top : bottom;
|
|
925
|
+
}
|
|
926
|
+
intersectLocalRay(origin, direction) {
|
|
927
|
+
const profile = this.getProfile();
|
|
928
|
+
if (profile.sphere)
|
|
929
|
+
return intersectSphere(origin, direction, profile.sphere.center, profile.sphere.radius);
|
|
930
|
+
const candidates = [];
|
|
931
|
+
const slope = (profile.top.radius - profile.bottom.radius) / (profile.top.y - profile.bottom.y);
|
|
932
|
+
const intercept = profile.bottom.radius - slope * profile.bottom.y;
|
|
933
|
+
const radialAtOrigin = intercept + slope * origin[1];
|
|
934
|
+
const radialAlongRay = slope * direction[1];
|
|
935
|
+
for (const distance of solveQuadratic(direction[0] ** 2 + direction[2] ** 2 - radialAlongRay ** 2, 2 * (origin[0] * direction[0] + origin[2] * direction[2] - radialAtOrigin * radialAlongRay), origin[0] ** 2 + origin[2] ** 2 - radialAtOrigin ** 2)) {
|
|
936
|
+
const y = origin[1] + distance * direction[1];
|
|
937
|
+
if (distance >= 0 && y >= profile.bottom.y - EPSILON2 && y <= profile.top.y + EPSILON2) {
|
|
938
|
+
const x = origin[0] + distance * direction[0];
|
|
939
|
+
const z = origin[2] + distance * direction[2];
|
|
940
|
+
const radial = Math.hypot(x, z) || 1;
|
|
941
|
+
const normal = [x / radial, -slope, z / radial];
|
|
942
|
+
const length = Math.hypot(...normal);
|
|
943
|
+
candidates.push({ distance, normal: normal.map((value) => value / length) });
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
for (const bottomHit of intersectSphereRoots(origin, direction, -this.height / 2, this.radiusBottom)) {
|
|
947
|
+
const y = origin[1] + bottomHit.distance * direction[1];
|
|
948
|
+
if (y <= profile.bottom.y + EPSILON2)
|
|
949
|
+
candidates.push(bottomHit);
|
|
950
|
+
}
|
|
951
|
+
for (const topHit of intersectSphereRoots(origin, direction, this.height / 2, this.radiusTop)) {
|
|
952
|
+
const y = origin[1] + topHit.distance * direction[1];
|
|
953
|
+
if (y >= profile.top.y - EPSILON2)
|
|
954
|
+
candidates.push(topHit);
|
|
955
|
+
}
|
|
956
|
+
return candidates.sort((a, b) => a.distance - b.distance)[0];
|
|
957
|
+
}
|
|
958
|
+
getProfile() {
|
|
959
|
+
const delta = this.radiusTop - this.radiusBottom;
|
|
960
|
+
if (Math.abs(delta) >= this.height) {
|
|
961
|
+
const topWins = this.radiusTop >= this.radiusBottom;
|
|
962
|
+
return {
|
|
963
|
+
sphere: {
|
|
964
|
+
center: topWins ? this.height / 2 : -this.height / 2,
|
|
965
|
+
radius: topWins ? this.radiusTop : this.radiusBottom
|
|
966
|
+
},
|
|
967
|
+
bottom: { radius: 0, y: 0 },
|
|
968
|
+
top: { radius: 0, y: 0 }
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
const sinSlope = delta / this.height;
|
|
972
|
+
const radialNormal = Math.sqrt(1 - sinSlope * sinSlope);
|
|
973
|
+
const normalY = -sinSlope;
|
|
974
|
+
return {
|
|
975
|
+
bottom: {
|
|
976
|
+
radius: this.radiusBottom * radialNormal,
|
|
977
|
+
y: -this.height / 2 + this.radiusBottom * normalY
|
|
978
|
+
},
|
|
979
|
+
top: { radius: this.radiusTop * radialNormal, y: this.height / 2 + this.radiusTop * normalY }
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
};
|
|
983
|
+
function intersectSphere(origin, direction, centerY, radius) {
|
|
984
|
+
return intersectSphereRoots(origin, direction, centerY, radius)[0];
|
|
985
|
+
}
|
|
986
|
+
function intersectSphereRoots(origin, direction, centerY, radius) {
|
|
987
|
+
if (radius === 0)
|
|
988
|
+
return [];
|
|
989
|
+
const relative = [origin[0], origin[1] - centerY, origin[2]];
|
|
990
|
+
return solveQuadratic(dot(direction, direction), 2 * dot(relative, direction), dot(relative, relative) - radius * radius).filter((distance) => distance >= 0).map((distance) => ({
|
|
991
|
+
distance,
|
|
992
|
+
normal: relative.map((value, i) => (value + distance * direction[i]) / radius)
|
|
993
|
+
}));
|
|
994
|
+
}
|
|
995
|
+
function dot(a, b) {
|
|
996
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// dist/lib/shapes/cylinder-shape.js
|
|
1000
|
+
var EPSILON3 = 1e-6;
|
|
1001
|
+
var CylinderShape = class _CylinderShape extends ImplicitShapeBase {
|
|
1002
|
+
constructor(props = {}) {
|
|
1003
|
+
super(props.matrix);
|
|
1004
|
+
this.type = "cylinder";
|
|
1005
|
+
this.height = props.height ?? 2;
|
|
1006
|
+
this.radiusBottom = props.radiusBottom ?? 0.5;
|
|
1007
|
+
this.radiusTop = props.radiusTop ?? 0.5;
|
|
1008
|
+
if (!Number.isFinite(this.height) || this.height <= 0)
|
|
1009
|
+
throw new Error("Cylinder height must be greater than zero");
|
|
1010
|
+
if (![this.radiusBottom, this.radiusTop].every((value) => Number.isFinite(value) && value >= 0))
|
|
1011
|
+
throw new Error("Cylinder radii must be non-negative");
|
|
1012
|
+
if (this.radiusBottom === 0 && this.radiusTop === 0)
|
|
1013
|
+
throw new Error("At least one cylinder radius must be greater than zero");
|
|
1014
|
+
}
|
|
1015
|
+
clone() {
|
|
1016
|
+
return new _CylinderShape({
|
|
1017
|
+
height: this.height,
|
|
1018
|
+
radiusBottom: this.radiusBottom,
|
|
1019
|
+
radiusTop: this.radiusTop,
|
|
1020
|
+
matrix: this.matrix
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
equals(shape) {
|
|
1024
|
+
return shape instanceof _CylinderShape && super.equals(shape) && this.height === shape.height && this.radiusBottom === shape.radiusBottom && this.radiusTop === shape.radiusTop;
|
|
1025
|
+
}
|
|
1026
|
+
containsLocalPoint(point) {
|
|
1027
|
+
const half = this.height / 2;
|
|
1028
|
+
if (point[1] < -half - EPSILON3 || point[1] > half + EPSILON3)
|
|
1029
|
+
return false;
|
|
1030
|
+
const t = (point[1] + half) / this.height;
|
|
1031
|
+
const radius = this.radiusBottom + (this.radiusTop - this.radiusBottom) * t;
|
|
1032
|
+
return Math.hypot(point[0], point[2]) <= radius + EPSILON3;
|
|
1033
|
+
}
|
|
1034
|
+
distanceToLocalPoint(point) {
|
|
1035
|
+
if (this.containsLocalPoint(point))
|
|
1036
|
+
return 0;
|
|
1037
|
+
const radial = Math.hypot(point[0], point[2]);
|
|
1038
|
+
const half = this.height / 2;
|
|
1039
|
+
const side = closestDistanceToSegment2D(radial, point[1], this.radiusBottom, -half, this.radiusTop, half);
|
|
1040
|
+
const bottom = closestDistanceToSegment2D(radial, point[1], 0, -half, this.radiusBottom, -half);
|
|
1041
|
+
const top = closestDistanceToSegment2D(radial, point[1], 0, half, this.radiusTop, half);
|
|
1042
|
+
return Math.min(side, bottom, top);
|
|
1043
|
+
}
|
|
1044
|
+
supportLocal(direction) {
|
|
1045
|
+
const radialLength = Math.hypot(direction[0], direction[2]);
|
|
1046
|
+
const x = radialLength ? direction[0] / radialLength : 1;
|
|
1047
|
+
const z = radialLength ? direction[2] / radialLength : 0;
|
|
1048
|
+
const half = this.height / 2;
|
|
1049
|
+
const bottomValue = radialLength * this.radiusBottom - direction[1] * half;
|
|
1050
|
+
const topValue = radialLength * this.radiusTop + direction[1] * half;
|
|
1051
|
+
return topValue >= bottomValue ? [x * this.radiusTop, half, z * this.radiusTop] : [x * this.radiusBottom, -half, z * this.radiusBottom];
|
|
1052
|
+
}
|
|
1053
|
+
intersectLocalRay(origin, direction) {
|
|
1054
|
+
const half = this.height / 2;
|
|
1055
|
+
const slope = (this.radiusTop - this.radiusBottom) / this.height;
|
|
1056
|
+
const intercept = (this.radiusTop + this.radiusBottom) / 2;
|
|
1057
|
+
const radialAtOrigin = intercept + slope * origin[1];
|
|
1058
|
+
const radialAlongRay = slope * direction[1];
|
|
1059
|
+
const candidates = [];
|
|
1060
|
+
const roots = solveQuadratic(direction[0] ** 2 + direction[2] ** 2 - radialAlongRay ** 2, 2 * (origin[0] * direction[0] + origin[2] * direction[2] - radialAtOrigin * radialAlongRay), origin[0] ** 2 + origin[2] ** 2 - radialAtOrigin ** 2);
|
|
1061
|
+
for (const distance of roots) {
|
|
1062
|
+
const y = origin[1] + distance * direction[1];
|
|
1063
|
+
if (distance >= 0 && y >= -half - EPSILON3 && y <= half + EPSILON3) {
|
|
1064
|
+
const x = origin[0] + distance * direction[0];
|
|
1065
|
+
const z = origin[2] + distance * direction[2];
|
|
1066
|
+
const radial = Math.hypot(x, z) || 1;
|
|
1067
|
+
const normal = [x / radial, -slope, z / radial];
|
|
1068
|
+
const length = Math.hypot(...normal);
|
|
1069
|
+
candidates.push({ distance, normal: normal.map((value) => value / length) });
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
if (Math.abs(direction[1]) > 1e-15) {
|
|
1073
|
+
for (const [y, radius, normalY] of [
|
|
1074
|
+
[-half, this.radiusBottom, -1],
|
|
1075
|
+
[half, this.radiusTop, 1]
|
|
1076
|
+
]) {
|
|
1077
|
+
const distance = (y - origin[1]) / direction[1];
|
|
1078
|
+
const x = origin[0] + distance * direction[0];
|
|
1079
|
+
const z = origin[2] + distance * direction[2];
|
|
1080
|
+
if (distance >= 0 && Math.hypot(x, z) <= radius + EPSILON3)
|
|
1081
|
+
candidates.push({ distance, normal: [0, normalY, 0] });
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
return candidates.sort((a, b) => a.distance - b.distance)[0];
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
// dist/lib/shapes/plane-shape.js
|
|
1089
|
+
var import_core8 = require("@math.gl/core");
|
|
1090
|
+
var PlaneShape = class _PlaneShape extends ImplicitShapeBase {
|
|
1091
|
+
constructor(props = {}) {
|
|
1092
|
+
super(props.matrix);
|
|
1093
|
+
this.type = "plane";
|
|
1094
|
+
this.sizeX = props.sizeX;
|
|
1095
|
+
this.sizeZ = props.sizeZ;
|
|
1096
|
+
if (this.sizeX !== void 0 && (!Number.isFinite(this.sizeX) || this.sizeX <= 0))
|
|
1097
|
+
throw new Error("Plane sizeX must be greater than zero");
|
|
1098
|
+
if (this.sizeZ !== void 0 && (!Number.isFinite(this.sizeZ) || this.sizeZ <= 0))
|
|
1099
|
+
throw new Error("Plane sizeZ must be greater than zero");
|
|
1100
|
+
}
|
|
1101
|
+
clone() {
|
|
1102
|
+
return new _PlaneShape({ sizeX: this.sizeX, sizeZ: this.sizeZ, matrix: this.matrix });
|
|
1103
|
+
}
|
|
1104
|
+
equals(shape) {
|
|
1105
|
+
return shape instanceof _PlaneShape && super.equals(shape) && this.sizeX === shape.sizeX && this.sizeZ === shape.sizeZ;
|
|
1106
|
+
}
|
|
1107
|
+
containsLocalPoint(point) {
|
|
1108
|
+
return point[1] <= 1e-12;
|
|
1109
|
+
}
|
|
1110
|
+
distanceToLocalPoint(point) {
|
|
1111
|
+
return Math.max(0, point[1]);
|
|
1112
|
+
}
|
|
1113
|
+
supportLocal() {
|
|
1114
|
+
throw new Error("An unbounded plane half-space has no finite support point");
|
|
1115
|
+
}
|
|
1116
|
+
intersectLocalRay(origin, direction) {
|
|
1117
|
+
if (Math.abs(direction[1]) < 1e-15)
|
|
1118
|
+
return void 0;
|
|
1119
|
+
const distance = -origin[1] / direction[1];
|
|
1120
|
+
if (distance < 0)
|
|
1121
|
+
return void 0;
|
|
1122
|
+
const x = origin[0] + distance * direction[0];
|
|
1123
|
+
const z = origin[2] + distance * direction[2];
|
|
1124
|
+
if (this.sizeX !== void 0 && Math.abs(x) > this.sizeX / 2 + 1e-12)
|
|
1125
|
+
return void 0;
|
|
1126
|
+
if (this.sizeZ !== void 0 && Math.abs(z) > this.sizeZ / 2 + 1e-12)
|
|
1127
|
+
return void 0;
|
|
1128
|
+
return { distance, normal: [0, 1, 0] };
|
|
1129
|
+
}
|
|
1130
|
+
intersectPlane(plane) {
|
|
1131
|
+
const boundaryPoint = new import_core8.Vector3(0, 0, 0).transform(this.matrix);
|
|
1132
|
+
const inverse = this.inverseMatrix;
|
|
1133
|
+
const boundaryNormal = new import_core8.Vector3(inverse[1], inverse[5], inverse[9]).normalize();
|
|
1134
|
+
const alignment = boundaryNormal.dot(plane.normal);
|
|
1135
|
+
if (Math.abs(Math.abs(alignment) - 1) > 1e-10)
|
|
1136
|
+
return "intersecting";
|
|
1137
|
+
const boundaryDistance = plane.getPointDistance(boundaryPoint);
|
|
1138
|
+
if (alignment < 0 && boundaryDistance > 0)
|
|
1139
|
+
return "inside";
|
|
1140
|
+
if (alignment > 0 && boundaryDistance < 0)
|
|
1141
|
+
return "outside";
|
|
1142
|
+
return "intersecting";
|
|
1143
|
+
}
|
|
1144
|
+
getAxisAlignedBoundingBox() {
|
|
1145
|
+
return void 0;
|
|
1146
|
+
}
|
|
1147
|
+
getBoundingSphere() {
|
|
1148
|
+
return void 0;
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
|
|
1152
|
+
// dist/lib/shapes/sphere-shape.js
|
|
1153
|
+
var EPSILON4 = 1e-6;
|
|
1154
|
+
var SphereShape = class _SphereShape extends ImplicitShapeBase {
|
|
1155
|
+
constructor(props = {}) {
|
|
1156
|
+
super(props.matrix);
|
|
1157
|
+
this.type = "sphere";
|
|
1158
|
+
this.radius = props.radius ?? 0.5;
|
|
1159
|
+
if (!Number.isFinite(this.radius) || this.radius <= 0)
|
|
1160
|
+
throw new Error("Sphere radius must be greater than zero");
|
|
1161
|
+
}
|
|
1162
|
+
clone() {
|
|
1163
|
+
return new _SphereShape({ radius: this.radius, matrix: this.matrix });
|
|
1164
|
+
}
|
|
1165
|
+
equals(shape) {
|
|
1166
|
+
return shape instanceof _SphereShape && super.equals(shape) && this.radius === shape.radius;
|
|
1167
|
+
}
|
|
1168
|
+
containsLocalPoint(point) {
|
|
1169
|
+
return Math.hypot(...point) <= this.radius + EPSILON4;
|
|
1170
|
+
}
|
|
1171
|
+
distanceToLocalPoint(point) {
|
|
1172
|
+
return Math.max(0, Math.hypot(...point) - this.radius);
|
|
1173
|
+
}
|
|
1174
|
+
supportLocal(direction) {
|
|
1175
|
+
const length = Math.hypot(...direction);
|
|
1176
|
+
return length ? direction.map((value) => value / length * this.radius) : [this.radius, 0, 0];
|
|
1177
|
+
}
|
|
1178
|
+
intersectLocalRay(origin, direction) {
|
|
1179
|
+
const roots = solveQuadratic(dot2(direction, direction), 2 * dot2(origin, direction), dot2(origin, origin) - this.radius * this.radius);
|
|
1180
|
+
const distance = roots.find((value) => value >= 0);
|
|
1181
|
+
if (distance === void 0)
|
|
1182
|
+
return void 0;
|
|
1183
|
+
const point = origin.map((value, i) => value + distance * direction[i]);
|
|
1184
|
+
return { distance, normal: point.map((value) => value / this.radius) };
|
|
1185
|
+
}
|
|
1186
|
+
};
|
|
1187
|
+
function dot2(a, b) {
|
|
1188
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
// dist/lib/perspective-off-center-frustum.js
|
|
1192
|
+
var import_core9 = require("@math.gl/core");
|
|
1193
|
+
var scratchPlaneUpVector = new import_core9.Vector3();
|
|
1194
|
+
var scratchPlaneRightVector = new import_core9.Vector3();
|
|
1195
|
+
var scratchPlaneNearCenter = new import_core9.Vector3();
|
|
1196
|
+
var scratchPlaneFarCenter = new import_core9.Vector3();
|
|
1197
|
+
var scratchPlaneNormal2 = new import_core9.Vector3();
|
|
1198
|
+
var PerspectiveOffCenterFrustum = class _PerspectiveOffCenterFrustum {
|
|
672
1199
|
/**
|
|
673
1200
|
* The viewing frustum is defined by 6 planes.
|
|
674
1201
|
* Each plane is represented by a {@link Vector4} object, where the x, y, and z components
|
|
@@ -698,8 +1225,8 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
698
1225
|
new Plane(),
|
|
699
1226
|
new Plane()
|
|
700
1227
|
]);
|
|
701
|
-
this._perspectiveMatrix = new
|
|
702
|
-
this._infinitePerspective = new
|
|
1228
|
+
this._perspectiveMatrix = new import_core9.Matrix4();
|
|
1229
|
+
this._infinitePerspective = new import_core9.Matrix4();
|
|
703
1230
|
const { near = 1, far = 5e8 } = options;
|
|
704
1231
|
this.left = options.left;
|
|
705
1232
|
this._left = void 0;
|
|
@@ -719,7 +1246,7 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
719
1246
|
* @returns {PerspectiveOffCenterFrustum} A new PerspectiveFrustum instance.
|
|
720
1247
|
* */
|
|
721
1248
|
clone() {
|
|
722
|
-
return new
|
|
1249
|
+
return new _PerspectiveOffCenterFrustum({
|
|
723
1250
|
right: this.right,
|
|
724
1251
|
left: this.left,
|
|
725
1252
|
top: this.top,
|
|
@@ -735,7 +1262,7 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
735
1262
|
* @returns {Boolean} <code>true</code> if they are equal, <code>false</code> otherwise.
|
|
736
1263
|
*/
|
|
737
1264
|
equals(other) {
|
|
738
|
-
return other && other instanceof
|
|
1265
|
+
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;
|
|
739
1266
|
}
|
|
740
1267
|
/**
|
|
741
1268
|
* Gets the perspective projection matrix computed from the view frustum.
|
|
@@ -770,9 +1297,9 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
770
1297
|
*/
|
|
771
1298
|
// eslint-disable-next-line complexity, max-statements
|
|
772
1299
|
computeCullingVolume(position, direction, up) {
|
|
773
|
-
(0,
|
|
774
|
-
(0,
|
|
775
|
-
(0,
|
|
1300
|
+
(0, import_core9.assert)(position, "position is required.");
|
|
1301
|
+
(0, import_core9.assert)(direction, "direction is required.");
|
|
1302
|
+
(0, import_core9.assert)(up, "up is required.");
|
|
776
1303
|
const planes = this._cullingVolume.planes;
|
|
777
1304
|
up = scratchPlaneUpVector.copy(up).normalize();
|
|
778
1305
|
const right = scratchPlaneRightVector.copy(direction).cross(up).normalize();
|
|
@@ -787,7 +1314,7 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
787
1314
|
planes[2].fromPointNormal(position, normal);
|
|
788
1315
|
normal.copy(up).multiplyByScalar(this.top).add(nearCenter).subtract(position).cross(right);
|
|
789
1316
|
planes[3].fromPointNormal(position, normal);
|
|
790
|
-
normal = new
|
|
1317
|
+
normal = new import_core9.Vector3().copy(direction);
|
|
791
1318
|
planes[4].fromPointNormal(nearCenter, normal);
|
|
792
1319
|
normal.negate();
|
|
793
1320
|
planes[5].fromPointNormal(farCenter, normal);
|
|
@@ -819,11 +1346,11 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
819
1346
|
*/
|
|
820
1347
|
getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result) {
|
|
821
1348
|
this._update();
|
|
822
|
-
(0,
|
|
823
|
-
(0,
|
|
824
|
-
(0,
|
|
825
|
-
(0,
|
|
826
|
-
(0,
|
|
1349
|
+
(0, import_core9.assert)(Number.isFinite(drawingBufferWidth) && Number.isFinite(drawingBufferHeight));
|
|
1350
|
+
(0, import_core9.assert)(drawingBufferWidth > 0);
|
|
1351
|
+
(0, import_core9.assert)(drawingBufferHeight > 0);
|
|
1352
|
+
(0, import_core9.assert)(distance > 0);
|
|
1353
|
+
(0, import_core9.assert)(result);
|
|
827
1354
|
const inverseNear = 1 / this.near;
|
|
828
1355
|
let tanTheta = this.top * inverseNear;
|
|
829
1356
|
const pixelHeight = 2 * distance * tanTheta / drawingBufferHeight;
|
|
@@ -835,17 +1362,17 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
835
1362
|
}
|
|
836
1363
|
// eslint-disable-next-line complexity, max-statements
|
|
837
1364
|
_update() {
|
|
838
|
-
(0,
|
|
1365
|
+
(0, import_core9.assert)(Number.isFinite(this.right) && Number.isFinite(this.left) && Number.isFinite(this.top) && Number.isFinite(this.bottom) && Number.isFinite(this.near) && Number.isFinite(this.far));
|
|
839
1366
|
const { top, bottom, right, left, near, far } = this;
|
|
840
1367
|
if (top !== this._top || bottom !== this._bottom || left !== this._left || right !== this._right || near !== this._near || far !== this._far) {
|
|
841
|
-
(0,
|
|
1368
|
+
(0, import_core9.assert)(this.near > 0 && this.near < this.far, "near must be greater than zero and less than far.");
|
|
842
1369
|
this._left = left;
|
|
843
1370
|
this._right = right;
|
|
844
1371
|
this._top = top;
|
|
845
1372
|
this._bottom = bottom;
|
|
846
1373
|
this._near = near;
|
|
847
1374
|
this._far = far;
|
|
848
|
-
this._perspectiveMatrix = new
|
|
1375
|
+
this._perspectiveMatrix = new import_core9.Matrix4().frustum({
|
|
849
1376
|
left,
|
|
850
1377
|
right,
|
|
851
1378
|
bottom,
|
|
@@ -853,7 +1380,7 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
853
1380
|
near,
|
|
854
1381
|
far
|
|
855
1382
|
});
|
|
856
|
-
this._infinitePerspective = new
|
|
1383
|
+
this._infinitePerspective = new import_core9.Matrix4().frustum({
|
|
857
1384
|
left,
|
|
858
1385
|
right,
|
|
859
1386
|
bottom,
|
|
@@ -866,9 +1393,9 @@ var PerspectiveOffCenterFrustum = class {
|
|
|
866
1393
|
};
|
|
867
1394
|
|
|
868
1395
|
// dist/lib/perspective-frustum.js
|
|
869
|
-
var
|
|
1396
|
+
var import_core10 = require("@math.gl/core");
|
|
870
1397
|
var defined = (val) => val !== null && typeof val !== "undefined";
|
|
871
|
-
var PerspectiveFrustum = class {
|
|
1398
|
+
var PerspectiveFrustum = class _PerspectiveFrustum {
|
|
872
1399
|
constructor(options = {}) {
|
|
873
1400
|
this._offCenterFrustum = new PerspectiveOffCenterFrustum();
|
|
874
1401
|
const { fov, aspectRatio, near = 1, far = 5e8, xOffset = 0, yOffset = 0 } = options;
|
|
@@ -883,7 +1410,7 @@ var PerspectiveFrustum = class {
|
|
|
883
1410
|
* Returns a duplicate of a PerspectiveFrustum instance.
|
|
884
1411
|
*/
|
|
885
1412
|
clone() {
|
|
886
|
-
return new
|
|
1413
|
+
return new _PerspectiveFrustum({
|
|
887
1414
|
aspectRatio: this.aspectRatio,
|
|
888
1415
|
fov: this.fov,
|
|
889
1416
|
near: this.near,
|
|
@@ -895,7 +1422,7 @@ var PerspectiveFrustum = class {
|
|
|
895
1422
|
* <code>true</code> if they are equal, <code>false</code> otherwise.
|
|
896
1423
|
*/
|
|
897
1424
|
equals(other) {
|
|
898
|
-
if (!defined(other) || !(other instanceof
|
|
1425
|
+
if (!defined(other) || !(other instanceof _PerspectiveFrustum)) {
|
|
899
1426
|
return false;
|
|
900
1427
|
}
|
|
901
1428
|
this._update();
|
|
@@ -968,16 +1495,16 @@ var PerspectiveFrustum = class {
|
|
|
968
1495
|
*/
|
|
969
1496
|
getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result) {
|
|
970
1497
|
this._update();
|
|
971
|
-
return this._offCenterFrustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result || new
|
|
1498
|
+
return this._offCenterFrustum.getPixelDimensions(drawingBufferWidth, drawingBufferHeight, distance, result || new import_core10.Vector2());
|
|
972
1499
|
}
|
|
973
1500
|
// eslint-disable-next-line complexity, max-statements
|
|
974
1501
|
_update() {
|
|
975
|
-
(0,
|
|
1502
|
+
(0, import_core10.assert)(Number.isFinite(this.fov) && Number.isFinite(this.aspectRatio) && Number.isFinite(this.near) && Number.isFinite(this.far));
|
|
976
1503
|
const f = this._offCenterFrustum;
|
|
977
1504
|
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) {
|
|
978
|
-
(0,
|
|
979
|
-
(0,
|
|
980
|
-
(0,
|
|
1505
|
+
(0, import_core10.assert)(this.fov >= 0 && this.fov < Math.PI);
|
|
1506
|
+
(0, import_core10.assert)(this.aspectRatio > 0);
|
|
1507
|
+
(0, import_core10.assert)(this.near >= 0 && this.near < this.far);
|
|
981
1508
|
this._aspectRatio = this.aspectRatio;
|
|
982
1509
|
this._fov = this.fov;
|
|
983
1510
|
this._fovy = this.aspectRatio <= 1 ? this.fov : Math.atan(Math.tan(this.fov * 0.5) / this.aspectRatio) * 2;
|
|
@@ -1001,19 +1528,19 @@ var PerspectiveFrustum = class {
|
|
|
1001
1528
|
};
|
|
1002
1529
|
|
|
1003
1530
|
// dist/lib/algorithms/bounding-sphere-from-points.js
|
|
1004
|
-
var
|
|
1005
|
-
var fromPointsXMin = new
|
|
1006
|
-
var fromPointsYMin = new
|
|
1007
|
-
var fromPointsZMin = new
|
|
1008
|
-
var fromPointsXMax = new
|
|
1009
|
-
var fromPointsYMax = new
|
|
1010
|
-
var fromPointsZMax = new
|
|
1011
|
-
var fromPointsCurrentPos = new
|
|
1012
|
-
var fromPointsScratch = new
|
|
1013
|
-
var fromPointsRitterCenter = new
|
|
1014
|
-
var fromPointsMinBoxPt = new
|
|
1015
|
-
var fromPointsMaxBoxPt = new
|
|
1016
|
-
var fromPointsNaiveCenterScratch = new
|
|
1531
|
+
var import_core11 = require("@math.gl/core");
|
|
1532
|
+
var fromPointsXMin = new import_core11.Vector3();
|
|
1533
|
+
var fromPointsYMin = new import_core11.Vector3();
|
|
1534
|
+
var fromPointsZMin = new import_core11.Vector3();
|
|
1535
|
+
var fromPointsXMax = new import_core11.Vector3();
|
|
1536
|
+
var fromPointsYMax = new import_core11.Vector3();
|
|
1537
|
+
var fromPointsZMax = new import_core11.Vector3();
|
|
1538
|
+
var fromPointsCurrentPos = new import_core11.Vector3();
|
|
1539
|
+
var fromPointsScratch = new import_core11.Vector3();
|
|
1540
|
+
var fromPointsRitterCenter = new import_core11.Vector3();
|
|
1541
|
+
var fromPointsMinBoxPt = new import_core11.Vector3();
|
|
1542
|
+
var fromPointsMaxBoxPt = new import_core11.Vector3();
|
|
1543
|
+
var fromPointsNaiveCenterScratch = new import_core11.Vector3();
|
|
1017
1544
|
function makeBoundingSphereFromPoints(positions, result = new BoundingSphere()) {
|
|
1018
1545
|
if (!positions || positions.length === 0) {
|
|
1019
1546
|
return result.fromCenterRadius([0, 0, 0], 0);
|
|
@@ -1109,17 +1636,17 @@ function makeBoundingSphereFromPoints(positions, result = new BoundingSphere())
|
|
|
1109
1636
|
}
|
|
1110
1637
|
|
|
1111
1638
|
// dist/lib/algorithms/bounding-box-from-points.js
|
|
1112
|
-
var
|
|
1639
|
+
var import_core13 = require("@math.gl/core");
|
|
1113
1640
|
|
|
1114
1641
|
// dist/lib/algorithms/compute-eigen-decomposition.js
|
|
1115
|
-
var
|
|
1116
|
-
var scratchMatrix = new
|
|
1117
|
-
var scratchUnitary = new
|
|
1118
|
-
var scratchDiagonal = new
|
|
1119
|
-
var jMatrix = new
|
|
1120
|
-
var jMatrixTranspose = new
|
|
1642
|
+
var import_core12 = require("@math.gl/core");
|
|
1643
|
+
var scratchMatrix = new import_core12.Matrix3();
|
|
1644
|
+
var scratchUnitary = new import_core12.Matrix3();
|
|
1645
|
+
var scratchDiagonal = new import_core12.Matrix3();
|
|
1646
|
+
var jMatrix = new import_core12.Matrix3();
|
|
1647
|
+
var jMatrixTranspose = new import_core12.Matrix3();
|
|
1121
1648
|
function computeEigenDecomposition(matrix, result = {}) {
|
|
1122
|
-
const EIGEN_TOLERANCE =
|
|
1649
|
+
const EIGEN_TOLERANCE = import_core12._MathUtils.EPSILON20;
|
|
1123
1650
|
const EIGEN_MAX_SWEEPS = 10;
|
|
1124
1651
|
let count = 0;
|
|
1125
1652
|
let sweep = 0;
|
|
@@ -1162,7 +1689,7 @@ function offDiagonalFrobeniusNorm(matrix) {
|
|
|
1162
1689
|
return Math.sqrt(norm);
|
|
1163
1690
|
}
|
|
1164
1691
|
function shurDecomposition(matrix, result) {
|
|
1165
|
-
const tolerance =
|
|
1692
|
+
const tolerance = import_core12._MathUtils.EPSILON15;
|
|
1166
1693
|
let maxDiagonal = 0;
|
|
1167
1694
|
let rotAxis = 1;
|
|
1168
1695
|
for (let i = 0; i < 3; ++i) {
|
|
@@ -1190,7 +1717,7 @@ function shurDecomposition(matrix, result) {
|
|
|
1190
1717
|
c = 1 / Math.sqrt(1 + t * t);
|
|
1191
1718
|
s = t * c;
|
|
1192
1719
|
}
|
|
1193
|
-
|
|
1720
|
+
import_core12.Matrix3.IDENTITY.to(result);
|
|
1194
1721
|
result[scratchMatrix.getElementIndex(p, p)] = result[scratchMatrix.getElementIndex(q, q)] = c;
|
|
1195
1722
|
result[scratchMatrix.getElementIndex(q, p)] = s;
|
|
1196
1723
|
result[scratchMatrix.getElementIndex(p, q)] = -s;
|
|
@@ -1198,24 +1725,24 @@ function shurDecomposition(matrix, result) {
|
|
|
1198
1725
|
}
|
|
1199
1726
|
|
|
1200
1727
|
// dist/lib/algorithms/bounding-box-from-points.js
|
|
1201
|
-
var scratchVector23 = new
|
|
1202
|
-
var scratchVector32 = new
|
|
1203
|
-
var scratchVector4 = new
|
|
1204
|
-
var scratchVector5 = new
|
|
1205
|
-
var scratchVector6 = new
|
|
1206
|
-
var scratchCovarianceResult = new
|
|
1728
|
+
var scratchVector23 = new import_core13.Vector3();
|
|
1729
|
+
var scratchVector32 = new import_core13.Vector3();
|
|
1730
|
+
var scratchVector4 = new import_core13.Vector3();
|
|
1731
|
+
var scratchVector5 = new import_core13.Vector3();
|
|
1732
|
+
var scratchVector6 = new import_core13.Vector3();
|
|
1733
|
+
var scratchCovarianceResult = new import_core13.Matrix3();
|
|
1207
1734
|
var scratchEigenResult = {
|
|
1208
|
-
diagonal: new
|
|
1209
|
-
unitary: new
|
|
1735
|
+
diagonal: new import_core13.Matrix3(),
|
|
1736
|
+
unitary: new import_core13.Matrix3()
|
|
1210
1737
|
};
|
|
1211
1738
|
function makeOrientedBoundingBoxFromPoints(positions, result = new OrientedBoundingBox()) {
|
|
1212
1739
|
if (!positions || positions.length === 0) {
|
|
1213
|
-
result.halfAxes = new
|
|
1214
|
-
result.center = new
|
|
1740
|
+
result.halfAxes = new import_core13.Matrix3([0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
|
1741
|
+
result.center = new import_core13.Vector3();
|
|
1215
1742
|
return result;
|
|
1216
1743
|
}
|
|
1217
1744
|
const length = positions.length;
|
|
1218
|
-
const meanPoint = new
|
|
1745
|
+
const meanPoint = new import_core13.Vector3(0, 0, 0);
|
|
1219
1746
|
for (const position of positions) {
|
|
1220
1747
|
meanPoint.add(position);
|
|
1221
1748
|
}
|
|
@@ -1277,7 +1804,7 @@ function makeOrientedBoundingBoxFromPoints(positions, result = new OrientedBound
|
|
|
1277
1804
|
v3 = v3.multiplyByScalar(0.5 * (l3 + u3));
|
|
1278
1805
|
result.center.copy(v1).add(v2).add(v3);
|
|
1279
1806
|
const scale = scratchVector32.set(u1 - l1, u2 - l2, u3 - l3).multiplyByScalar(0.5);
|
|
1280
|
-
const scaleMatrix = new
|
|
1807
|
+
const scaleMatrix = new import_core13.Matrix3([scale[0], 0, 0, 0, scale[1], 0, 0, 0, scale[2]]);
|
|
1281
1808
|
result.halfAxes.multiplyRight(scaleMatrix);
|
|
1282
1809
|
return result;
|
|
1283
1810
|
}
|