@math.gl/culling 3.5.6 → 3.6.0-alpha.2

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 (129) 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 +0 -12
  7. package/dist/es5/index.js.map +1 -1
  8. package/dist/es5/lib/algorithms/bounding-box-from-points.js.map +1 -1
  9. package/dist/es5/lib/algorithms/bounding-sphere-from-points.js.map +1 -1
  10. package/dist/es5/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
  11. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js +12 -6
  12. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
  13. package/dist/es5/lib/bounding-volumes/bounding-sphere.js +8 -4
  14. package/dist/es5/lib/bounding-volumes/bounding-sphere.js.map +1 -1
  15. package/dist/es5/lib/bounding-volumes/bounding-volume.js +2 -0
  16. package/dist/es5/lib/bounding-volumes/bounding-volume.js.map +1 -0
  17. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js +4 -0
  18. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
  19. package/dist/es5/lib/culling-volume.js +6 -20
  20. package/dist/es5/lib/culling-volume.js.map +1 -1
  21. package/dist/es5/lib/perspective-frustum.js +17 -7
  22. package/dist/es5/lib/perspective-frustum.js.map +1 -1
  23. package/dist/es5/lib/perspective-off-center-frustum.js +17 -5
  24. package/dist/es5/lib/perspective-off-center-frustum.js.map +1 -1
  25. package/dist/es5/lib/plane.js +5 -1
  26. package/dist/es5/lib/plane.js.map +1 -1
  27. package/dist/esm/constants.js +7 -5
  28. package/dist/esm/constants.js.map +1 -1
  29. package/dist/esm/index.js +0 -2
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/lib/algorithms/bounding-box-from-points.js.map +1 -1
  32. package/dist/esm/lib/algorithms/bounding-sphere-from-points.js.map +1 -1
  33. package/dist/esm/lib/algorithms/compute-eigen-decomposition.js.map +1 -1
  34. package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js +15 -6
  35. package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
  36. package/dist/esm/lib/bounding-volumes/bounding-sphere.js +9 -4
  37. package/dist/esm/lib/bounding-volumes/bounding-sphere.js.map +1 -1
  38. package/dist/esm/lib/bounding-volumes/bounding-volume.js +2 -0
  39. package/dist/esm/lib/bounding-volumes/bounding-volume.js.map +1 -0
  40. package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js +5 -0
  41. package/dist/esm/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
  42. package/dist/esm/lib/culling-volume.js +10 -16
  43. package/dist/esm/lib/culling-volume.js.map +1 -1
  44. package/dist/esm/lib/perspective-frustum.js +31 -5
  45. package/dist/esm/lib/perspective-frustum.js.map +1 -1
  46. package/dist/esm/lib/perspective-off-center-frustum.js +31 -3
  47. package/dist/esm/lib/perspective-off-center-frustum.js.map +1 -1
  48. package/dist/esm/lib/plane.js +6 -1
  49. package/dist/esm/lib/plane.js.map +1 -1
  50. package/dist/index.d.ts +12 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +13 -0
  53. package/{src → dist}/lib/algorithms/bounding-box-from-points.d.ts +3 -10
  54. package/dist/lib/algorithms/bounding-box-from-points.d.ts.map +1 -0
  55. package/dist/lib/algorithms/bounding-box-from-points.js +131 -0
  56. package/dist/{esm/lib → lib}/algorithms/bounding-sphere-from-points.d.ts +2 -5
  57. package/dist/lib/algorithms/bounding-sphere-from-points.d.ts.map +1 -0
  58. package/dist/lib/algorithms/bounding-sphere-from-points.js +140 -0
  59. package/dist/{es5/lib → lib}/algorithms/compute-eigen-decomposition.d.ts +7 -9
  60. package/dist/lib/algorithms/compute-eigen-decomposition.d.ts.map +1 -0
  61. package/dist/lib/algorithms/compute-eigen-decomposition.js +131 -0
  62. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +56 -0
  63. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -0
  64. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js +111 -0
  65. package/dist/lib/bounding-volumes/bounding-sphere.d.ts +40 -0
  66. package/dist/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -0
  67. package/dist/lib/bounding-volumes/bounding-sphere.js +118 -0
  68. package/dist/lib/bounding-volumes/bounding-volume.d.ts +30 -0
  69. package/dist/lib/bounding-volumes/bounding-volume.d.ts.map +1 -0
  70. package/dist/lib/bounding-volumes/bounding-volume.js +1 -0
  71. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +67 -0
  72. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -0
  73. package/dist/lib/bounding-volumes/oriented-bounding-box.js +256 -0
  74. package/dist/lib/culling-volume.d.ts +46 -0
  75. package/dist/lib/culling-volume.d.ts.map +1 -0
  76. package/dist/lib/culling-volume.js +121 -0
  77. package/dist/lib/perspective-frustum.d.ts +140 -0
  78. package/dist/lib/perspective-frustum.d.ts.map +1 -0
  79. package/dist/lib/perspective-frustum.js +205 -0
  80. package/dist/lib/perspective-off-center-frustum.d.ts +122 -0
  81. package/dist/lib/perspective-off-center-frustum.d.ts.map +1 -0
  82. package/dist/lib/perspective-off-center-frustum.js +305 -0
  83. package/dist/lib/plane.d.ts +26 -0
  84. package/dist/lib/plane.d.ts.map +1 -0
  85. package/dist/lib/plane.js +63 -0
  86. package/package.json +5 -5
  87. package/src/constants.ts +8 -0
  88. package/src/{index.js → index.ts} +0 -4
  89. package/src/lib/algorithms/{bounding-box-from-points.js → bounding-box-from-points.ts} +17 -4
  90. package/src/lib/algorithms/{bounding-sphere-from-points.js → bounding-sphere-from-points.ts} +15 -3
  91. package/src/lib/algorithms/{compute-eigen-decomposition.js → compute-eigen-decomposition.ts} +40 -1
  92. package/src/lib/bounding-volumes/{axis-aligned-bounding-box.js → axis-aligned-bounding-box.ts} +45 -14
  93. package/src/lib/bounding-volumes/{bounding-sphere.js → bounding-sphere.ts} +44 -29
  94. package/src/lib/bounding-volumes/{bounding-volume.d.ts → bounding-volume.ts} +7 -7
  95. package/src/lib/bounding-volumes/{oriented-bounding-box.js → oriented-bounding-box.ts} +72 -14
  96. package/src/lib/{culling-volume.js → culling-volume.ts} +42 -34
  97. package/src/lib/{perspective-frustum.js → perspective-frustum.ts} +48 -66
  98. package/src/lib/{perspective-off-center-frustum.js → perspective-off-center-frustum.ts} +24 -14
  99. package/src/lib/{plane.js → plane.ts} +24 -17
  100. package/dist/es5/constants.d.ts +0 -6
  101. package/dist/es5/index.d.ts +0 -20
  102. package/dist/es5/lib/algorithms/bounding-box-from-points.d.ts +0 -22
  103. package/dist/es5/lib/algorithms/bounding-sphere-from-points.d.ts +0 -17
  104. package/dist/es5/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
  105. package/dist/es5/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
  106. package/dist/es5/lib/bounding-volumes/bounding-volume.d.ts +0 -32
  107. package/dist/es5/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
  108. package/dist/es5/lib/culling-volume.d.ts +0 -55
  109. package/dist/es5/lib/plane.d.ts +0 -38
  110. package/dist/esm/constants.d.ts +0 -6
  111. package/dist/esm/index.d.ts +0 -20
  112. package/dist/esm/lib/algorithms/bounding-box-from-points.d.ts +0 -22
  113. package/dist/esm/lib/algorithms/compute-eigen-decomposition.d.ts +0 -39
  114. package/dist/esm/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
  115. package/dist/esm/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
  116. package/dist/esm/lib/bounding-volumes/bounding-volume.d.ts +0 -32
  117. package/dist/esm/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
  118. package/dist/esm/lib/culling-volume.d.ts +0 -55
  119. package/dist/esm/lib/plane.d.ts +0 -38
  120. package/src/constants.d.ts +0 -6
  121. package/src/constants.js +0 -8
  122. package/src/index.d.ts +0 -20
  123. package/src/lib/algorithms/bounding-sphere-from-points.d.ts +0 -17
  124. package/src/lib/algorithms/compute-eigen-decomposition.d.ts +0 -39
  125. package/src/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +0 -51
  126. package/src/lib/bounding-volumes/bounding-sphere.d.ts +0 -52
  127. package/src/lib/bounding-volumes/oriented-bounding-box.d.ts +0 -83
  128. package/src/lib/culling-volume.d.ts +0 -55
  129. 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.6",
8
+ "version": "3.6.0-alpha.2",
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.6",
39
- "gl-matrix": "~3.3.0"
38
+ "@math.gl/core": "3.6.0-alpha.2",
39
+ "gl-matrix": "^3.4.0"
40
40
  },
41
- "gitHead": "0e69c70ff2e6373fed84d303cbf8198a6972944f"
41
+ "gitHead": "ea7dc265c98b68af56218302d1d42b7d65f74ccb"
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();
@@ -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);
@@ -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
  }
@@ -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
 
@@ -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,36 +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) {
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
- distanceTo(point) {
109
- point = scratchVector.from(point);
110
- const delta = point.subtract(this.center);
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
- // Determines which side of a plane a sphere is located.
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 {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
  }
@@ -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
- export default class OrientedBoundingBox {
29
- constructor(center = [0, 0, 0], halfAxes = [0, 0, 0, 0, 0, 0, 0, 0, 0]) {
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
- get halfSize() {
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
- get quaternion() {
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
- fromCenterHalfSizeQuaternion(center, halfSize, quaternion) {
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
- clone() {
93
+ /** Duplicates a OrientedBoundingBox instance. */
94
+ clone(): OrientedBoundingBox {
69
95
  return new OrientedBoundingBox(this.center, this.halfAxes);
70
96
  }
71
97
 
72
- equals(right) {
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
- getBoundingSphere(result = new BoundingSphere()) {
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
- intersectPlane(plane) {
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
- distanceTo(point) {
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
- distanceSquaredTo(point) {
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(position, direction, result = [-0, -0]) {
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
- transform(transformation) {
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);