Physics · class
PhysicsWorld
Explained in Your first game, Rigid bodies.
class PhysicsWorld implements IslandSolverimport { PhysicsWorld } from '@driftengine/physics';Constructor
new
constructor(options?: WorldOptions)| Parameter | Type | Description |
|---|---|---|
options? | WorldOptions |
Properties
| Name | Type | Description |
|---|---|---|
bodiesreadonly | BodySet | |
jointsreadonly | JointSet | |
eventsreadonly | ContactEvents | What touched what during the last tick, ordered by pair key. Drain it after step. |
substepsreadonly | number | |
iterationsreadonly | number | |
gravityX | number | |
gravityY | number | |
gravityZ | number | |
contactHertz | number | |
contactDamping | number | |
jointHertz | number | |
jointDamping | number | |
linearDamping | number | |
angularDamping | number | |
speculativeMargin | number | |
allowSleep | boolean | |
frictionModel | FrictionModel | Read at every substep, so a consumer may switch it between ticks. See WorldOptions. |
executor | Executor | Who runs the islands. Swappable, and a gate asserts two characters agree. |
parallelismreadonly | Parallelism | What the island solving is actually doing.MoreRead it rather than assuming the |
Accessors
| Name | Type | Description |
|---|---|---|
solveStateget | IslandSolveState | The flat view of this world an island's solve needs, and the only view a worker could hold.MoreBuilt fresh because Public because a character off this thread needs it. |
islandCountget | number | How many islands the last step found. |
Methods
dispose
dispose(): voidStop the worker pool, if there is one. Safe to call twice, and safe on a world without one.
More
A world with a pool must be disposed. Its workers hold the staging SharedArrayBuffer, so
a consumer replacing a world between levels leaks both the threads and every body's state with
them.
addJoint
addJoint(desc: JointDesc): numberJoin two bodies. The relative pose they are in now becomes the one the joint holds.
| Parameter | Type | Description |
|---|---|---|
desc | JointDesc |
addBody
addBody(desc: BodyDesc): number| Parameter | Type | Description |
|---|---|---|
desc | BodyDesc |
ignorePair
ignorePair(a: number, b: number): voidNever collide these two, whichever order they are given in and whatever their layers say.
| Parameter | Type | Description |
|---|---|---|
a | number | |
b | number |
More
Both indices are followed through removeBody, so an exclusion cannot outlive the body it
was made about and cannot be inherited by whatever takes its slot.
allowPair
allowPair(a: number, b: number): voidUndo one ignorePair. Doing it to a pair that was never excluded is not an error.
| Parameter | Type | Description |
|---|---|---|
a | number | |
b | number |
pairIgnored
pairIgnored(a: number, b: number): booleanWhether these two are excluded.
| Parameter | Type | Description |
|---|---|---|
a | number | |
b | number |
removeBody
removeBody(index: number): numberRemove a body, filling its index with the last body — whose index this returns, or −1 when the
removed body was the last. Every index past the removed one can change, so a caller keeping
body indices follows the returned one; StaticRegions is the worked example.
| Parameter | Type | Description |
|---|---|---|
index | number |
step
step(dt: number): voidAdvance one fixed tick.
| Parameter | Type | Description |
|---|---|---|
dt | number |
solveIsland
solveIsland(island: number): voidAdvance one island through every substep. The executor calls this; nothing else should.
| Parameter | Type | Description |
|---|---|---|
island | number |
More
Integration is over this island's bodies only, which is what makes the call independent of every other island rather than merely ordered against them.
wakeIsland
wakeIsland(index: number): voidWake a body and everything sharing its island, which is what an external impulse must do.
| Parameter | Type | Description |
|---|---|---|
index | number |
raycast
raycast(ox: number, oy: number, oz: number, dx: number, dy: number, dz: number, maxDistance: number, out: RayHit, filter?: QueryFilter): booleanThe nearest body a ray meets. Fills out and allocates nothing.
| Parameter | Type | Description |
|---|---|---|
ox | number | |
oy | number | |
oz | number | |
dx | number | |
dy | number | |
dz | number | |
maxDistance | number | |
out | RayHit | |
filter? | QueryFilter |
shapecast
shapecast(shape: ConvexShape, pose: ShapePose, dx: number, dy: number, dz: number, out: RayHit, filter?: QueryFilter): booleanThe first body a swept shape touches.
| Parameter | Type | Description |
|---|---|---|
shape | ConvexShape | |
pose | ShapePose | |
dx | number | |
dy | number | |
dz | number | |
out | RayHit | |
filter? | QueryFilter |
overlap
overlap(shape: ConvexShape, pose: ShapePose, out: Int32Array, filter?: QueryFilter): numberEvery body overlapping a shape, filling out to its length. Returns how many were written.
| Parameter | Type | Description |
|---|---|---|
shape | ConvexShape | |
pose | ShapePose | |
out | Int32Array | |
filter? | QueryFilter |
applyImpulse
applyImpulse(body: number, px: number, py: number, pz: number, atX: number, atY: number, atZ: number): voidApply an impulse at a world-space point.
| Parameter | Type | Description |
|---|---|---|
body | number | |
px | number | |
py | number | |
pz | number | |
atX | number | |
atY | number | |
atZ | number |
More
The point is not optional, and bindings/core.ts makes it required at the language boundary
for the reason AGENTS.md's step four gives: a caller who omits it gets an impulse through the
centre of mass, which produces no rotation at all. That is a wrong result rather than an
error, and it reads as a broken impulse rather than as a missing argument.
applyForce
applyForce(body: number, fx: number, fy: number, fz: number, dt: number, atX: number, atY: number, atZ: number): voidA force applied for one tick, which is an impulse of force · dt.
| Parameter | Type | Description |
|---|---|---|
body | number | |
fx | number | |
fy | number | |
fz | number | |
dt | number | |
atX | number | |
atY | number | |
atZ | number |
setVelocity
setVelocity(body: number, vx: number, vy: number, vz: number): voidSet a body's velocity outright, waking whatever it was resting against.
| Parameter | Type | Description |
|---|---|---|
body | number | |
vx | number | |
vy | number | |
vz | number |
setPosition
setPosition(body: number, x: number, y: number, z: number): voidMove a body outright, which is a teleport rather than a push.
| Parameter | Type | Description |
|---|---|---|
body | number | |
x | number | |
y | number | |
z | number |
More
The broadphase proxy moves with it, or the body would be found where it used to be until it next drifted out of its own fat bounds.
bodyMass
bodyMass(body: number): numberA body's mass, or zero where it has none because it is static or kinematic.
| Parameter | Type | Description |
|---|---|---|
body | number |
sleeping
sleeping(index: number): booleanWhether a body is currently asleep, for a caller deciding whether to bother.
| Parameter | Type | Description |
|---|---|---|
index | number |