@flighthq/collision 0.1.0
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/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/manifold.d.ts +4 -0
- package/dist/manifold.d.ts.map +1 -0
- package/dist/manifold.js +14 -0
- package/dist/manifold.js.map +1 -0
- package/dist/pointContainment.d.ts +3 -0
- package/dist/pointContainment.d.ts.map +1 -0
- package/dist/pointContainment.js +71 -0
- package/dist/pointContainment.js.map +1 -0
- package/dist/segmentCollision.d.ts +7 -0
- package/dist/segmentCollision.d.ts.map +1 -0
- package/dist/segmentCollision.js +161 -0
- package/dist/segmentCollision.js.map +1 -0
- package/dist/shapeCollision.d.ts +12 -0
- package/dist/shapeCollision.d.ts.map +1 -0
- package/dist/shapeCollision.js +441 -0
- package/dist/shapeCollision.js.map +1 -0
- package/dist/testCollision.d.ts +3 -0
- package/dist/testCollision.d.ts.map +1 -0
- package/dist/testCollision.js +90 -0
- package/dist/testCollision.js.map +1 -0
- package/package.json +38 -0
- package/src/manifold.test.ts +31 -0
- package/src/pointContainment.test.ts +56 -0
- package/src/segmentCollision.test.ts +108 -0
- package/src/shapeCollision.test.ts +329 -0
- package/src/testCollision.test.ts +60 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { createVector2, normalizeVector2 } from '@flighthq/geometry';
|
|
2
|
+
import { clearCollisionManifold } from './manifold';
|
|
3
|
+
// The 2D narrow-phase pair tests. Each writes an `out` CollisionManifold and returns whether the
|
|
4
|
+
// pair overlaps. On overlap the manifold normal is the unit minimum-translation axis oriented to
|
|
5
|
+
// push shape **A** (the first argument) out of **B**, with `depth` the penetration along it; on a
|
|
6
|
+
// miss the manifold is cleared. Touching (zero penetration) counts as **not** overlapping.
|
|
7
|
+
//
|
|
8
|
+
// AABB/OBB/convex-polygon pairs route through a single separating-axis (SAT) core over materialized
|
|
9
|
+
// vertex lists; circle pairs are special-cased with closest-point / radial math (SAT does not model
|
|
10
|
+
// a circle's infinite axis set). The hot path allocates nothing: box vertices are written into
|
|
11
|
+
// module-level scratch buffers and the manifold is written last, after all inputs are read.
|
|
12
|
+
//
|
|
13
|
+
// Polygons are assumed convex; `points` is a flat `[x0,y0,...]` list. Winding does not matter — the
|
|
14
|
+
// core orients the manifold by comparing shape centroids.
|
|
15
|
+
const EPS = 1e-9;
|
|
16
|
+
// Axis-aligned box vs axis-aligned box. Direct min-overlap test (no SAT needed): the only candidate
|
|
17
|
+
// separating axes are X and Y, and the manifold uses whichever has the smaller penetration.
|
|
18
|
+
export function testAabbAabbCollision(a, b, out) {
|
|
19
|
+
const aMinX = a.minX;
|
|
20
|
+
const aMinY = a.minY;
|
|
21
|
+
const aMaxX = a.maxX;
|
|
22
|
+
const aMaxY = a.maxY;
|
|
23
|
+
const bMinX = b.minX;
|
|
24
|
+
const bMinY = b.minY;
|
|
25
|
+
const bMaxX = b.maxX;
|
|
26
|
+
const bMaxY = b.maxY;
|
|
27
|
+
// Penetration = the smaller of the two ways to separate along each axis (handles containment,
|
|
28
|
+
// where the intersection length would understate the distance needed to push the boxes apart).
|
|
29
|
+
const penLeftX = aMaxX - bMinX;
|
|
30
|
+
const penRightX = bMaxX - aMinX;
|
|
31
|
+
const overlapX = penLeftX < penRightX ? penLeftX : penRightX;
|
|
32
|
+
const penDownY = aMaxY - bMinY;
|
|
33
|
+
const penUpY = bMaxY - aMinY;
|
|
34
|
+
const overlapY = penDownY < penUpY ? penDownY : penUpY;
|
|
35
|
+
if (overlapX <= 0 || overlapY <= 0) {
|
|
36
|
+
clearCollisionManifold(out);
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (overlapX < overlapY) {
|
|
40
|
+
out.normalX = penLeftX < penRightX ? -1 : 1;
|
|
41
|
+
out.normalY = 0;
|
|
42
|
+
out.depth = overlapX;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
out.normalX = 0;
|
|
46
|
+
out.normalY = penDownY < penUpY ? -1 : 1;
|
|
47
|
+
out.depth = overlapY;
|
|
48
|
+
}
|
|
49
|
+
out.overlapping = true;
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
// Axis-aligned box vs oriented box (SAT over both boxes' four corners).
|
|
53
|
+
export function testAabbObbCollision(a, b, out) {
|
|
54
|
+
writeAabbVertices(a, scratchA);
|
|
55
|
+
writeObbVertices(b, scratchB);
|
|
56
|
+
return satConvexOverlap(scratchA, 4, scratchB, 4, out);
|
|
57
|
+
}
|
|
58
|
+
// Axis-aligned box vs convex polygon (SAT).
|
|
59
|
+
export function testAabbPolygonCollision(a, b, out) {
|
|
60
|
+
writeAabbVertices(a, scratchA);
|
|
61
|
+
const bPoints = b.points;
|
|
62
|
+
return satConvexOverlap(scratchA, 4, bPoints, bPoints.length >> 1, out);
|
|
63
|
+
}
|
|
64
|
+
// Circle vs axis-aligned box. Closest-point when the center is outside the box; nearest-face
|
|
65
|
+
// push-out when the center is inside it.
|
|
66
|
+
export function testCircleAabbCollision(a, b, out) {
|
|
67
|
+
return circleAabbOverlap(a.x, a.y, a.radius, b.minX, b.minY, b.maxX, b.maxY, out);
|
|
68
|
+
}
|
|
69
|
+
// Circle vs circle. Radial: overlapping when the centers are closer than the radius sum; the normal
|
|
70
|
+
// points from B's center to A's center. Concentric centers fall back to a +X normal at full depth.
|
|
71
|
+
export function testCircleCircleCollision(a, b, out) {
|
|
72
|
+
const ax = a.x;
|
|
73
|
+
const ay = a.y;
|
|
74
|
+
const bx = b.x;
|
|
75
|
+
const by = b.y;
|
|
76
|
+
const radiusSum = a.radius + b.radius;
|
|
77
|
+
const dx = ax - bx;
|
|
78
|
+
const dy = ay - by;
|
|
79
|
+
const distSquared = dx * dx + dy * dy;
|
|
80
|
+
if (distSquared >= radiusSum * radiusSum) {
|
|
81
|
+
clearCollisionManifold(out);
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
const dist = Math.sqrt(distSquared);
|
|
85
|
+
if (dist > EPS) {
|
|
86
|
+
const inv = 1 / dist;
|
|
87
|
+
out.normalX = dx * inv;
|
|
88
|
+
out.normalY = dy * inv;
|
|
89
|
+
out.depth = radiusSum - dist;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
out.normalX = 1;
|
|
93
|
+
out.normalY = 0;
|
|
94
|
+
out.depth = radiusSum;
|
|
95
|
+
}
|
|
96
|
+
out.overlapping = true;
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// Circle vs oriented box. The circle center is transformed into the box's local frame, tested as
|
|
100
|
+
// circle-vs-AABB there, then the resulting normal is rotated back into world space.
|
|
101
|
+
export function testCircleObbCollision(a, b, out) {
|
|
102
|
+
const cx = a.x;
|
|
103
|
+
const cy = a.y;
|
|
104
|
+
const radius = a.radius;
|
|
105
|
+
const halfW = b.halfW;
|
|
106
|
+
const halfH = b.halfH;
|
|
107
|
+
const cos = Math.cos(b.rotation);
|
|
108
|
+
const sin = Math.sin(b.rotation);
|
|
109
|
+
const dx = cx - b.x;
|
|
110
|
+
const dy = cy - b.y;
|
|
111
|
+
const localX = dx * cos + dy * sin;
|
|
112
|
+
const localY = -dx * sin + dy * cos;
|
|
113
|
+
if (!circleAabbOverlap(localX, localY, radius, -halfW, -halfH, halfW, halfH, out)) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const localNormalX = out.normalX;
|
|
117
|
+
const localNormalY = out.normalY;
|
|
118
|
+
out.normalX = localNormalX * cos - localNormalY * sin;
|
|
119
|
+
out.normalY = localNormalX * sin + localNormalY * cos;
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
// Circle vs convex polygon (SAT: polygon edge normals plus the axis from the circle center to its
|
|
123
|
+
// nearest polygon vertex, the axis SAT would otherwise miss at a corner).
|
|
124
|
+
export function testCirclePolygonCollision(a, b, out) {
|
|
125
|
+
const points = b.points;
|
|
126
|
+
return satCircleConvexOverlap(a.x, a.y, a.radius, points, points.length >> 1, out);
|
|
127
|
+
}
|
|
128
|
+
// Oriented box vs oriented box (SAT over both boxes' four corners).
|
|
129
|
+
export function testObbObbCollision(a, b, out) {
|
|
130
|
+
writeObbVertices(a, scratchA);
|
|
131
|
+
writeObbVertices(b, scratchB);
|
|
132
|
+
return satConvexOverlap(scratchA, 4, scratchB, 4, out);
|
|
133
|
+
}
|
|
134
|
+
// Oriented box vs convex polygon (SAT).
|
|
135
|
+
export function testObbPolygonCollision(a, b, out) {
|
|
136
|
+
writeObbVertices(a, scratchA);
|
|
137
|
+
const bPoints = b.points;
|
|
138
|
+
return satConvexOverlap(scratchA, 4, bPoints, bPoints.length >> 1, out);
|
|
139
|
+
}
|
|
140
|
+
// Convex polygon vs convex polygon (SAT — the general convex core).
|
|
141
|
+
export function testPolygonPolygonCollision(a, b, out) {
|
|
142
|
+
const aPoints = a.points;
|
|
143
|
+
const bPoints = b.points;
|
|
144
|
+
return satConvexOverlap(aPoints, aPoints.length >> 1, bPoints, bPoints.length >> 1, out);
|
|
145
|
+
}
|
|
146
|
+
// Circle (`cx`,`cy`,`radius`) vs axis-aligned box given as min/max. Writes the manifold pushing the
|
|
147
|
+
// circle out of the box. Shared by the circle-AABB and circle-OBB (local-frame) entry points.
|
|
148
|
+
function circleAabbOverlap(cx, cy, radius, minX, minY, maxX, maxY, out) {
|
|
149
|
+
const closestX = cx < minX ? minX : cx > maxX ? maxX : cx;
|
|
150
|
+
const closestY = cy < minY ? minY : cy > maxY ? maxY : cy;
|
|
151
|
+
const dx = cx - closestX;
|
|
152
|
+
const dy = cy - closestY;
|
|
153
|
+
const distSquared = dx * dx + dy * dy;
|
|
154
|
+
if (distSquared > EPS * EPS) {
|
|
155
|
+
// Center outside the box: separate along the closest-point direction.
|
|
156
|
+
const dist = Math.sqrt(distSquared);
|
|
157
|
+
if (dist >= radius) {
|
|
158
|
+
clearCollisionManifold(out);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const inv = 1 / dist;
|
|
162
|
+
out.normalX = dx * inv;
|
|
163
|
+
out.normalY = dy * inv;
|
|
164
|
+
out.depth = radius - dist;
|
|
165
|
+
out.overlapping = true;
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
// Center inside the box: push out through the nearest face.
|
|
169
|
+
const left = cx - minX;
|
|
170
|
+
const right = maxX - cx;
|
|
171
|
+
const bottom = cy - minY;
|
|
172
|
+
const top = maxY - cy;
|
|
173
|
+
let min = left;
|
|
174
|
+
let normalX = -1;
|
|
175
|
+
let normalY = 0;
|
|
176
|
+
if (right < min) {
|
|
177
|
+
min = right;
|
|
178
|
+
normalX = 1;
|
|
179
|
+
normalY = 0;
|
|
180
|
+
}
|
|
181
|
+
if (bottom < min) {
|
|
182
|
+
min = bottom;
|
|
183
|
+
normalX = 0;
|
|
184
|
+
normalY = -1;
|
|
185
|
+
}
|
|
186
|
+
if (top < min) {
|
|
187
|
+
min = top;
|
|
188
|
+
normalX = 0;
|
|
189
|
+
normalY = 1;
|
|
190
|
+
}
|
|
191
|
+
out.normalX = normalX;
|
|
192
|
+
out.normalY = normalY;
|
|
193
|
+
out.depth = min + radius;
|
|
194
|
+
out.overlapping = true;
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
// SAT for a circle vs a convex polygon. Tests every polygon edge normal plus the center-to-nearest-
|
|
198
|
+
// vertex axis, tracking the least-penetration axis. Orients the normal from the polygon toward the
|
|
199
|
+
// circle so it pushes the circle out.
|
|
200
|
+
function satCircleConvexOverlap(cx, cy, radius, px, pn, out) {
|
|
201
|
+
let minOverlap = Infinity;
|
|
202
|
+
let normalX = 0;
|
|
203
|
+
let normalY = 0;
|
|
204
|
+
for (let i = 0; i < pn; i++) {
|
|
205
|
+
const j = (i + 1) % pn;
|
|
206
|
+
const x0 = px[i << 1];
|
|
207
|
+
const y0 = px[(i << 1) + 1];
|
|
208
|
+
const x1 = px[j << 1];
|
|
209
|
+
const y1 = px[(j << 1) + 1];
|
|
210
|
+
scratchAxis.x = y1 - y0;
|
|
211
|
+
scratchAxis.y = -(x1 - x0);
|
|
212
|
+
const len = normalizeVector2(scratchAxis, scratchAxis);
|
|
213
|
+
if (len < EPS)
|
|
214
|
+
continue;
|
|
215
|
+
const axisX = scratchAxis.x;
|
|
216
|
+
const axisY = scratchAxis.y;
|
|
217
|
+
const overlap = circlePolygonAxisOverlap(axisX, axisY, cx, cy, radius, px, pn);
|
|
218
|
+
if (overlap <= 0) {
|
|
219
|
+
clearCollisionManifold(out);
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
if (overlap < minOverlap) {
|
|
223
|
+
minOverlap = overlap;
|
|
224
|
+
normalX = axisX;
|
|
225
|
+
normalY = axisY;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Center-to-nearest-vertex axis (the corner case a pure edge-normal test misses).
|
|
229
|
+
let nearestX = 0;
|
|
230
|
+
let nearestY = 0;
|
|
231
|
+
let nearestDistSquared = Infinity;
|
|
232
|
+
for (let i = 0; i < pn; i++) {
|
|
233
|
+
const vx = px[i << 1];
|
|
234
|
+
const vy = px[(i << 1) + 1];
|
|
235
|
+
const ddx = cx - vx;
|
|
236
|
+
const ddy = cy - vy;
|
|
237
|
+
const d2 = ddx * ddx + ddy * ddy;
|
|
238
|
+
if (d2 < nearestDistSquared) {
|
|
239
|
+
nearestDistSquared = d2;
|
|
240
|
+
nearestX = vx;
|
|
241
|
+
nearestY = vy;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
scratchAxis.x = cx - nearestX;
|
|
245
|
+
scratchAxis.y = cy - nearestY;
|
|
246
|
+
const vertexAxisLen = normalizeVector2(scratchAxis, scratchAxis);
|
|
247
|
+
if (vertexAxisLen > EPS) {
|
|
248
|
+
const axisX = scratchAxis.x;
|
|
249
|
+
const axisY = scratchAxis.y;
|
|
250
|
+
const overlap = circlePolygonAxisOverlap(axisX, axisY, cx, cy, radius, px, pn);
|
|
251
|
+
if (overlap <= 0) {
|
|
252
|
+
clearCollisionManifold(out);
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
if (overlap < minOverlap) {
|
|
256
|
+
minOverlap = overlap;
|
|
257
|
+
normalX = axisX;
|
|
258
|
+
normalY = axisY;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
if (minOverlap === Infinity) {
|
|
262
|
+
clearCollisionManifold(out);
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
let centroidX = 0;
|
|
266
|
+
let centroidY = 0;
|
|
267
|
+
for (let i = 0; i < pn; i++) {
|
|
268
|
+
centroidX += px[i << 1];
|
|
269
|
+
centroidY += px[(i << 1) + 1];
|
|
270
|
+
}
|
|
271
|
+
centroidX /= pn;
|
|
272
|
+
centroidY /= pn;
|
|
273
|
+
if (normalX * (cx - centroidX) + normalY * (cy - centroidY) < 0) {
|
|
274
|
+
normalX = -normalX;
|
|
275
|
+
normalY = -normalY;
|
|
276
|
+
}
|
|
277
|
+
out.normalX = normalX;
|
|
278
|
+
out.normalY = normalY;
|
|
279
|
+
out.depth = minOverlap;
|
|
280
|
+
out.overlapping = true;
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
// Penetration of a circle and a polygon along one unit axis, or a non-positive value if they are
|
|
284
|
+
// separated (or merely touching) on it.
|
|
285
|
+
function circlePolygonAxisOverlap(axisX, axisY, cx, cy, radius, px, pn) {
|
|
286
|
+
let minP = Infinity;
|
|
287
|
+
let maxP = -Infinity;
|
|
288
|
+
for (let i = 0; i < pn; i++) {
|
|
289
|
+
const d = px[i << 1] * axisX + px[(i << 1) + 1] * axisY;
|
|
290
|
+
if (d < minP)
|
|
291
|
+
minP = d;
|
|
292
|
+
if (d > maxP)
|
|
293
|
+
maxP = d;
|
|
294
|
+
}
|
|
295
|
+
const c = cx * axisX + cy * axisY;
|
|
296
|
+
const cMin = c - radius;
|
|
297
|
+
const cMax = c + radius;
|
|
298
|
+
// Separation penetration (min of the two push directions), not the intersection length.
|
|
299
|
+
const penLow = maxP - cMin;
|
|
300
|
+
const penHigh = cMax - minP;
|
|
301
|
+
return penLow < penHigh ? penLow : penHigh;
|
|
302
|
+
}
|
|
303
|
+
// SAT for two convex polygons given as flat vertex lists. Tests each polygon's edge normals,
|
|
304
|
+
// tracking the least-penetration separating axis, and orients the normal to push A out of B.
|
|
305
|
+
function satConvexOverlap(ax, an, bx, bn, out) {
|
|
306
|
+
minOverlapAxis.overlap = Infinity;
|
|
307
|
+
minOverlapAxis.x = 0;
|
|
308
|
+
minOverlapAxis.y = 0;
|
|
309
|
+
if (!accumulatePolygonAxes(ax, an, ax, an, bx, bn, out))
|
|
310
|
+
return false;
|
|
311
|
+
if (!accumulatePolygonAxes(bx, bn, ax, an, bx, bn, out))
|
|
312
|
+
return false;
|
|
313
|
+
if (minOverlapAxis.overlap === Infinity) {
|
|
314
|
+
clearCollisionManifold(out);
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
let aCentroidX = 0;
|
|
318
|
+
let aCentroidY = 0;
|
|
319
|
+
for (let i = 0; i < an; i++) {
|
|
320
|
+
aCentroidX += ax[i << 1];
|
|
321
|
+
aCentroidY += ax[(i << 1) + 1];
|
|
322
|
+
}
|
|
323
|
+
aCentroidX /= an;
|
|
324
|
+
aCentroidY /= an;
|
|
325
|
+
let bCentroidX = 0;
|
|
326
|
+
let bCentroidY = 0;
|
|
327
|
+
for (let i = 0; i < bn; i++) {
|
|
328
|
+
bCentroidX += bx[i << 1];
|
|
329
|
+
bCentroidY += bx[(i << 1) + 1];
|
|
330
|
+
}
|
|
331
|
+
bCentroidX /= bn;
|
|
332
|
+
bCentroidY /= bn;
|
|
333
|
+
let normalX = minOverlapAxis.x;
|
|
334
|
+
let normalY = minOverlapAxis.y;
|
|
335
|
+
if (normalX * (aCentroidX - bCentroidX) + normalY * (aCentroidY - bCentroidY) < 0) {
|
|
336
|
+
normalX = -normalX;
|
|
337
|
+
normalY = -normalY;
|
|
338
|
+
}
|
|
339
|
+
out.normalX = normalX;
|
|
340
|
+
out.normalY = normalY;
|
|
341
|
+
out.depth = minOverlapAxis.overlap;
|
|
342
|
+
out.overlapping = true;
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
// Tests every edge normal of the source polygon (`sx`,`sn`) as a separating axis for the pair
|
|
346
|
+
// (`ax`/`bx`), updating the tracked least-penetration axis. Returns false (and clears `out`) as soon
|
|
347
|
+
// as a separating axis with no positive overlap is found.
|
|
348
|
+
function accumulatePolygonAxes(sx, sn, ax, an, bx, bn, out) {
|
|
349
|
+
for (let i = 0; i < sn; i++) {
|
|
350
|
+
const j = (i + 1) % sn;
|
|
351
|
+
const x0 = sx[i << 1];
|
|
352
|
+
const y0 = sx[(i << 1) + 1];
|
|
353
|
+
const x1 = sx[j << 1];
|
|
354
|
+
const y1 = sx[(j << 1) + 1];
|
|
355
|
+
scratchAxis.x = y1 - y0;
|
|
356
|
+
scratchAxis.y = -(x1 - x0);
|
|
357
|
+
const len = normalizeVector2(scratchAxis, scratchAxis);
|
|
358
|
+
if (len < EPS)
|
|
359
|
+
continue;
|
|
360
|
+
const axisX = scratchAxis.x;
|
|
361
|
+
const axisY = scratchAxis.y;
|
|
362
|
+
const overlap = polygonAxisOverlap(axisX, axisY, ax, an, bx, bn);
|
|
363
|
+
if (overlap <= 0) {
|
|
364
|
+
clearCollisionManifold(out);
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
if (overlap < minOverlapAxis.overlap) {
|
|
368
|
+
minOverlapAxis.overlap = overlap;
|
|
369
|
+
minOverlapAxis.x = axisX;
|
|
370
|
+
minOverlapAxis.y = axisY;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return true;
|
|
374
|
+
}
|
|
375
|
+
// Penetration of two polygons' projections onto one unit axis, or a non-positive value if they are
|
|
376
|
+
// separated (or merely touching) on it.
|
|
377
|
+
function polygonAxisOverlap(axisX, axisY, ax, an, bx, bn) {
|
|
378
|
+
let minA = Infinity;
|
|
379
|
+
let maxA = -Infinity;
|
|
380
|
+
for (let i = 0; i < an; i++) {
|
|
381
|
+
const d = ax[i << 1] * axisX + ax[(i << 1) + 1] * axisY;
|
|
382
|
+
if (d < minA)
|
|
383
|
+
minA = d;
|
|
384
|
+
if (d > maxA)
|
|
385
|
+
maxA = d;
|
|
386
|
+
}
|
|
387
|
+
let minB = Infinity;
|
|
388
|
+
let maxB = -Infinity;
|
|
389
|
+
for (let i = 0; i < bn; i++) {
|
|
390
|
+
const d = bx[i << 1] * axisX + bx[(i << 1) + 1] * axisY;
|
|
391
|
+
if (d < minB)
|
|
392
|
+
minB = d;
|
|
393
|
+
if (d > maxB)
|
|
394
|
+
maxB = d;
|
|
395
|
+
}
|
|
396
|
+
// Separation penetration (min of the two push directions), not the intersection length.
|
|
397
|
+
const penLow = maxA - minB;
|
|
398
|
+
const penHigh = maxB - minA;
|
|
399
|
+
return penLow < penHigh ? penLow : penHigh;
|
|
400
|
+
}
|
|
401
|
+
// Writes the four corners of an axis-aligned box into `out` as a flat `[x0,y0,...]` list.
|
|
402
|
+
function writeAabbVertices(aabb, out) {
|
|
403
|
+
const minX = aabb.minX;
|
|
404
|
+
const minY = aabb.minY;
|
|
405
|
+
const maxX = aabb.maxX;
|
|
406
|
+
const maxY = aabb.maxY;
|
|
407
|
+
out[0] = minX;
|
|
408
|
+
out[1] = minY;
|
|
409
|
+
out[2] = maxX;
|
|
410
|
+
out[3] = minY;
|
|
411
|
+
out[4] = maxX;
|
|
412
|
+
out[5] = maxY;
|
|
413
|
+
out[6] = minX;
|
|
414
|
+
out[7] = maxY;
|
|
415
|
+
}
|
|
416
|
+
// Writes the four world-space corners of an oriented box into `out` as a flat `[x0,y0,...]` list.
|
|
417
|
+
function writeObbVertices(obb, out) {
|
|
418
|
+
const cx = obb.x;
|
|
419
|
+
const cy = obb.y;
|
|
420
|
+
const halfW = obb.halfW;
|
|
421
|
+
const halfH = obb.halfH;
|
|
422
|
+
const cos = Math.cos(obb.rotation);
|
|
423
|
+
const sin = Math.sin(obb.rotation);
|
|
424
|
+
const wx = cos * halfW;
|
|
425
|
+
const wy = sin * halfW;
|
|
426
|
+
const hx = -sin * halfH;
|
|
427
|
+
const hy = cos * halfH;
|
|
428
|
+
out[0] = cx - wx - hx;
|
|
429
|
+
out[1] = cy - wy - hy;
|
|
430
|
+
out[2] = cx + wx - hx;
|
|
431
|
+
out[3] = cy + wy - hy;
|
|
432
|
+
out[4] = cx + wx + hx;
|
|
433
|
+
out[5] = cy + wy + hy;
|
|
434
|
+
out[6] = cx - wx + hx;
|
|
435
|
+
out[7] = cy - wy + hy;
|
|
436
|
+
}
|
|
437
|
+
const scratchA = new Float64Array(8);
|
|
438
|
+
const scratchB = new Float64Array(8);
|
|
439
|
+
const scratchAxis = createVector2();
|
|
440
|
+
const minOverlapAxis = { overlap: Infinity, x: 0, y: 0 };
|
|
441
|
+
//# sourceMappingURL=shapeCollision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shapeCollision.js","sourceRoot":"","sources":["../src/shapeCollision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testCollision.d.ts","sourceRoot":"","sources":["../src/testCollision.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAsB,MAAM,iBAAiB,CAAC;AAuB7F,wBAAgB,aAAa,CAC3B,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC3B,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,EAC3B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAiET"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { clearCollisionManifold } from './manifold';
|
|
2
|
+
import { testAabbAabbCollision, testAabbObbCollision, testAabbPolygonCollision, testCircleAabbCollision, testCircleCircleCollision, testCircleObbCollision, testCirclePolygonCollision, testObbObbCollision, testObbPolygonCollision, testPolygonPolygonCollision, } from './shapeCollision';
|
|
3
|
+
// Generic narrow-phase test: dispatches on the two shapes' `kind`s to the matching per-pair test and
|
|
4
|
+
// writes the manifold pushing **A out of B**. Shapes are canonically ordered by kind rank before
|
|
5
|
+
// dispatch so only the ten manifold-bearing pairs (circle/aabb/obb/polygon) need explicit branches;
|
|
6
|
+
// when the arguments arrive in the reversed order the shared normal is negated to preserve the
|
|
7
|
+
// A-out-of-B orientation. Area-less kinds (`segment`, `point`) and unknown kinds carry no manifold —
|
|
8
|
+
// the pair is reported as non-overlapping; use `getCollisionShapeContainsPoint` or the
|
|
9
|
+
// `testSegment*Collision` queries for those. The direct per-pair functions remain the hot path.
|
|
10
|
+
export function testCollision(a, b, out) {
|
|
11
|
+
const rankA = shapeKindRank(a.kind);
|
|
12
|
+
const rankB = shapeKindRank(b.kind);
|
|
13
|
+
if (rankA < 0 || rankB < 0) {
|
|
14
|
+
clearCollisionManifold(out);
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const swapped = rankA > rankB;
|
|
18
|
+
const lo = swapped ? b : a;
|
|
19
|
+
const hi = swapped ? a : b;
|
|
20
|
+
let overlapping = false;
|
|
21
|
+
switch (lo.kind) {
|
|
22
|
+
case 'circle':
|
|
23
|
+
switch (hi.kind) {
|
|
24
|
+
case 'circle':
|
|
25
|
+
overlapping = testCircleCircleCollision(lo, hi, out);
|
|
26
|
+
break;
|
|
27
|
+
case 'aabb':
|
|
28
|
+
overlapping = testCircleAabbCollision(lo, hi, out);
|
|
29
|
+
break;
|
|
30
|
+
case 'obb':
|
|
31
|
+
overlapping = testCircleObbCollision(lo, hi, out);
|
|
32
|
+
break;
|
|
33
|
+
case 'polygon':
|
|
34
|
+
overlapping = testCirclePolygonCollision(lo, hi, out);
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
case 'aabb':
|
|
39
|
+
switch (hi.kind) {
|
|
40
|
+
case 'aabb':
|
|
41
|
+
overlapping = testAabbAabbCollision(lo, hi, out);
|
|
42
|
+
break;
|
|
43
|
+
case 'obb':
|
|
44
|
+
overlapping = testAabbObbCollision(lo, hi, out);
|
|
45
|
+
break;
|
|
46
|
+
case 'polygon':
|
|
47
|
+
overlapping = testAabbPolygonCollision(lo, hi, out);
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
break;
|
|
51
|
+
case 'obb':
|
|
52
|
+
switch (hi.kind) {
|
|
53
|
+
case 'obb':
|
|
54
|
+
overlapping = testObbObbCollision(lo, hi, out);
|
|
55
|
+
break;
|
|
56
|
+
case 'polygon':
|
|
57
|
+
overlapping = testObbPolygonCollision(lo, hi, out);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
case 'polygon':
|
|
62
|
+
if (hi.kind === 'polygon') {
|
|
63
|
+
overlapping = testPolygonPolygonCollision(lo, hi, out);
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
if (overlapping && swapped) {
|
|
68
|
+
out.normalX = -out.normalX;
|
|
69
|
+
out.normalY = -out.normalY;
|
|
70
|
+
}
|
|
71
|
+
return overlapping;
|
|
72
|
+
}
|
|
73
|
+
// Canonical dispatch rank of a shape kind, or -1 for kinds that carry no manifold (segment, point,
|
|
74
|
+
// and any custom kind). Ordering the pair by rank collapses the 4x4 kind matrix to its ten lower-
|
|
75
|
+
// triangular manifold pairs.
|
|
76
|
+
function shapeKindRank(kind) {
|
|
77
|
+
switch (kind) {
|
|
78
|
+
case 'circle':
|
|
79
|
+
return 0;
|
|
80
|
+
case 'aabb':
|
|
81
|
+
return 1;
|
|
82
|
+
case 'obb':
|
|
83
|
+
return 2;
|
|
84
|
+
case 'polygon':
|
|
85
|
+
return 3;
|
|
86
|
+
default:
|
|
87
|
+
return -1;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=testCollision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testCollision.js","sourceRoot":"","sources":["../src/testCollision.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flighthq/collision",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"src/**/*.test.ts",
|
|
16
|
+
"!dist/**/*.test.js",
|
|
17
|
+
"!dist/**/*.test.d.ts",
|
|
18
|
+
"!dist/**/*.test.js.map",
|
|
19
|
+
"!dist/**/*.test.d.ts.map"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -b",
|
|
23
|
+
"clean": "tsc -b --clean",
|
|
24
|
+
"test": "vitest run --config vitest.config.ts",
|
|
25
|
+
"test:watch": "vitest --watch --config vitest.config.ts",
|
|
26
|
+
"prepack": "npm run clean && npm run clean:dist && npm run build",
|
|
27
|
+
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@flighthq/geometry": "0.1.0",
|
|
31
|
+
"@flighthq/types": "0.1.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"typescript": "^5.3.0"
|
|
35
|
+
},
|
|
36
|
+
"description": "2D narrow-phase collision — discrete shape-vs-shape overlap returning a contact manifold (minimum-translation normal + depth), plus point/segment queries",
|
|
37
|
+
"sideEffects": false
|
|
38
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { clearCollisionManifold, createCollisionManifold } from './manifold';
|
|
4
|
+
|
|
5
|
+
describe('clearCollisionManifold', () => {
|
|
6
|
+
it('resets every field to the non-overlapping state', () => {
|
|
7
|
+
const manifold = { overlapping: true, normalX: 0.5, normalY: -0.5, depth: 3 };
|
|
8
|
+
clearCollisionManifold(manifold);
|
|
9
|
+
expect(manifold.overlapping).toBe(false);
|
|
10
|
+
expect(manifold.normalX).toBe(0);
|
|
11
|
+
expect(manifold.normalY).toBe(0);
|
|
12
|
+
expect(manifold.depth).toBe(0);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
describe('createCollisionManifold', () => {
|
|
17
|
+
it('allocates a fresh manifold in the non-overlapping state', () => {
|
|
18
|
+
const manifold = createCollisionManifold();
|
|
19
|
+
expect(manifold.overlapping).toBe(false);
|
|
20
|
+
expect(manifold.normalX).toBe(0);
|
|
21
|
+
expect(manifold.normalY).toBe(0);
|
|
22
|
+
expect(manifold.depth).toBe(0);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('returns an independent object each call', () => {
|
|
26
|
+
const a = createCollisionManifold();
|
|
27
|
+
const b = createCollisionManifold();
|
|
28
|
+
a.overlapping = true;
|
|
29
|
+
expect(b.overlapping).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
});
|