@math.gl/culling 4.1.0 → 4.2.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +51 -0
- package/README.md +8 -1
- package/dist/index.cjs +660 -83
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +1 -1
- package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -1
- package/dist/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
- package/dist/lib/plane.d.ts +9 -0
- package/dist/lib/plane.d.ts.map +1 -1
- package/dist/lib/plane.js +22 -1
- package/dist/lib/plane.js.map +1 -1
- package/dist/lib/ray.d.ts +13 -0
- package/dist/lib/ray.d.ts.map +1 -0
- package/dist/lib/ray.js +28 -0
- package/dist/lib/ray.js.map +1 -0
- package/dist/lib/shapes/box-shape.d.ts +19 -0
- package/dist/lib/shapes/box-shape.d.ts.map +1 -0
- package/dist/lib/shapes/box-shape.js +69 -0
- package/dist/lib/shapes/box-shape.js.map +1 -0
- package/dist/lib/shapes/capsule-shape.d.ts +23 -0
- package/dist/lib/shapes/capsule-shape.d.ts.map +1 -0
- package/dist/lib/shapes/capsule-shape.js +151 -0
- package/dist/lib/shapes/capsule-shape.js.map +1 -0
- package/dist/lib/shapes/cylinder-shape.d.ts +22 -0
- package/dist/lib/shapes/cylinder-shape.d.ts.map +1 -0
- package/dist/lib/shapes/cylinder-shape.js +99 -0
- package/dist/lib/shapes/cylinder-shape.js.map +1 -0
- package/dist/lib/shapes/implicit-shape.d.ts +55 -0
- package/dist/lib/shapes/implicit-shape.d.ts.map +1 -0
- package/dist/lib/shapes/implicit-shape.js +143 -0
- package/dist/lib/shapes/implicit-shape.js.map +1 -0
- package/dist/lib/shapes/plane-shape.d.ts +26 -0
- package/dist/lib/shapes/plane-shape.d.ts.map +1 -0
- package/dist/lib/shapes/plane-shape.js +72 -0
- package/dist/lib/shapes/plane-shape.js.map +1 -0
- package/dist/lib/shapes/sphere-shape.d.ts +18 -0
- package/dist/lib/shapes/sphere-shape.d.ts.map +1 -0
- package/dist/lib/shapes/sphere-shape.js +43 -0
- package/dist/lib/shapes/sphere-shape.js.map +1 -0
- package/package.json +4 -4
- package/src/index.ts +13 -0
- package/src/lib/bounding-volumes/oriented-bounding-box.ts +2 -1
- package/src/lib/plane.ts +28 -1
- package/src/lib/ray.ts +31 -0
- package/src/lib/shapes/box-shape.ts +78 -0
- package/src/lib/shapes/capsule-shape.ts +232 -0
- package/src/lib/shapes/cylinder-shape.ts +133 -0
- package/src/lib/shapes/implicit-shape.ts +209 -0
- package/src/lib/shapes/plane-shape.ts +78 -0
- package/src/lib/shapes/sphere-shape.ts +60 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { Matrix4, Vector3 } from '@math.gl/core';
|
|
5
|
+
import { INTERSECTION } from "../../constants.js";
|
|
6
|
+
import { AxisAlignedBoundingBox } from "../bounding-volumes/axis-aligned-bounding-box.js";
|
|
7
|
+
import { BoundingSphere } from "../bounding-volumes/bounding-sphere.js";
|
|
8
|
+
/** Shared affine transform, support mapping and query implementation for finite convex shapes. */
|
|
9
|
+
export class ImplicitShapeBase {
|
|
10
|
+
constructor(matrix) {
|
|
11
|
+
this.matrix = new Matrix4();
|
|
12
|
+
if (matrix)
|
|
13
|
+
this.matrix.copy(matrix);
|
|
14
|
+
validateAffineMatrix(this.matrix);
|
|
15
|
+
this.inverseMatrix = this.matrix.clone().invert();
|
|
16
|
+
}
|
|
17
|
+
equals(shape) {
|
|
18
|
+
if (this.type !== shape.type)
|
|
19
|
+
return false;
|
|
20
|
+
for (let i = 0; i < 16; i++)
|
|
21
|
+
if (this.matrix[i] !== shape.matrix[i])
|
|
22
|
+
return false;
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
transform(transform) {
|
|
26
|
+
const next = new Matrix4().copy(transform);
|
|
27
|
+
validateAffineMatrix(next);
|
|
28
|
+
this.matrix.multiplyLeft(next);
|
|
29
|
+
validateAffineMatrix(this.matrix);
|
|
30
|
+
this.inverseMatrix.copy(this.matrix).invert();
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
containsPoint(point) {
|
|
34
|
+
return this.containsLocalPoint(this.inverseMatrix.transformAsPoint(point));
|
|
35
|
+
}
|
|
36
|
+
distanceSquaredTo(point) {
|
|
37
|
+
const distance = this.distanceTo(point);
|
|
38
|
+
return distance * distance;
|
|
39
|
+
}
|
|
40
|
+
/** Exact for rigid/uniform transforms; conservative estimate for non-uniform scale or shear. */
|
|
41
|
+
distanceTo(point) {
|
|
42
|
+
const localPoint = this.inverseMatrix.transformAsPoint(point);
|
|
43
|
+
const localDistance = this.distanceToLocalPoint(localPoint);
|
|
44
|
+
const scales = this.matrix.getScale();
|
|
45
|
+
return localDistance * Math.min(scales[0], scales[1], scales[2]);
|
|
46
|
+
}
|
|
47
|
+
intersectPlane(plane) {
|
|
48
|
+
const maximum = this.getSupportPoint(plane.normal);
|
|
49
|
+
const minimum = this.getSupportPoint([-plane.normal[0], -plane.normal[1], -plane.normal[2]]);
|
|
50
|
+
const maxDistance = plane.getPointDistance(maximum);
|
|
51
|
+
const minDistance = plane.getPointDistance(minimum);
|
|
52
|
+
if (minDistance > 0)
|
|
53
|
+
return INTERSECTION.INSIDE;
|
|
54
|
+
if (maxDistance < 0)
|
|
55
|
+
return INTERSECTION.OUTSIDE;
|
|
56
|
+
return INTERSECTION.INTERSECTING;
|
|
57
|
+
}
|
|
58
|
+
intersectRay(ray) {
|
|
59
|
+
const localOrigin = this.inverseMatrix.transformAsPoint(ray.origin);
|
|
60
|
+
const localDirection = this.inverseMatrix.transformAsVector(ray.direction);
|
|
61
|
+
const hit = this.intersectLocalRay(localOrigin, localDirection);
|
|
62
|
+
if (!hit || hit.distance < 0)
|
|
63
|
+
return undefined;
|
|
64
|
+
const point = new Vector3(ray.direction).scale(hit.distance).add(ray.origin);
|
|
65
|
+
const inverse = this.inverseMatrix;
|
|
66
|
+
const normal = new Vector3(inverse[0] * hit.normal[0] + inverse[1] * hit.normal[1] + inverse[2] * hit.normal[2], inverse[4] * hit.normal[0] + inverse[5] * hit.normal[1] + inverse[6] * hit.normal[2], inverse[8] * hit.normal[0] + inverse[9] * hit.normal[1] + inverse[10] * hit.normal[2]).normalize();
|
|
67
|
+
return { distance: hit.distance, point, normal, entering: ray.direction.dot(normal) < 0 };
|
|
68
|
+
}
|
|
69
|
+
getAxisAlignedBoundingBox() {
|
|
70
|
+
const minimum = new Vector3();
|
|
71
|
+
const maximum = new Vector3();
|
|
72
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
73
|
+
const direction = [0, 0, 0];
|
|
74
|
+
direction[axis] = 1;
|
|
75
|
+
maximum[axis] = this.getSupportPoint(direction)[axis];
|
|
76
|
+
direction[axis] = -1;
|
|
77
|
+
minimum[axis] = this.getSupportPoint(direction)[axis];
|
|
78
|
+
}
|
|
79
|
+
return new AxisAlignedBoundingBox(minimum, maximum);
|
|
80
|
+
}
|
|
81
|
+
getBoundingSphere() {
|
|
82
|
+
const box = this.getAxisAlignedBoundingBox();
|
|
83
|
+
if (!box)
|
|
84
|
+
return undefined;
|
|
85
|
+
return new BoundingSphere().fromCornerPoints(box.minimum, box.maximum);
|
|
86
|
+
}
|
|
87
|
+
getSupportPoint(worldDirection) {
|
|
88
|
+
const matrix = this.matrix;
|
|
89
|
+
const localDirection = [
|
|
90
|
+
matrix[0] * worldDirection[0] + matrix[1] * worldDirection[1] + matrix[2] * worldDirection[2],
|
|
91
|
+
matrix[4] * worldDirection[0] + matrix[5] * worldDirection[1] + matrix[6] * worldDirection[2],
|
|
92
|
+
matrix[8] * worldDirection[0] + matrix[9] * worldDirection[1] + matrix[10] * worldDirection[2]
|
|
93
|
+
];
|
|
94
|
+
return new Vector3(this.supportLocal(localDirection)).transform(this.matrix);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export function validateAffineMatrix(matrix) {
|
|
98
|
+
if (matrix.length !== 16 || matrix.some(value => !Number.isFinite(value))) {
|
|
99
|
+
throw new Error('Shape matrix must contain 16 finite values');
|
|
100
|
+
}
|
|
101
|
+
if (Math.abs(matrix[3]) > 1e-12 ||
|
|
102
|
+
Math.abs(matrix[7]) > 1e-12 ||
|
|
103
|
+
Math.abs(matrix[11]) > 1e-12 ||
|
|
104
|
+
Math.abs(matrix[15] - 1) > 1e-12) {
|
|
105
|
+
throw new Error('Shape matrix must be affine');
|
|
106
|
+
}
|
|
107
|
+
if (Math.abs(new Matrix4().copy(matrix).determinant()) < 1e-15)
|
|
108
|
+
throw new Error('Shape matrix must be invertible');
|
|
109
|
+
}
|
|
110
|
+
export function solveQuadratic(a, b, c) {
|
|
111
|
+
if (Math.abs(a) < 1e-15)
|
|
112
|
+
return Math.abs(b) < 1e-15 ? [] : [-c / b];
|
|
113
|
+
const discriminant = b * b - 4 * a * c;
|
|
114
|
+
if (discriminant < 0)
|
|
115
|
+
return [];
|
|
116
|
+
const root = Math.sqrt(Math.max(0, discriminant));
|
|
117
|
+
return [(-b - root) / (2 * a), (-b + root) / (2 * a)].sort((left, right) => left - right);
|
|
118
|
+
}
|
|
119
|
+
export function closestDistanceToSegment2D(px, py, ax, ay, bx, by) {
|
|
120
|
+
const dx = bx - ax;
|
|
121
|
+
const dy = by - ay;
|
|
122
|
+
const denominator = dx * dx + dy * dy;
|
|
123
|
+
const t = denominator
|
|
124
|
+
? Math.max(0, Math.min(1, ((px - ax) * dx + (py - ay) * dy) / denominator))
|
|
125
|
+
: 0;
|
|
126
|
+
return Math.hypot(px - (ax + t * dx), py - (ay + t * dy));
|
|
127
|
+
}
|
|
128
|
+
/** Distance in the radial/Y half-plane to a spherical profile arc selected by normal Y range. */
|
|
129
|
+
export function closestDistanceToCircleArc2D(px, py, centerY, radius, minimumNormalY, maximumNormalY) {
|
|
130
|
+
if (radius === 0)
|
|
131
|
+
return Math.hypot(px, py - centerY);
|
|
132
|
+
const dx = px;
|
|
133
|
+
const dy = py - centerY;
|
|
134
|
+
const length = Math.hypot(dx, dy);
|
|
135
|
+
const normalY = length ? dy / length : 0;
|
|
136
|
+
if (normalY >= minimumNormalY && normalY <= maximumNormalY) {
|
|
137
|
+
return Math.abs(length - radius);
|
|
138
|
+
}
|
|
139
|
+
const minimumRadius = radius * Math.sqrt(Math.max(0, 1 - minimumNormalY ** 2));
|
|
140
|
+
const maximumRadius = radius * Math.sqrt(Math.max(0, 1 - maximumNormalY ** 2));
|
|
141
|
+
return Math.min(Math.hypot(px - minimumRadius, py - (centerY + radius * minimumNormalY)), Math.hypot(px - maximumRadius, py - (centerY + radius * maximumNormalY)));
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=implicit-shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"implicit-shape.js","sourceRoot":"","sources":["../../../src/lib/shapes/implicit-shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ImplicitShapeBase, type ImplicitShape, type LocalRayIntersection } from "./implicit-shape.js";
|
|
2
|
+
import type { AxisAlignedBoundingBox } from "../bounding-volumes/axis-aligned-bounding-box.js";
|
|
3
|
+
import type { BoundingSphere } from "../bounding-volumes/bounding-sphere.js";
|
|
4
|
+
import type { Plane } from "../plane.js";
|
|
5
|
+
export type PlaneShapeProps = {
|
|
6
|
+
sizeX?: number;
|
|
7
|
+
sizeZ?: number;
|
|
8
|
+
matrix?: readonly number[];
|
|
9
|
+
};
|
|
10
|
+
/** Analytic glTF plane. The surface faces +Y and the negative-Y half-space is inside. */
|
|
11
|
+
export declare class PlaneShape extends ImplicitShapeBase {
|
|
12
|
+
readonly type: "plane";
|
|
13
|
+
readonly sizeX?: number;
|
|
14
|
+
readonly sizeZ?: number;
|
|
15
|
+
constructor(props?: PlaneShapeProps);
|
|
16
|
+
clone(): PlaneShape;
|
|
17
|
+
equals(shape: ImplicitShape): boolean;
|
|
18
|
+
containsLocalPoint(point: readonly number[]): boolean;
|
|
19
|
+
distanceToLocalPoint(point: readonly number[]): number;
|
|
20
|
+
supportLocal(): readonly number[];
|
|
21
|
+
intersectLocalRay(origin: readonly number[], direction: readonly number[]): LocalRayIntersection | undefined;
|
|
22
|
+
intersectPlane(plane: Plane): number;
|
|
23
|
+
getAxisAlignedBoundingBox(): AxisAlignedBoundingBox | undefined;
|
|
24
|
+
getBoundingSphere(): BoundingSphere | undefined;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=plane-shape.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plane-shape.d.ts","sourceRoot":"","sources":["../../../src/lib/shapes/plane-shape.ts"],"names":[],"mappings":"AAMA,OAAO,EAAC,iBAAiB,EAAE,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAC,4BAAyB;AAClG,OAAO,KAAK,EAAC,sBAAsB,EAAC,yDAAsD;AAC1F,OAAO,KAAK,EAAC,cAAc,EAAC,+CAA4C;AACxE,OAAO,KAAK,EAAC,KAAK,EAAC,oBAAiB;AAEpC,MAAM,MAAM,eAAe,GAAG;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAC,CAAC;AAE3F,yFAAyF;AACzF,qBAAa,UAAW,SAAQ,iBAAiB;IAC/C,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;gBACZ,KAAK,GAAE,eAAoB;IASvC,KAAK,IAAI,UAAU;IAGV,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAQ9C,kBAAkB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO;IAGrD,oBAAoB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM;IAGtD,YAAY,IAAI,SAAS,MAAM,EAAE;IAGjC,iBAAiB,CACf,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,oBAAoB,GAAG,SAAS;IAU1B,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM;IAWpC,yBAAyB,IAAI,sBAAsB,GAAG,SAAS;IAG/D,iBAAiB,IAAI,cAAc,GAAG,SAAS;CAGzD"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { Vector3 } from '@math.gl/core';
|
|
5
|
+
import { INTERSECTION } from "../../constants.js";
|
|
6
|
+
import { ImplicitShapeBase } from "./implicit-shape.js";
|
|
7
|
+
/** Analytic glTF plane. The surface faces +Y and the negative-Y half-space is inside. */
|
|
8
|
+
export class PlaneShape extends ImplicitShapeBase {
|
|
9
|
+
constructor(props = {}) {
|
|
10
|
+
super(props.matrix);
|
|
11
|
+
this.type = 'plane';
|
|
12
|
+
this.sizeX = props.sizeX;
|
|
13
|
+
this.sizeZ = props.sizeZ;
|
|
14
|
+
if (this.sizeX !== undefined && (!Number.isFinite(this.sizeX) || this.sizeX <= 0))
|
|
15
|
+
throw new Error('Plane sizeX must be greater than zero');
|
|
16
|
+
if (this.sizeZ !== undefined && (!Number.isFinite(this.sizeZ) || this.sizeZ <= 0))
|
|
17
|
+
throw new Error('Plane sizeZ must be greater than zero');
|
|
18
|
+
}
|
|
19
|
+
clone() {
|
|
20
|
+
return new PlaneShape({ sizeX: this.sizeX, sizeZ: this.sizeZ, matrix: this.matrix });
|
|
21
|
+
}
|
|
22
|
+
equals(shape) {
|
|
23
|
+
return (shape instanceof PlaneShape &&
|
|
24
|
+
super.equals(shape) &&
|
|
25
|
+
this.sizeX === shape.sizeX &&
|
|
26
|
+
this.sizeZ === shape.sizeZ);
|
|
27
|
+
}
|
|
28
|
+
containsLocalPoint(point) {
|
|
29
|
+
return point[1] <= 1e-12;
|
|
30
|
+
}
|
|
31
|
+
distanceToLocalPoint(point) {
|
|
32
|
+
return Math.max(0, point[1]);
|
|
33
|
+
}
|
|
34
|
+
supportLocal() {
|
|
35
|
+
throw new Error('An unbounded plane half-space has no finite support point');
|
|
36
|
+
}
|
|
37
|
+
intersectLocalRay(origin, direction) {
|
|
38
|
+
if (Math.abs(direction[1]) < 1e-15)
|
|
39
|
+
return undefined;
|
|
40
|
+
const distance = -origin[1] / direction[1];
|
|
41
|
+
if (distance < 0)
|
|
42
|
+
return undefined;
|
|
43
|
+
const x = origin[0] + distance * direction[0];
|
|
44
|
+
const z = origin[2] + distance * direction[2];
|
|
45
|
+
if (this.sizeX !== undefined && Math.abs(x) > this.sizeX / 2 + 1e-12)
|
|
46
|
+
return undefined;
|
|
47
|
+
if (this.sizeZ !== undefined && Math.abs(z) > this.sizeZ / 2 + 1e-12)
|
|
48
|
+
return undefined;
|
|
49
|
+
return { distance, normal: [0, 1, 0] };
|
|
50
|
+
}
|
|
51
|
+
intersectPlane(plane) {
|
|
52
|
+
const boundaryPoint = new Vector3(0, 0, 0).transform(this.matrix);
|
|
53
|
+
const inverse = this.inverseMatrix;
|
|
54
|
+
const boundaryNormal = new Vector3(inverse[1], inverse[5], inverse[9]).normalize();
|
|
55
|
+
const alignment = boundaryNormal.dot(plane.normal);
|
|
56
|
+
if (Math.abs(Math.abs(alignment) - 1) > 1e-10)
|
|
57
|
+
return INTERSECTION.INTERSECTING;
|
|
58
|
+
const boundaryDistance = plane.getPointDistance(boundaryPoint);
|
|
59
|
+
if (alignment < 0 && boundaryDistance > 0)
|
|
60
|
+
return INTERSECTION.INSIDE;
|
|
61
|
+
if (alignment > 0 && boundaryDistance < 0)
|
|
62
|
+
return INTERSECTION.OUTSIDE;
|
|
63
|
+
return INTERSECTION.INTERSECTING;
|
|
64
|
+
}
|
|
65
|
+
getAxisAlignedBoundingBox() {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
getBoundingSphere() {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=plane-shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plane-shape.js","sourceRoot":"","sources":["../../../src/lib/shapes/plane-shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ImplicitShapeBase, type ImplicitShape, type LocalRayIntersection } from "./implicit-shape.js";
|
|
2
|
+
export type SphereShapeProps = {
|
|
3
|
+
radius?: number;
|
|
4
|
+
matrix?: readonly number[];
|
|
5
|
+
};
|
|
6
|
+
/** Analytic glTF sphere shape. */
|
|
7
|
+
export declare class SphereShape extends ImplicitShapeBase {
|
|
8
|
+
readonly type: "sphere";
|
|
9
|
+
readonly radius: number;
|
|
10
|
+
constructor(props?: SphereShapeProps);
|
|
11
|
+
clone(): SphereShape;
|
|
12
|
+
equals(shape: ImplicitShape): boolean;
|
|
13
|
+
containsLocalPoint(point: readonly number[]): boolean;
|
|
14
|
+
distanceToLocalPoint(point: readonly number[]): number;
|
|
15
|
+
supportLocal(direction: readonly number[]): readonly number[];
|
|
16
|
+
intersectLocalRay(origin: readonly number[], direction: readonly number[]): LocalRayIntersection | undefined;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=sphere-shape.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sphere-shape.d.ts","sourceRoot":"","sources":["../../../src/lib/shapes/sphere-shape.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EAEjB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EAC1B,4BAAyB;AAI1B,MAAM,MAAM,gBAAgB,GAAG;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAC,CAAC;AAE7E,kCAAkC;AAClC,qBAAa,WAAY,SAAQ,iBAAiB;IAChD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,KAAK,GAAE,gBAAqB;IAMxC,KAAK,IAAI,WAAW;IAGX,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAG9C,kBAAkB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO;IAGrD,oBAAoB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM;IAGtD,YAAY,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE;IAI7D,iBAAiB,CACf,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,oBAAoB,GAAG,SAAS;CAWpC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
import { ImplicitShapeBase, solveQuadratic } from "./implicit-shape.js";
|
|
5
|
+
const EPSILON = 1e-6;
|
|
6
|
+
/** Analytic glTF sphere shape. */
|
|
7
|
+
export class SphereShape extends ImplicitShapeBase {
|
|
8
|
+
constructor(props = {}) {
|
|
9
|
+
super(props.matrix);
|
|
10
|
+
this.type = 'sphere';
|
|
11
|
+
this.radius = props.radius ?? 0.5;
|
|
12
|
+
if (!Number.isFinite(this.radius) || this.radius <= 0)
|
|
13
|
+
throw new Error('Sphere radius must be greater than zero');
|
|
14
|
+
}
|
|
15
|
+
clone() {
|
|
16
|
+
return new SphereShape({ radius: this.radius, matrix: this.matrix });
|
|
17
|
+
}
|
|
18
|
+
equals(shape) {
|
|
19
|
+
return shape instanceof SphereShape && super.equals(shape) && this.radius === shape.radius;
|
|
20
|
+
}
|
|
21
|
+
containsLocalPoint(point) {
|
|
22
|
+
return Math.hypot(...point) <= this.radius + EPSILON;
|
|
23
|
+
}
|
|
24
|
+
distanceToLocalPoint(point) {
|
|
25
|
+
return Math.max(0, Math.hypot(...point) - this.radius);
|
|
26
|
+
}
|
|
27
|
+
supportLocal(direction) {
|
|
28
|
+
const length = Math.hypot(...direction);
|
|
29
|
+
return length ? direction.map(value => (value / length) * this.radius) : [this.radius, 0, 0];
|
|
30
|
+
}
|
|
31
|
+
intersectLocalRay(origin, direction) {
|
|
32
|
+
const roots = solveQuadratic(dot(direction, direction), 2 * dot(origin, direction), dot(origin, origin) - this.radius * this.radius);
|
|
33
|
+
const distance = roots.find(value => value >= 0);
|
|
34
|
+
if (distance === undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
const point = origin.map((value, i) => value + distance * direction[i]);
|
|
37
|
+
return { distance, normal: point.map(value => value / this.radius) };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function dot(a, b) {
|
|
41
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=sphere-shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sphere-shape.js","sourceRoot":"","sources":["../../../src/lib/shapes/sphere-shape.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,OAAO,EACL,iBAAiB,EACjB,cAAc,EAGf,4BAAyB;AAE1B,MAAM,OAAO,GAAG,IAAI,CAAC;AAIrB,kCAAkC;AAClC,MAAM,OAAO,WAAY,SAAQ,iBAAiB;IAGhD,YAAY,QAA0B,EAAE;QACtC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAHb,SAAI,GAAG,QAAiB,CAAC;QAIhC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC/D,CAAC;IACD,KAAK;QACH,OAAO,IAAI,WAAW,CAAC,EAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAC,CAAC,CAAC;IACrE,CAAC;IACQ,MAAM,CAAC,KAAoB;QAClC,OAAO,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;IAC7F,CAAC;IACD,kBAAkB,CAAC,KAAwB;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;IACvD,CAAC;IACD,oBAAoB,CAAC,KAAwB;QAC3C,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IACD,YAAY,CAAC,SAA4B;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,CAAC;QACxC,OAAO,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/F,CAAC;IACD,iBAAiB,CACf,MAAyB,EACzB,SAA4B;QAE5B,MAAM,KAAK,GAAG,cAAc,CAC1B,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,EACzB,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAChD,CAAC;QACF,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,EAAC,CAAC;IACrE,CAAC;CACF;AAED,SAAS,GAAG,CAAC,CAAoB,EAAE,CAAoB;IACrD,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
8
8
|
},
|
|
9
|
-
"version": "4.
|
|
9
|
+
"version": "4.2.0-alpha.5",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"webgl",
|
|
12
12
|
"javascript",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"src"
|
|
43
43
|
],
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@math.gl/core": "4.
|
|
46
|
-
"@math.gl/types": "4.
|
|
45
|
+
"@math.gl/core": "4.2.0-alpha.5",
|
|
46
|
+
"@math.gl/types": "4.2.0-alpha.5"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "9c13785761867748e2edb167b5f2749dce803039"
|
|
49
49
|
}
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,19 @@ export {BoundingSphere} from './lib/bounding-volumes/bounding-sphere';
|
|
|
9
9
|
export {OrientedBoundingBox} from './lib/bounding-volumes/oriented-bounding-box';
|
|
10
10
|
export {CullingVolume} from './lib/culling-volume';
|
|
11
11
|
export {Plane} from './lib/plane';
|
|
12
|
+
export {Ray} from './lib/ray';
|
|
13
|
+
|
|
14
|
+
export type {ImplicitShape, RayIntersection} from './lib/shapes/implicit-shape';
|
|
15
|
+
export {BoxShape} from './lib/shapes/box-shape';
|
|
16
|
+
export type {BoxShapeProps} from './lib/shapes/box-shape';
|
|
17
|
+
export {CapsuleShape} from './lib/shapes/capsule-shape';
|
|
18
|
+
export type {CapsuleShapeProps} from './lib/shapes/capsule-shape';
|
|
19
|
+
export {CylinderShape} from './lib/shapes/cylinder-shape';
|
|
20
|
+
export type {CylinderShapeProps} from './lib/shapes/cylinder-shape';
|
|
21
|
+
export {PlaneShape} from './lib/shapes/plane-shape';
|
|
22
|
+
export type {PlaneShapeProps} from './lib/shapes/plane-shape';
|
|
23
|
+
export {SphereShape} from './lib/shapes/sphere-shape';
|
|
24
|
+
export type {SphereShapeProps} from './lib/shapes/sphere-shape';
|
|
12
25
|
|
|
13
26
|
export {PerspectiveOffCenterFrustum as _PerspectiveOffCenterFrustum} from './lib/perspective-off-center-frustum';
|
|
14
27
|
export {PerspectiveFrustum as _PerspectiveFrustum} from './lib/perspective-frustum';
|
|
@@ -7,9 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
import {NumericArray} from '@math.gl/types';
|
|
9
9
|
import {Vector3, Matrix3, Matrix4, Quaternion} from '@math.gl/core';
|
|
10
|
+
|
|
10
11
|
import type {BoundingVolume} from './bounding-volume';
|
|
11
12
|
import {BoundingSphere} from './bounding-sphere';
|
|
12
|
-
import
|
|
13
|
+
import {Plane} from '../plane';
|
|
13
14
|
import {INTERSECTION} from '../../constants';
|
|
14
15
|
|
|
15
16
|
const scratchVector3 = new Vector3();
|
package/src/lib/plane.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
7
7
|
|
|
8
8
|
/* eslint-disable */
|
|
9
|
-
import {Vector3, equals, assert, NumericArray} from '@math.gl/core';
|
|
9
|
+
import {Vector3, equals, assert, NumericArray, _MathUtils} from '@math.gl/core';
|
|
10
|
+
import {Ray} from './ray';
|
|
10
11
|
|
|
11
12
|
const scratchPosition = new Vector3();
|
|
12
13
|
const scratchNormal = new Vector3();
|
|
@@ -86,4 +87,30 @@ export class Plane {
|
|
|
86
87
|
|
|
87
88
|
return scratchPoint.subtract(scaledNormal).to(result);
|
|
88
89
|
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Computes the intersection of a ray and this plane.
|
|
93
|
+
*
|
|
94
|
+
* @param {Ray} ray The ray.
|
|
95
|
+
* @param {Vector3} [result] The object onto which to store the result.
|
|
96
|
+
* @returns {Vector3} The intersection point or undefined if there is no intersection.
|
|
97
|
+
*/
|
|
98
|
+
intersectWithRay(ray: Ray, result: Vector3 = new Vector3()): Vector3 | undefined {
|
|
99
|
+
const origin = ray.origin;
|
|
100
|
+
const direction = ray.direction;
|
|
101
|
+
const normal = this.normal;
|
|
102
|
+
const denominator = normal.dot(direction);
|
|
103
|
+
|
|
104
|
+
if (Math.abs(denominator) < _MathUtils.EPSILON15) {
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const t = (-this.distance - normal.dot(origin)) / denominator;
|
|
109
|
+
|
|
110
|
+
if (t < 0) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return result.copy(direction).multiplyByScalar(t).add(origin);
|
|
115
|
+
}
|
|
89
116
|
}
|
package/src/lib/ray.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT and Apache-2.0
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// This file is derived from the Cesium library under Apache 2 license
|
|
6
|
+
// See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md
|
|
7
|
+
|
|
8
|
+
import {Vector3} from '@math.gl/core';
|
|
9
|
+
|
|
10
|
+
/* Represents a ray that extends infinitely from the provided origin in the provided direction. */
|
|
11
|
+
export class Ray {
|
|
12
|
+
origin: Vector3;
|
|
13
|
+
direction: Vector3;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new ray that extends infinitely from the provided origin in the provided direction.
|
|
17
|
+
*
|
|
18
|
+
* @param [origin=Vector3] The origin of the ray.
|
|
19
|
+
* @param [direction=Vector3] The direction of the ray.
|
|
20
|
+
*/
|
|
21
|
+
constructor(origin?: Vector3, direction?: Vector3) {
|
|
22
|
+
if (origin) origin = origin.clone();
|
|
23
|
+
else origin = new Vector3();
|
|
24
|
+
|
|
25
|
+
if (direction) direction = direction.clone().normalize();
|
|
26
|
+
else direction = new Vector3();
|
|
27
|
+
|
|
28
|
+
this.origin = origin;
|
|
29
|
+
this.direction = direction;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// math.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {ImplicitShapeBase, type ImplicitShape, type LocalRayIntersection} from './implicit-shape';
|
|
6
|
+
|
|
7
|
+
const EPSILON = 1e-6;
|
|
8
|
+
|
|
9
|
+
export type BoxShapeProps = {size?: readonly [number, number, number]; matrix?: readonly number[]};
|
|
10
|
+
|
|
11
|
+
/** Analytic glTF box shape. */
|
|
12
|
+
export class BoxShape extends ImplicitShapeBase {
|
|
13
|
+
readonly type = 'box' as const;
|
|
14
|
+
readonly size: readonly [number, number, number];
|
|
15
|
+
private readonly halfSize: readonly [number, number, number];
|
|
16
|
+
|
|
17
|
+
constructor(props: BoxShapeProps = {}) {
|
|
18
|
+
super(props.matrix);
|
|
19
|
+
this.size = props.size ? [...props.size] : [1, 1, 1];
|
|
20
|
+
if (this.size.some(value => !Number.isFinite(value) || value <= 0))
|
|
21
|
+
throw new Error('Box size values must be greater than zero');
|
|
22
|
+
this.halfSize = [this.size[0] / 2, this.size[1] / 2, this.size[2] / 2];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
clone(): BoxShape {
|
|
26
|
+
return new BoxShape({size: this.size, matrix: this.matrix});
|
|
27
|
+
}
|
|
28
|
+
override equals(shape: ImplicitShape): boolean {
|
|
29
|
+
return (
|
|
30
|
+
shape instanceof BoxShape &&
|
|
31
|
+
super.equals(shape) &&
|
|
32
|
+
this.size.every((value, i) => value === shape.size[i])
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
containsLocalPoint(point: readonly number[]): boolean {
|
|
36
|
+
return point.every((value, i) => Math.abs(value) <= this.halfSize[i] + EPSILON);
|
|
37
|
+
}
|
|
38
|
+
distanceToLocalPoint(point: readonly number[]): number {
|
|
39
|
+
return Math.hypot(...point.map((value, i) => Math.max(0, Math.abs(value) - this.halfSize[i])));
|
|
40
|
+
}
|
|
41
|
+
supportLocal(direction: readonly number[]): readonly number[] {
|
|
42
|
+
return direction.map((value, i) => (value < 0 ? -this.halfSize[i] : this.halfSize[i]));
|
|
43
|
+
}
|
|
44
|
+
intersectLocalRay(
|
|
45
|
+
origin: readonly number[],
|
|
46
|
+
direction: readonly number[]
|
|
47
|
+
): LocalRayIntersection | undefined {
|
|
48
|
+
let near = -Infinity;
|
|
49
|
+
let far = Infinity;
|
|
50
|
+
let nearAxis = 0;
|
|
51
|
+
let farAxis = 0;
|
|
52
|
+
for (let axis = 0; axis < 3; axis++) {
|
|
53
|
+
if (Math.abs(direction[axis]) < 1e-15) {
|
|
54
|
+
if (Math.abs(origin[axis]) > this.halfSize[axis]) return undefined;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
let t1 = (-this.halfSize[axis] - origin[axis]) / direction[axis];
|
|
58
|
+
let t2 = (this.halfSize[axis] - origin[axis]) / direction[axis];
|
|
59
|
+
if (t1 > t2) [t1, t2] = [t2, t1];
|
|
60
|
+
if (t1 > near) {
|
|
61
|
+
near = t1;
|
|
62
|
+
nearAxis = axis;
|
|
63
|
+
}
|
|
64
|
+
if (t2 < far) {
|
|
65
|
+
far = t2;
|
|
66
|
+
farAxis = axis;
|
|
67
|
+
}
|
|
68
|
+
if (near > far) return undefined;
|
|
69
|
+
}
|
|
70
|
+
const distance = near >= 0 ? near : far;
|
|
71
|
+
if (distance < 0 || !Number.isFinite(distance)) return undefined;
|
|
72
|
+
const axis = near >= 0 ? nearAxis : farAxis;
|
|
73
|
+
const pointCoordinate = origin[axis] + distance * direction[axis];
|
|
74
|
+
const normal = [0, 0, 0];
|
|
75
|
+
normal[axis] = pointCoordinate < 0 ? -1 : 1;
|
|
76
|
+
return {distance, normal};
|
|
77
|
+
}
|
|
78
|
+
}
|