@math.gl/culling 3.5.7 → 3.6.0-alpha.3
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/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/es5/constants.js +7 -5
- package/dist/es5/constants.js.map +1 -1
- package/dist/es5/index.js +0 -12
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/algorithms/bounding-box-from-points.js.map +1 -1
- package/dist/es5/lib/algorithms/bounding-sphere-from-points.js.map +1 -1
- package/dist/es5/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
- package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js +12 -6
- package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
- package/dist/es5/lib/bounding-volumes/bounding-sphere.js +8 -4
- package/dist/es5/lib/bounding-volumes/bounding-sphere.js.map +1 -1
- package/dist/es5/lib/bounding-volumes/bounding-volume.js +2 -0
- package/dist/es5/lib/bounding-volumes/bounding-volume.js.map +1 -0
- package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js +4 -0
- package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
- package/dist/es5/lib/culling-volume.js +6 -20
- package/dist/es5/lib/culling-volume.js.map +1 -1
- package/dist/es5/lib/perspective-frustum.js +17 -7
- package/dist/es5/lib/perspective-frustum.js.map +1 -1
- package/dist/es5/lib/perspective-off-center-frustum.js +17 -5
- package/dist/es5/lib/perspective-off-center-frustum.js.map +1 -1
- package/dist/es5/lib/plane.js +5 -1
- package/dist/es5/lib/plane.js.map +1 -1
- package/dist/esm/constants.js +7 -5
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/index.js +0 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/algorithms/bounding-box-from-points.js.map +1 -1
- package/dist/esm/lib/algorithms/bounding-sphere-from-points.js.map +1 -1
- package/dist/esm/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
- package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js +15 -6
- package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
- package/dist/esm/lib/bounding-volumes/bounding-sphere.js +9 -4
- package/dist/esm/lib/bounding-volumes/bounding-sphere.js.map +1 -1
- package/dist/esm/lib/bounding-volumes/bounding-volume.js +2 -0
- package/dist/esm/lib/bounding-volumes/bounding-volume.js.map +1 -0
- package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js +5 -0
- package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
- package/dist/esm/lib/culling-volume.js +10 -16
- package/dist/esm/lib/culling-volume.js.map +1 -1
- package/dist/esm/lib/perspective-frustum.js +31 -5
- package/dist/esm/lib/perspective-frustum.js.map +1 -1
- package/dist/esm/lib/perspective-off-center-frustum.js +31 -3
- package/dist/esm/lib/perspective-off-center-frustum.js.map +1 -1
- package/dist/esm/lib/plane.js +6 -1
- package/dist/esm/lib/plane.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/{src → dist}/lib/algorithms/bounding-box-from-points.d.ts +3 -10
- package/dist/lib/algorithms/bounding-box-from-points.d.ts.map +1 -0
- package/dist/lib/algorithms/bounding-box-from-points.js +131 -0
- package/dist/{esm/lib → lib}/algorithms/bounding-sphere-from-points.d.ts +2 -5
- package/dist/lib/algorithms/bounding-sphere-from-points.d.ts.map +1 -0
- package/dist/lib/algorithms/bounding-sphere-from-points.js +140 -0
- package/dist/{es5/lib → lib}/algorithms/compute-eigen-decomposition.d.ts +7 -9
- package/dist/lib/algorithms/compute-eigen-decomposition.d.ts.map +1 -0
- package/dist/lib/algorithms/compute-eigen-decomposition.js +131 -0
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +56 -0
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -0
- package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js +111 -0
- package/dist/lib/bounding-volumes/bounding-sphere.d.ts +40 -0
- package/dist/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -0
- package/dist/lib/bounding-volumes/bounding-sphere.js +118 -0
- package/dist/lib/bounding-volumes/bounding-volume.d.ts +30 -0
- package/dist/lib/bounding-volumes/bounding-volume.d.ts.map +1 -0
- package/dist/lib/bounding-volumes/bounding-volume.js +1 -0
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +67 -0
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -0
- package/dist/lib/bounding-volumes/oriented-bounding-box.js +256 -0
- package/dist/lib/culling-volume.d.ts +46 -0
- package/dist/lib/culling-volume.d.ts.map +1 -0
- package/dist/lib/culling-volume.js +121 -0
- package/dist/lib/perspective-frustum.d.ts +140 -0
- package/dist/lib/perspective-frustum.d.ts.map +1 -0
- package/dist/lib/perspective-frustum.js +205 -0
- package/dist/lib/perspective-off-center-frustum.d.ts +122 -0
- package/dist/lib/perspective-off-center-frustum.d.ts.map +1 -0
- package/dist/lib/perspective-off-center-frustum.js +305 -0
- package/dist/lib/plane.d.ts +26 -0
- package/dist/lib/plane.d.ts.map +1 -0
- package/dist/lib/plane.js +63 -0
- package/package.json +5 -5
- package/src/constants.ts +8 -0
- package/src/{index.js → index.ts} +0 -4
- package/src/lib/algorithms/{bounding-box-from-points.js → bounding-box-from-points.ts} +17 -4
- package/src/lib/algorithms/{bounding-sphere-from-points.js → bounding-sphere-from-points.ts} +15 -3
- package/src/lib/algorithms/{compute-eigen-decomposition.js → compute-eigen-decomposition.ts} +40 -1
- package/src/lib/bounding-volumes/{axis-aligned-bounding-box.js → axis-aligned-bounding-box.ts} +45 -14
- package/src/lib/bounding-volumes/{bounding-sphere.js → bounding-sphere.ts} +44 -29
- package/src/lib/bounding-volumes/{bounding-volume.d.ts → bounding-volume.ts} +7 -7
- package/src/lib/bounding-volumes/{oriented-bounding-box.js → oriented-bounding-box.ts} +72 -14
- package/src/lib/{culling-volume.js → culling-volume.ts} +42 -34
- package/src/lib/{perspective-frustum.js → perspective-frustum.ts} +48 -66
- package/src/lib/{perspective-off-center-frustum.js → perspective-off-center-frustum.ts} +24 -14
- package/src/lib/{plane.js → plane.ts} +24 -17
- package/dist/es5/constants.d.ts +0 -6
- package/dist/es5/index.d.ts +0 -20
- package/dist/es5/lib/algorithms/bounding-box-from-points.d.ts +0 -22
- package/dist/es5/lib/algorithms/bounding-sphere-from-points.d.ts +0 -17
- package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
- package/dist/es5/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
- package/dist/es5/lib/bounding-volumes/bounding-volume.d.ts +0 -32
- package/dist/es5/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
- package/dist/es5/lib/culling-volume.d.ts +0 -55
- package/dist/es5/lib/plane.d.ts +0 -38
- package/dist/esm/constants.d.ts +0 -6
- package/dist/esm/index.d.ts +0 -20
- package/dist/esm/lib/algorithms/bounding-box-from-points.d.ts +0 -22
- package/dist/esm/lib/algorithms/compute-eigen-decomposition.d.ts +0 -39
- package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
- package/dist/esm/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
- package/dist/esm/lib/bounding-volumes/bounding-volume.d.ts +0 -32
- package/dist/esm/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
- package/dist/esm/lib/culling-volume.d.ts +0 -55
- package/dist/esm/lib/plane.d.ts +0 -38
- package/src/constants.d.ts +0 -6
- package/src/constants.js +0 -8
- package/src/index.d.ts +0 -20
- package/src/lib/algorithms/bounding-sphere-from-points.d.ts +0 -17
- package/src/lib/algorithms/compute-eigen-decomposition.d.ts +0 -39
- package/src/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
- package/src/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
- package/src/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
- package/src/lib/culling-volume.d.ts +0 -55
- package/src/lib/plane.d.ts +0 -38
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// This file is derived from the Cesium math library under Apache 2 license
|
|
2
|
+
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
import { Vector3, equals, assert } from '@math.gl/core';
|
|
5
|
+
const scratchPosition = new Vector3();
|
|
6
|
+
const scratchNormal = new Vector3();
|
|
7
|
+
// A plane in Hessian Normal Form
|
|
8
|
+
export default class Plane {
|
|
9
|
+
constructor(normal = [0, 0, 1], distance = 0) {
|
|
10
|
+
this.normal = new Vector3();
|
|
11
|
+
this.distance = -0;
|
|
12
|
+
this.fromNormalDistance(normal, distance);
|
|
13
|
+
}
|
|
14
|
+
/** Creates a plane from a normal and a distance from the origin. */
|
|
15
|
+
fromNormalDistance(normal, distance) {
|
|
16
|
+
assert(Number.isFinite(distance));
|
|
17
|
+
this.normal.from(normal).normalize();
|
|
18
|
+
this.distance = distance;
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
/** Creates a plane from a normal and a point on the plane. */
|
|
22
|
+
fromPointNormal(point, normal) {
|
|
23
|
+
point = scratchPosition.from(point);
|
|
24
|
+
this.normal.from(normal).normalize();
|
|
25
|
+
const distance = -this.normal.dot(point);
|
|
26
|
+
this.distance = distance;
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
/** Creates a plane from the general equation */
|
|
30
|
+
fromCoefficients(a, b, c, d) {
|
|
31
|
+
this.normal.set(a, b, c);
|
|
32
|
+
assert(equals(this.normal.len(), 1));
|
|
33
|
+
this.distance = d;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
/** Duplicates a Plane instance. */
|
|
37
|
+
clone() {
|
|
38
|
+
return new Plane(this.normal, this.distance);
|
|
39
|
+
}
|
|
40
|
+
/** Compares the provided Planes by normal and distance */
|
|
41
|
+
equals(right) {
|
|
42
|
+
return equals(this.distance, right.distance) && equals(this.normal, right.normal);
|
|
43
|
+
}
|
|
44
|
+
/** Computes the signed shortest distance of a point to a plane.
|
|
45
|
+
* The sign of the distance determines which side of the plane the point is on.
|
|
46
|
+
*/
|
|
47
|
+
getPointDistance(point) {
|
|
48
|
+
return this.normal.dot(point) + this.distance;
|
|
49
|
+
}
|
|
50
|
+
/** Transforms the plane by the given transformation matrix. */
|
|
51
|
+
transform(matrix4) {
|
|
52
|
+
const normal = scratchNormal.copy(this.normal).transformAsVector(matrix4).normalize();
|
|
53
|
+
const point = this.normal.scale(-this.distance).transform(matrix4);
|
|
54
|
+
return this.fromPointNormal(point, normal);
|
|
55
|
+
}
|
|
56
|
+
projectPointOntoPlane(point, result = [0, 0, 0]) {
|
|
57
|
+
point = scratchPosition.from(point);
|
|
58
|
+
// projectedPoint = point - (normal.point + scale) * normal
|
|
59
|
+
const pointDistance = this.getPointDistance(point);
|
|
60
|
+
const scaledNormal = scratchNormal.copy(this.normal).scale(pointDistance);
|
|
61
|
+
return point.subtract(scaledNormal).to(result);
|
|
62
|
+
}
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"version": "3.
|
|
8
|
+
"version": "3.6.0-alpha.3",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"webgl",
|
|
11
11
|
"javascript",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"type": "git",
|
|
27
27
|
"url": "https://github.com/uber-web/math.gl.git"
|
|
28
28
|
},
|
|
29
|
-
"types": "
|
|
29
|
+
"types": "dist/index.d.ts",
|
|
30
30
|
"main": "dist/es5/index.js",
|
|
31
31
|
"module": "dist/esm/index.js",
|
|
32
32
|
"files": [
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
],
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@babel/runtime": "^7.12.0",
|
|
38
|
-
"@math.gl/core": "3.
|
|
39
|
-
"gl-matrix": "
|
|
38
|
+
"@math.gl/core": "3.6.0-alpha.3",
|
|
39
|
+
"gl-matrix": "^3.4.0"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "ec2a4af3e64b97f0354a75c370d23d3de0aa3b43"
|
|
42
42
|
}
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// This file is derived from the Cesium math library under Apache 2 license
|
|
2
|
+
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
3
|
+
|
|
4
|
+
export enum INTERSECTION {
|
|
5
|
+
OUTSIDE = -1, // Represents that an object is not contained within the frustum.
|
|
6
|
+
INTERSECTING = 0, // Represents that an object intersects one of the frustum's planes.
|
|
7
|
+
INSIDE = 1 // Represents that an object is fully within the frustum.
|
|
8
|
+
}
|
|
@@ -18,7 +18,3 @@ export {
|
|
|
18
18
|
makeOrientedBoundingBoxFromPoints
|
|
19
19
|
} from './lib/algorithms/bounding-box-from-points';
|
|
20
20
|
export {default as computeEigenDecomposition} from './lib/algorithms/compute-eigen-decomposition';
|
|
21
|
-
|
|
22
|
-
// Deprecated
|
|
23
|
-
export {INTERSECTION as Intersect} from './constants';
|
|
24
|
-
export {INTERSECTION as INTERSECT} from './constants';
|
|
@@ -23,8 +23,17 @@ const scratchEigenResult = {
|
|
|
23
23
|
unitary: new Matrix3()
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Computes an instance of an OrientedBoundingBox of the given positions.
|
|
28
|
+
*
|
|
29
|
+
* This is an implementation of Stefan Gottschalk's Collision Queries using Oriented Bounding Boxes solution (PHD thesis).
|
|
30
|
+
* Reference: http://gamma.cs.unc.edu/users/gottschalk/main.pdf
|
|
31
|
+
*/
|
|
26
32
|
/* eslint-disable max-statements */
|
|
27
|
-
export function makeOrientedBoundingBoxFromPoints(
|
|
33
|
+
export function makeOrientedBoundingBoxFromPoints(
|
|
34
|
+
positions: number[][],
|
|
35
|
+
result: OrientedBoundingBox = new OrientedBoundingBox()
|
|
36
|
+
): OrientedBoundingBox {
|
|
28
37
|
if (!positions || positions.length === 0) {
|
|
29
38
|
result.halfAxes = new Matrix3([0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
|
30
39
|
result.center = new Vector3();
|
|
@@ -113,10 +122,14 @@ export function makeOrientedBoundingBoxFromPoints(positions, result = new Orient
|
|
|
113
122
|
return result;
|
|
114
123
|
}
|
|
115
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Computes an instance of an AxisAlignedBoundingBox. The box is determined by
|
|
127
|
+
* finding the points spaced the farthest apart on the x, y, and z axes.
|
|
128
|
+
*/
|
|
116
129
|
export function makeAxisAlignedBoundingBoxFromPoints(
|
|
117
|
-
positions,
|
|
118
|
-
result = new AxisAlignedBoundingBox()
|
|
119
|
-
) {
|
|
130
|
+
positions: readonly number[][],
|
|
131
|
+
result: AxisAlignedBoundingBox = new AxisAlignedBoundingBox()
|
|
132
|
+
): AxisAlignedBoundingBox {
|
|
120
133
|
if (!positions || positions.length === 0) {
|
|
121
134
|
result.minimum.set(0, 0, 0);
|
|
122
135
|
result.maximum.set(0, 0, 0);
|
package/src/lib/algorithms/{bounding-sphere-from-points.js → bounding-sphere-from-points.ts}
RENAMED
|
@@ -19,7 +19,21 @@ const fromPointsMaxBoxPt = new Vector3();
|
|
|
19
19
|
const fromPointsNaiveCenterScratch = new Vector3();
|
|
20
20
|
const volumeConstant = (4.0 / 3.0) * Math.PI;
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Computes a tight-fitting bounding sphere enclosing a list of 3D Cartesian points.
|
|
24
|
+
*
|
|
25
|
+
* The bounding sphere is computed by running two algorithms, a naive algorithm and
|
|
26
|
+
* Ritter's algorithm. The smaller of the two spheres is used to ensure a tight fit.
|
|
27
|
+
* Bounding sphere computation article http://blogs.agi.com/insight3d/index.php/2008/02/04/a-bounding
|
|
28
|
+
*
|
|
29
|
+
* @param positions An array of points that the bounding sphere will enclose.
|
|
30
|
+
* @param result Optional object onto which to store the result.
|
|
31
|
+
* @returns The modified result parameter or a new `BoundingSphere` instance if not provided.
|
|
32
|
+
*/
|
|
33
|
+
export default function makeBoundingSphereFromPoints(
|
|
34
|
+
positions: number[][],
|
|
35
|
+
result: BoundingSphere = new BoundingSphere()
|
|
36
|
+
): BoundingSphere {
|
|
23
37
|
if (!positions || positions.length === 0) {
|
|
24
38
|
return result.fromCenterRadius([0, 0, 0], 0);
|
|
25
39
|
}
|
|
@@ -145,11 +159,9 @@ export default function makeBoundingSphereFromPoints(positions, result = new Bou
|
|
|
145
159
|
|
|
146
160
|
if (ritterRadius < naiveRadius) {
|
|
147
161
|
ritterCenter.to(result.center);
|
|
148
|
-
// @ts-ignore TS2540: Cannot assign to 'radius' because it is a read-only property.
|
|
149
162
|
result.radius = ritterRadius;
|
|
150
163
|
} else {
|
|
151
164
|
naiveCenter.to(result.center);
|
|
152
|
-
// @ts-ignore TS2540: Cannot assign to 'radius' because it is a read-only property.
|
|
153
165
|
result.radius = naiveRadius;
|
|
154
166
|
}
|
|
155
167
|
|
package/src/lib/algorithms/{compute-eigen-decomposition.js → compute-eigen-decomposition.ts}
RENAMED
|
@@ -10,7 +10,46 @@ const scratchDiagonal = new Matrix3();
|
|
|
10
10
|
const jMatrix = new Matrix3();
|
|
11
11
|
const jMatrixTranspose = new Matrix3();
|
|
12
12
|
|
|
13
|
-
export
|
|
13
|
+
export type EigenDecomposition = {
|
|
14
|
+
unitary: Matrix3;
|
|
15
|
+
diagonal: Matrix3;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Computes the eigenvectors and eigenvalues of a symmetric matrix.
|
|
20
|
+
*
|
|
21
|
+
* - Returns a diagonal matrix and unitary matrix such that:
|
|
22
|
+
* `matrix = unitary matrix * diagonal matrix * transpose(unitary matrix)`
|
|
23
|
+
* - The values along the diagonal of the diagonal matrix are the eigenvalues. The columns
|
|
24
|
+
* of the unitary matrix are the corresponding eigenvectors.
|
|
25
|
+
* - This routine was created based upon Matrix Computations, 3rd ed., by Golub and Van Loan,
|
|
26
|
+
* section 8.4.3 The Classical Jacobi Algorithm
|
|
27
|
+
*
|
|
28
|
+
* @param matrix The 3x3 matrix to decompose into diagonal and unitary matrix. Expected to be symmetric.
|
|
29
|
+
* @param result Optional object with unitary and diagonal properties which are matrices onto which to store the result.
|
|
30
|
+
* @returns An object with unitary and diagonal properties which are the unitary and diagonal matrices, respectively.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const a = //... symmetric matrix
|
|
34
|
+
* const result = {
|
|
35
|
+
* unitary : new Matrix3(),
|
|
36
|
+
* diagonal : new Matrix3()
|
|
37
|
+
* };
|
|
38
|
+
* computeEigenDecomposition(a, result);
|
|
39
|
+
*
|
|
40
|
+
* const unitaryTranspose = Matrix3.transpose(result.unitary, new Matrix3());
|
|
41
|
+
* const b = Matrix3.multiply(result.unitary, result.diagonal, new Matrix3());
|
|
42
|
+
* Matrix3.multiply(b, unitaryTranspose, b); // b is now equal to a
|
|
43
|
+
*
|
|
44
|
+
* const lambda = result.diagonal.getColumn(0, new Vector3()).x; // first eigenvalue
|
|
45
|
+
* const v = result.unitary.getColumn(0, new Vector3()); // first eigenvector
|
|
46
|
+
* const c = v.multiplyByScalar(lambda); // equal to v.transformByMatrix3(a)
|
|
47
|
+
*/
|
|
48
|
+
export default function computeEigenDecomposition(
|
|
49
|
+
matrix: number[],
|
|
50
|
+
// @ts-expect-error accept empty object type
|
|
51
|
+
result: EigenDecomposition = {}
|
|
52
|
+
): EigenDecomposition {
|
|
14
53
|
const EIGEN_TOLERANCE = _MathUtils.EPSILON20;
|
|
15
54
|
const EIGEN_MAX_SWEEPS = 10;
|
|
16
55
|
|
package/src/lib/bounding-volumes/{axis-aligned-bounding-box.js → axis-aligned-bounding-box.ts}
RENAMED
|
@@ -1,11 +1,38 @@
|
|
|
1
|
+
import {BoundingVolume} from './bounding-volume';
|
|
1
2
|
import {Vector3} from '@math.gl/core';
|
|
3
|
+
import Plane from '../plane';
|
|
2
4
|
import {INTERSECTION} from '../../constants';
|
|
3
5
|
|
|
4
6
|
const scratchVector = new Vector3();
|
|
5
7
|
const scratchNormal = new Vector3();
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* An axis aligned bounding box - aligned with coordinate axes
|
|
11
|
+
* @see BoundingVolume
|
|
12
|
+
* @see BoundingRectangle
|
|
13
|
+
* @see OrientedBoundingBox
|
|
14
|
+
*/
|
|
15
|
+
export default class AxisAlignedBoundingBox implements BoundingVolume {
|
|
16
|
+
/** The center point of the bounding box. */
|
|
17
|
+
readonly center: Vector3;
|
|
18
|
+
/** The positive half diagonal of the bounding box. */
|
|
19
|
+
readonly halfDiagonal: Vector3;
|
|
20
|
+
/** The minimum point defining the bounding box. [0, 0, 0] for empty box */
|
|
21
|
+
readonly minimum: Vector3;
|
|
22
|
+
/** The maximum point defining the bounding box. [0, 0, 0] for empty box */
|
|
23
|
+
readonly maximum: Vector3;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Creates an instance of an AxisAlignedBoundingBox from the minimum and maximum points along the x, y, and z axes.
|
|
27
|
+
* @param minimum=[0, 0, 0] The minimum point along the x, y, and z axes.
|
|
28
|
+
* @param maximum=[0, 0, 0] The maximum point along the x, y, and z axes.
|
|
29
|
+
* @param center The center of the box; automatically computed if not supplied.
|
|
30
|
+
*/
|
|
31
|
+
constructor(
|
|
32
|
+
minimum: readonly number[] = [0, 0, 0],
|
|
33
|
+
maximum: readonly number[] = [0, 0, 0],
|
|
34
|
+
center?: readonly number[]
|
|
35
|
+
) {
|
|
9
36
|
// If center was not defined, compute it.
|
|
10
37
|
center = center || scratchVector.copy(minimum).add(maximum).scale(0.5);
|
|
11
38
|
this.center = new Vector3(center);
|
|
@@ -49,19 +76,24 @@ export default class AxisAlignedBoundingBox {
|
|
|
49
76
|
);
|
|
50
77
|
}
|
|
51
78
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Applies a 4x4 affine transformation matrix to a bounding sphere.
|
|
81
|
+
* @param transform The transformation matrix to apply to the bounding sphere.
|
|
82
|
+
* @returns itself, i.e. the modified BoundingVolume.
|
|
83
|
+
*/
|
|
84
|
+
transform(transform: readonly number[]): this {
|
|
85
|
+
this.center.transformAsPoint(transform);
|
|
86
|
+
// TODO - this.halfDiagonal.transformAsVector(transform);
|
|
87
|
+
this.halfDiagonal.transform(transform);
|
|
88
|
+
this.minimum.transform(transform);
|
|
89
|
+
this.maximum.transform(transform);
|
|
58
90
|
return this;
|
|
59
91
|
}
|
|
60
92
|
|
|
61
93
|
/**
|
|
62
94
|
* Determines which side of a plane a box is located.
|
|
63
95
|
*/
|
|
64
|
-
intersectPlane(plane) {
|
|
96
|
+
intersectPlane(plane: Plane): INTERSECTION {
|
|
65
97
|
const {halfDiagonal} = this;
|
|
66
98
|
const normal = scratchNormal.from(plane.normal);
|
|
67
99
|
const e =
|
|
@@ -82,14 +114,13 @@ export default class AxisAlignedBoundingBox {
|
|
|
82
114
|
return INTERSECTION.INTERSECTING;
|
|
83
115
|
}
|
|
84
116
|
|
|
85
|
-
|
|
86
|
-
distanceTo(point) {
|
|
117
|
+
/** Computes the estimated distance from the closest point on a bounding box to a point. */
|
|
118
|
+
distanceTo(point: readonly number[]): number {
|
|
87
119
|
return Math.sqrt(this.distanceSquaredTo(point));
|
|
88
120
|
}
|
|
89
121
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
distanceSquaredTo(point) {
|
|
122
|
+
/** Computes the estimated distance squared from the closest point on a bounding box to a point. */
|
|
123
|
+
distanceSquaredTo(point: readonly number[]): number {
|
|
93
124
|
const offset = scratchVector.from(point).subtract(this.center);
|
|
94
125
|
const {halfDiagonal} = this;
|
|
95
126
|
|
|
@@ -1,55 +1,60 @@
|
|
|
1
1
|
// This file is derived from the Cesium math library under Apache 2 license
|
|
2
2
|
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
3
3
|
|
|
4
|
-
import {Vector3} from '@math.gl/core';
|
|
4
|
+
import {NumericArray, Vector3} from '@math.gl/core';
|
|
5
5
|
import * as mat4 from 'gl-matrix/mat4';
|
|
6
6
|
import {INTERSECTION} from '../../constants';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
// const defaultProjection = new GeographicProjection();
|
|
11
|
-
// const fromRectangle2DLowerLeft = new Vector3();
|
|
12
|
-
// const fromRectangle2DUpperRight = new Vector3();
|
|
13
|
-
// const fromRectangle2DSouthwest = new Cartographic();
|
|
14
|
-
// const fromRectangle2DNortheast = new Cartographic();
|
|
15
|
-
|
|
16
|
-
// const fromRectangle3DScratch = [];
|
|
7
|
+
import {BoundingVolume} from './bounding-volume';
|
|
8
|
+
import Plane from '../plane';
|
|
17
9
|
|
|
18
10
|
const scratchVector = new Vector3();
|
|
19
11
|
const scratchVector2 = new Vector3();
|
|
20
12
|
|
|
21
|
-
|
|
22
|
-
|
|
13
|
+
/** A BoundingSphere */
|
|
14
|
+
export default class BoundingSphere implements BoundingVolume {
|
|
15
|
+
center: Vector3;
|
|
16
|
+
radius: number;
|
|
17
|
+
|
|
18
|
+
/** Creates a bounding sphere */
|
|
19
|
+
constructor(center: readonly number[] = [0, 0, 0], radius: number = 0.0) {
|
|
23
20
|
this.radius = -0;
|
|
24
21
|
this.center = new Vector3();
|
|
25
22
|
this.fromCenterRadius(center, radius);
|
|
26
23
|
}
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
/** Sets the bounding sphere from `center` and `radius`. */
|
|
26
|
+
fromCenterRadius(center: readonly number[], radius: number): this {
|
|
29
27
|
this.center.from(center);
|
|
30
28
|
this.radius = radius;
|
|
31
29
|
return this;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Computes a bounding sphere from the corner points of an axis-aligned bounding box. The sphere
|
|
34
|
+
* tightly and fully encompasses the box.
|
|
35
|
+
*/
|
|
36
|
+
fromCornerPoints(corner: readonly number[], oppositeCorner: readonly number[]): this {
|
|
35
37
|
oppositeCorner = scratchVector.from(oppositeCorner);
|
|
36
38
|
this.center = new Vector3().from(corner).add(oppositeCorner).scale(0.5);
|
|
37
39
|
this.radius = this.center.distance(oppositeCorner);
|
|
38
40
|
return this;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
/** Compares the provided BoundingSphere component wise */
|
|
44
|
+
equals(right: BoundingSphere): boolean {
|
|
42
45
|
return (
|
|
43
46
|
this === right ||
|
|
44
47
|
(Boolean(right) && this.center.equals(right.center) && this.radius === right.radius)
|
|
45
48
|
);
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
/** Duplicates a BoundingSphere instance. */
|
|
52
|
+
clone(): BoundingSphere {
|
|
49
53
|
return new BoundingSphere(this.center, this.radius);
|
|
50
54
|
}
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
/** Computes a bounding sphere that contains both the left and right bounding spheres. */
|
|
57
|
+
union(boundingSphere: BoundingSphere): BoundingSphere {
|
|
53
58
|
const leftCenter = this.center;
|
|
54
59
|
const leftRadius = this.radius;
|
|
55
60
|
const rightCenter = boundingSphere.center;
|
|
@@ -83,36 +88,46 @@ export default class BoundingSphere {
|
|
|
83
88
|
return this;
|
|
84
89
|
}
|
|
85
90
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
91
|
+
/** Computes a bounding sphere by enlarging the provided sphere to contain the provided point. */
|
|
92
|
+
expand(point: readonly number[]): this {
|
|
93
|
+
const scratchPoint = scratchVector.from(point);
|
|
94
|
+
const radius = scratchPoint.subtract(this.center).magnitude();
|
|
89
95
|
if (radius > this.radius) {
|
|
90
96
|
this.radius = radius;
|
|
91
97
|
}
|
|
92
98
|
return this;
|
|
93
99
|
}
|
|
94
100
|
|
|
95
|
-
|
|
101
|
+
// BoundingVolume interface
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Applies a 4x4 affine transformation matrix to a bounding sphere.
|
|
105
|
+
* @param sphere The bounding sphere to apply the transformation to.
|
|
106
|
+
* @param transform The transformation matrix to apply to the bounding sphere.
|
|
107
|
+
* @returns self.
|
|
108
|
+
*/
|
|
109
|
+
transform(transform: readonly number[]): this {
|
|
96
110
|
this.center.transform(transform);
|
|
97
111
|
const scale = mat4.getScaling(scratchVector, transform);
|
|
98
112
|
this.radius = Math.max(scale[0], Math.max(scale[1], scale[2])) * this.radius;
|
|
99
113
|
return this;
|
|
100
114
|
}
|
|
101
115
|
|
|
102
|
-
|
|
103
|
-
distanceSquaredTo(point) {
|
|
116
|
+
/** Computes the estimated distance squared from the closest point on a bounding sphere to a point. */
|
|
117
|
+
distanceSquaredTo(point: Readonly<NumericArray>): number {
|
|
104
118
|
const d = this.distanceTo(point);
|
|
105
119
|
return d * d;
|
|
106
120
|
}
|
|
107
121
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
122
|
+
/** Computes the estimated distance from the closest point on a bounding sphere to a point. */
|
|
123
|
+
distanceTo(point: Readonly<NumericArray>): number {
|
|
124
|
+
const scratchPoint = scratchVector.from(point);
|
|
125
|
+
const delta = scratchPoint.subtract(this.center);
|
|
111
126
|
return Math.max(0, delta.len() - this.radius);
|
|
112
127
|
}
|
|
113
128
|
|
|
114
|
-
|
|
115
|
-
intersectPlane(plane) {
|
|
129
|
+
/** Determines which side of a plane a sphere is located. */
|
|
130
|
+
intersectPlane(plane: Plane): INTERSECTION {
|
|
116
131
|
const center = this.center;
|
|
117
132
|
const radius = this.radius;
|
|
118
133
|
const normal = plane.normal;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {INTERSECTION} from '../../constants';
|
|
2
2
|
import Plane from '../plane';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -12,12 +12,12 @@ export interface BoundingVolume {
|
|
|
12
12
|
* @param transform The transformation matrix to apply to the bounding sphere.
|
|
13
13
|
* @returns itself, i.e. the modified BoundingVolume.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
transform(transform: readonly number[]): this;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
/** Computes the estimated distance squared from the closest point on a bounding sphere to a point. */
|
|
18
|
+
distanceSquaredTo(point: readonly number[]): number;
|
|
19
|
+
/** Computes the estimated distance from the closest point on a bounding sphere to a point. */
|
|
20
|
+
distanceTo(point: readonly number[]): number;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Determines which side of a plane the oriented bounding box is located.
|
|
@@ -28,5 +28,5 @@ export interface BoundingVolume {
|
|
|
28
28
|
* - `INTERSECTION.OUTSIDE` if the entire box is on the opposite side.
|
|
29
29
|
* - `INTERSECTION.INTERSECTING` if the box intersects the plane.
|
|
30
30
|
*/
|
|
31
|
-
intersectPlane(plane: Plane):
|
|
31
|
+
intersectPlane(plane: Plane): INTERSECTION;
|
|
32
32
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
// This file is derived from the Cesium math library under Apache 2 license
|
|
2
2
|
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
3
3
|
|
|
4
|
-
import {Vector3, Matrix3, Quaternion} from '@math.gl/core';
|
|
4
|
+
import {Vector3, Matrix3, Quaternion, NumericArray} from '@math.gl/core';
|
|
5
|
+
import type {BoundingVolume} from './bounding-volume';
|
|
5
6
|
import BoundingSphere from './bounding-sphere';
|
|
7
|
+
import type Plane from '../plane';
|
|
6
8
|
import {INTERSECTION} from '../../constants';
|
|
7
9
|
|
|
8
10
|
const scratchVector3 = new Vector3();
|
|
@@ -25,20 +27,36 @@ const MATRIX3 = {
|
|
|
25
27
|
COLUMN2ROW2: 8
|
|
26
28
|
};
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
/**
|
|
31
|
+
* An OrientedBoundingBox of some object is a closed and convex cuboid.
|
|
32
|
+
* It can provide a tighter bounding volume than `BoundingSphere` or
|
|
33
|
+
* `AxisAlignedBoundingBox` in many cases.
|
|
34
|
+
*/
|
|
35
|
+
export default class OrientedBoundingBox implements BoundingVolume {
|
|
36
|
+
center: Vector3;
|
|
37
|
+
halfAxes: Matrix3;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* An OrientedBoundingBox of some object is a closed and convex cuboid.
|
|
41
|
+
* It can provide a tighter bounding volume than
|
|
42
|
+
* `BoundingSphere` or `AxisAlignedBoundingBox` in many cases.
|
|
43
|
+
*/
|
|
44
|
+
constructor(center?: readonly number[], halfAxes?: readonly number[]);
|
|
45
|
+
constructor(center: Readonly<NumericArray> = [0, 0, 0], halfAxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]) {
|
|
30
46
|
this.center = new Vector3().from(center);
|
|
31
47
|
this.halfAxes = new Matrix3(halfAxes);
|
|
32
48
|
}
|
|
33
49
|
|
|
34
|
-
|
|
50
|
+
/** Returns an array with three halfSizes for the bounding box */
|
|
51
|
+
get halfSize(): number[] {
|
|
35
52
|
const xAxis = this.halfAxes.getColumn(0);
|
|
36
53
|
const yAxis = this.halfAxes.getColumn(1);
|
|
37
54
|
const zAxis = this.halfAxes.getColumn(2);
|
|
38
55
|
return [new Vector3(xAxis).len(), new Vector3(yAxis).len(), new Vector3(zAxis).len()];
|
|
39
56
|
}
|
|
40
57
|
|
|
41
|
-
|
|
58
|
+
/** Returns a quaternion describing the orientation of the bounding box */
|
|
59
|
+
get quaternion(): Quaternion {
|
|
42
60
|
const xAxis = this.halfAxes.getColumn(0);
|
|
43
61
|
const yAxis = this.halfAxes.getColumn(1);
|
|
44
62
|
const zAxis = this.halfAxes.getColumn(2);
|
|
@@ -48,7 +66,14 @@ export default class OrientedBoundingBox {
|
|
|
48
66
|
return new Quaternion().fromMatrix3(new Matrix3([...normXAxis, ...normYAxis, ...normZAxis]));
|
|
49
67
|
}
|
|
50
68
|
|
|
51
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Create OrientedBoundingBox from quaternion based OBB,
|
|
71
|
+
*/
|
|
72
|
+
fromCenterHalfSizeQuaternion(
|
|
73
|
+
center: number[],
|
|
74
|
+
halfSize: number[],
|
|
75
|
+
quaternion: number[]
|
|
76
|
+
): OrientedBoundingBox {
|
|
52
77
|
const quaternionObject = new Quaternion(quaternion);
|
|
53
78
|
const directionsMatrix = new Matrix3().fromQuaternion(quaternionObject);
|
|
54
79
|
directionsMatrix[0] = directionsMatrix[0] * halfSize[0];
|
|
@@ -65,18 +90,21 @@ export default class OrientedBoundingBox {
|
|
|
65
90
|
return this;
|
|
66
91
|
}
|
|
67
92
|
|
|
68
|
-
|
|
93
|
+
/** Duplicates a OrientedBoundingBox instance. */
|
|
94
|
+
clone(): OrientedBoundingBox {
|
|
69
95
|
return new OrientedBoundingBox(this.center, this.halfAxes);
|
|
70
96
|
}
|
|
71
97
|
|
|
72
|
-
|
|
98
|
+
/** Compares the provided OrientedBoundingBox component wise and returns */
|
|
99
|
+
equals(right: OrientedBoundingBox): boolean {
|
|
73
100
|
return (
|
|
74
101
|
this === right ||
|
|
75
102
|
(Boolean(right) && this.center.equals(right.center) && this.halfAxes.equals(right.halfAxes))
|
|
76
103
|
);
|
|
77
104
|
}
|
|
78
105
|
|
|
79
|
-
|
|
106
|
+
/** Computes a tight-fitting bounding sphere enclosing the provided oriented bounding box. */
|
|
107
|
+
getBoundingSphere(result = new BoundingSphere()): BoundingSphere {
|
|
80
108
|
const halfAxes = this.halfAxes;
|
|
81
109
|
const u = halfAxes.getColumn(0, scratchVectorU);
|
|
82
110
|
const v = halfAxes.getColumn(1, scratchVectorV);
|
|
@@ -91,7 +119,8 @@ export default class OrientedBoundingBox {
|
|
|
91
119
|
return result;
|
|
92
120
|
}
|
|
93
121
|
|
|
94
|
-
|
|
122
|
+
/** Determines which side of a plane the oriented bounding box is located. */
|
|
123
|
+
intersectPlane(plane: Plane): INTERSECTION {
|
|
95
124
|
const center = this.center;
|
|
96
125
|
const normal = plane.normal;
|
|
97
126
|
const halfAxes = this.halfAxes;
|
|
@@ -129,11 +158,17 @@ export default class OrientedBoundingBox {
|
|
|
129
158
|
return INTERSECTION.INTERSECTING;
|
|
130
159
|
}
|
|
131
160
|
|
|
132
|
-
|
|
161
|
+
/** Computes the estimated distance from the closest point on a bounding box to a point. */
|
|
162
|
+
distanceTo(point: readonly number[]): number {
|
|
133
163
|
return Math.sqrt(this.distanceSquaredTo(point));
|
|
134
164
|
}
|
|
135
165
|
|
|
136
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Computes the estimated distance squared from the closest point
|
|
168
|
+
* on a bounding box to a point.
|
|
169
|
+
* See Geometric Tools for Computer Graphics 10.4.2
|
|
170
|
+
*/
|
|
171
|
+
distanceSquaredTo(point: readonly number[]): number {
|
|
137
172
|
// Computes the estimated distance squared from the
|
|
138
173
|
// closest point on a bounding box to a point.
|
|
139
174
|
// See Geometric Tools for Computer Graphics 10.4.2
|
|
@@ -173,8 +208,26 @@ export default class OrientedBoundingBox {
|
|
|
173
208
|
return distanceSquared;
|
|
174
209
|
}
|
|
175
210
|
|
|
211
|
+
/**
|
|
212
|
+
* The distances calculated by the vector from the center of the bounding box
|
|
213
|
+
* to position projected onto direction.
|
|
214
|
+
*
|
|
215
|
+
* - If you imagine the infinite number of planes with normal direction,
|
|
216
|
+
* this computes the smallest distance to the closest and farthest planes
|
|
217
|
+
* from `position` that intersect the bounding box.
|
|
218
|
+
*
|
|
219
|
+
* @param position The position to calculate the distance from.
|
|
220
|
+
* @param direction The direction from position.
|
|
221
|
+
* @param result An Interval (array of length 2) to store the nearest and farthest distances.
|
|
222
|
+
* @returns Interval (array of length 2) with nearest and farthest distances
|
|
223
|
+
* on the bounding box from position in direction.
|
|
224
|
+
*/
|
|
176
225
|
// eslint-disable-next-line max-statements
|
|
177
|
-
computePlaneDistances(
|
|
226
|
+
computePlaneDistances(
|
|
227
|
+
position: readonly number[],
|
|
228
|
+
direction: Vector3,
|
|
229
|
+
result: number[] = [-0, -0]
|
|
230
|
+
): number[] {
|
|
178
231
|
let minDist = Number.POSITIVE_INFINITY;
|
|
179
232
|
let maxDist = Number.NEGATIVE_INFINITY;
|
|
180
233
|
|
|
@@ -262,7 +315,12 @@ export default class OrientedBoundingBox {
|
|
|
262
315
|
return result;
|
|
263
316
|
}
|
|
264
317
|
|
|
265
|
-
|
|
318
|
+
/**
|
|
319
|
+
* Applies a 4x4 affine transformation matrix to a bounding sphere.
|
|
320
|
+
* @param transform The transformation matrix to apply to the bounding sphere.
|
|
321
|
+
* @returns itself, i.e. the modified BoundingVolume.
|
|
322
|
+
*/
|
|
323
|
+
transform(transformation: readonly number[]): this {
|
|
266
324
|
this.center.transformAsPoint(transformation);
|
|
267
325
|
|
|
268
326
|
const xAxis = this.halfAxes.getColumn(0, scratchVectorU);
|