Physics · function

ejectFromSolid

Push a body out of solid geometry it has ended up inside.

Explained in Your first game, Rigid bodies.

function ejectFromSolid(body: Body, colliders: ColliderSet, scratch: Int32Array, probe: Aabb): boolean
import { ejectFromSolid } from '@driftengine/physics';

Parameters

ParameterTypeDescription
bodyBody
collidersColliderSet
scratchInt32Array
probeAabb

In depth

This is not collision, and that distinction is the whole of why it exists. moveAxis resolves a move against what is in the way, and it is a swept test: it asks how far a body may travel before it touches something. A body that is already interpenetrating has nothing left to sweep against — both of the plain path's clamps test a face the body is already past, so neither fires, and an overlapping body moves freely. That is the mechanism behind the complaint that a character "sometimes passes through" a surface: one frame inside a column and the column has stopped existing for as long as the body remains in it.

It is also why such a body can stand in mid-air inside a slab and be told it is grounded: nothing clamped the downward move, so contactSupport keeps the true it starts with, and every backstop a consumer has — a wedge counter, a refused-move flag — is waiting for the world to push back, which it has stopped doing.

Gated on the body's centre, not on overlap. Overlap on its own is ordinary and expected: a deck's hull sits a give below the surface a character rides, so a grounded body's feet are inside it by design, and a pad's box is sunk under the pad. What none of those produce is a centre inside the box — a standing body's centre is half its height above its feet. So the centre test separates riding from burial exactly, and this can be run every tick without ever firing on a body that is merely resting on something.

Hulls are skipped, deliberately. A hull collider's box is its broad phase and its real volume is the convex shape inside it, so a centre inside the box says nothing about whether the body is inside the hull. Pushing on that evidence would move bodies that are simply near a deck. What this covers is every plain collider — the columns, the props, the pads, the arch feet — which is where the reported pass-throughs were captured.

The push is the shortest way out and it is applied whole: half a resolution leaves the body inside, which is the state this exists to end. Returns true when something moved, so a caller can treat it as the event it is rather than polling.

Allocation-free: the caller owns scratch and probe, as everywhere else in this module.