How Matter.Pairs.update Preserves Contacts
In Matter.js, Matter.Pairs.update maintains the state of
colliding rigid bodies across successive frames by caching, updating,
and pruning contact pairs. Rather than reallocating collision records
every frame, this method matches fresh collision detections against an
internal hash table of existing pairs. This persistence mechanism
enables accurate collision event lifecycles—such as distinguishing when
collisions start, persist, or end—and allows the engine to preserve
accumulated impulse data necessary for warm-starting the constraint
solver and eliminating physical jitter.
Deterministic Pair Indexing
Contact persistence relies on consistent identification of
interacting bodies. During the broadphase and narrowphase steps,
collision detectors evaluate interactions between bodies. When a
collision occurs between two objects, Matter.js derives a deterministic
string identifier via Pair.id(bodyA, bodyB). This
identifier orders body IDs canonically (ensuring that an interaction
between Body A and Body B produces the same key regardless of argument
order).
Matter.Pairs maintains a lookup table
(pairs.table) indexed by these keys. During
Pairs.update, incoming collisions are checked against
pairs.table to determine whether the contact is newly
formed or already established.
In-Place State Mutation
When a collision matches an existing entry in
pairs.table:
- Object Retention: The engine does not instantiate a
new
Pairobject. It updates the existing reference with new geometric data, including the collision normal, penetration depth, and contact points calculated by the Separating Axis Theorem (SAT). - Lifecycle Flagging: The pair's
isActiveflag is maintained, and internal timestamps (timeUpdated) are refreshed to match the current engine tick. This avoids the garbage collection overhead associated with allocating new objects on every physics step. - Event Classification: By comparing the current
active pairs with those from the previous frame, the system determines
which contacts trigger
collisionStart, which continue ascollisionActive, and which are removed to firecollisionEnd.
Impulse Preservation and Warm Starting
Preserving contact pairs across frames is critical for physical stability. The iterative constraint solver in Matter.js resolves resting contacts, stacking, and friction by accumulating impulses over multiple iterations.
Because Pairs.update mutates existing pair references
instead of replacing them, the engine retains previously calculated
normal and tangential impulses. The constraint solver utilizes these
stored values as an initial guess for the next frame—a technique known
as warm starting. Warm starting significantly improves convergence
rates, prevents bodies from sinking into one another, and stops resting
stacks from jittering.
Pruning Inactive Contacts
To ensure memory does not leak and non-colliding bodies do not retain
phantom contacts, Matter.Pairs.update tracks pair
validity:
- Any pair in
pairs.tablethat does not receive a matching collision during the narrowphase update is flagged as inactive. - Inactive pairs are removed from the active
pairs.listarray and scheduled for cleanup. - Once removed, the engine fires the corresponding separation events, and the stored impulse counters are discarded, resetting the contact state for any future interactions between those two bodies.