dacha 0.17.2 → 0.18.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/contrib/components/collider/index.d.ts +17 -4
- package/build/contrib/components/collider/index.js +30 -2
- package/build/contrib/components/rigid-body/index.d.ts +29 -17
- package/build/contrib/components/rigid-body/index.js +64 -21
- package/build/contrib/components/shape/index.d.ts +17 -2
- package/build/contrib/components/shape/index.js +16 -0
- package/build/contrib/events/index.d.ts +10 -75
- package/build/contrib/events/index.js +0 -36
- package/build/contrib/systems/camera-system/{service.d.ts → api.d.ts} +4 -4
- package/build/contrib/systems/camera-system/{service.js → api.js} +2 -2
- package/build/contrib/systems/camera-system/index.d.ts +1 -1
- package/build/contrib/systems/camera-system/index.js +1 -1
- package/build/contrib/systems/camera-system/system.d.ts +1 -1
- package/build/contrib/systems/camera-system/system.js +5 -4
- package/build/contrib/systems/index.d.ts +3 -3
- package/build/contrib/systems/index.js +3 -3
- package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.d.ts +0 -1
- package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.js +4 -5
- package/build/contrib/systems/physics-system/api.d.ts +58 -0
- package/build/contrib/systems/physics-system/api.js +67 -0
- package/build/contrib/systems/physics-system/index.d.ts +2 -21
- package/build/contrib/systems/physics-system/index.js +2 -40
- package/build/contrib/systems/physics-system/physics-system.d.ts +24 -0
- package/build/contrib/systems/physics-system/physics-system.js +47 -0
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/collision.d.ts +5 -3
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/collision.js +7 -5
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.d.ts +4 -6
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.js +20 -17
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-circle-aabb.js +1 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-point-aabb.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-point-aabb.js +7 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-ray-aabb.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-ray-aabb.js +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-segment-aabb.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-segment-aabb.js +14 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/index.js +6 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.d.ts +3 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.js +52 -16
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.d.ts +3 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.js +32 -7
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-point-geometry.d.ts +3 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-point-geometry.js +5 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-ray-geometry.d.ts +3 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-ray-geometry.js +7 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.d.ts +3 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.js +33 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.d.ts +12 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.js +6 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +21 -9
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +177 -92
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.js +36 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.d.ts +17 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.js +126 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-circle/check-box-and-circle-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-circle/check-box-and-circle-intersection.js +46 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.js +28 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/utils.d.ts +19 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/utils.js +76 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-circle/check-circles-intersection.d.ts +12 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-circle/check-circles-intersection.js +47 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-segment/check-circle-and-segment-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-segment/check-circle-and-segment-intersection.js +33 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.d.ts +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.js +27 -3
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-box/check-point-and-box-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-box/check-point-and-box-intersection.js +36 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-circle/check-point-and-circle-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-circle/check-point-and-circle-intersection.js +33 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-segment/check-point-and-segment-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-segment/check-point-and-segment-intersection.js +26 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-box/check-ray-and-box-intersection.d.ts +11 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-box/check-ray-and-box-intersection.js +69 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-circle/check-ray-and-circle-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-circle/check-ray-and-circle-intersection.js +45 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/check-ray-and-segment-intersection.d.ts +16 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/check-ray-and-segment-intersection.js +51 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/utils.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/utils.js +4 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.d.ts +20 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.js +69 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/utils.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/utils.js +23 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.js +63 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/reorientation-checkers/check-collider.js +17 -8
- package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +41 -11
- package/build/contrib/systems/physics-system/subsystems/collision-detection/types.js +0 -3
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +7 -10
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +117 -79
- package/build/contrib/systems/physics-system/subsystems/index.d.ts +0 -1
- package/build/contrib/systems/physics-system/subsystems/index.js +0 -1
- package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +3 -9
- package/build/contrib/systems/physics-system/subsystems/physics/index.js +57 -93
- package/build/contrib/systems/physics-system/types.d.ts +37 -0
- package/build/contrib/systems/renderer/actor-render-tree.js +1 -2
- package/build/contrib/systems/renderer/{service → api}/index.d.ts +6 -6
- package/build/contrib/systems/renderer/{service → api}/index.js +14 -16
- package/build/contrib/systems/renderer/api/utils.d.ts +4 -0
- package/build/contrib/systems/renderer/{service → api}/utils.js +5 -0
- package/build/contrib/systems/renderer/builders/shape-builder/index.js +9 -1
- package/build/contrib/systems/renderer/builders/shape-builder/utils.js +16 -0
- package/build/contrib/systems/renderer/index.d.ts +1 -1
- package/build/contrib/systems/renderer/index.js +1 -1
- package/build/contrib/systems/renderer/renderer.d.ts +2 -1
- package/build/contrib/systems/renderer/renderer.js +9 -7
- package/build/engine/actor/actor-creator.js +6 -4
- package/build/engine/math-lib/math/ops.d.ts +1 -2
- package/build/engine/math-lib/math/ops.js +3 -3
- package/build/engine/math-lib/vector/ops.d.ts +18 -3
- package/build/engine/math-lib/vector/ops.js +28 -5
- package/build/engine/math-lib/vector/vector2.d.ts +22 -7
- package/build/engine/math-lib/vector/vector2.js +29 -5
- package/build/engine/template/template-collection.js +1 -1
- package/build/engine/world/index.d.ts +4 -24
- package/build/engine/world/index.js +5 -33
- package/build/engine/world/system-api-registry.d.ts +17 -0
- package/build/engine/world/system-api-registry.js +34 -0
- package/build/events/index.d.ts +2 -2
- package/build/events/index.js +1 -1
- package/build/types/global.d.ts +4 -0
- package/package.json +4 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.d.ts +0 -16
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.js +0 -80
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-boxes-intersection.d.ts +0 -6
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-boxes-intersection.js +0 -72
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-circles-intersection.d.ts +0 -11
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-circles-intersection.js +0 -39
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.d.ts +0 -10
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.js +0 -50
- package/build/contrib/systems/renderer/service/utils.d.ts +0 -3
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Vector2, VectorOps } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { INTERSECTION_EPSILON, projectPolygon } from '../utils';
|
|
3
|
+
export const CONTACT_EPSILON = 1e-4;
|
|
4
|
+
export const MAX_CONTACT_POINTS = 2;
|
|
5
|
+
export const findMinBoxesOverlap = (geometry1, geometry2) => {
|
|
6
|
+
let minOverlap = Infinity;
|
|
7
|
+
let bestAxis = geometry1.edges[0].normal;
|
|
8
|
+
for (const edge of geometry1.edges) {
|
|
9
|
+
const axis = edge.normal;
|
|
10
|
+
const projection1 = projectPolygon(geometry1.points, axis);
|
|
11
|
+
const projection2 = projectPolygon(geometry2.points, axis);
|
|
12
|
+
const distance1 = projection1.min - projection2.max;
|
|
13
|
+
const distance2 = projection2.min - projection1.max;
|
|
14
|
+
if (distance1 > INTERSECTION_EPSILON || distance2 > INTERSECTION_EPSILON) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const overlap = Math.min(Math.abs(distance1), Math.abs(distance2));
|
|
18
|
+
if (overlap < minOverlap) {
|
|
19
|
+
minOverlap = overlap;
|
|
20
|
+
bestAxis = axis;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
axis: bestAxis,
|
|
25
|
+
overlap: minOverlap,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
const clipSegmentToLine = (vertices, normal, offset) => {
|
|
29
|
+
const clipped = [];
|
|
30
|
+
const distance1 = VectorOps.dotProduct(vertices[0], normal) - offset;
|
|
31
|
+
const distance2 = VectorOps.dotProduct(vertices[1], normal) - offset;
|
|
32
|
+
if (distance1 <= CONTACT_EPSILON) {
|
|
33
|
+
clipped.push(vertices[0]);
|
|
34
|
+
}
|
|
35
|
+
if (distance2 <= CONTACT_EPSILON) {
|
|
36
|
+
clipped.push(vertices[1]);
|
|
37
|
+
}
|
|
38
|
+
if (distance1 * distance2 < 0) {
|
|
39
|
+
const t = distance1 / (distance1 - distance2);
|
|
40
|
+
const point1 = vertices[0];
|
|
41
|
+
const point2 = vertices[1];
|
|
42
|
+
clipped.push({
|
|
43
|
+
x: point1.x + (point2.x - point1.x) * t,
|
|
44
|
+
y: point1.y + (point2.y - point1.y) * t,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return clipped;
|
|
48
|
+
};
|
|
49
|
+
const getMostAntiParallelEdge = (polygon, normal) => {
|
|
50
|
+
let bestEdge = polygon.edges[0];
|
|
51
|
+
let minDot = VectorOps.dotProduct(bestEdge.normal, normal);
|
|
52
|
+
for (const edge of polygon.edges) {
|
|
53
|
+
const dot = VectorOps.dotProduct(edge.normal, normal);
|
|
54
|
+
if (dot < minDot) {
|
|
55
|
+
minDot = dot;
|
|
56
|
+
bestEdge = edge;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return bestEdge;
|
|
60
|
+
};
|
|
61
|
+
const getMostParallelEdge = (polygon, normal) => {
|
|
62
|
+
let bestEdge = polygon.edges[0];
|
|
63
|
+
let maxDot = VectorOps.dotProduct(bestEdge.normal, normal);
|
|
64
|
+
for (const edge of polygon.edges) {
|
|
65
|
+
const dot = VectorOps.dotProduct(edge.normal, normal);
|
|
66
|
+
if (dot > maxDot) {
|
|
67
|
+
maxDot = dot;
|
|
68
|
+
bestEdge = edge;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return bestEdge;
|
|
72
|
+
};
|
|
73
|
+
const dedupePoints = (points) => {
|
|
74
|
+
const unique = [];
|
|
75
|
+
for (const point of points) {
|
|
76
|
+
if (unique.some((entry) => Math.abs(entry.x - point.x) <= CONTACT_EPSILON &&
|
|
77
|
+
Math.abs(entry.y - point.y) <= CONTACT_EPSILON)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
unique.push(point);
|
|
81
|
+
if (unique.length === MAX_CONTACT_POINTS) {
|
|
82
|
+
return unique;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return unique;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Builds up to two box-vs-box contact points by clipping the incident edge
|
|
89
|
+
* against the side planes of the reference edge.
|
|
90
|
+
*
|
|
91
|
+
* The returned points lie on the reference face plane, which makes them
|
|
92
|
+
* suitable to use as world-space contact points in a simple impulse solver.
|
|
93
|
+
*/
|
|
94
|
+
export const buildContactPoints = (referencePolygon, referenceNormal, incidentPolygon) => {
|
|
95
|
+
const referenceEdge = getMostParallelEdge(referencePolygon, referenceNormal);
|
|
96
|
+
const incidentEdge = getMostAntiParallelEdge(incidentPolygon, referenceNormal);
|
|
97
|
+
const tangent = new Vector2(referenceEdge.point2.x - referenceEdge.point1.x, referenceEdge.point2.y - referenceEdge.point1.y);
|
|
98
|
+
tangent.normalize();
|
|
99
|
+
const minTangentOffset = VectorOps.dotProduct(referenceEdge.point1, tangent);
|
|
100
|
+
const maxTangentOffset = VectorOps.dotProduct(referenceEdge.point2, tangent);
|
|
101
|
+
let clippedPoints = [incidentEdge.point1, incidentEdge.point2];
|
|
102
|
+
clippedPoints = clipSegmentToLine(clippedPoints, tangent, maxTangentOffset);
|
|
103
|
+
if (clippedPoints.length === 0) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
if (clippedPoints.length === 2) {
|
|
107
|
+
tangent.multiplyNumber(-1);
|
|
108
|
+
clippedPoints = clipSegmentToLine(clippedPoints, tangent, -minTangentOffset);
|
|
109
|
+
if (clippedPoints.length === 0) {
|
|
110
|
+
return [];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const frontOffset = VectorOps.dotProduct(referenceEdge.point1, referenceNormal);
|
|
114
|
+
const contacts = [];
|
|
115
|
+
clippedPoints.forEach((point) => {
|
|
116
|
+
const separation = VectorOps.dotProduct(point, referenceNormal) - frontOffset;
|
|
117
|
+
if (separation > CONTACT_EPSILON) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
contacts.push({
|
|
121
|
+
x: point.x - referenceNormal.x * separation,
|
|
122
|
+
y: point.y - referenceNormal.y * separation,
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
return dedupePoints(contacts);
|
|
126
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks box and circle colliders for intersection.
|
|
4
|
+
*
|
|
5
|
+
* The closest point on the box is used as the world-space contact point.
|
|
6
|
+
* For circles inside the box, the nearest face normal is used as the
|
|
7
|
+
* collision direction and penetration is measured to that face.
|
|
8
|
+
*/
|
|
9
|
+
export declare const checkBoxAndCircleIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { MathOps, Vector2, VectorOps, } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { orientNormal, INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
const buildNormal = (circle, closestEdge, closestPoint) => {
|
|
4
|
+
let normal = new Vector2(circle.center.x - closestPoint.x, circle.center.y - closestPoint.y);
|
|
5
|
+
if (normal.magnitude === 0) {
|
|
6
|
+
normal = closestEdge.normal.clone();
|
|
7
|
+
}
|
|
8
|
+
return normal.normalize();
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Checks box and circle colliders for intersection.
|
|
12
|
+
*
|
|
13
|
+
* The closest point on the box is used as the world-space contact point.
|
|
14
|
+
* For circles inside the box, the nearest face normal is used as the
|
|
15
|
+
* collision direction and penetration is measured to that face.
|
|
16
|
+
*/
|
|
17
|
+
export const checkBoxAndCircleIntersection = (arg1, arg2) => {
|
|
18
|
+
const isBoxFirst = 'radius' in arg2.geometry;
|
|
19
|
+
const box = (isBoxFirst ? arg1.geometry : arg2.geometry);
|
|
20
|
+
const circle = (isBoxFirst ? arg2.geometry : arg1.geometry);
|
|
21
|
+
let closestEdge = box.edges[0];
|
|
22
|
+
let closestPoint = box.points[0];
|
|
23
|
+
let minDistance = Infinity;
|
|
24
|
+
box.edges.forEach((edge) => {
|
|
25
|
+
const candidate = VectorOps.getClosestPointOnEdge(circle.center, edge);
|
|
26
|
+
const distance = MathOps.getDistanceBetweenTwoPoints(candidate.x, circle.center.x, candidate.y, circle.center.y);
|
|
27
|
+
if (distance < minDistance) {
|
|
28
|
+
minDistance = distance;
|
|
29
|
+
closestEdge = edge;
|
|
30
|
+
closestPoint = candidate;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const isCircleInsideBox = VectorOps.isPointInPolygon(circle.center, box.edges);
|
|
34
|
+
if (!isCircleInsideBox &&
|
|
35
|
+
minDistance > circle.radius + INTERSECTION_EPSILON) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
const penetration = isCircleInsideBox
|
|
39
|
+
? circle.radius + minDistance
|
|
40
|
+
: Math.max(0, circle.radius - minDistance);
|
|
41
|
+
return {
|
|
42
|
+
normal: orientNormal(buildNormal(circle, closestEdge, closestPoint), arg1.geometry.center, arg2.geometry.center),
|
|
43
|
+
penetration,
|
|
44
|
+
contactPoints: [closestPoint],
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a box against a segment.
|
|
4
|
+
*
|
|
5
|
+
* SAT is used with the box face normals plus the segment normal to determine
|
|
6
|
+
* whether the finite segment overlaps the convex box. Contact points are then
|
|
7
|
+
* collected from segment endpoints inside the box, box vertices lying on the
|
|
8
|
+
* segment, and explicit edge/segment intersections.
|
|
9
|
+
*/
|
|
10
|
+
export declare const checkBoxAndSegmentIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { buildBoxSegmentContactPoints, findMinBoxSegmentOverlap } from './utils';
|
|
2
|
+
import { orientNormal } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks a box against a segment.
|
|
5
|
+
*
|
|
6
|
+
* SAT is used with the box face normals plus the segment normal to determine
|
|
7
|
+
* whether the finite segment overlaps the convex box. Contact points are then
|
|
8
|
+
* collected from segment endpoints inside the box, box vertices lying on the
|
|
9
|
+
* segment, and explicit edge/segment intersections.
|
|
10
|
+
*/
|
|
11
|
+
export const checkBoxAndSegmentIntersection = (arg1, arg2) => {
|
|
12
|
+
const isBoxFirst = 'edges' in arg1.geometry;
|
|
13
|
+
const box = (isBoxFirst ? arg1.geometry : arg2.geometry);
|
|
14
|
+
const segment = (isBoxFirst ? arg2.geometry : arg1.geometry);
|
|
15
|
+
const overlap = findMinBoxSegmentOverlap(box, segment);
|
|
16
|
+
if (overlap === false) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const contactPoints = buildBoxSegmentContactPoints(box, segment);
|
|
20
|
+
if (contactPoints.length === 0) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
normal: orientNormal(overlap.axis.clone(), arg1.geometry.center, arg2.geometry.center),
|
|
25
|
+
penetration: overlap.overlap,
|
|
26
|
+
contactPoints,
|
|
27
|
+
};
|
|
28
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Vector2 } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import type { BoxGeometry, Point, SegmentGeometry } from '../../types';
|
|
3
|
+
export declare const lerpPoint: (point1: Point, point2: Point, value: number) => Point;
|
|
4
|
+
export declare const findMinBoxSegmentOverlap: (box: BoxGeometry, segment: SegmentGeometry) => {
|
|
5
|
+
axis: Vector2;
|
|
6
|
+
overlap: number;
|
|
7
|
+
} | false;
|
|
8
|
+
/**
|
|
9
|
+
* Clips the segment against each box edge's inward half-space.
|
|
10
|
+
*
|
|
11
|
+
* The segment is treated parametrically, with `t = 0` at `point1` and
|
|
12
|
+
* `t = 1` at `point2`. Each box edge can only shrink that valid `[start, end]`
|
|
13
|
+
* interval. After all four edges are processed, the surviving interval is:
|
|
14
|
+
* - empty: no intersection
|
|
15
|
+
* - a single `t`: one touching point
|
|
16
|
+
* - a finite interval: the overlapping subsegment inside the box
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
export declare const buildBoxSegmentContactPoints: (box: BoxGeometry, segment: SegmentGeometry) => Point[];
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { MathOps, VectorOps, } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { INTERSECTION_EPSILON, projectPolygon } from '../utils';
|
|
3
|
+
const arePointsEqual = (point1, point2) => Math.abs(point1.x - point2.x) <= INTERSECTION_EPSILON &&
|
|
4
|
+
Math.abs(point1.y - point2.y) <= INTERSECTION_EPSILON;
|
|
5
|
+
export const lerpPoint = (point1, point2, value) => ({
|
|
6
|
+
x: point1.x + (point2.x - point1.x) * value,
|
|
7
|
+
y: point1.y + (point2.y - point1.y) * value,
|
|
8
|
+
});
|
|
9
|
+
export const findMinBoxSegmentOverlap = (box, segment) => {
|
|
10
|
+
const axes = [...box.edges.map((edge) => edge.normal), segment.normal];
|
|
11
|
+
let minOverlap = Infinity;
|
|
12
|
+
let bestAxis = axes[0];
|
|
13
|
+
for (const axis of axes) {
|
|
14
|
+
const boxProjection = projectPolygon(box.points, axis);
|
|
15
|
+
const segmentProjection = projectPolygon([segment.point1, segment.point2], axis);
|
|
16
|
+
const distance1 = segmentProjection.min - boxProjection.max;
|
|
17
|
+
const distance2 = boxProjection.min - segmentProjection.max;
|
|
18
|
+
if (distance1 > INTERSECTION_EPSILON || distance2 > INTERSECTION_EPSILON) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
const overlap = Math.min(Math.abs(distance1), Math.abs(distance2));
|
|
22
|
+
if (overlap < minOverlap) {
|
|
23
|
+
minOverlap = overlap;
|
|
24
|
+
bestAxis = axis;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
axis: bestAxis,
|
|
29
|
+
overlap: minOverlap,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Clips the segment against each box edge's inward half-space.
|
|
34
|
+
*
|
|
35
|
+
* The segment is treated parametrically, with `t = 0` at `point1` and
|
|
36
|
+
* `t = 1` at `point2`. Each box edge can only shrink that valid `[start, end]`
|
|
37
|
+
* interval. After all four edges are processed, the surviving interval is:
|
|
38
|
+
* - empty: no intersection
|
|
39
|
+
* - a single `t`: one touching point
|
|
40
|
+
* - a finite interval: the overlapping subsegment inside the box
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
43
|
+
export const buildBoxSegmentContactPoints = (box, segment) => {
|
|
44
|
+
let start = 0;
|
|
45
|
+
let end = 1;
|
|
46
|
+
for (const edge of box.edges) {
|
|
47
|
+
const offset = VectorOps.dotProduct(edge.point1, edge.normal);
|
|
48
|
+
const point1Distance = VectorOps.dotProduct(segment.point1, edge.normal) - offset;
|
|
49
|
+
const point2Distance = VectorOps.dotProduct(segment.point2, edge.normal) - offset;
|
|
50
|
+
if (point1Distance > INTERSECTION_EPSILON &&
|
|
51
|
+
point2Distance > INTERSECTION_EPSILON) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
if (point1Distance <= INTERSECTION_EPSILON &&
|
|
55
|
+
point2Distance <= INTERSECTION_EPSILON) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const denominator = point1Distance - point2Distance;
|
|
59
|
+
const t = denominator === 0 ? 0 : point1Distance / denominator;
|
|
60
|
+
if (point1Distance > INTERSECTION_EPSILON) {
|
|
61
|
+
start = Math.max(start, t);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
end = Math.min(end, t);
|
|
65
|
+
}
|
|
66
|
+
if (start > end + INTERSECTION_EPSILON) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const contact1 = lerpPoint(segment.point1, segment.point2, MathOps.clamp(start, 0, 1));
|
|
71
|
+
if (Math.abs(end - start) <= INTERSECTION_EPSILON) {
|
|
72
|
+
return [contact1];
|
|
73
|
+
}
|
|
74
|
+
const contact2 = lerpPoint(segment.point1, segment.point2, MathOps.clamp(end, 0, 1));
|
|
75
|
+
return arePointsEqual(contact1, contact2) ? [contact1] : [contact1, contact2];
|
|
76
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks circles for intersection.
|
|
4
|
+
*
|
|
5
|
+
* The manifold is straightforward:
|
|
6
|
+
* - the normal follows the line between circle centers
|
|
7
|
+
* - penetration is the overlap of the radii along that line
|
|
8
|
+
* - the contact point lies on the surface of the first circle
|
|
9
|
+
*
|
|
10
|
+
* When both centers are equal, the X axis is used as a deterministic fallback.
|
|
11
|
+
*/
|
|
12
|
+
export declare const checkCirclesIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Vector2 } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks circles for intersection.
|
|
5
|
+
*
|
|
6
|
+
* The manifold is straightforward:
|
|
7
|
+
* - the normal follows the line between circle centers
|
|
8
|
+
* - penetration is the overlap of the radii along that line
|
|
9
|
+
* - the contact point lies on the surface of the first circle
|
|
10
|
+
*
|
|
11
|
+
* When both centers are equal, the X axis is used as a deterministic fallback.
|
|
12
|
+
*/
|
|
13
|
+
export const checkCirclesIntersection = (arg1, arg2) => {
|
|
14
|
+
const { radius: radius1, center: { x: x1, y: y1 }, } = arg1.geometry;
|
|
15
|
+
const { radius: radius2, center: { x: x2, y: y2 }, } = arg2.geometry;
|
|
16
|
+
const offsetX = x2 - x1;
|
|
17
|
+
const offsetY = y2 - y1;
|
|
18
|
+
const distance = Math.sqrt(offsetX ** 2 + offsetY ** 2);
|
|
19
|
+
if (distance > radius1 + radius2 + INTERSECTION_EPSILON) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const penetration = Math.max(0, radius1 + radius2 - distance);
|
|
23
|
+
if (distance === 0) {
|
|
24
|
+
return {
|
|
25
|
+
normal: new Vector2(1, 0),
|
|
26
|
+
penetration,
|
|
27
|
+
contactPoints: [
|
|
28
|
+
{
|
|
29
|
+
x: x1 + radius1,
|
|
30
|
+
y: y1,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const normal = new Vector2(offsetX, offsetY);
|
|
36
|
+
normal.normalize();
|
|
37
|
+
return {
|
|
38
|
+
normal,
|
|
39
|
+
penetration,
|
|
40
|
+
contactPoints: [
|
|
41
|
+
{
|
|
42
|
+
x: x1 + normal.x * radius1,
|
|
43
|
+
y: y1 + normal.y * radius1,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a circle against a segment.
|
|
4
|
+
*
|
|
5
|
+
* The circle center is projected onto the finite segment. When the distance
|
|
6
|
+
* from that closest point to the center is within the circle radius, the
|
|
7
|
+
* projected point becomes the contact point and the normal points away from
|
|
8
|
+
* the segment toward the circle center.
|
|
9
|
+
*/
|
|
10
|
+
export declare const checkCircleAndSegmentIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { MathOps, Vector2, VectorOps, } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { orientNormal, INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks a circle against a segment.
|
|
5
|
+
*
|
|
6
|
+
* The circle center is projected onto the finite segment. When the distance
|
|
7
|
+
* from that closest point to the center is within the circle radius, the
|
|
8
|
+
* projected point becomes the contact point and the normal points away from
|
|
9
|
+
* the segment toward the circle center.
|
|
10
|
+
*/
|
|
11
|
+
export const checkCircleAndSegmentIntersection = (arg1, arg2) => {
|
|
12
|
+
const isSegmentFirst = 'point1' in arg1.geometry;
|
|
13
|
+
const segment = (isSegmentFirst ? arg1.geometry : arg2.geometry);
|
|
14
|
+
const circle = (isSegmentFirst ? arg2.geometry : arg1.geometry);
|
|
15
|
+
const closestPoint = VectorOps.getClosestPointOnEdge(circle.center, segment);
|
|
16
|
+
const distance = MathOps.getDistanceBetweenTwoPoints(circle.center.x, closestPoint.x, circle.center.y, closestPoint.y);
|
|
17
|
+
if (distance > circle.radius + INTERSECTION_EPSILON) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const normal = new Vector2(circle.center.x - closestPoint.x, circle.center.y - closestPoint.y);
|
|
21
|
+
if (normal.magnitude === 0) {
|
|
22
|
+
normal.x = segment.normal.x;
|
|
23
|
+
normal.y = segment.normal.y;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
normal.normalize();
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
normal: orientNormal(normal, arg1.geometry.center, arg2.geometry.center),
|
|
30
|
+
penetration: Math.max(0, circle.radius - distance),
|
|
31
|
+
contactPoints: [closestPoint],
|
|
32
|
+
};
|
|
33
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type CheckIntersectionFn = (arg1:
|
|
1
|
+
import type { Proxy, Intersection } from '../types';
|
|
2
|
+
export type CheckIntersectionFn = (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
3
3
|
export declare const intersectionCheckers: Record<string, Record<string, CheckIntersectionFn>>;
|
|
@@ -1,13 +1,37 @@
|
|
|
1
|
-
import { checkBoxAndCircleIntersection } from './check-box-and-circle-intersection';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { checkBoxAndCircleIntersection } from './box-circle/check-box-and-circle-intersection';
|
|
2
|
+
import { checkBoxAndSegmentIntersection } from './box-segment/check-box-and-segment-intersection';
|
|
3
|
+
import { checkBoxesIntersection } from './box-box/check-boxes-intersection';
|
|
4
|
+
import { checkCirclesIntersection } from './circle-circle/check-circles-intersection';
|
|
5
|
+
import { checkCircleAndSegmentIntersection } from './circle-segment/check-circle-and-segment-intersection';
|
|
6
|
+
import { checkPointAndBoxIntersection } from './point-box/check-point-and-box-intersection';
|
|
7
|
+
import { checkPointAndCircleIntersection } from './point-circle/check-point-and-circle-intersection';
|
|
8
|
+
import { checkPointAndSegmentIntersection } from './point-segment/check-point-and-segment-intersection';
|
|
9
|
+
import { checkRayAndBoxIntersection } from './ray-box/check-ray-and-box-intersection';
|
|
10
|
+
import { checkRayAndCircleIntersection } from './ray-circle/check-ray-and-circle-intersection';
|
|
11
|
+
import { checkRayAndSegmentIntersection } from './ray-segment/check-ray-and-segment-intersection';
|
|
4
12
|
export const intersectionCheckers = {
|
|
5
13
|
box: {
|
|
6
14
|
box: checkBoxesIntersection,
|
|
7
15
|
circle: checkBoxAndCircleIntersection,
|
|
16
|
+
segment: checkBoxAndSegmentIntersection,
|
|
8
17
|
},
|
|
9
18
|
circle: {
|
|
10
19
|
circle: checkCirclesIntersection,
|
|
11
20
|
box: checkBoxAndCircleIntersection,
|
|
21
|
+
segment: checkCircleAndSegmentIntersection,
|
|
22
|
+
},
|
|
23
|
+
segment: {
|
|
24
|
+
box: checkBoxAndSegmentIntersection,
|
|
25
|
+
circle: checkCircleAndSegmentIntersection,
|
|
26
|
+
},
|
|
27
|
+
point: {
|
|
28
|
+
box: checkPointAndBoxIntersection,
|
|
29
|
+
circle: checkPointAndCircleIntersection,
|
|
30
|
+
segment: checkPointAndSegmentIntersection,
|
|
31
|
+
},
|
|
32
|
+
ray: {
|
|
33
|
+
box: checkRayAndBoxIntersection,
|
|
34
|
+
circle: checkRayAndCircleIntersection,
|
|
35
|
+
segment: checkRayAndSegmentIntersection,
|
|
12
36
|
},
|
|
13
37
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks point and box colliders for intersection.
|
|
4
|
+
*
|
|
5
|
+
* The manifold uses the nearest point on the box boundary as the contact.
|
|
6
|
+
* For points inside the box, penetration is the distance to the nearest edge.
|
|
7
|
+
* When the point lies exactly on the boundary, penetration is reported as zero.
|
|
8
|
+
*/
|
|
9
|
+
export declare const checkPointAndBoxIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { VectorOps } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { orientNormal, INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks point and box colliders for intersection.
|
|
5
|
+
*
|
|
6
|
+
* The manifold uses the nearest point on the box boundary as the contact.
|
|
7
|
+
* For points inside the box, penetration is the distance to the nearest edge.
|
|
8
|
+
* When the point lies exactly on the boundary, penetration is reported as zero.
|
|
9
|
+
*/
|
|
10
|
+
export const checkPointAndBoxIntersection = (arg1, arg2) => {
|
|
11
|
+
const isBoxFirst = 'edges' in arg1.geometry;
|
|
12
|
+
const box = (isBoxFirst ? arg1.geometry : arg2.geometry);
|
|
13
|
+
const point = (isBoxFirst ? arg2.geometry : arg1.geometry);
|
|
14
|
+
let bestEdge = box.edges[0];
|
|
15
|
+
let bestSignedDistance = -Infinity;
|
|
16
|
+
for (const edge of box.edges) {
|
|
17
|
+
const signedDistance = VectorOps.dotProduct({
|
|
18
|
+
x: point.center.x - edge.point1.x,
|
|
19
|
+
y: point.center.y - edge.point1.y,
|
|
20
|
+
}, edge.normal);
|
|
21
|
+
if (signedDistance > INTERSECTION_EPSILON) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
if (signedDistance > bestSignedDistance) {
|
|
25
|
+
bestSignedDistance = signedDistance;
|
|
26
|
+
bestEdge = edge;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const contactPoint = VectorOps.getClosestPointOnEdge(point.center, bestEdge);
|
|
30
|
+
const isPointOnBoxBoundary = Math.abs(bestSignedDistance) <= INTERSECTION_EPSILON;
|
|
31
|
+
return {
|
|
32
|
+
normal: orientNormal(bestEdge.normal.clone(), arg1.geometry.center, arg2.geometry.center),
|
|
33
|
+
penetration: isPointOnBoxBoundary ? 0 : -bestSignedDistance,
|
|
34
|
+
contactPoints: [contactPoint],
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks point and circle colliders for intersection.
|
|
4
|
+
*
|
|
5
|
+
* The manifold uses the nearest point on the circle boundary as the contact.
|
|
6
|
+
* When the point lies at the circle center, the X axis is used as a
|
|
7
|
+
* deterministic fallback.
|
|
8
|
+
*/
|
|
9
|
+
export declare const checkPointAndCircleIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Vector2 } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { orientNormal, INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks point and circle colliders for intersection.
|
|
5
|
+
*
|
|
6
|
+
* The manifold uses the nearest point on the circle boundary as the contact.
|
|
7
|
+
* When the point lies at the circle center, the X axis is used as a
|
|
8
|
+
* deterministic fallback.
|
|
9
|
+
*/
|
|
10
|
+
export const checkPointAndCircleIntersection = (arg1, arg2) => {
|
|
11
|
+
const isCircleFirst = 'radius' in arg1.geometry;
|
|
12
|
+
const circle = (isCircleFirst ? arg1.geometry : arg2.geometry);
|
|
13
|
+
const point = (isCircleFirst ? arg2.geometry : arg1.geometry);
|
|
14
|
+
const offsetX = point.center.x - circle.center.x;
|
|
15
|
+
const offsetY = point.center.y - circle.center.y;
|
|
16
|
+
const distance = Math.sqrt(offsetX ** 2 + offsetY ** 2);
|
|
17
|
+
if (distance > circle.radius + INTERSECTION_EPSILON) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const normal = distance === 0
|
|
21
|
+
? new Vector2(1, 0)
|
|
22
|
+
: new Vector2(offsetX, offsetY).normalize();
|
|
23
|
+
return {
|
|
24
|
+
normal: orientNormal(normal, arg1.geometry.center, arg2.geometry.center),
|
|
25
|
+
penetration: Math.max(0, circle.radius - distance),
|
|
26
|
+
contactPoints: [
|
|
27
|
+
{
|
|
28
|
+
x: circle.center.x + normal.x * circle.radius,
|
|
29
|
+
y: circle.center.y + normal.y * circle.radius,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether a query point lies on a segment.
|
|
4
|
+
*
|
|
5
|
+
* The closest point on the finite segment is projected from the point.
|
|
6
|
+
* If the projected distance is near zero, that projected point becomes
|
|
7
|
+
* the contact point and the stored segment normal is used for orientation.
|
|
8
|
+
*/
|
|
9
|
+
export declare const checkPointAndSegmentIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MathOps, Vector2, VectorOps, } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { orientNormal, INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks whether a query point lies on a segment.
|
|
5
|
+
*
|
|
6
|
+
* The closest point on the finite segment is projected from the point.
|
|
7
|
+
* If the projected distance is near zero, that projected point becomes
|
|
8
|
+
* the contact point and the stored segment normal is used for orientation.
|
|
9
|
+
*/
|
|
10
|
+
export const checkPointAndSegmentIntersection = (arg1, arg2) => {
|
|
11
|
+
const isSegmentFirst = 'point1' in arg1.geometry;
|
|
12
|
+
const segment = (isSegmentFirst ? arg1.geometry : arg2.geometry);
|
|
13
|
+
const point = (isSegmentFirst ? arg2.geometry : arg1.geometry);
|
|
14
|
+
const closestPoint = VectorOps.getClosestPointOnEdge(point.center, segment);
|
|
15
|
+
const distance = MathOps.getDistanceBetweenTwoPoints(point.center.x, closestPoint.x, point.center.y, closestPoint.y);
|
|
16
|
+
if (distance > INTERSECTION_EPSILON) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
normal: orientNormal(segment.normal.magnitude === 0
|
|
21
|
+
? new Vector2(1, 0)
|
|
22
|
+
: segment.normal.clone(), arg1.geometry.center, arg2.geometry.center),
|
|
23
|
+
penetration: 0,
|
|
24
|
+
contactPoints: [closestPoint],
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a ray against a convex box using half-space clipping.
|
|
4
|
+
*
|
|
5
|
+
* The intersection interval is clipped against each box face.
|
|
6
|
+
* - `tEnter` tracks the first point where the ray enters the box
|
|
7
|
+
* - `tExit` tracks the first point where the ray leaves the box
|
|
8
|
+
*
|
|
9
|
+
* When the ray starts inside the box, the first hit is the exit point.
|
|
10
|
+
*/
|
|
11
|
+
export declare const checkRayAndBoxIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|