@flighthq/physics2d 0.3.0-next.1021.f5f1ee0
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 +6 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +6 -0
- package/dist/contract.js.map +1 -0
- 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/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 +6 -0
- package/dist/solver.d.ts.map +1 -0
- package/dist/solver.js +119 -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 +268 -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 +116 -0
- package/dist/world.js.map +1 -0
- package/package.json +49 -0
- package/src/colliderTransform.test.ts +115 -0
- package/src/massProperties.test.ts +185 -0
- package/src/solver.test.ts +167 -0
- package/src/step.test.ts +236 -0
- package/src/world.test.ts +142 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CollisionShape, Physics2DCollider, RigidBody2D } from '@flighthq/types/contract';
|
|
2
|
+
export declare function createPhysics2DColliderWorldShape(local: Readonly<CollisionShape>): CollisionShape;
|
|
3
|
+
export declare function updatePhysics2DColliderWorldShape(collider: Physics2DCollider, body: Readonly<RigidBody2D>): void;
|
|
4
|
+
export declare function writePhysics2DColliderBounds(collider: Readonly<Physics2DCollider>, out: {
|
|
5
|
+
minX: number;
|
|
6
|
+
minY: number;
|
|
7
|
+
maxX: number;
|
|
8
|
+
maxY: number;
|
|
9
|
+
}): void;
|
|
10
|
+
//# sourceMappingURL=colliderTransform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colliderTransform.d.ts","sourceRoot":"","sources":["../src/colliderTransform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAK/F,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,cAAc,CAYjG;AAWD,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CA8ChH;AAMD,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EACrC,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9D,IAAI,CA2DN"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// Allocates the world-space shape a collider needs for `local`, choosing the kind the transform can
|
|
2
|
+
// actually express. Every field is filled at creation so the shape is never read half-initialised, and
|
|
3
|
+
// polygon storage is sized once here so the per-step transform can write in place.
|
|
4
|
+
export function createPhysics2DColliderWorldShape(local) {
|
|
5
|
+
switch (local.kind) {
|
|
6
|
+
case 'circle':
|
|
7
|
+
return { kind: 'circle', x: local.x, y: local.y, radius: local.radius };
|
|
8
|
+
case 'aabb':
|
|
9
|
+
case 'obb':
|
|
10
|
+
return { kind: 'obb', x: 0, y: 0, halfW: 0, halfH: 0, rotation: 0 };
|
|
11
|
+
case 'polygon':
|
|
12
|
+
return { kind: 'polygon', points: local.points.slice() };
|
|
13
|
+
default:
|
|
14
|
+
return { kind: 'point', x: 0, y: 0 };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// Rewrites `collider.world` from its local shape and the body's current transform. Called once per
|
|
18
|
+
// collider per step, before the narrow phase — never per contact test, because a body with four
|
|
19
|
+
// colliders against a hundred broadphase candidates would otherwise transform the same shape a hundred
|
|
20
|
+
// times to produce the same answer.
|
|
21
|
+
//
|
|
22
|
+
// The world shape is preallocated at collider creation and mutated in place, so a step allocates
|
|
23
|
+
// nothing. Polygon points are the only variable-length part, and the world array is sized once from the
|
|
24
|
+
// local one; a caller that reshapes a collider must rebuild it through `createPhysics2DCollider` rather
|
|
25
|
+
// than mutating `local.points` in place.
|
|
26
|
+
export function updatePhysics2DColliderWorldShape(collider, body) {
|
|
27
|
+
const local = collider.local;
|
|
28
|
+
const world = collider.world;
|
|
29
|
+
const cos = Math.cos(body.angle);
|
|
30
|
+
const sin = Math.sin(body.angle);
|
|
31
|
+
if (local.kind === 'circle' && world.kind === 'circle') {
|
|
32
|
+
world.x = body.x + local.x * cos - local.y * sin;
|
|
33
|
+
world.y = body.y + local.x * sin + local.y * cos;
|
|
34
|
+
world.radius = local.radius;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// An axis-aligned box promotes to an oriented box in world space: rotate it and it is no longer
|
|
38
|
+
// axis-aligned, and silently keeping the `aabb` kind would grow the box to its bounding extent the
|
|
39
|
+
// first time the body turned.
|
|
40
|
+
if (local.kind === 'aabb' && world.kind === 'obb') {
|
|
41
|
+
const centerX = (local.minX + local.maxX) / 2;
|
|
42
|
+
const centerY = (local.minY + local.maxY) / 2;
|
|
43
|
+
world.x = body.x + centerX * cos - centerY * sin;
|
|
44
|
+
world.y = body.y + centerX * sin + centerY * cos;
|
|
45
|
+
world.halfW = (local.maxX - local.minX) / 2;
|
|
46
|
+
world.halfH = (local.maxY - local.minY) / 2;
|
|
47
|
+
world.rotation = body.angle;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (local.kind === 'obb' && world.kind === 'obb') {
|
|
51
|
+
world.x = body.x + local.x * cos - local.y * sin;
|
|
52
|
+
world.y = body.y + local.x * sin + local.y * cos;
|
|
53
|
+
world.halfW = local.halfW;
|
|
54
|
+
world.halfH = local.halfH;
|
|
55
|
+
world.rotation = body.angle + local.rotation;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (local.kind === 'polygon' && world.kind === 'polygon') {
|
|
59
|
+
const source = local.points;
|
|
60
|
+
const target = world.points;
|
|
61
|
+
for (let i = 0; i < source.length; i += 2) {
|
|
62
|
+
const x = source[i];
|
|
63
|
+
const y = source[i + 1];
|
|
64
|
+
target[i] = body.x + x * cos - y * sin;
|
|
65
|
+
target[i + 1] = body.y + x * sin + y * cos;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Writes `collider.world`'s axis-aligned bounds into `out` — the broadphase's view of the collider.
|
|
70
|
+
// Bounds are computed from the WORLD shape rather than by transforming local bounds, because rotating
|
|
71
|
+
// an extent and rotating a shape's bounds are different boxes: the second is the bound of the first and
|
|
72
|
+
// grows without limit as the body spins.
|
|
73
|
+
export function writePhysics2DColliderBounds(collider, out) {
|
|
74
|
+
const shape = collider.world;
|
|
75
|
+
switch (shape.kind) {
|
|
76
|
+
case 'circle':
|
|
77
|
+
out.minX = shape.x - shape.radius;
|
|
78
|
+
out.minY = shape.y - shape.radius;
|
|
79
|
+
out.maxX = shape.x + shape.radius;
|
|
80
|
+
out.maxY = shape.y + shape.radius;
|
|
81
|
+
return;
|
|
82
|
+
case 'aabb':
|
|
83
|
+
out.minX = shape.minX;
|
|
84
|
+
out.minY = shape.minY;
|
|
85
|
+
out.maxX = shape.maxX;
|
|
86
|
+
out.maxY = shape.maxY;
|
|
87
|
+
return;
|
|
88
|
+
case 'obb': {
|
|
89
|
+
const cos = Math.abs(Math.cos(shape.rotation));
|
|
90
|
+
const sin = Math.abs(Math.sin(shape.rotation));
|
|
91
|
+
const extentX = shape.halfW * cos + shape.halfH * sin;
|
|
92
|
+
const extentY = shape.halfW * sin + shape.halfH * cos;
|
|
93
|
+
out.minX = shape.x - extentX;
|
|
94
|
+
out.minY = shape.y - extentY;
|
|
95
|
+
out.maxX = shape.x + extentX;
|
|
96
|
+
out.maxY = shape.y + extentY;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
case 'polygon': {
|
|
100
|
+
const points = shape.points;
|
|
101
|
+
if (points.length < 2) {
|
|
102
|
+
out.minX = 0;
|
|
103
|
+
out.minY = 0;
|
|
104
|
+
out.maxX = 0;
|
|
105
|
+
out.maxY = 0;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
let minX = points[0];
|
|
109
|
+
let minY = points[1];
|
|
110
|
+
let maxX = minX;
|
|
111
|
+
let maxY = minY;
|
|
112
|
+
for (let i = 2; i < points.length; i += 2) {
|
|
113
|
+
const x = points[i];
|
|
114
|
+
const y = points[i + 1];
|
|
115
|
+
if (x < minX)
|
|
116
|
+
minX = x;
|
|
117
|
+
else if (x > maxX)
|
|
118
|
+
maxX = x;
|
|
119
|
+
if (y < minY)
|
|
120
|
+
minY = y;
|
|
121
|
+
else if (y > maxY)
|
|
122
|
+
maxY = y;
|
|
123
|
+
}
|
|
124
|
+
out.minX = minX;
|
|
125
|
+
out.minY = minY;
|
|
126
|
+
out.maxX = maxX;
|
|
127
|
+
out.maxY = maxY;
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
default:
|
|
131
|
+
out.minX = 0;
|
|
132
|
+
out.minY = 0;
|
|
133
|
+
out.maxX = 0;
|
|
134
|
+
out.maxY = 0;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=colliderTransform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colliderTransform.js","sourceRoot":"","sources":["../src/colliderTransform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createPhysics2DColliderWorldShape, updatePhysics2DColliderWorldShape, writePhysics2DColliderBounds, } from './colliderTransform';
|
|
2
|
+
export { computePhysics2DColliderMassData, updateRigidBody2DMassData } from './massProperties';
|
|
3
|
+
export { applyPhysics2DImpulse, relativeNormalVelocity, solvePhysics2DContacts, warmStartPhysics2DContacts, } from './solver';
|
|
4
|
+
export { stepPhysics2D } from './step';
|
|
5
|
+
export { addPhysics2DBody, findPhysics2DBody, createPhysics2DCollider, createPhysics2DSolverConfig, createPhysics2DWorld, createRigidBody2D, isPhysics2DPairOrdered, removePhysics2DBody, } from './world';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { createPhysics2DColliderWorldShape, updatePhysics2DColliderWorldShape, writePhysics2DColliderBounds, } from './colliderTransform';
|
|
2
|
+
export { computePhysics2DColliderMassData, updateRigidBody2DMassData } from './massProperties';
|
|
3
|
+
export { applyPhysics2DImpulse, relativeNormalVelocity, solvePhysics2DContacts, warmStartPhysics2DContacts, } from './solver';
|
|
4
|
+
export { stepPhysics2D } from './step';
|
|
5
|
+
export { addPhysics2DBody, findPhysics2DBody, createPhysics2DCollider, createPhysics2DSolverConfig, createPhysics2DWorld, createRigidBody2D, isPhysics2DPairOrdered, removePhysics2DBody, } from './world';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,EACjC,iCAAiC,EACjC,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Physics2DCollider, Physics2DMassData, RigidBody2D } from '@flighthq/types/contract';
|
|
2
|
+
export declare function computePhysics2DColliderMassData(collider: Readonly<Physics2DCollider>, out: Physics2DMassData): void;
|
|
3
|
+
export declare function updateRigidBody2DMassData(body: RigidBody2D): void;
|
|
4
|
+
//# sourceMappingURL=massProperties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"massProperties.d.ts","sourceRoot":"","sources":["../src/massProperties.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAalG,wBAAgB,gCAAgC,CAAC,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE,iBAAiB,GAAG,IAAI,CA0CpH;AAYD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAmCjE"}
|
|
@@ -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,6 @@
|
|
|
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 warmStartPhysics2DContacts(world: Physics2DWorld): void;
|
|
6
|
+
//# 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;AAarH,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,CAWlE;AAYD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAmBtE"}
|
package/dist/solver.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { findPhysics2DBody } from './world';
|
|
2
|
+
// Applies equal and opposite impulses at the pair's contact point. The angular term is the lever arm
|
|
3
|
+
// crossed with the impulse — the reason an off-centre contact spins a body instead of only shoving it.
|
|
4
|
+
// A static body's zero inverse mass and inverse inertia make both of its updates no-ops without a branch.
|
|
5
|
+
//
|
|
6
|
+
// A POSITIVE impulse pushes A along the contact normal and B against it, because `@flighthq/collision`
|
|
7
|
+
// documents its manifold normal as the direction that separates **A out of B**. That is the opposite of
|
|
8
|
+
// the A-to-B convention most sequential-impulse literature is written in, and getting it backwards does
|
|
9
|
+
// not look like a sign error — it looks like gravity working, since the solver then drives bodies
|
|
10
|
+
// together and a resting box settles below the floor instead of on it.
|
|
11
|
+
export function applyPhysics2DImpulse(bodyA, bodyB, rAX, rAY, rBX, rBY, impulseX, impulseY) {
|
|
12
|
+
bodyA.velocityX += impulseX * bodyA.inverseMass;
|
|
13
|
+
bodyA.velocityY += impulseY * bodyA.inverseMass;
|
|
14
|
+
bodyA.angularVelocity += bodyA.inverseInertia * (rAX * impulseY - rAY * impulseX);
|
|
15
|
+
bodyB.velocityX -= impulseX * bodyB.inverseMass;
|
|
16
|
+
bodyB.velocityY -= impulseY * bodyB.inverseMass;
|
|
17
|
+
bodyB.angularVelocity -= bodyB.inverseInertia * (rBX * impulseY - rBY * impulseX);
|
|
18
|
+
}
|
|
19
|
+
export function relativeNormalVelocity(bodyA, bodyB, point, normalX, normalY) {
|
|
20
|
+
const vax = bodyA.velocityX - bodyA.angularVelocity * point.rAY;
|
|
21
|
+
const vay = bodyA.velocityY + bodyA.angularVelocity * point.rAX;
|
|
22
|
+
const vbx = bodyB.velocityX - bodyB.angularVelocity * point.rBY;
|
|
23
|
+
const vby = bodyB.velocityY + bodyB.angularVelocity * point.rBX;
|
|
24
|
+
return (vax - vbx) * normalX + (vay - vby) * normalY;
|
|
25
|
+
}
|
|
26
|
+
// One contact's velocity constraint: friction first, then the normal.
|
|
27
|
+
//
|
|
28
|
+
// Friction is solved BEFORE the normal on each pass, and the order is deliberate. The friction bound is
|
|
29
|
+
// Coulomb's — the tangential impulse cannot exceed the normal impulse times the coefficient — so it needs
|
|
30
|
+
// a normal impulse to bound against. Using the value the previous iteration converged on is standard and
|
|
31
|
+
// stable; using the one this iteration is about to produce would make the bound depend on a number that
|
|
32
|
+
// does not exist yet.
|
|
33
|
+
function solvePhysics2DContact(contact, bodyA, bodyB) {
|
|
34
|
+
const normalX = contact.normalX;
|
|
35
|
+
const normalY = contact.normalY;
|
|
36
|
+
const tangentX = -normalY;
|
|
37
|
+
const tangentY = normalX;
|
|
38
|
+
for (let i = 0; i < contact.pointCount; i++) {
|
|
39
|
+
const point = contact.points[i];
|
|
40
|
+
const tangentVelocity = relativeAxisVelocity(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, tangentX, tangentY);
|
|
41
|
+
let tangentImpulse = -point.tangentMass * tangentVelocity;
|
|
42
|
+
const limit = contact.friction * point.normalImpulse;
|
|
43
|
+
const clampedTangent = Math.max(-limit, Math.min(limit, point.tangentImpulse + tangentImpulse));
|
|
44
|
+
tangentImpulse = clampedTangent - point.tangentImpulse;
|
|
45
|
+
point.tangentImpulse = clampedTangent;
|
|
46
|
+
applyPhysics2DImpulse(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, tangentImpulse * tangentX, tangentImpulse * tangentY);
|
|
47
|
+
const normalVelocity = relativeNormalVelocity(bodyA, bodyB, point, normalX, normalY);
|
|
48
|
+
let normalImpulse = -point.normalMass * (normalVelocity + point.bias);
|
|
49
|
+
const clampedNormal = Math.max(0, point.normalImpulse + normalImpulse);
|
|
50
|
+
normalImpulse = clampedNormal - point.normalImpulse;
|
|
51
|
+
point.normalImpulse = clampedNormal;
|
|
52
|
+
applyPhysics2DImpulse(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, normalImpulse * normalX, normalImpulse * normalY);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// The sequential-impulse velocity solve: projected Gauss-Seidel over the contact list, `velocityIterations`
|
|
56
|
+
// times.
|
|
57
|
+
//
|
|
58
|
+
// "Sequential" is the whole method — each impulse is applied immediately, so the next constraint sees the
|
|
59
|
+
// velocities the previous one left behind. That is why the solver converges, and equally why contact
|
|
60
|
+
// ORDER changes the result: the list is sorted canonically before it gets here for exactly that reason.
|
|
61
|
+
//
|
|
62
|
+
// The accumulated impulse, not the incremental one, is what gets clamped. Clamping each increment would
|
|
63
|
+
// let a contact pull bodies together on any iteration where the incremental impulse came out negative;
|
|
64
|
+
// clamping the accumulation lets an iteration correct an earlier overshoot while keeping the total
|
|
65
|
+
// non-negative, which is the difference between a stable stack and one that vibrates.
|
|
66
|
+
export function solvePhysics2DContacts(world) {
|
|
67
|
+
const iterations = world.config.velocityIterations;
|
|
68
|
+
for (let iteration = 0; iteration < iterations; iteration++) {
|
|
69
|
+
for (const contact of world.contacts) {
|
|
70
|
+
if (contact.sensor)
|
|
71
|
+
continue;
|
|
72
|
+
const bodyA = findPhysics2DBody(world, contact.bodyA);
|
|
73
|
+
const bodyB = findPhysics2DBody(world, contact.bodyB);
|
|
74
|
+
if (bodyA === null || bodyB === null)
|
|
75
|
+
continue;
|
|
76
|
+
solvePhysics2DContact(contact, bodyA, bodyB);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Applies each contact's cached impulses before the first iteration — the warm start.
|
|
81
|
+
//
|
|
82
|
+
// This is what makes a stack settle rather than visibly sink. A sequential-impulse solver converges
|
|
83
|
+
// toward the correct impulse over its iterations; starting each step from zero throws away everything
|
|
84
|
+
// the previous step learned, so a tall stack never reaches equilibrium within a frame's budget and the
|
|
85
|
+
// bottom box is compressed by everything above it. Re-applying last step's converged impulse starts the
|
|
86
|
+
// iteration from an answer that was nearly right, and a handful of iterations finishes the job.
|
|
87
|
+
//
|
|
88
|
+
// The cached impulses were matched by feature id when the contact was merged, so a point that is no
|
|
89
|
+
// longer the same feature arrives here with zero rather than a stranger's force.
|
|
90
|
+
export function warmStartPhysics2DContacts(world) {
|
|
91
|
+
for (const contact of world.contacts) {
|
|
92
|
+
if (contact.sensor)
|
|
93
|
+
continue;
|
|
94
|
+
const bodyA = findPhysics2DBody(world, contact.bodyA);
|
|
95
|
+
const bodyB = findPhysics2DBody(world, contact.bodyB);
|
|
96
|
+
if (bodyA === null || bodyB === null)
|
|
97
|
+
continue;
|
|
98
|
+
const normalX = contact.normalX;
|
|
99
|
+
const normalY = contact.normalY;
|
|
100
|
+
const tangentX = -normalY;
|
|
101
|
+
const tangentY = normalX;
|
|
102
|
+
for (let i = 0; i < contact.pointCount; i++) {
|
|
103
|
+
const point = contact.points[i];
|
|
104
|
+
const impulseX = point.normalImpulse * normalX + point.tangentImpulse * tangentX;
|
|
105
|
+
const impulseY = point.normalImpulse * normalY + point.tangentImpulse * tangentY;
|
|
106
|
+
applyPhysics2DImpulse(bodyA, bodyB, point.rAX, point.rAY, point.rBX, point.rBY, impulseX, impulseY);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function relativeAxisVelocity(bodyA, bodyB, rAX, rAY, rBX, rBY, axisX, axisY) {
|
|
111
|
+
const vax = bodyA.velocityX - bodyA.angularVelocity * rAY;
|
|
112
|
+
const vay = bodyA.velocityY + bodyA.angularVelocity * rAX;
|
|
113
|
+
const vbx = bodyB.velocityX - bodyB.angularVelocity * rBY;
|
|
114
|
+
const vby = bodyB.velocityY + bodyB.angularVelocity * rBX;
|
|
115
|
+
// A's velocity relative to B, matching the normal's "separates A out of B" direction: negative means
|
|
116
|
+
// the pair is closing along that axis.
|
|
117
|
+
return (vax - vbx) * axisX + (vay - vby) * axisY;
|
|
118
|
+
}
|
|
119
|
+
//# 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,EAIV,cAAc,EAIf,MAAM,0BAA0B,CAAC;AA+OlC,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAsCrE"}
|