@math.gl/culling 3.5.3 → 3.6.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/dist/constants.d.ts +6 -0
  2. package/dist/constants.d.ts.map +1 -0
  3. package/dist/constants.js +8 -0
  4. package/dist/es5/constants.js +7 -5
  5. package/dist/es5/constants.js.map +1 -1
  6. package/dist/es5/index.js +12 -24
  7. package/dist/es5/index.js.map +1 -1
  8. package/dist/es5/lib/algorithms/bounding-box-from-points.js +72 -122
  9. package/dist/es5/lib/algorithms/bounding-box-from-points.js.map +1 -1
  10. package/dist/es5/lib/algorithms/bounding-sphere-from-points.js +81 -109
  11. package/dist/es5/lib/algorithms/bounding-sphere-from-points.js.map +1 -1
  12. package/dist/es5/lib/algorithms/compute-eigen-decomposition.js +36 -37
  13. package/dist/es5/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
  14. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js +68 -74
  15. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
  16. package/dist/es5/lib/bounding-volumes/bounding-sphere.js +93 -109
  17. package/dist/es5/lib/bounding-volumes/bounding-sphere.js.map +1 -1
  18. package/dist/es5/lib/bounding-volumes/bounding-volume.js +2 -0
  19. package/dist/es5/lib/bounding-volumes/bounding-volume.js.map +1 -0
  20. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js +190 -211
  21. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
  22. package/dist/es5/lib/culling-volume.js +80 -131
  23. package/dist/es5/lib/culling-volume.js.map +1 -1
  24. package/dist/es5/lib/perspective-frustum.js +73 -84
  25. package/dist/es5/lib/perspective-frustum.js.map +1 -1
  26. package/dist/es5/lib/perspective-off-center-frustum.js +114 -117
  27. package/dist/es5/lib/perspective-off-center-frustum.js.map +1 -1
  28. package/dist/es5/lib/plane.js +55 -69
  29. package/dist/es5/lib/plane.js.map +1 -1
  30. package/dist/esm/constants.js +7 -5
  31. package/dist/esm/constants.js.map +1 -1
  32. package/dist/esm/index.js +0 -2
  33. package/dist/esm/index.js.map +1 -1
  34. package/dist/esm/lib/algorithms/bounding-box-from-points.js +7 -6
  35. package/dist/esm/lib/algorithms/bounding-box-from-points.js.map +1 -1
  36. package/dist/esm/lib/algorithms/bounding-sphere-from-points.js +6 -6
  37. package/dist/esm/lib/algorithms/bounding-sphere-from-points.js.map +1 -1
  38. package/dist/esm/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
  39. package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js +15 -6
  40. package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
  41. package/dist/esm/lib/bounding-volumes/bounding-sphere.js +12 -6
  42. package/dist/esm/lib/bounding-volumes/bounding-sphere.js.map +1 -1
  43. package/dist/esm/lib/bounding-volumes/bounding-volume.js +2 -0
  44. package/dist/esm/lib/bounding-volumes/bounding-volume.js.map +1 -0
  45. package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js +5 -0
  46. package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
  47. package/dist/esm/lib/culling-volume.js +10 -16
  48. package/dist/esm/lib/culling-volume.js.map +1 -1
  49. package/dist/esm/lib/perspective-frustum.js +31 -5
  50. package/dist/esm/lib/perspective-frustum.js.map +1 -1
  51. package/dist/esm/lib/perspective-off-center-frustum.js +31 -3
  52. package/dist/esm/lib/perspective-off-center-frustum.js.map +1 -1
  53. package/dist/esm/lib/plane.js +6 -1
  54. package/dist/esm/lib/plane.js.map +1 -1
  55. package/dist/index.d.ts +12 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +13 -0
  58. package/{src → dist}/lib/algorithms/bounding-box-from-points.d.ts +3 -10
  59. package/dist/lib/algorithms/bounding-box-from-points.d.ts.map +1 -0
  60. package/dist/lib/algorithms/bounding-box-from-points.js +131 -0
  61. package/dist/{esm/lib → lib}/algorithms/bounding-sphere-from-points.d.ts +2 -5
  62. package/dist/lib/algorithms/bounding-sphere-from-points.d.ts.map +1 -0
  63. package/dist/lib/algorithms/bounding-sphere-from-points.js +142 -0
  64. package/dist/{es5/lib → lib}/algorithms/compute-eigen-decomposition.d.ts +7 -9
  65. package/dist/lib/algorithms/compute-eigen-decomposition.d.ts.map +1 -0
  66. package/dist/lib/algorithms/compute-eigen-decomposition.js +131 -0
  67. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +56 -0
  68. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -0
  69. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js +111 -0
  70. package/dist/lib/bounding-volumes/bounding-sphere.d.ts +40 -0
  71. package/dist/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -0
  72. package/dist/lib/bounding-volumes/bounding-sphere.js +118 -0
  73. package/dist/lib/bounding-volumes/bounding-volume.d.ts +30 -0
  74. package/dist/lib/bounding-volumes/bounding-volume.d.ts.map +1 -0
  75. package/dist/lib/bounding-volumes/bounding-volume.js +1 -0
  76. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +67 -0
  77. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -0
  78. package/dist/lib/bounding-volumes/oriented-bounding-box.js +256 -0
  79. package/dist/lib/culling-volume.d.ts +46 -0
  80. package/dist/lib/culling-volume.d.ts.map +1 -0
  81. package/dist/lib/culling-volume.js +121 -0
  82. package/dist/lib/perspective-frustum.d.ts +140 -0
  83. package/dist/lib/perspective-frustum.d.ts.map +1 -0
  84. package/dist/lib/perspective-frustum.js +205 -0
  85. package/dist/lib/perspective-off-center-frustum.d.ts +122 -0
  86. package/dist/lib/perspective-off-center-frustum.d.ts.map +1 -0
  87. package/dist/lib/perspective-off-center-frustum.js +305 -0
  88. package/dist/lib/plane.d.ts +26 -0
  89. package/dist/lib/plane.d.ts.map +1 -0
  90. package/dist/lib/plane.js +63 -0
  91. package/package.json +5 -5
  92. package/src/constants.ts +8 -0
  93. package/src/{index.js → index.ts} +0 -4
  94. package/src/lib/algorithms/{bounding-box-from-points.js → bounding-box-from-points.ts} +25 -10
  95. package/src/lib/algorithms/{bounding-sphere-from-points.js → bounding-sphere-from-points.ts} +21 -7
  96. package/src/lib/algorithms/{compute-eigen-decomposition.js → compute-eigen-decomposition.ts} +40 -1
  97. package/src/lib/bounding-volumes/{axis-aligned-bounding-box.js → axis-aligned-bounding-box.ts} +45 -14
  98. package/src/lib/bounding-volumes/{bounding-sphere.js → bounding-sphere.ts} +47 -31
  99. package/src/lib/bounding-volumes/{bounding-volume.d.ts → bounding-volume.ts} +7 -7
  100. package/src/lib/bounding-volumes/{oriented-bounding-box.js → oriented-bounding-box.ts} +72 -14
  101. package/src/lib/{culling-volume.js → culling-volume.ts} +42 -34
  102. package/src/lib/{perspective-frustum.js → perspective-frustum.ts} +48 -66
  103. package/src/lib/{perspective-off-center-frustum.js → perspective-off-center-frustum.ts} +24 -14
  104. package/src/lib/{plane.js → plane.ts} +24 -17
  105. package/dist/es5/constants.d.ts +0 -6
  106. package/dist/es5/index.d.ts +0 -20
  107. package/dist/es5/lib/algorithms/bounding-box-from-points.d.ts +0 -22
  108. package/dist/es5/lib/algorithms/bounding-sphere-from-points.d.ts +0 -17
  109. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
  110. package/dist/es5/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
  111. package/dist/es5/lib/bounding-volumes/bounding-volume.d.ts +0 -32
  112. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
  113. package/dist/es5/lib/culling-volume.d.ts +0 -55
  114. package/dist/es5/lib/plane.d.ts +0 -38
  115. package/dist/esm/constants.d.ts +0 -6
  116. package/dist/esm/index.d.ts +0 -20
  117. package/dist/esm/lib/algorithms/bounding-box-from-points.d.ts +0 -22
  118. package/dist/esm/lib/algorithms/compute-eigen-decomposition.d.ts +0 -39
  119. package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
  120. package/dist/esm/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
  121. package/dist/esm/lib/bounding-volumes/bounding-volume.d.ts +0 -32
  122. package/dist/esm/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
  123. package/dist/esm/lib/culling-volume.d.ts +0 -55
  124. package/dist/esm/lib/plane.d.ts +0 -38
  125. package/src/constants.d.ts +0 -6
  126. package/src/constants.js +0 -8
  127. package/src/index.d.ts +0 -20
  128. package/src/lib/algorithms/bounding-sphere-from-points.d.ts +0 -17
  129. package/src/lib/algorithms/compute-eigen-decomposition.d.ts +0 -39
  130. package/src/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
  131. package/src/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
  132. package/src/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
  133. package/src/lib/culling-volume.d.ts +0 -55
  134. 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.5.3",
8
+ "version": "3.6.0-alpha.1",
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": "src/index.d.ts",
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.5.3",
39
- "gl-matrix": "^3.0.0"
38
+ "@math.gl/core": "3.6.0-alpha.1",
39
+ "gl-matrix": "~3.3.0"
40
40
  },
41
- "gitHead": "b9183c9ec46dd309a601e1de7beb90a18a3e0fea"
41
+ "gitHead": "45386981340895bf201c2ebb76257c9bbffd8ff6"
42
42
  }
@@ -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(positions, result = new OrientedBoundingBox()) {
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();
@@ -89,13 +98,15 @@ export function makeOrientedBoundingBoxFromPoints(positions, result = new Orient
89
98
  let l3 = Number.MAX_VALUE;
90
99
 
91
100
  for (const position of positions) {
92
- u1 = Math.max(position.dot(v1), u1);
93
- u2 = Math.max(position.dot(v2), u2);
94
- u3 = Math.max(position.dot(v3), u3);
101
+ scratchVector2.copy(position);
95
102
 
96
- l1 = Math.min(position.dot(v1), l1);
97
- l2 = Math.min(position.dot(v2), l2);
98
- l3 = Math.min(position.dot(v3), l3);
103
+ u1 = Math.max(scratchVector2.dot(v1), u1);
104
+ u2 = Math.max(scratchVector2.dot(v2), u2);
105
+ u3 = Math.max(scratchVector2.dot(v3), u3);
106
+
107
+ l1 = Math.min(scratchVector2.dot(v1), l1);
108
+ l2 = Math.min(scratchVector2.dot(v2), l2);
109
+ l3 = Math.min(scratchVector2.dot(v3), l3);
99
110
  }
100
111
 
101
112
  v1 = v1.multiplyByScalar(0.5 * (l1 + u1));
@@ -111,10 +122,14 @@ export function makeOrientedBoundingBoxFromPoints(positions, result = new Orient
111
122
  return result;
112
123
  }
113
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
+ */
114
129
  export function makeAxisAlignedBoundingBoxFromPoints(
115
- positions,
116
- result = new AxisAlignedBoundingBox()
117
- ) {
130
+ positions: readonly number[][],
131
+ result: AxisAlignedBoundingBox = new AxisAlignedBoundingBox()
132
+ ): AxisAlignedBoundingBox {
118
133
  if (!positions || positions.length === 0) {
119
134
  result.minimum.set(0, 0, 0);
120
135
  result.maximum.set(0, 0, 0);
@@ -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
- export default function makeBoundingSphereFromPoints(positions, result = new BoundingSphere()) {
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
  }
@@ -43,27 +57,27 @@ export default function makeBoundingSphereFromPoints(positions, result = new Bou
43
57
 
44
58
  // Store points containing the the smallest and largest components
45
59
  if (x < xMin.x) {
46
- currentPos.copy(xMin);
60
+ xMin.copy(currentPos);
47
61
  }
48
62
 
49
63
  if (x > xMax.x) {
50
- currentPos.copy(xMax);
64
+ xMax.copy(currentPos);
51
65
  }
52
66
 
53
67
  if (y < yMin.y) {
54
- currentPos.copy(yMin);
68
+ yMin.copy(currentPos);
55
69
  }
56
70
 
57
71
  if (y > yMax.y) {
58
- currentPos.copy(yMax);
72
+ yMax.copy(currentPos);
59
73
  }
60
74
 
61
75
  if (z < zMin.z) {
62
- currentPos.copy(zMin);
76
+ zMin.copy(currentPos);
63
77
  }
64
78
 
65
79
  if (z > zMax.z) {
66
- currentPos.copy(zMax);
80
+ zMax.copy(currentPos);
67
81
  }
68
82
  }
69
83
 
@@ -10,7 +10,46 @@ const scratchDiagonal = new Matrix3();
10
10
  const jMatrix = new Matrix3();
11
11
  const jMatrixTranspose = new Matrix3();
12
12
 
13
- export default function computeEigenDecomposition(matrix, result = {}) {
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
 
@@ -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
- export default class AxisAlignedBoundingBox {
8
- constructor(minimum = [0, 0, 0], maximum = [0, 0, 0], center = null) {
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
- transform(transformation) {
53
- this.center.transformAsPoint(transformation);
54
- // TODO - this.halfDiagonal.transformAsVector(transformation);
55
- this.halfDiagonal.transform(transformation);
56
- this.minimum.transform(transformation);
57
- this.maximum.transform(transformation);
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
- // Computes the estimated distance from the closest point on a bounding box to a point.
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
- // Computes the estimated distance squared from the closest point on a bounding box to a point.
91
- // A simplified version of OrientedBoundingBox.distanceSquaredTo
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
- // import Rectangle from './rectangle';
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
- export default class BoundingSphere {
22
- constructor(center = [0, 0, 0], radius = 0.0) {
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
- fromCenterRadius(center, radius) {
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
- fromCornerPoints(corner, oppositeCorner) {
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
- equals(right) {
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
- clone() {
51
+ /** Duplicates a BoundingSphere instance. */
52
+ clone(): BoundingSphere {
49
53
  return new BoundingSphere(this.center, this.radius);
50
54
  }
51
55
 
52
- union(boundingSphere) {
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,35 +88,46 @@ export default class BoundingSphere {
83
88
  return this;
84
89
  }
85
90
 
86
- expand(point) {
87
- point = scratchVector.from(point);
88
- const radius = point.subtract(this.center).magnitude();
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
- transform(transform) {
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
- // Computes the estimated distance squared from the closest point on a bounding sphere to a point.
103
- distanceSquaredTo(point) {
104
- point = scratchVector.from(point);
105
- const delta = point.subtract(this.center);
106
- return delta.lengthSquared() - this.radius * this.radius;
116
+ /** Computes the estimated distance squared from the closest point on a bounding sphere to a point. */
117
+ distanceSquaredTo(point: Readonly<NumericArray>): number {
118
+ const d = this.distanceTo(point);
119
+ return d * d;
107
120
  }
108
121
 
109
- distanceTo(point) {
110
- return Math.sqrt(this.distanceSquaredTo(point));
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);
126
+ return Math.max(0, delta.len() - this.radius);
111
127
  }
112
128
 
113
- // Determines which side of a plane a sphere is located.
114
- intersectPlane(plane) {
129
+ /** Determines which side of a plane a sphere is located. */
130
+ intersectPlane(plane: Plane): INTERSECTION {
115
131
  const center = this.center;
116
132
  const radius = this.radius;
117
133
  const normal = plane.normal;
@@ -1,4 +1,4 @@
1
- import {INTERSECTION_ENUM} from '../../constants';
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
- transform(transform: readonly number[]): this;
15
+ transform(transform: readonly number[]): this;
16
16
 
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;
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): INTERSECTION_ENUM;
31
+ intersectPlane(plane: Plane): INTERSECTION;
32
32
  }