@codexo/exojs-physics 0.13.0 → 0.15.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/README.md +17 -10
- package/dist/esm/Collider.d.ts +17 -6
- package/dist/esm/Collider.js +28 -6
- package/dist/esm/Collider.js.map +1 -1
- package/dist/esm/ContactGraph.d.ts +49 -3
- package/dist/esm/ContactGraph.js +132 -44
- package/dist/esm/ContactGraph.js.map +1 -1
- package/dist/esm/PhysicsBody.d.ts +145 -15
- package/dist/esm/PhysicsBody.js +282 -21
- package/dist/esm/PhysicsBody.js.map +1 -1
- package/dist/esm/PhysicsWorld.d.ts +177 -39
- package/dist/esm/PhysicsWorld.js +412 -35
- package/dist/esm/PhysicsWorld.js.map +1 -1
- package/dist/esm/backend/NativePhysicsBackend.d.ts +5 -0
- package/dist/esm/backend/NativePhysicsBackend.js +14 -0
- package/dist/esm/backend/NativePhysicsBackend.js.map +1 -1
- package/dist/esm/backend/PhysicsBackend.d.ts +9 -1
- package/dist/esm/binding/BindingRegistry.d.ts +1 -2
- package/dist/esm/binding/BindingRegistry.js +2 -2
- package/dist/esm/binding/BindingRegistry.js.map +1 -1
- package/dist/esm/binding/PhysicsBinding.d.ts +7 -18
- package/dist/esm/binding/PhysicsBinding.js +9 -8
- package/dist/esm/binding/PhysicsBinding.js.map +1 -1
- package/dist/esm/broadphase/SweepAndPrune.d.ts +1 -0
- package/dist/esm/broadphase/SweepAndPrune.js +32 -3
- package/dist/esm/broadphase/SweepAndPrune.js.map +1 -1
- package/dist/esm/collision/CollisionProxy.d.ts +2 -2
- package/dist/esm/collision/narrowphase.js +91 -38
- package/dist/esm/collision/narrowphase.js.map +1 -1
- package/dist/esm/debug/PhysicsDebugDraw.d.ts +8 -1
- package/dist/esm/debug/PhysicsDebugDraw.js +26 -2
- package/dist/esm/debug/PhysicsDebugDraw.js.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/joints/DistanceJoint.d.ts +71 -0
- package/dist/esm/joints/DistanceJoint.js +176 -0
- package/dist/esm/joints/DistanceJoint.js.map +1 -0
- package/dist/esm/joints/Joint.d.ts +25 -0
- package/dist/esm/joints/Joint.js +24 -0
- package/dist/esm/joints/Joint.js.map +1 -0
- package/dist/esm/joints/MouseJoint.d.ts +57 -0
- package/dist/esm/joints/MouseJoint.js +137 -0
- package/dist/esm/joints/MouseJoint.js.map +1 -0
- package/dist/esm/joints/PrismaticJoint.d.ts +85 -0
- package/dist/esm/joints/PrismaticJoint.js +241 -0
- package/dist/esm/joints/PrismaticJoint.js.map +1 -0
- package/dist/esm/joints/RevoluteJoint.d.ts +81 -0
- package/dist/esm/joints/RevoluteJoint.js +217 -0
- package/dist/esm/joints/RevoluteJoint.js.map +1 -0
- package/dist/esm/joints/WeldJoint.d.ts +61 -0
- package/dist/esm/joints/WeldJoint.js +159 -0
- package/dist/esm/joints/WeldJoint.js.map +1 -0
- package/dist/esm/joints/WheelJoint.d.ts +92 -0
- package/dist/esm/joints/WheelJoint.js +256 -0
- package/dist/esm/joints/WheelJoint.js.map +1 -0
- package/dist/esm/math.js +15 -1
- package/dist/esm/math.js.map +1 -1
- package/dist/esm/physicsBuildInfo.js +2 -2
- package/dist/esm/public.d.ts +9 -2
- package/dist/esm/query/QueryEngine.d.ts +2 -2
- package/dist/esm/query/QueryEngine.js +13 -4
- package/dist/esm/query/QueryEngine.js.map +1 -1
- package/dist/esm/shapes/AnyShape.d.ts +9 -0
- package/dist/esm/shapes/CircleShape.d.ts +1 -2
- package/dist/esm/shapes/CircleShape.js.map +1 -1
- package/dist/esm/shapes/PolygonShape.d.ts +1 -2
- package/dist/esm/shapes/PolygonShape.js +45 -17
- package/dist/esm/shapes/PolygonShape.js.map +1 -1
- package/dist/esm/shapes/index.d.ts +1 -0
- package/dist/esm/solver/ContactSolver.d.ts +87 -0
- package/dist/esm/solver/ContactSolver.js +490 -0
- package/dist/esm/solver/ContactSolver.js.map +1 -0
- package/dist/esm/sort.d.ts +17 -0
- package/dist/esm/sort.js +54 -0
- package/dist/esm/sort.js.map +1 -0
- package/package.json +3 -3
package/dist/esm/PhysicsWorld.js
CHANGED
|
@@ -1,21 +1,45 @@
|
|
|
1
1
|
import { Signal, Vector } from '@codexo/exojs';
|
|
2
2
|
import { NativePhysicsBackend } from './backend/NativePhysicsBackend.js';
|
|
3
3
|
import { BindingRegistry } from './binding/BindingRegistry.js';
|
|
4
|
+
import { Collider } from './Collider.js';
|
|
4
5
|
import { PhysicsBody } from './PhysicsBody.js';
|
|
5
6
|
import { QueryEngine } from './query/QueryEngine.js';
|
|
6
7
|
import { TimeStepper } from './TimeStepper.js';
|
|
7
8
|
|
|
9
|
+
/** Gap left between a clamped bullet and the surface it hit (so it does not re-hit from inside). */
|
|
10
|
+
const ccdSkin = 0.05;
|
|
8
11
|
/**
|
|
9
12
|
* The collision/query world: owns bodies, colliders, the detection backend,
|
|
10
13
|
* bindings, the query engine and the fixed-step accumulator. Stepped by the
|
|
11
|
-
* caller (commonly from a `Scene.update`),
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
14
|
+
* caller (commonly from a `Scene.update`), each fixed sub-step it integrates
|
|
15
|
+
* body velocities, runs broad- and narrow-phase detection, solves contacts and
|
|
16
|
+
* integrates positions, then fires immutable contact/sensor events and writes
|
|
17
|
+
* bound node transforms. It holds **no module-level state**, so any number of
|
|
18
|
+
* worlds run in isolation (gate I-1).
|
|
15
19
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
20
|
+
* The dynamics are a native, warm-started **TGS-Soft** solver (Box2D-v3 "soft
|
|
21
|
+
* step"): each fixed step runs detection once, then several sub-steps, each
|
|
22
|
+
* integrating gravity over the sub-step and solving contacts with a soft
|
|
23
|
+
* position bias plus a bias-free relax pass; a 2-point block normal solve
|
|
24
|
+
* propagates stack loads, and restitution is a separate final pass. Decoupling
|
|
25
|
+
* stiffness from the iteration count keeps tall towers stable. The detection
|
|
26
|
+
* backend sits behind an internal seam, so the solver is swappable without
|
|
27
|
+
* touching this public surface.
|
|
28
|
+
*
|
|
29
|
+
* **Operating envelope.** The soft solver trades a little accuracy for
|
|
30
|
+
* robustness, so it has a few documented limits — each stays finite/stable and
|
|
31
|
+
* each is pinned by a gate in `dynamics.test.ts`:
|
|
32
|
+
* - **Mass ratio** — resting stacks are slop-accurate up to ~100:1. Beyond that
|
|
33
|
+
* the velocity-capped soft push-out (`maxBiasVelocity`) lets the lighter body
|
|
34
|
+
* settle progressively deeper (≈6px at 500:1, fully through a thin floor by
|
|
35
|
+
* ~5000:1) — always finite, never exploding (SG-MR3).
|
|
36
|
+
* - **No CCD** — detection runs once per fixed step with no swept test, so a
|
|
37
|
+
* body that travels farther than an obstacle's thickness in one step tunnels
|
|
38
|
+
* straight through it (it stays finite). Reliably stopping fast projectiles is
|
|
39
|
+
* a future bullet-mode feature (SG-X5).
|
|
40
|
+
* - **{@link PhysicsWorldOptions.subStepCount}** — the default `4` is
|
|
41
|
+
* load-bearing for tall-stack stability; lowering it below `2` visibly
|
|
42
|
+
* degrades stacking, so do not reduce it for performance.
|
|
19
43
|
*/
|
|
20
44
|
class PhysicsWorld {
|
|
21
45
|
/** Fires when two solid colliders begin touching. Argument is an immutable snapshot. */
|
|
@@ -26,32 +50,60 @@ class PhysicsWorld {
|
|
|
26
50
|
onSensorEnter = new Signal();
|
|
27
51
|
/** Fires when a collider leaves a sensor. */
|
|
28
52
|
onSensorExit = new Signal();
|
|
29
|
-
/** World gravity (px/s², +Y down).
|
|
53
|
+
/** World gravity (px/s², +Y down). Integrated each sub-step. */
|
|
30
54
|
gravity;
|
|
31
55
|
/** The fixed-step accumulator. */
|
|
32
56
|
timeStepper;
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
|
|
57
|
+
/** TGS-Soft sub-steps per fixed step. */
|
|
58
|
+
subStepCount;
|
|
59
|
+
/** Soft-contact stiffness in Hz. */
|
|
60
|
+
contactHertz;
|
|
61
|
+
/** Soft-contact damping ratio. */
|
|
62
|
+
dampingRatio;
|
|
63
|
+
/** Whether resting bodies are put to sleep. */
|
|
64
|
+
enableSleeping;
|
|
65
|
+
/** Linear sleep threshold (px/s). */
|
|
66
|
+
sleepLinearVelocity;
|
|
67
|
+
/** Angular sleep threshold (rad/s). */
|
|
68
|
+
sleepAngularVelocity;
|
|
69
|
+
/** Seconds below the thresholds before a body sleeps. */
|
|
70
|
+
timeToSleep;
|
|
39
71
|
_backend = new NativePhysicsBackend();
|
|
40
72
|
_bodies = [];
|
|
41
73
|
_colliders = [];
|
|
74
|
+
_joints = [];
|
|
42
75
|
_bindings = new BindingRegistry();
|
|
43
76
|
_query;
|
|
44
77
|
_commands = [];
|
|
78
|
+
/** Pooled union-find parent array for the per-step island pass (reused; sized to the body count). */
|
|
79
|
+
_islandParent = [];
|
|
80
|
+
/** Pooled per-island minimum sleep time, indexed by union-find root. */
|
|
81
|
+
_islandMinSleep = [];
|
|
82
|
+
/** Pooled ray-hit buffer + origin/direction for the CCD swept test. */
|
|
83
|
+
_ccdHits = [];
|
|
84
|
+
_ccdOrigin = { x: 0, y: 0 };
|
|
85
|
+
_ccdDir = { x: 0, y: 0 };
|
|
45
86
|
_nextBodyId = 1;
|
|
46
87
|
_nextColliderId = 1;
|
|
47
88
|
_dispatching = false;
|
|
48
89
|
_destroyed = false;
|
|
49
90
|
constructor(options = {}) {
|
|
50
91
|
this.gravity = new Vector(options.gravity?.x ?? 0, options.gravity?.y ?? 0);
|
|
51
|
-
this.timeStepper = new TimeStepper({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
92
|
+
this.timeStepper = new TimeStepper({
|
|
93
|
+
...(options.fixedDelta !== undefined && { fixedDelta: options.fixedDelta }),
|
|
94
|
+
...(options.maxSubSteps !== undefined && { maxSubSteps: options.maxSubSteps }),
|
|
95
|
+
});
|
|
96
|
+
const subStepCount = options.subStepCount ?? 4;
|
|
97
|
+
if (!Number.isInteger(subStepCount) || subStepCount < 1) {
|
|
98
|
+
throw new RangeError(`PhysicsWorld: subStepCount must be an integer ≥ 1, received ${subStepCount}.`);
|
|
99
|
+
}
|
|
100
|
+
this.subStepCount = subStepCount;
|
|
101
|
+
this.contactHertz = options.contactHertz ?? 30;
|
|
102
|
+
this.dampingRatio = options.dampingRatio ?? 10;
|
|
103
|
+
this.enableSleeping = options.enableSleeping ?? true;
|
|
104
|
+
this.sleepLinearVelocity = options.sleepLinearVelocity ?? 5;
|
|
105
|
+
this.sleepAngularVelocity = options.sleepAngularVelocity ?? 0.06;
|
|
106
|
+
this.timeToSleep = options.timeToSleep ?? 0.5;
|
|
55
107
|
this._query = new QueryEngine(this._colliders);
|
|
56
108
|
}
|
|
57
109
|
/** Live bodies (read-only view). */
|
|
@@ -63,10 +115,24 @@ class PhysicsWorld {
|
|
|
63
115
|
return this._colliders;
|
|
64
116
|
}
|
|
65
117
|
// ── lifecycle ──────────────────────────────────────────────────────────
|
|
66
|
-
/**
|
|
67
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Add a body to the world: allocates the body and its collider ids, registers
|
|
120
|
+
* the colliders, computes the mass model and tracks the body for stepping.
|
|
121
|
+
* Construct the body freely first (`new PhysicsBody({ … })`), then add it.
|
|
122
|
+
* Safe to call inside an event callback — the body push is deferred to the end
|
|
123
|
+
* of the step, exactly like collider registration. Returns the body.
|
|
124
|
+
*
|
|
125
|
+
* @throws if the body has already been added to a world.
|
|
126
|
+
*/
|
|
127
|
+
add(body) {
|
|
68
128
|
this._assertAlive();
|
|
69
|
-
|
|
129
|
+
if (body.attached) {
|
|
130
|
+
throw new Error('PhysicsWorld.add: this body has already been added to a world.');
|
|
131
|
+
}
|
|
132
|
+
// Allocate the id + link/register colliders + aggregate mass now (matches the
|
|
133
|
+
// old createBody, which allocated the id synchronously); only the body-list
|
|
134
|
+
// push is deferred so it is safe inside an event dispatch.
|
|
135
|
+
body._attachToWorld(this, this._nextBodyId++);
|
|
70
136
|
this._defer(() => {
|
|
71
137
|
if (!body.destroyed) {
|
|
72
138
|
this._bodies.push(body);
|
|
@@ -74,10 +140,34 @@ class PhysicsWorld {
|
|
|
74
140
|
});
|
|
75
141
|
return body;
|
|
76
142
|
}
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
143
|
+
/**
|
|
144
|
+
* Convenience: create a body carrying a single collider, add it to the world
|
|
145
|
+
* and bind it to `node` in one call. The node tracks `body.position` after each
|
|
146
|
+
* step. Returns the body. Equivalent to `new PhysicsBody(...)` + `add` + `bind`.
|
|
147
|
+
*/
|
|
148
|
+
attach(node, options) {
|
|
149
|
+
const body = new PhysicsBody({
|
|
150
|
+
...(options.type !== undefined && { type: options.type }),
|
|
151
|
+
...(options.position !== undefined && { position: options.position }),
|
|
152
|
+
...(options.angle !== undefined && { angle: options.angle }),
|
|
153
|
+
...(options.gravityScale !== undefined && { gravityScale: options.gravityScale }),
|
|
154
|
+
...(options.fixedRotation !== undefined && { fixedRotation: options.fixedRotation }),
|
|
155
|
+
colliders: [
|
|
156
|
+
new Collider({
|
|
157
|
+
shape: options.shape,
|
|
158
|
+
...(options.offset !== undefined && { offset: options.offset }),
|
|
159
|
+
...(options.rotation !== undefined && { rotation: options.rotation }),
|
|
160
|
+
...(options.density !== undefined && { density: options.density }),
|
|
161
|
+
...(options.friction !== undefined && { friction: options.friction }),
|
|
162
|
+
...(options.restitution !== undefined && { restitution: options.restitution }),
|
|
163
|
+
...(options.isSensor !== undefined && { isSensor: options.isSensor }),
|
|
164
|
+
...(options.filter !== undefined && { filter: options.filter }),
|
|
165
|
+
}),
|
|
166
|
+
],
|
|
167
|
+
});
|
|
168
|
+
this.add(body);
|
|
169
|
+
this.bind(body, node);
|
|
170
|
+
return body;
|
|
81
171
|
}
|
|
82
172
|
/** Destroy a body and its colliders. Deferred when called inside a callback. */
|
|
83
173
|
destroyBody(body) {
|
|
@@ -87,22 +177,115 @@ class PhysicsWorld {
|
|
|
87
177
|
destroyCollider(collider) {
|
|
88
178
|
this._defer(() => this._removeCollider(collider));
|
|
89
179
|
}
|
|
180
|
+
/** Live joints (read-only view). */
|
|
181
|
+
get joints() {
|
|
182
|
+
return this._joints;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Add a constraint joint. Construct it first (`new DistanceJoint({ … })`),
|
|
186
|
+
* then add it. Wakes both bodies; safe inside a callback (registration is
|
|
187
|
+
* deferred). Returns the joint.
|
|
188
|
+
*/
|
|
189
|
+
addJoint(joint) {
|
|
190
|
+
this._assertAlive();
|
|
191
|
+
joint.bodyA.wake();
|
|
192
|
+
joint.bodyB.wake();
|
|
193
|
+
this._defer(() => {
|
|
194
|
+
if (!this._joints.includes(joint)) {
|
|
195
|
+
this._joints.push(joint);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
return joint;
|
|
199
|
+
}
|
|
200
|
+
/** Remove a joint, waking both bodies so they respond to the lost constraint. Deferred when called inside a callback. */
|
|
201
|
+
removeJoint(joint) {
|
|
202
|
+
joint.bodyA.wake();
|
|
203
|
+
joint.bodyB.wake();
|
|
204
|
+
this._defer(() => {
|
|
205
|
+
const index = this._joints.indexOf(joint);
|
|
206
|
+
if (index !== -1) {
|
|
207
|
+
this._joints.splice(index, 1);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
90
211
|
// ── stepping ───────────────────────────────────────────────────────────
|
|
91
212
|
/**
|
|
92
|
-
* Advance the world by `frameDeltaSeconds`. Accumulates into fixed
|
|
93
|
-
* runs detection
|
|
213
|
+
* Advance the world by `frameDeltaSeconds`. Accumulates into fixed steps; each
|
|
214
|
+
* fixed step runs detection once, then a TGS-Soft sub-step loop (integrate
|
|
215
|
+
* gravity, solve contacts with a soft bias, integrate positions, relax) and a
|
|
216
|
+
* restitution pass, then writes the accumulated motion into each body. Finally
|
|
217
|
+
* dispatches events and writes bound node transforms.
|
|
94
218
|
*/
|
|
95
219
|
step(frameDeltaSeconds) {
|
|
96
220
|
this._assertAlive();
|
|
97
221
|
const steps = this.timeStepper.advance(frameDeltaSeconds);
|
|
98
222
|
if (steps > 0) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
223
|
+
const subStepCount = this.subStepCount;
|
|
224
|
+
const h = this.timeStepper.fixedDelta / subStepCount;
|
|
225
|
+
const gravityX = this.gravity.x;
|
|
226
|
+
const gravityY = this.gravity.y;
|
|
227
|
+
const contactHertz = this.contactHertz;
|
|
228
|
+
const dampingRatio = this.dampingRatio;
|
|
229
|
+
const hasJoints = this._joints.length > 0;
|
|
230
|
+
const hasBullets = this._hasBullets();
|
|
231
|
+
for (let step = 0; step < steps; step++) {
|
|
232
|
+
// Detection runs once per fixed step (collider geometry is already current
|
|
233
|
+
// from the previous frame's finalize / attach / setTransform). TGS-Soft
|
|
234
|
+
// reuses the manifolds across the sub-steps below.
|
|
235
|
+
this._backend.detect(this._colliders);
|
|
236
|
+
// Sleep decision runs after detection (islands need the current contact
|
|
237
|
+
// set) and before the solver (so sleeping contacts are skipped, and a
|
|
238
|
+
// sleeping island touched by an awake body is woken first).
|
|
239
|
+
if (this.enableSleeping) {
|
|
240
|
+
this._updateSleeping(this.timeStepper.fixedDelta);
|
|
241
|
+
}
|
|
242
|
+
this._backend.prepareSolve(h, contactHertz, dampingRatio);
|
|
243
|
+
if (hasJoints) {
|
|
244
|
+
this._prepareJoints(h);
|
|
245
|
+
}
|
|
246
|
+
if (hasBullets) {
|
|
247
|
+
this._recordBulletPositions();
|
|
248
|
+
}
|
|
249
|
+
for (let subStep = 0; subStep < subStepCount; subStep++) {
|
|
250
|
+
// Integrate gravity/forces over the sub-step (forces persist across
|
|
251
|
+
// sub-steps; cleared once per frame by `_finalizePosition`).
|
|
252
|
+
for (const body of this._bodies) {
|
|
253
|
+
body._integrateVelocity(h, gravityX, gravityY);
|
|
254
|
+
}
|
|
255
|
+
// Warm-start every sub-step (Box2D-v3 soft step): the relax pass leaves
|
|
256
|
+
// each contact's normal velocity at zero, so re-applying the
|
|
257
|
+
// accumulated impulse re-balances exactly this sub-step's gravity — the
|
|
258
|
+
// impulse converges to the per-sub-step load (m·h·g), not the per-frame
|
|
259
|
+
// load, which is what keeps tall stacks from pumping energy.
|
|
260
|
+
this._backend.warmStart();
|
|
261
|
+
if (hasJoints) {
|
|
262
|
+
this._warmStartJoints();
|
|
263
|
+
}
|
|
264
|
+
// Main soft-bias velocity solve, integrate positions (accumulating
|
|
265
|
+
// per-body delta), then the bias-free relax pass. Joints solve right
|
|
266
|
+
// after the contacts in each pass (contacts are the stiffer constraint).
|
|
267
|
+
this._backend.solveVelocities(true);
|
|
268
|
+
if (hasJoints) {
|
|
269
|
+
this._solveJoints(true);
|
|
270
|
+
}
|
|
271
|
+
for (const body of this._bodies) {
|
|
272
|
+
body._integratePosition(h);
|
|
273
|
+
}
|
|
274
|
+
this._backend.solveVelocities(false);
|
|
275
|
+
if (hasJoints) {
|
|
276
|
+
this._solveJoints(false);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Separate restitution pass, then write the accumulated delta into each
|
|
280
|
+
// body's transform and re-sync collider geometry.
|
|
281
|
+
this._backend.applyRestitution();
|
|
282
|
+
for (const body of this._bodies) {
|
|
283
|
+
body._finalizePosition();
|
|
284
|
+
}
|
|
285
|
+
if (hasBullets) {
|
|
286
|
+
this._advanceBullets();
|
|
287
|
+
}
|
|
104
288
|
}
|
|
105
|
-
this._backend.detect(this._colliders);
|
|
106
289
|
this._dispatchEvents();
|
|
107
290
|
}
|
|
108
291
|
this._bindings.sync();
|
|
@@ -110,8 +293,8 @@ class PhysicsWorld {
|
|
|
110
293
|
}
|
|
111
294
|
// ── binding ────────────────────────────────────────────────────────────
|
|
112
295
|
/** Link a body to a scene node; the node tracks the body after each step. */
|
|
113
|
-
bind(body, node
|
|
114
|
-
return this._bindings.bind(body, node
|
|
296
|
+
bind(body, node) {
|
|
297
|
+
return this._bindings.bind(body, node);
|
|
115
298
|
}
|
|
116
299
|
/** Remove a body↔node link. */
|
|
117
300
|
unbind(body) {
|
|
@@ -153,6 +336,7 @@ class PhysicsWorld {
|
|
|
153
336
|
}
|
|
154
337
|
this._bodies.length = 0;
|
|
155
338
|
this._colliders.length = 0;
|
|
339
|
+
this._joints.length = 0;
|
|
156
340
|
this._commands.length = 0;
|
|
157
341
|
this._bindings.clear();
|
|
158
342
|
this._backend.destroy();
|
|
@@ -194,6 +378,199 @@ class PhysicsWorld {
|
|
|
194
378
|
}
|
|
195
379
|
this._dispatching = false;
|
|
196
380
|
}
|
|
381
|
+
/**
|
|
382
|
+
* Accumulate per-body sleep timers and put/keep islands of resting bodies
|
|
383
|
+
* asleep so a stack sleeps and wakes as one unit. An island is a connected
|
|
384
|
+
* component of dynamic bodies joined by touching solid contacts (static and
|
|
385
|
+
* kinematic bodies are boundaries, not nodes); it sleeps once every member has
|
|
386
|
+
* stayed below the sleep thresholds for `timeToSleep`, and wakes the instant
|
|
387
|
+
* any member does (e.g. an awake body merges into it via a new contact).
|
|
388
|
+
* Deterministic: union-find roots break ties by lower index and the contact
|
|
389
|
+
* set is id-sorted.
|
|
390
|
+
*/
|
|
391
|
+
_updateSleeping(dt) {
|
|
392
|
+
const bodies = this._bodies;
|
|
393
|
+
const count = bodies.length;
|
|
394
|
+
const parent = this._islandParent;
|
|
395
|
+
const minSleep = this._islandMinSleep;
|
|
396
|
+
// Assign dense indices, reset the union-find, and accumulate sleep timers for
|
|
397
|
+
// awake dynamic bodies (a sleeping body's timer stays frozen ≥ timeToSleep).
|
|
398
|
+
for (let i = 0; i < count; i++) {
|
|
399
|
+
const body = bodies[i];
|
|
400
|
+
body._islandIndex = i;
|
|
401
|
+
parent[i] = i;
|
|
402
|
+
minSleep[i] = Infinity;
|
|
403
|
+
if (body.type === 'dynamic' && !body.isSleeping) {
|
|
404
|
+
body._accumulateSleepTime(dt, this.sleepLinearVelocity, this.sleepAngularVelocity);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
parent.length = count;
|
|
408
|
+
minSleep.length = count;
|
|
409
|
+
// Union dynamic↔dynamic solid contacts into islands.
|
|
410
|
+
for (const contact of this._backend.contactGraph.solidContacts) {
|
|
411
|
+
const bodyA = contact.a.body;
|
|
412
|
+
const bodyB = contact.b.body;
|
|
413
|
+
if (bodyA.type === 'dynamic' && bodyB.type === 'dynamic') {
|
|
414
|
+
this._union(bodyA._islandIndex, bodyB._islandIndex);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
// Joints couple their two bodies into the same island (sleep/wake together).
|
|
418
|
+
for (const joint of this._joints) {
|
|
419
|
+
const bodyA = joint.bodyA;
|
|
420
|
+
const bodyB = joint.bodyB;
|
|
421
|
+
if (joint.enabled && bodyA.type === 'dynamic' && bodyB.type === 'dynamic') {
|
|
422
|
+
this._union(bodyA._islandIndex, bodyB._islandIndex);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// Per-island minimum sleep time over its dynamic members.
|
|
426
|
+
for (let i = 0; i < count; i++) {
|
|
427
|
+
const body = bodies[i];
|
|
428
|
+
if (body.type === 'dynamic') {
|
|
429
|
+
const root = this._find(i);
|
|
430
|
+
if (body._sleepTime < minSleep[root]) {
|
|
431
|
+
minSleep[root] = body._sleepTime;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
// Sleep an island iff every member has rested for `timeToSleep`; otherwise
|
|
436
|
+
// wake it (which also wakes any member dragged awake by a fresh contact).
|
|
437
|
+
const timeToSleep = this.timeToSleep;
|
|
438
|
+
for (let i = 0; i < count; i++) {
|
|
439
|
+
const body = bodies[i];
|
|
440
|
+
if (body.type === 'dynamic') {
|
|
441
|
+
body._setSleeping(minSleep[this._find(i)] >= timeToSleep);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/** Union-find union by lower index (deterministic roots). */
|
|
446
|
+
_union(a, b) {
|
|
447
|
+
const rootA = this._find(a);
|
|
448
|
+
const rootB = this._find(b);
|
|
449
|
+
if (rootA < rootB) {
|
|
450
|
+
this._islandParent[rootB] = rootA;
|
|
451
|
+
}
|
|
452
|
+
else if (rootB < rootA) {
|
|
453
|
+
this._islandParent[rootA] = rootB;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
/** Union-find find with path halving. */
|
|
457
|
+
_find(index) {
|
|
458
|
+
const parent = this._islandParent;
|
|
459
|
+
while (parent[index] !== index) {
|
|
460
|
+
const grandparent = parent[parent[index]];
|
|
461
|
+
parent[index] = grandparent;
|
|
462
|
+
index = grandparent;
|
|
463
|
+
}
|
|
464
|
+
return index;
|
|
465
|
+
}
|
|
466
|
+
/** Build each joint's per-frame constraint data (once per fixed step). */
|
|
467
|
+
_prepareJoints(h) {
|
|
468
|
+
for (const joint of this._joints) {
|
|
469
|
+
joint._prepare(h);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
/** Re-apply each joint's accumulated impulse (each sub-step). */
|
|
473
|
+
_warmStartJoints() {
|
|
474
|
+
for (const joint of this._joints) {
|
|
475
|
+
joint._warmStart();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/** One joint velocity pass (each sub-step, after the contacts). */
|
|
479
|
+
_solveJoints(useBias) {
|
|
480
|
+
for (const joint of this._joints) {
|
|
481
|
+
joint._solve(useBias);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
/** Whether any dynamic body is flagged for continuous collision (bullet mode). */
|
|
485
|
+
_hasBullets() {
|
|
486
|
+
for (const body of this._bodies) {
|
|
487
|
+
if (body.isBullet && body.type === 'dynamic') {
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
/** Snapshot each bullet's centre of mass at the start of the fixed step (the swept-test origin). */
|
|
494
|
+
_recordBulletPositions() {
|
|
495
|
+
for (const body of this._bodies) {
|
|
496
|
+
if (body.isBullet && body.type === 'dynamic') {
|
|
497
|
+
body._ccdPrevX = body.worldCenterOfMassX;
|
|
498
|
+
body._ccdPrevY = body.worldCenterOfMassY;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Sweep each bullet's centre of mass along this fixed step's motion against every
|
|
504
|
+
* other body's colliders; if it would cross one, clamp the body just short of the
|
|
505
|
+
* surface and resolve the impact about the surface normal (a slide for a non-bouncy
|
|
506
|
+
* body, an elastic reflection as restitution → 1) so it cannot tunnel. Sweeps the
|
|
507
|
+
* centre point — good for small/point-like projectiles; a full swept-shape TOI for
|
|
508
|
+
* large fast bodies is backlog (raise sub-steps or thicken geometry meanwhile).
|
|
509
|
+
*/
|
|
510
|
+
_advanceBullets() {
|
|
511
|
+
for (const body of this._bodies) {
|
|
512
|
+
if (!body.isBullet || body.type !== 'dynamic' || body.isSleeping) {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
const newX = body.worldCenterOfMassX;
|
|
516
|
+
const newY = body.worldCenterOfMassY;
|
|
517
|
+
let dirX = newX - body._ccdPrevX;
|
|
518
|
+
let dirY = newY - body._ccdPrevY;
|
|
519
|
+
const distance = Math.hypot(dirX, dirY);
|
|
520
|
+
if (distance < 1e-6) {
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
dirX /= distance;
|
|
524
|
+
dirY /= distance;
|
|
525
|
+
this._ccdOrigin.x = body._ccdPrevX;
|
|
526
|
+
this._ccdOrigin.y = body._ccdPrevY;
|
|
527
|
+
this._ccdDir.x = dirX;
|
|
528
|
+
this._ccdDir.y = dirY;
|
|
529
|
+
const hits = this._query.rayCastAll(this._ccdOrigin, this._ccdDir, undefined, this._ccdHits, distance);
|
|
530
|
+
let blocked = null;
|
|
531
|
+
for (const hit of hits) {
|
|
532
|
+
// Sweep against every other body (static, kinematic, dynamic); sensors never
|
|
533
|
+
// block. Hits are distance-sorted, so the first match is the nearest surface.
|
|
534
|
+
if (hit.body !== body && !hit.collider.isSensor) {
|
|
535
|
+
blocked = hit;
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
if (blocked === null) {
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
// Clamp the CoM just short of the surface (a pure translation — the rotation
|
|
543
|
+
// is already applied), then resolve the impact about the surface normal.
|
|
544
|
+
const clampDistance = Math.max(0, blocked.distance - ccdSkin);
|
|
545
|
+
const deltaX = body._ccdPrevX + dirX * clampDistance - newX;
|
|
546
|
+
const deltaY = body._ccdPrevY + dirY * clampDistance - newY;
|
|
547
|
+
this._ccdOrigin.x = body.x + deltaX;
|
|
548
|
+
this._ccdOrigin.y = body.y + deltaY;
|
|
549
|
+
body.setTransform(this._ccdOrigin, body.angle);
|
|
550
|
+
// Reflect about the true surface normal: a slide for a non-bouncy body
|
|
551
|
+
// (restitution 0), an elastic bounce as restitution → 1. The body's own
|
|
552
|
+
// restitution combines (max) with the surface's, matching the contact solver.
|
|
553
|
+
const nx = blocked.normal.x;
|
|
554
|
+
const ny = blocked.normal.y;
|
|
555
|
+
const vn = body.linearVelocityX * nx + body.linearVelocityY * ny;
|
|
556
|
+
if (vn < 0) {
|
|
557
|
+
const restitution = vn < -1 ? Math.max(this._bulletRestitution(body), blocked.collider.restitution) : 0;
|
|
558
|
+
const impulse = -(1 + restitution) * vn;
|
|
559
|
+
body.linearVelocityX += impulse * nx;
|
|
560
|
+
body.linearVelocityY += impulse * ny;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
/** The highest restitution among a body's colliders (its CCD bounce factor). */
|
|
565
|
+
_bulletRestitution(body) {
|
|
566
|
+
let restitution = 0;
|
|
567
|
+
for (const collider of body.colliders) {
|
|
568
|
+
if (collider.restitution > restitution) {
|
|
569
|
+
restitution = collider.restitution;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return restitution;
|
|
573
|
+
}
|
|
197
574
|
/** Run `command` now, or queue it when inside an event dispatch (deferred to end of step). */
|
|
198
575
|
_defer(command) {
|
|
199
576
|
if (this._dispatching) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhysicsWorld.js","sources":["../../../src/PhysicsWorld.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PhysicsWorld.js","sources":["../../../src/PhysicsWorld.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -11,9 +11,14 @@ import type { PhysicsBackend } from './PhysicsBackend';
|
|
|
11
11
|
export declare class NativePhysicsBackend implements PhysicsBackend {
|
|
12
12
|
readonly contactGraph: ContactGraph;
|
|
13
13
|
private readonly _broadPhase;
|
|
14
|
+
private readonly _solver;
|
|
14
15
|
private readonly _pairs;
|
|
15
16
|
get candidatePairs(): readonly CandidatePair[];
|
|
16
17
|
detect(colliders: readonly Collider[]): void;
|
|
18
|
+
prepareSolve(h: number, contactHertz: number, dampingRatio: number): void;
|
|
19
|
+
warmStart(): void;
|
|
20
|
+
solveVelocities(useBias: boolean): void;
|
|
21
|
+
applyRestitution(): void;
|
|
17
22
|
removeCollider(collider: Collider): void;
|
|
18
23
|
destroy(): void;
|
|
19
24
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SweepAndPrune } from '../broadphase/SweepAndPrune.js';
|
|
2
2
|
import { ContactGraph } from '../ContactGraph.js';
|
|
3
|
+
import { ContactSolver } from '../solver/ContactSolver.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* The native, dependency-free backend: a {@link BroadPhase} (sweep-and-prune in
|
|
@@ -10,6 +11,7 @@ import { ContactGraph } from '../ContactGraph.js';
|
|
|
10
11
|
class NativePhysicsBackend {
|
|
11
12
|
contactGraph = new ContactGraph();
|
|
12
13
|
_broadPhase = new SweepAndPrune();
|
|
14
|
+
_solver = new ContactSolver();
|
|
13
15
|
_pairs = [];
|
|
14
16
|
get candidatePairs() {
|
|
15
17
|
return this._pairs;
|
|
@@ -18,6 +20,18 @@ class NativePhysicsBackend {
|
|
|
18
20
|
this._broadPhase.computePairs(colliders, this._pairs);
|
|
19
21
|
this.contactGraph.update(this._pairs);
|
|
20
22
|
}
|
|
23
|
+
prepareSolve(h, contactHertz, dampingRatio) {
|
|
24
|
+
this._solver.prepare(this.contactGraph.solidContacts, h, contactHertz, dampingRatio);
|
|
25
|
+
}
|
|
26
|
+
warmStart() {
|
|
27
|
+
this._solver.warmStart();
|
|
28
|
+
}
|
|
29
|
+
solveVelocities(useBias) {
|
|
30
|
+
this._solver.solveVelocities(useBias);
|
|
31
|
+
}
|
|
32
|
+
applyRestitution() {
|
|
33
|
+
this._solver.applyRestitution();
|
|
34
|
+
}
|
|
21
35
|
removeCollider(collider) {
|
|
22
36
|
this.contactGraph.removeCollider(collider);
|
|
23
37
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativePhysicsBackend.js","sources":["../../../../src/backend/NativePhysicsBackend.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"NativePhysicsBackend.js","sources":["../../../../src/backend/NativePhysicsBackend.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAOA;;;;;AAKG;MACU,oBAAoB,CAAA;AACf,IAAA,YAAY,GAAG,IAAI,YAAY,EAAE;AAEhC,IAAA,WAAW,GAAe,IAAI,aAAa,EAAE;AAC7C,IAAA,OAAO,GAAG,IAAI,aAAa,EAAE;IAC7B,MAAM,GAAoB,EAAE;AAE7C,IAAA,IAAW,cAAc,GAAA;QACvB,OAAO,IAAI,CAAC,MAAM;IACpB;AAEO,IAAA,MAAM,CAAC,SAA8B,EAAA;QAC1C,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;QACrD,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;IACvC;AAEO,IAAA,YAAY,CAAC,CAAS,EAAE,YAAoB,EAAE,YAAoB,EAAA;AACvE,QAAA,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,EAAE,YAAY,EAAE,YAAY,CAAC;IACtF;IAEO,SAAS,GAAA;AACd,QAAA,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;IAC1B;AAEO,IAAA,eAAe,CAAC,OAAgB,EAAA;AACrC,QAAA,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC;IACvC;IAEO,gBAAgB,GAAA;AACrB,QAAA,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE;IACjC;AAEO,IAAA,cAAc,CAAC,QAAkB,EAAA;AACtC,QAAA,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC;IAC5C;IAEO,OAAO,GAAA;AACZ,QAAA,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;IACxB;AACD;;;;"}
|