@math.gl/culling 4.2.0-alpha.3 → 4.2.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +51 -0
  2. package/README.md +8 -1
  3. package/dist/constants.d.ts +10 -5
  4. package/dist/constants.d.ts.map +1 -1
  5. package/dist/constants.js +9 -5
  6. package/dist/constants.js.map +1 -1
  7. package/dist/index.cjs +640 -113
  8. package/dist/index.cjs.map +3 -4
  9. package/dist/index.d.ts +12 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +5 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts +2 -1
  14. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.d.ts.map +1 -1
  15. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js +3 -4
  16. package/dist/lib/bounding-volumes/axis-aligned-bounding-box.js.map +1 -1
  17. package/dist/lib/bounding-volumes/bounding-sphere.d.ts +2 -1
  18. package/dist/lib/bounding-volumes/bounding-sphere.d.ts.map +1 -1
  19. package/dist/lib/bounding-volumes/bounding-sphere.js +3 -4
  20. package/dist/lib/bounding-volumes/bounding-sphere.js.map +1 -1
  21. package/dist/lib/bounding-volumes/bounding-volume.d.ts +5 -4
  22. package/dist/lib/bounding-volumes/bounding-volume.d.ts.map +1 -1
  23. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts +2 -1
  24. package/dist/lib/bounding-volumes/oriented-bounding-box.d.ts.map +1 -1
  25. package/dist/lib/bounding-volumes/oriented-bounding-box.js +3 -4
  26. package/dist/lib/bounding-volumes/oriented-bounding-box.js.map +1 -1
  27. package/dist/lib/culling-volume.d.ts +2 -1
  28. package/dist/lib/culling-volume.d.ts.map +1 -1
  29. package/dist/lib/culling-volume.js +7 -8
  30. package/dist/lib/culling-volume.js.map +1 -1
  31. package/dist/lib/plane.d.ts +2 -2
  32. package/dist/lib/plane.d.ts.map +1 -1
  33. package/dist/lib/plane.js +3 -6
  34. package/dist/lib/plane.js.map +1 -1
  35. package/dist/lib/shapes/box-shape.d.ts +19 -0
  36. package/dist/lib/shapes/box-shape.d.ts.map +1 -0
  37. package/dist/lib/shapes/box-shape.js +69 -0
  38. package/dist/lib/shapes/box-shape.js.map +1 -0
  39. package/dist/lib/shapes/capsule-shape.d.ts +23 -0
  40. package/dist/lib/shapes/capsule-shape.d.ts.map +1 -0
  41. package/dist/lib/shapes/capsule-shape.js +151 -0
  42. package/dist/lib/shapes/capsule-shape.js.map +1 -0
  43. package/dist/lib/shapes/cylinder-shape.d.ts +22 -0
  44. package/dist/lib/shapes/cylinder-shape.d.ts.map +1 -0
  45. package/dist/lib/shapes/cylinder-shape.js +99 -0
  46. package/dist/lib/shapes/cylinder-shape.js.map +1 -0
  47. package/dist/lib/shapes/implicit-shape.d.ts +56 -0
  48. package/dist/lib/shapes/implicit-shape.d.ts.map +1 -0
  49. package/dist/lib/shapes/implicit-shape.js +142 -0
  50. package/dist/lib/shapes/implicit-shape.js.map +1 -0
  51. package/dist/lib/shapes/plane-shape.d.ts +27 -0
  52. package/dist/lib/shapes/plane-shape.d.ts.map +1 -0
  53. package/dist/lib/shapes/plane-shape.js +71 -0
  54. package/dist/lib/shapes/plane-shape.js.map +1 -0
  55. package/dist/lib/shapes/sphere-shape.d.ts +18 -0
  56. package/dist/lib/shapes/sphere-shape.d.ts.map +1 -0
  57. package/dist/lib/shapes/sphere-shape.js +43 -0
  58. package/dist/lib/shapes/sphere-shape.js.map +1 -0
  59. package/package.json +4 -4
  60. package/src/constants.ts +11 -5
  61. package/src/index.ts +13 -0
  62. package/src/lib/bounding-volumes/axis-aligned-bounding-box.ts +5 -5
  63. package/src/lib/bounding-volumes/bounding-sphere.ts +5 -5
  64. package/src/lib/bounding-volumes/bounding-volume.ts +5 -4
  65. package/src/lib/bounding-volumes/oriented-bounding-box.ts +5 -5
  66. package/src/lib/culling-volume.ts +9 -9
  67. package/src/lib/plane.ts +3 -6
  68. package/src/lib/shapes/box-shape.ts +78 -0
  69. package/src/lib/shapes/capsule-shape.ts +232 -0
  70. package/src/lib/shapes/cylinder-shape.ts +133 -0
  71. package/src/lib/shapes/implicit-shape.ts +209 -0
  72. package/src/lib/shapes/plane-shape.ts +78 -0
  73. package/src/lib/shapes/sphere-shape.ts +60 -0
@@ -0,0 +1,99 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { closestDistanceToSegment2D, ImplicitShapeBase, solveQuadratic } from "./implicit-shape.js";
5
+ const EPSILON = 1e-6;
6
+ /** Analytic closed, Y-aligned glTF cylinder shape, including tapered cylinders. */
7
+ export class CylinderShape extends ImplicitShapeBase {
8
+ constructor(props = {}) {
9
+ super(props.matrix);
10
+ this.type = 'cylinder';
11
+ this.height = props.height ?? 2;
12
+ this.radiusBottom = props.radiusBottom ?? 0.5;
13
+ this.radiusTop = props.radiusTop ?? 0.5;
14
+ if (!Number.isFinite(this.height) || this.height <= 0)
15
+ throw new Error('Cylinder height must be greater than zero');
16
+ if (![this.radiusBottom, this.radiusTop].every(value => Number.isFinite(value) && value >= 0))
17
+ throw new Error('Cylinder radii must be non-negative');
18
+ if (this.radiusBottom === 0 && this.radiusTop === 0)
19
+ throw new Error('At least one cylinder radius must be greater than zero');
20
+ }
21
+ clone() {
22
+ return new CylinderShape({
23
+ height: this.height,
24
+ radiusBottom: this.radiusBottom,
25
+ radiusTop: this.radiusTop,
26
+ matrix: this.matrix
27
+ });
28
+ }
29
+ equals(shape) {
30
+ return (shape instanceof CylinderShape &&
31
+ super.equals(shape) &&
32
+ this.height === shape.height &&
33
+ this.radiusBottom === shape.radiusBottom &&
34
+ this.radiusTop === shape.radiusTop);
35
+ }
36
+ containsLocalPoint(point) {
37
+ const half = this.height / 2;
38
+ if (point[1] < -half - EPSILON || point[1] > half + EPSILON)
39
+ return false;
40
+ const t = (point[1] + half) / this.height;
41
+ const radius = this.radiusBottom + (this.radiusTop - this.radiusBottom) * t;
42
+ return Math.hypot(point[0], point[2]) <= radius + EPSILON;
43
+ }
44
+ distanceToLocalPoint(point) {
45
+ if (this.containsLocalPoint(point))
46
+ return 0;
47
+ const radial = Math.hypot(point[0], point[2]);
48
+ const half = this.height / 2;
49
+ const side = closestDistanceToSegment2D(radial, point[1], this.radiusBottom, -half, this.radiusTop, half);
50
+ const bottom = closestDistanceToSegment2D(radial, point[1], 0, -half, this.radiusBottom, -half);
51
+ const top = closestDistanceToSegment2D(radial, point[1], 0, half, this.radiusTop, half);
52
+ return Math.min(side, bottom, top);
53
+ }
54
+ supportLocal(direction) {
55
+ const radialLength = Math.hypot(direction[0], direction[2]);
56
+ const x = radialLength ? direction[0] / radialLength : 1;
57
+ const z = radialLength ? direction[2] / radialLength : 0;
58
+ const half = this.height / 2;
59
+ const bottomValue = radialLength * this.radiusBottom - direction[1] * half;
60
+ const topValue = radialLength * this.radiusTop + direction[1] * half;
61
+ return topValue >= bottomValue
62
+ ? [x * this.radiusTop, half, z * this.radiusTop]
63
+ : [x * this.radiusBottom, -half, z * this.radiusBottom];
64
+ }
65
+ intersectLocalRay(origin, direction) {
66
+ const half = this.height / 2;
67
+ const slope = (this.radiusTop - this.radiusBottom) / this.height;
68
+ const intercept = (this.radiusTop + this.radiusBottom) / 2;
69
+ const radialAtOrigin = intercept + slope * origin[1];
70
+ const radialAlongRay = slope * direction[1];
71
+ const candidates = [];
72
+ const roots = solveQuadratic(direction[0] ** 2 + direction[2] ** 2 - radialAlongRay ** 2, 2 * (origin[0] * direction[0] + origin[2] * direction[2] - radialAtOrigin * radialAlongRay), origin[0] ** 2 + origin[2] ** 2 - radialAtOrigin ** 2);
73
+ for (const distance of roots) {
74
+ const y = origin[1] + distance * direction[1];
75
+ if (distance >= 0 && y >= -half - EPSILON && y <= half + EPSILON) {
76
+ const x = origin[0] + distance * direction[0];
77
+ const z = origin[2] + distance * direction[2];
78
+ const radial = Math.hypot(x, z) || 1;
79
+ const normal = [x / radial, -slope, z / radial];
80
+ const length = Math.hypot(...normal);
81
+ candidates.push({ distance, normal: normal.map(value => value / length) });
82
+ }
83
+ }
84
+ if (Math.abs(direction[1]) > 1e-15) {
85
+ for (const [y, radius, normalY] of [
86
+ [-half, this.radiusBottom, -1],
87
+ [half, this.radiusTop, 1]
88
+ ]) {
89
+ const distance = (y - origin[1]) / direction[1];
90
+ const x = origin[0] + distance * direction[0];
91
+ const z = origin[2] + distance * direction[2];
92
+ if (distance >= 0 && Math.hypot(x, z) <= radius + EPSILON)
93
+ candidates.push({ distance, normal: [0, normalY, 0] });
94
+ }
95
+ }
96
+ return candidates.sort((a, b) => a.distance - b.distance)[0];
97
+ }
98
+ }
99
+ //# sourceMappingURL=cylinder-shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cylinder-shape.js","sourceRoot":"","sources":["../../../src/lib/shapes/cylinder-shape.ts"],"names":[],"mappings":"AAAA,UAAU;AACV,+BAA+B;AAC/B,oCAAoC;AAEpC,OAAO,EACL,0BAA0B,EAC1B,iBAAiB,EACjB,cAAc,EAGf,4BAAyB;AAE1B,MAAM,OAAO,GAAG,IAAI,CAAC;AASrB,mFAAmF;AACnF,MAAM,OAAO,aAAc,SAAQ,iBAAiB;IAMlD,YAAY,QAA4B,EAAE;QACxC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QANb,SAAI,GAAG,UAAmB,CAAC;QAOlC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,GAAG,CAAC;QAC9C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC3F,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK;QACH,OAAO,IAAI,aAAa,CAAC;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;IACL,CAAC;IACQ,MAAM,CAAC,KAAoB;QAClC,OAAO,CACL,KAAK,YAAY,aAAa;YAC9B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC;YACnB,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;YAC5B,IAAI,CAAC,YAAY,KAAK,KAAK,CAAC,YAAY;YACxC,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,CACnC,CAAC;IACJ,CAAC;IACD,kBAAkB,CAAC,KAAwB;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,OAAO;YAAE,OAAO,KAAK,CAAC;QAC1E,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,GAAG,OAAO,CAAC;IAC5D,CAAC;IACD,oBAAoB,CAAC,KAAwB;QAC3C,IAAI,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,0BAA0B,CACrC,MAAM,EACN,KAAK,CAAC,CAAC,CAAC,EACR,IAAI,CAAC,YAAY,EACjB,CAAC,IAAI,EACL,IAAI,CAAC,SAAS,EACd,IAAI,CACL,CAAC;QACF,MAAM,MAAM,GAAG,0BAA0B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,CAAC;QAChG,MAAM,GAAG,GAAG,0BAA0B,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACxF,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,YAAY,CAAC,SAA4B;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,MAAM,WAAW,GAAG,YAAY,GAAG,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QAC3E,MAAM,QAAQ,GAAG,YAAY,GAAG,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACrE,OAAO,QAAQ,IAAI,WAAW;YAC5B,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;YAChD,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5D,CAAC;IACD,iBAAiB,CACf,MAAyB,EACzB,SAA4B;QAE5B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QACjE,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3D,MAAM,cAAc,GAAG,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACrD,MAAM,cAAc,GAAG,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,cAAc,CAC1B,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,cAAc,IAAI,CAAC,EAC3D,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,cAAc,GAAG,cAAc,CAAC,EAC3F,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,cAAc,IAAI,CAAC,CACtD,CAAC;QACF,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC9C,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,IAAI,GAAG,OAAO,EAAE,CAAC;gBACjE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;gBACrC,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC;gBACrC,UAAU,CAAC,IAAI,CAAC,EAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,EAAC,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC;YACnC,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI;gBACjC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;gBAC9B,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;aAC1B,EAAE,CAAC;gBACF,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAChD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC9C,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,GAAG,OAAO;oBACvD,UAAU,CAAC,IAAI,CAAC,EAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAC,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QACD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC;CACF"}
@@ -0,0 +1,56 @@
1
+ import { Matrix4, Vector3 } from '@math.gl/core';
2
+ import type { CullingResult } from "../../constants.js";
3
+ import { AxisAlignedBoundingBox } from "../bounding-volumes/axis-aligned-bounding-box.js";
4
+ import { BoundingSphere } from "../bounding-volumes/bounding-sphere.js";
5
+ import type { BoundingVolume } from "../bounding-volumes/bounding-volume.js";
6
+ import type { Plane } from "../plane.js";
7
+ import type { Ray } from "../ray.js";
8
+ export type RayIntersection = {
9
+ distance: number;
10
+ point: Vector3;
11
+ normal: Vector3;
12
+ entering: boolean;
13
+ };
14
+ export interface ImplicitShape extends BoundingVolume {
15
+ readonly type: 'box' | 'capsule' | 'cylinder' | 'plane' | 'sphere';
16
+ readonly matrix: Matrix4;
17
+ clone(): ImplicitShape;
18
+ equals(shape: ImplicitShape): boolean;
19
+ containsPoint(point: readonly number[]): boolean;
20
+ intersectRay(ray: Ray): RayIntersection | undefined;
21
+ getAxisAlignedBoundingBox(): AxisAlignedBoundingBox | undefined;
22
+ getBoundingSphere(): BoundingSphere | undefined;
23
+ }
24
+ export type LocalRayIntersection = {
25
+ distance: number;
26
+ normal: readonly number[];
27
+ };
28
+ /** Shared affine transform, support mapping and query implementation for finite convex shapes. */
29
+ export declare abstract class ImplicitShapeBase implements ImplicitShape {
30
+ abstract readonly type: ImplicitShape['type'];
31
+ readonly matrix: Matrix4;
32
+ protected inverseMatrix: Matrix4;
33
+ constructor(matrix?: readonly number[]);
34
+ abstract clone(): ImplicitShapeBase;
35
+ abstract containsLocalPoint(point: readonly number[]): boolean;
36
+ abstract distanceToLocalPoint(point: readonly number[]): number;
37
+ abstract supportLocal(direction: readonly number[]): readonly number[];
38
+ abstract intersectLocalRay(origin: readonly number[], direction: readonly number[]): LocalRayIntersection | undefined;
39
+ equals(shape: ImplicitShape): boolean;
40
+ transform(transform: readonly number[]): this;
41
+ containsPoint(point: readonly number[]): boolean;
42
+ distanceSquaredTo(point: readonly number[]): number;
43
+ /** Exact for rigid/uniform transforms; conservative estimate for non-uniform scale or shear. */
44
+ distanceTo(point: readonly number[]): number;
45
+ intersectPlane(plane: Plane): CullingResult;
46
+ intersectRay(ray: Ray): RayIntersection | undefined;
47
+ getAxisAlignedBoundingBox(): AxisAlignedBoundingBox | undefined;
48
+ getBoundingSphere(): BoundingSphere | undefined;
49
+ protected getSupportPoint(worldDirection: readonly number[]): Vector3;
50
+ }
51
+ export declare function validateAffineMatrix(matrix: readonly number[]): void;
52
+ export declare function solveQuadratic(a: number, b: number, c: number): number[];
53
+ export declare function closestDistanceToSegment2D(px: number, py: number, ax: number, ay: number, bx: number, by: number): number;
54
+ /** Distance in the radial/Y half-plane to a spherical profile arc selected by normal Y range. */
55
+ export declare function closestDistanceToCircleArc2D(px: number, py: number, centerY: number, radius: number, minimumNormalY: number, maximumNormalY: number): number;
56
+ //# sourceMappingURL=implicit-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"implicit-shape.d.ts","sourceRoot":"","sources":["../../../src/lib/shapes/implicit-shape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,142 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { Matrix4, Vector3 } from '@math.gl/core';
5
+ import { AxisAlignedBoundingBox } from "../bounding-volumes/axis-aligned-bounding-box.js";
6
+ import { BoundingSphere } from "../bounding-volumes/bounding-sphere.js";
7
+ /** Shared affine transform, support mapping and query implementation for finite convex shapes. */
8
+ export class ImplicitShapeBase {
9
+ constructor(matrix) {
10
+ this.matrix = new Matrix4();
11
+ if (matrix)
12
+ this.matrix.copy(matrix);
13
+ validateAffineMatrix(this.matrix);
14
+ this.inverseMatrix = this.matrix.clone().invert();
15
+ }
16
+ equals(shape) {
17
+ if (this.type !== shape.type)
18
+ return false;
19
+ for (let i = 0; i < 16; i++)
20
+ if (this.matrix[i] !== shape.matrix[i])
21
+ return false;
22
+ return true;
23
+ }
24
+ transform(transform) {
25
+ const next = new Matrix4().copy(transform);
26
+ validateAffineMatrix(next);
27
+ this.matrix.multiplyLeft(next);
28
+ validateAffineMatrix(this.matrix);
29
+ this.inverseMatrix.copy(this.matrix).invert();
30
+ return this;
31
+ }
32
+ containsPoint(point) {
33
+ return this.containsLocalPoint(this.inverseMatrix.transformAsPoint(point));
34
+ }
35
+ distanceSquaredTo(point) {
36
+ const distance = this.distanceTo(point);
37
+ return distance * distance;
38
+ }
39
+ /** Exact for rigid/uniform transforms; conservative estimate for non-uniform scale or shear. */
40
+ distanceTo(point) {
41
+ const localPoint = this.inverseMatrix.transformAsPoint(point);
42
+ const localDistance = this.distanceToLocalPoint(localPoint);
43
+ const scales = this.matrix.getScale();
44
+ return localDistance * Math.min(scales[0], scales[1], scales[2]);
45
+ }
46
+ intersectPlane(plane) {
47
+ const maximum = this.getSupportPoint(plane.normal);
48
+ const minimum = this.getSupportPoint([-plane.normal[0], -plane.normal[1], -plane.normal[2]]);
49
+ const maxDistance = plane.getPointDistance(maximum);
50
+ const minDistance = plane.getPointDistance(minimum);
51
+ if (minDistance > 0)
52
+ return 'inside';
53
+ if (maxDistance < 0)
54
+ return 'outside';
55
+ return 'intersecting';
56
+ }
57
+ intersectRay(ray) {
58
+ const localOrigin = this.inverseMatrix.transformAsPoint(ray.origin);
59
+ const localDirection = this.inverseMatrix.transformAsVector(ray.direction);
60
+ const hit = this.intersectLocalRay(localOrigin, localDirection);
61
+ if (!hit || hit.distance < 0)
62
+ return undefined;
63
+ const point = new Vector3(ray.direction).scale(hit.distance).add(ray.origin);
64
+ const inverse = this.inverseMatrix;
65
+ 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();
66
+ return { distance: hit.distance, point, normal, entering: ray.direction.dot(normal) < 0 };
67
+ }
68
+ getAxisAlignedBoundingBox() {
69
+ const minimum = new Vector3();
70
+ const maximum = new Vector3();
71
+ for (let axis = 0; axis < 3; axis++) {
72
+ const direction = [0, 0, 0];
73
+ direction[axis] = 1;
74
+ maximum[axis] = this.getSupportPoint(direction)[axis];
75
+ direction[axis] = -1;
76
+ minimum[axis] = this.getSupportPoint(direction)[axis];
77
+ }
78
+ return new AxisAlignedBoundingBox(minimum, maximum);
79
+ }
80
+ getBoundingSphere() {
81
+ const box = this.getAxisAlignedBoundingBox();
82
+ if (!box)
83
+ return undefined;
84
+ return new BoundingSphere().fromCornerPoints(box.minimum, box.maximum);
85
+ }
86
+ getSupportPoint(worldDirection) {
87
+ const matrix = this.matrix;
88
+ const localDirection = [
89
+ matrix[0] * worldDirection[0] + matrix[1] * worldDirection[1] + matrix[2] * worldDirection[2],
90
+ matrix[4] * worldDirection[0] + matrix[5] * worldDirection[1] + matrix[6] * worldDirection[2],
91
+ matrix[8] * worldDirection[0] + matrix[9] * worldDirection[1] + matrix[10] * worldDirection[2]
92
+ ];
93
+ return new Vector3(this.supportLocal(localDirection)).transform(this.matrix);
94
+ }
95
+ }
96
+ export function validateAffineMatrix(matrix) {
97
+ if (matrix.length !== 16 || matrix.some(value => !Number.isFinite(value))) {
98
+ throw new Error('Shape matrix must contain 16 finite values');
99
+ }
100
+ if (Math.abs(matrix[3]) > 1e-12 ||
101
+ Math.abs(matrix[7]) > 1e-12 ||
102
+ Math.abs(matrix[11]) > 1e-12 ||
103
+ Math.abs(matrix[15] - 1) > 1e-12) {
104
+ throw new Error('Shape matrix must be affine');
105
+ }
106
+ if (Math.abs(new Matrix4().copy(matrix).determinant()) < 1e-15)
107
+ throw new Error('Shape matrix must be invertible');
108
+ }
109
+ export function solveQuadratic(a, b, c) {
110
+ if (Math.abs(a) < 1e-15)
111
+ return Math.abs(b) < 1e-15 ? [] : [-c / b];
112
+ const discriminant = b * b - 4 * a * c;
113
+ if (discriminant < 0)
114
+ return [];
115
+ const root = Math.sqrt(Math.max(0, discriminant));
116
+ return [(-b - root) / (2 * a), (-b + root) / (2 * a)].sort((left, right) => left - right);
117
+ }
118
+ export function closestDistanceToSegment2D(px, py, ax, ay, bx, by) {
119
+ const dx = bx - ax;
120
+ const dy = by - ay;
121
+ const denominator = dx * dx + dy * dy;
122
+ const t = denominator
123
+ ? Math.max(0, Math.min(1, ((px - ax) * dx + (py - ay) * dy) / denominator))
124
+ : 0;
125
+ return Math.hypot(px - (ax + t * dx), py - (ay + t * dy));
126
+ }
127
+ /** Distance in the radial/Y half-plane to a spherical profile arc selected by normal Y range. */
128
+ export function closestDistanceToCircleArc2D(px, py, centerY, radius, minimumNormalY, maximumNormalY) {
129
+ if (radius === 0)
130
+ return Math.hypot(px, py - centerY);
131
+ const dx = px;
132
+ const dy = py - centerY;
133
+ const length = Math.hypot(dx, dy);
134
+ const normalY = length ? dy / length : 0;
135
+ if (normalY >= minimumNormalY && normalY <= maximumNormalY) {
136
+ return Math.abs(length - radius);
137
+ }
138
+ const minimumRadius = radius * Math.sqrt(Math.max(0, 1 - minimumNormalY ** 2));
139
+ const maximumRadius = radius * Math.sqrt(Math.max(0, 1 - maximumNormalY ** 2));
140
+ return Math.min(Math.hypot(px - minimumRadius, py - (centerY + radius * minimumNormalY)), Math.hypot(px - maximumRadius, py - (centerY + radius * maximumNormalY)));
141
+ }
142
+ //# 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,27 @@
1
+ import type { CullingResult } from "../../constants.js";
2
+ import { ImplicitShapeBase, type ImplicitShape, type LocalRayIntersection } from "./implicit-shape.js";
3
+ import type { AxisAlignedBoundingBox } from "../bounding-volumes/axis-aligned-bounding-box.js";
4
+ import type { BoundingSphere } from "../bounding-volumes/bounding-sphere.js";
5
+ import type { Plane } from "../plane.js";
6
+ export type PlaneShapeProps = {
7
+ sizeX?: number;
8
+ sizeZ?: number;
9
+ matrix?: readonly number[];
10
+ };
11
+ /** Analytic glTF plane. The surface faces +Y and the negative-Y half-space is inside. */
12
+ export declare class PlaneShape extends ImplicitShapeBase {
13
+ readonly type: "plane";
14
+ readonly sizeX?: number;
15
+ readonly sizeZ?: number;
16
+ constructor(props?: PlaneShapeProps);
17
+ clone(): PlaneShape;
18
+ equals(shape: ImplicitShape): boolean;
19
+ containsLocalPoint(point: readonly number[]): boolean;
20
+ distanceToLocalPoint(point: readonly number[]): number;
21
+ supportLocal(): readonly number[];
22
+ intersectLocalRay(origin: readonly number[], direction: readonly number[]): LocalRayIntersection | undefined;
23
+ intersectPlane(plane: Plane): CullingResult;
24
+ getAxisAlignedBoundingBox(): AxisAlignedBoundingBox | undefined;
25
+ getBoundingSphere(): BoundingSphere | undefined;
26
+ }
27
+ //# 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":"AAKA,OAAO,KAAK,EAAC,aAAa,EAAC,2BAAwB;AACnD,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,aAAa;IAW3C,yBAAyB,IAAI,sBAAsB,GAAG,SAAS;IAG/D,iBAAiB,IAAI,cAAc,GAAG,SAAS;CAGzD"}
@@ -0,0 +1,71 @@
1
+ // math.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { Vector3 } from '@math.gl/core';
5
+ import { ImplicitShapeBase } from "./implicit-shape.js";
6
+ /** Analytic glTF plane. The surface faces +Y and the negative-Y half-space is inside. */
7
+ export class PlaneShape extends ImplicitShapeBase {
8
+ constructor(props = {}) {
9
+ super(props.matrix);
10
+ this.type = 'plane';
11
+ this.sizeX = props.sizeX;
12
+ this.sizeZ = props.sizeZ;
13
+ if (this.sizeX !== undefined && (!Number.isFinite(this.sizeX) || this.sizeX <= 0))
14
+ throw new Error('Plane sizeX must be greater than zero');
15
+ if (this.sizeZ !== undefined && (!Number.isFinite(this.sizeZ) || this.sizeZ <= 0))
16
+ throw new Error('Plane sizeZ must be greater than zero');
17
+ }
18
+ clone() {
19
+ return new PlaneShape({ sizeX: this.sizeX, sizeZ: this.sizeZ, matrix: this.matrix });
20
+ }
21
+ equals(shape) {
22
+ return (shape instanceof PlaneShape &&
23
+ super.equals(shape) &&
24
+ this.sizeX === shape.sizeX &&
25
+ this.sizeZ === shape.sizeZ);
26
+ }
27
+ containsLocalPoint(point) {
28
+ return point[1] <= 1e-12;
29
+ }
30
+ distanceToLocalPoint(point) {
31
+ return Math.max(0, point[1]);
32
+ }
33
+ supportLocal() {
34
+ throw new Error('An unbounded plane half-space has no finite support point');
35
+ }
36
+ intersectLocalRay(origin, direction) {
37
+ if (Math.abs(direction[1]) < 1e-15)
38
+ return undefined;
39
+ const distance = -origin[1] / direction[1];
40
+ if (distance < 0)
41
+ return undefined;
42
+ const x = origin[0] + distance * direction[0];
43
+ const z = origin[2] + distance * direction[2];
44
+ if (this.sizeX !== undefined && Math.abs(x) > this.sizeX / 2 + 1e-12)
45
+ return undefined;
46
+ if (this.sizeZ !== undefined && Math.abs(z) > this.sizeZ / 2 + 1e-12)
47
+ return undefined;
48
+ return { distance, normal: [0, 1, 0] };
49
+ }
50
+ intersectPlane(plane) {
51
+ const boundaryPoint = new Vector3(0, 0, 0).transform(this.matrix);
52
+ const inverse = this.inverseMatrix;
53
+ const boundaryNormal = new Vector3(inverse[1], inverse[5], inverse[9]).normalize();
54
+ const alignment = boundaryNormal.dot(plane.normal);
55
+ if (Math.abs(Math.abs(alignment) - 1) > 1e-10)
56
+ return 'intersecting';
57
+ const boundaryDistance = plane.getPointDistance(boundaryPoint);
58
+ if (alignment < 0 && boundaryDistance > 0)
59
+ return 'inside';
60
+ if (alignment > 0 && boundaryDistance < 0)
61
+ return 'outside';
62
+ return 'intersecting';
63
+ }
64
+ getAxisAlignedBoundingBox() {
65
+ return undefined;
66
+ }
67
+ getBoundingSphere() {
68
+ return undefined;
69
+ }
70
+ }
71
+ //# 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":"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"}
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },
9
- "version": "4.2.0-alpha.3",
9
+ "version": "4.2.0-alpha.6",
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.2.0-alpha.3",
46
- "@math.gl/types": "4.2.0-alpha.3"
45
+ "@math.gl/core": "4.2.0-alpha.6",
46
+ "@math.gl/types": "4.2.0-alpha.6"
47
47
  },
48
- "gitHead": "4238aa95fb38da43a65c6e5f2b8343a875666d92"
48
+ "gitHead": "b1d477a0afa7033ce6ac837bb4c811b425e99566"
49
49
  }
package/src/constants.ts CHANGED
@@ -2,8 +2,14 @@
2
2
  // SPDX-License-Identifier: MIT
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
- export const INTERSECTION = {
6
- OUTSIDE: -1, // Represents that an object is not contained within the frustum.
7
- INTERSECTING: 0, // Represents that an object intersects one of the frustum's planes.
8
- INSIDE: 1 // Represents that an object is fully within the frustum.
9
- } as const;
5
+ /** Classification returned by culling intersection tests. */
6
+ export type CullingResult = 'outside' | 'intersecting' | 'inside';
7
+
8
+ /**
9
+ * @deprecated Use the string values of {@link CullingResult} directly.
10
+ */
11
+ export enum INTERSECTION {
12
+ OUTSIDE = 'outside', // The object is not contained within the frustum.
13
+ INTERSECTING = 'intersecting', // The object intersects one or more frustum planes.
14
+ INSIDE = 'inside' // The object is fully within the frustum.
15
+ }
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  export {INTERSECTION} from './constants';
6
+ export type {CullingResult} from './constants';
6
7
 
7
8
  export {AxisAlignedBoundingBox} from './lib/bounding-volumes/axis-aligned-bounding-box';
8
9
  export {BoundingSphere} from './lib/bounding-volumes/bounding-sphere';
@@ -11,6 +12,18 @@ export {CullingVolume} from './lib/culling-volume';
11
12
  export {Plane} from './lib/plane';
12
13
  export {Ray} from './lib/ray';
13
14
 
15
+ export type {ImplicitShape, RayIntersection} from './lib/shapes/implicit-shape';
16
+ export {BoxShape} from './lib/shapes/box-shape';
17
+ export type {BoxShapeProps} from './lib/shapes/box-shape';
18
+ export {CapsuleShape} from './lib/shapes/capsule-shape';
19
+ export type {CapsuleShapeProps} from './lib/shapes/capsule-shape';
20
+ export {CylinderShape} from './lib/shapes/cylinder-shape';
21
+ export type {CylinderShapeProps} from './lib/shapes/cylinder-shape';
22
+ export {PlaneShape} from './lib/shapes/plane-shape';
23
+ export type {PlaneShapeProps} from './lib/shapes/plane-shape';
24
+ export {SphereShape} from './lib/shapes/sphere-shape';
25
+ export type {SphereShapeProps} from './lib/shapes/sphere-shape';
26
+
14
27
  export {PerspectiveOffCenterFrustum as _PerspectiveOffCenterFrustum} from './lib/perspective-off-center-frustum';
15
28
  export {PerspectiveFrustum as _PerspectiveFrustum} from './lib/perspective-frustum';
16
29
 
@@ -5,7 +5,7 @@
5
5
  import {BoundingVolume} from './bounding-volume';
6
6
  import {Vector3} from '@math.gl/core';
7
7
  import {Plane} from '../plane';
8
- import {INTERSECTION} from '../../constants';
8
+ import type {CullingResult} from '../../constants';
9
9
 
10
10
  const scratchVector = new Vector3();
11
11
  const scratchNormal = new Vector3();
@@ -97,7 +97,7 @@ export class AxisAlignedBoundingBox implements BoundingVolume {
97
97
  /**
98
98
  * Determines which side of a plane a box is located.
99
99
  */
100
- intersectPlane(plane: Plane): number {
100
+ intersectPlane(plane: Plane): CullingResult {
101
101
  const {halfDiagonal} = this;
102
102
  const normal = scratchNormal.from(plane.normal);
103
103
  const e =
@@ -107,15 +107,15 @@ export class AxisAlignedBoundingBox implements BoundingVolume {
107
107
  const s = this.center.dot(normal) + plane.distance; // signed distance from center
108
108
 
109
109
  if (s - e > 0) {
110
- return INTERSECTION.INSIDE;
110
+ return 'inside';
111
111
  }
112
112
 
113
113
  if (s + e < 0) {
114
114
  // Not in front because normals point inward
115
- return INTERSECTION.OUTSIDE;
115
+ return 'outside';
116
116
  }
117
117
 
118
- return INTERSECTION.INTERSECTING;
118
+ return 'intersecting';
119
119
  }
120
120
 
121
121
  /** Computes the estimated distance from the closest point on a bounding box to a point. */