@flighthq/physics2d 0.3.0-edge.1458.0c01b63
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/colliderTransform.d.ts +10 -0
- package/dist/colliderTransform.d.ts.map +1 -0
- package/dist/colliderTransform.js +137 -0
- package/dist/colliderTransform.js.map +1 -0
- package/dist/contract.d.ts +9 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +9 -0
- package/dist/contract.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/islands.d.ts +38 -0
- package/dist/islands.d.ts.map +1 -0
- package/dist/islands.js +159 -0
- package/dist/islands.js.map +1 -0
- package/dist/jointRegistry.d.ts +6 -0
- package/dist/jointRegistry.d.ts.map +1 -0
- package/dist/jointRegistry.js +78 -0
- package/dist/jointRegistry.js.map +1 -0
- package/dist/joints.d.ts +39 -0
- package/dist/joints.d.ts.map +1 -0
- package/dist/joints.js +561 -0
- package/dist/joints.js.map +1 -0
- package/dist/massProperties.d.ts +4 -0
- package/dist/massProperties.d.ts.map +1 -0
- package/dist/massProperties.js +146 -0
- package/dist/massProperties.js.map +1 -0
- package/dist/solver.d.ts +7 -0
- package/dist/solver.d.ts.map +1 -0
- package/dist/solver.js +129 -0
- package/dist/solver.js.map +1 -0
- package/dist/step.d.ts +3 -0
- package/dist/step.d.ts.map +1 -0
- package/dist/step.js +414 -0
- package/dist/step.js.map +1 -0
- package/dist/world.d.ts +10 -0
- package/dist/world.d.ts.map +1 -0
- package/dist/world.js +133 -0
- package/dist/world.js.map +1 -0
- package/package.json +49 -0
- package/src/colliderTransform.test.ts +115 -0
- package/src/islands.test.ts +262 -0
- package/src/jointRegistry.test.ts +205 -0
- package/src/joints.test.ts +951 -0
- package/src/massProperties.test.ts +169 -0
- package/src/solver.test.ts +186 -0
- package/src/step.test.ts +745 -0
- package/src/world.test.ts +142 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
// Mass properties are DERIVED from collider geometry and density, never assigned. A body whose mass
|
|
2
|
+
// was set independently of its shape can be given a rotational inertia that contradicts its outline —
|
|
3
|
+
// a long plank that spins like a marble — and nothing in the solver can detect the inconsistency,
|
|
4
|
+
// because both numbers are individually plausible. Deriving both from one source makes that
|
|
5
|
+
// unrepresentable.
|
|
6
|
+
// Writes `collider`'s mass, rotational inertia, and centroid into `out`, in the body's local space.
|
|
7
|
+
//
|
|
8
|
+
// The inertia is about the collider's OWN centroid, not the body origin; combining colliders shifts it
|
|
9
|
+
// with the parallel-axis theorem. Area-less shapes (segment, point) and unrecognised kinds carry no
|
|
10
|
+
// mass: they are legitimate as sensors and triggers, so they zero the entry rather than faulting.
|
|
11
|
+
export function computePhysics2DColliderMassData(collider, out) {
|
|
12
|
+
const shape = collider.local;
|
|
13
|
+
const density = collider.material.density;
|
|
14
|
+
switch (shape.kind) {
|
|
15
|
+
case 'circle': {
|
|
16
|
+
const area = Math.PI * shape.radius * shape.radius;
|
|
17
|
+
out.mass = area * density;
|
|
18
|
+
// A disc's second moment about its centre: ½·m·r².
|
|
19
|
+
out.inertia = 0.5 * out.mass * shape.radius * shape.radius;
|
|
20
|
+
out.centerX = shape.x;
|
|
21
|
+
out.centerY = shape.y;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
case 'aabb': {
|
|
25
|
+
const width = shape.maxX - shape.minX;
|
|
26
|
+
const height = shape.maxY - shape.minY;
|
|
27
|
+
out.mass = width * height * density;
|
|
28
|
+
out.inertia = (out.mass * (width * width + height * height)) / 12;
|
|
29
|
+
out.centerX = (shape.minX + shape.maxX) / 2;
|
|
30
|
+
out.centerY = (shape.minY + shape.maxY) / 2;
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
case 'obb': {
|
|
34
|
+
const width = shape.halfW * 2;
|
|
35
|
+
const height = shape.halfH * 2;
|
|
36
|
+
out.mass = width * height * density;
|
|
37
|
+
// Rotation about the z axis does not change a rectangle's second moment about its own centre,
|
|
38
|
+
// so an oriented box uses the same expression as an axis-aligned one.
|
|
39
|
+
out.inertia = (out.mass * (width * width + height * height)) / 12;
|
|
40
|
+
out.centerX = shape.x;
|
|
41
|
+
out.centerY = shape.y;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
case 'polygon':
|
|
45
|
+
writePolygonMassData(shape.points, density, out);
|
|
46
|
+
return;
|
|
47
|
+
default:
|
|
48
|
+
out.mass = 0;
|
|
49
|
+
out.inertia = 0;
|
|
50
|
+
out.centerX = 0;
|
|
51
|
+
out.centerY = 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Recomputes `body`'s mass, rotational inertia, centre of mass, and the inverses the solver divides
|
|
55
|
+
// by, from its colliders. Call after adding, removing, or reshaping a collider, or after changing a
|
|
56
|
+
// material's density.
|
|
57
|
+
//
|
|
58
|
+
// Static and kinematic bodies keep their computed centre — the lever arms in a contact are measured
|
|
59
|
+
// from it either way — but take zero inverse mass and inverse inertia. Zero is not a guard here, it is
|
|
60
|
+
// the arithmetic: an impulse scaled by an inverse mass of zero moves the body not at all, so
|
|
61
|
+
// "infinite mass" needs no branch anywhere in the solver. A dynamic body with no area gets the same
|
|
62
|
+
// treatment, since dividing by its zero mass is what would otherwise produce NaN velocities that
|
|
63
|
+
// spread to everything it touches.
|
|
64
|
+
export function updateRigidBody2DMassData(body) {
|
|
65
|
+
let mass = 0;
|
|
66
|
+
let weightedX = 0;
|
|
67
|
+
let weightedY = 0;
|
|
68
|
+
for (const collider of body.colliders) {
|
|
69
|
+
computePhysics2DColliderMassData(collider, scratch);
|
|
70
|
+
mass += scratch.mass;
|
|
71
|
+
weightedX += scratch.centerX * scratch.mass;
|
|
72
|
+
weightedY += scratch.centerY * scratch.mass;
|
|
73
|
+
}
|
|
74
|
+
if (mass > 0) {
|
|
75
|
+
body.centerX = weightedX / mass;
|
|
76
|
+
body.centerY = weightedY / mass;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
body.centerX = 0;
|
|
80
|
+
body.centerY = 0;
|
|
81
|
+
}
|
|
82
|
+
// Second pass: each collider's inertia is about its own centroid, so shift every one to the body's
|
|
83
|
+
// combined centre before summing (parallel-axis theorem). This cannot fold into the loop above,
|
|
84
|
+
// because the centre it shifts to is not known until every collider has been weighed.
|
|
85
|
+
let inertia = 0;
|
|
86
|
+
for (const collider of body.colliders) {
|
|
87
|
+
computePhysics2DColliderMassData(collider, scratch);
|
|
88
|
+
const offsetX = scratch.centerX - body.centerX;
|
|
89
|
+
const offsetY = scratch.centerY - body.centerY;
|
|
90
|
+
inertia += scratch.inertia + scratch.mass * (offsetX * offsetX + offsetY * offsetY);
|
|
91
|
+
}
|
|
92
|
+
const simulated = body.type === 'dynamic';
|
|
93
|
+
body.mass = simulated ? mass : 0;
|
|
94
|
+
body.inertia = simulated ? inertia : 0;
|
|
95
|
+
body.inverseMass = simulated && mass > 0 ? 1 / mass : 0;
|
|
96
|
+
body.inverseInertia = simulated && inertia > 0 ? 1 / inertia : 0;
|
|
97
|
+
}
|
|
98
|
+
// Centroid and second moment of a simple polygon, accumulated per triangle fanned from the origin.
|
|
99
|
+
// Each triangle's signed area weights its contribution, so the winding cancels correctly on concave
|
|
100
|
+
// spans and the total comes out positive for either winding direction.
|
|
101
|
+
function writePolygonMassData(points, density, out) {
|
|
102
|
+
const count = points.length >> 1;
|
|
103
|
+
if (count < 3) {
|
|
104
|
+
out.mass = 0;
|
|
105
|
+
out.inertia = 0;
|
|
106
|
+
out.centerX = 0;
|
|
107
|
+
out.centerY = 0;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
let area = 0;
|
|
111
|
+
let centroidX = 0;
|
|
112
|
+
let centroidY = 0;
|
|
113
|
+
let moment = 0;
|
|
114
|
+
for (let i = 0; i < count; i++) {
|
|
115
|
+
const j = (i + 1) % count;
|
|
116
|
+
const x0 = points[i * 2];
|
|
117
|
+
const y0 = points[i * 2 + 1];
|
|
118
|
+
const x1 = points[j * 2];
|
|
119
|
+
const y1 = points[j * 2 + 1];
|
|
120
|
+
const cross = x0 * y1 - x1 * y0;
|
|
121
|
+
area += cross;
|
|
122
|
+
centroidX += (x0 + x1) * cross;
|
|
123
|
+
centroidY += (y0 + y1) * cross;
|
|
124
|
+
moment += cross * (x0 * x0 + x0 * x1 + x1 * x1 + y0 * y0 + y0 * y1 + y1 * y1);
|
|
125
|
+
}
|
|
126
|
+
area *= 0.5;
|
|
127
|
+
// A zero-area polygon — every vertex collinear or coincident — would divide the centroid by zero.
|
|
128
|
+
// It is degenerate rather than malformed, so it weighs nothing, exactly like a segment.
|
|
129
|
+
if (area === 0) {
|
|
130
|
+
out.mass = 0;
|
|
131
|
+
out.inertia = 0;
|
|
132
|
+
out.centerX = 0;
|
|
133
|
+
out.centerY = 0;
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const absoluteArea = Math.abs(area);
|
|
137
|
+
out.mass = absoluteArea * density;
|
|
138
|
+
out.centerX = centroidX / (6 * area);
|
|
139
|
+
out.centerY = centroidY / (6 * area);
|
|
140
|
+
// Shift the origin-relative second moment onto the centroid.
|
|
141
|
+
const originMoment = (Math.abs(moment) / 12) * density;
|
|
142
|
+
const offsetSquared = out.centerX * out.centerX + out.centerY * out.centerY;
|
|
143
|
+
out.inertia = originMoment - out.mass * offsetSquared;
|
|
144
|
+
}
|
|
145
|
+
const scratch = { mass: 0, inertia: 0, centerX: 0, centerY: 0 };
|
|
146
|
+
//# sourceMappingURL=massProperties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"massProperties.js","sourceRoot":"","sources":["../src/massProperties.ts"],"names":[],"mappings":"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"}
|
package/dist/solver.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Physics2DContactPoint, Physics2DWorld, RigidBody2D } from '@flighthq/types/contract';
|
|
2
|
+
export declare function applyPhysics2DImpulse(bodyA: RigidBody2D, bodyB: RigidBody2D, rAX: number, rAY: number, rBX: number, rBY: number, impulseX: number, impulseY: number): void;
|
|
3
|
+
export declare function relativeNormalVelocity(bodyA: Readonly<RigidBody2D>, bodyB: Readonly<RigidBody2D>, point: Readonly<Physics2DContactPoint>, normalX: number, normalY: number): number;
|
|
4
|
+
export declare function solvePhysics2DContacts(world: Physics2DWorld): void;
|
|
5
|
+
export declare function solvePhysics2DContactsOnce(world: Physics2DWorld): void;
|
|
6
|
+
export declare function warmStartPhysics2DContacts(world: Physics2DWorld): void;
|
|
7
|
+
//# sourceMappingURL=solver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,qBAAqB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAcrH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,IAAI,CAON;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC5B,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC5B,KAAK,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CAMR;AAyED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAGlE;AAKD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAStE;AAYD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAoBtE"}
|
package/dist/solver.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { isRigidBody2DPairAwake } from './islands';
|
|
2
|
+
import { findPhysics2DBody } from './world';
|
|
3
|
+
// Applies equal and opposite impulses at the pair's contact point. The angular term is the lever arm
|
|
4
|
+
// crossed with the impulse — the reason an off-centre contact spins a body instead of only shoving it.
|
|
5
|
+
// A static body's zero inverse mass and inverse inertia make both of its updates no-ops without a branch.
|
|
6
|
+
//
|
|
7
|
+
// A POSITIVE impulse pushes A along the contact normal and B against it, because `@flighthq/collision`
|
|
8
|
+
// documents its manifold normal as the direction that separates **A out of B**. That is the opposite of
|
|
9
|
+
// the A-to-B convention most sequential-impulse literature is written in, and getting it backwards does
|
|
10
|
+
// not look like a sign error — it looks like gravity working, since the solver then drives bodies
|
|
11
|
+
// together and a resting box settles below the floor instead of on it.
|
|
12
|
+
export function applyPhysics2DImpulse(bodyA, bodyB, rAX, rAY, rBX, rBY, impulseX, impulseY) {
|
|
13
|
+
bodyA.velocityX += impulseX * bodyA.inverseMass;
|
|
14
|
+
bodyA.velocityY += impulseY * bodyA.inverseMass;
|
|
15
|
+
bodyA.angularVelocity += bodyA.inverseInertia * (rAX * impulseY - rAY * impulseX);
|
|
16
|
+
bodyB.velocityX -= impulseX * bodyB.inverseMass;
|
|
17
|
+
bodyB.velocityY -= impulseY * bodyB.inverseMass;
|
|
18
|
+
bodyB.angularVelocity -= bodyB.inverseInertia * (rBX * impulseY - rBY * impulseX);
|
|
19
|
+
}
|
|
20
|
+
export function relativeNormalVelocity(bodyA, bodyB, point, normalX, normalY) {
|
|
21
|
+
const vax = bodyA.velocityX - bodyA.angularVelocity * point.rAY;
|
|
22
|
+
const vay = bodyA.velocityY + bodyA.angularVelocity * point.rAX;
|
|
23
|
+
const vbx = bodyB.velocityX - bodyB.angularVelocity * point.rBY;
|
|
24
|
+
const vby = bodyB.velocityY + bodyB.angularVelocity * point.rBX;
|
|
25
|
+
return (vax - vbx) * normalX + (vay - vby) * normalY;
|
|
26
|
+
}
|
|
27
|
+
// One contact's velocity constraint: friction first, then the normal.
|
|
28
|
+
//
|
|
29
|
+
// Friction is solved BEFORE the normal on each pass, and the order is deliberate. The friction bound is
|
|
30
|
+
// Coulomb's — the tangential impulse cannot exceed the normal impulse times the coefficient — so it needs
|
|
31
|
+
// a normal impulse to bound against. Using the value the previous iteration converged on is standard and
|
|
32
|
+
// stable; using the one this iteration is about to produce would make the bound depend on a number that
|
|
33
|
+
// does not exist yet.
|
|
34
|
+
function solvePhysics2DContact(contact, bodyA, bodyB) {
|
|
35
|
+
const normalX = contact.normalX;
|
|
36
|
+
const normalY = contact.normalY;
|
|
37
|
+
const tangentX = -normalY;
|
|
38
|
+
const tangentY = normalX;
|
|
39
|
+
for (let i = 0; i < contact.pointCount; i++) {
|
|
40
|
+
const point = contact.points[i];
|
|
41
|
+
const tangentVelocity = relativeAxisVelocity(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, tangentX, tangentY);
|
|
42
|
+
let tangentImpulse = -point.tangentMass * tangentVelocity;
|
|
43
|
+
const limit = contact.friction * point.normalImpulse;
|
|
44
|
+
const clampedTangent = Math.max(-limit, Math.min(limit, point.tangentImpulse + tangentImpulse));
|
|
45
|
+
tangentImpulse = clampedTangent - point.tangentImpulse;
|
|
46
|
+
point.tangentImpulse = clampedTangent;
|
|
47
|
+
applyPhysics2DImpulse(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, tangentImpulse * tangentX, tangentImpulse * tangentY);
|
|
48
|
+
const normalVelocity = relativeNormalVelocity(bodyA, bodyB, point, normalX, normalY);
|
|
49
|
+
let normalImpulse = -point.normalMass * (normalVelocity + point.bias);
|
|
50
|
+
const clampedNormal = Math.max(0, point.normalImpulse + normalImpulse);
|
|
51
|
+
normalImpulse = clampedNormal - point.normalImpulse;
|
|
52
|
+
point.normalImpulse = clampedNormal;
|
|
53
|
+
applyPhysics2DImpulse(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, normalImpulse * normalX, normalImpulse * normalY);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// The sequential-impulse velocity solve: projected Gauss-Seidel over the contact list, `velocityIterations`
|
|
57
|
+
// times.
|
|
58
|
+
//
|
|
59
|
+
// "Sequential" is the whole method — each impulse is applied immediately, so the next constraint sees the
|
|
60
|
+
// velocities the previous one left behind. That is why the solver converges, and equally why contact
|
|
61
|
+
// ORDER changes the result: the list is sorted canonically before it gets here for exactly that reason.
|
|
62
|
+
//
|
|
63
|
+
// The accumulated impulse, not the incremental one, is what gets clamped. Clamping each increment would
|
|
64
|
+
// let a contact pull bodies together on any iteration where the incremental impulse came out negative;
|
|
65
|
+
// clamping the accumulation lets an iteration correct an earlier overshoot while keeping the total
|
|
66
|
+
// non-negative, which is the difference between a stable stack and one that vibrates.
|
|
67
|
+
export function solvePhysics2DContacts(world) {
|
|
68
|
+
const iterations = world.config.velocityIterations;
|
|
69
|
+
for (let iteration = 0; iteration < iterations; iteration++)
|
|
70
|
+
solvePhysics2DContactsOnce(world);
|
|
71
|
+
}
|
|
72
|
+
// One pass over the contact list. Split out so the step can interleave it with the joint pass inside a
|
|
73
|
+
// single iteration loop: joints and contacts constrain the same bodies, and giving either a whole pass to
|
|
74
|
+
// itself lets it undo what the other just corrected.
|
|
75
|
+
export function solvePhysics2DContactsOnce(world) {
|
|
76
|
+
for (const contact of world.contacts) {
|
|
77
|
+
if (contact.sensor)
|
|
78
|
+
continue;
|
|
79
|
+
const bodyA = findPhysics2DBody(world, contact.bodyA);
|
|
80
|
+
const bodyB = findPhysics2DBody(world, contact.bodyB);
|
|
81
|
+
if (bodyA === null || bodyB === null)
|
|
82
|
+
continue;
|
|
83
|
+
if (!isRigidBody2DPairAwake(bodyA, bodyB))
|
|
84
|
+
continue;
|
|
85
|
+
solvePhysics2DContact(contact, bodyA, bodyB);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Applies each contact's cached impulses before the first iteration — the warm start.
|
|
89
|
+
//
|
|
90
|
+
// This is what makes a stack settle rather than visibly sink. A sequential-impulse solver converges
|
|
91
|
+
// toward the correct impulse over its iterations; starting each step from zero throws away everything
|
|
92
|
+
// the previous step learned, so a tall stack never reaches equilibrium within a frame's budget and the
|
|
93
|
+
// bottom box is compressed by everything above it. Re-applying last step's converged impulse starts the
|
|
94
|
+
// iteration from an answer that was nearly right, and a handful of iterations finishes the job.
|
|
95
|
+
//
|
|
96
|
+
// The cached impulses were matched by feature id when the contact was merged, so a point that is no
|
|
97
|
+
// longer the same feature arrives here with zero rather than a stranger's force.
|
|
98
|
+
export function warmStartPhysics2DContacts(world) {
|
|
99
|
+
for (const contact of world.contacts) {
|
|
100
|
+
if (contact.sensor)
|
|
101
|
+
continue;
|
|
102
|
+
const bodyA = findPhysics2DBody(world, contact.bodyA);
|
|
103
|
+
const bodyB = findPhysics2DBody(world, contact.bodyB);
|
|
104
|
+
if (bodyA === null || bodyB === null)
|
|
105
|
+
continue;
|
|
106
|
+
if (!isRigidBody2DPairAwake(bodyA, bodyB))
|
|
107
|
+
continue;
|
|
108
|
+
const normalX = contact.normalX;
|
|
109
|
+
const normalY = contact.normalY;
|
|
110
|
+
const tangentX = -normalY;
|
|
111
|
+
const tangentY = normalX;
|
|
112
|
+
for (let i = 0; i < contact.pointCount; i++) {
|
|
113
|
+
const point = contact.points[i];
|
|
114
|
+
const impulseX = point.normalImpulse * normalX + point.tangentImpulse * tangentX;
|
|
115
|
+
const impulseY = point.normalImpulse * normalY + point.tangentImpulse * tangentY;
|
|
116
|
+
applyPhysics2DImpulse(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, impulseX, impulseY);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function relativeAxisVelocity(bodyA, bodyB, rAX, rAY, rBX, rBY, axisX, axisY) {
|
|
121
|
+
const vax = bodyA.velocityX - bodyA.angularVelocity * rAY;
|
|
122
|
+
const vay = bodyA.velocityY + bodyA.angularVelocity * rAX;
|
|
123
|
+
const vbx = bodyB.velocityX - bodyB.angularVelocity * rBY;
|
|
124
|
+
const vby = bodyB.velocityY + bodyB.angularVelocity * rBX;
|
|
125
|
+
// A's velocity relative to B, matching the normal's "separates A out of B" direction: negative means
|
|
126
|
+
// the pair is closing along that axis.
|
|
127
|
+
return (vax - vbx) * axisX + (vay - vby) * axisY;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=solver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solver.js","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"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"}
|
package/dist/step.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../src/step.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAKV,cAAc,EAIf,MAAM,0BAA0B,CAAC;AA+SlC,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAsFrE"}
|