Resetting Matter.js Body Velocity for Object Pooling
Object pooling in Matter.js optimizes performance by reusing existing rigid bodies instead of repeatedly allocating and garbage-collecting them. However, reusing a body requires completely clearing residual forces, linear velocities, angular velocities, and internal momentum trackers to prevent erratic movement upon re-entry into the simulation. This guide details the essential properties and methods required to sanitize a Matter.js body before recycling it.
Why Resetting Is Necessary
Matter.js calculates motion using a Verlet integration scheme that
relies on both the current position and the previous position
(positionPrev), alongside accumulated force vectors. Simply
moving a body to a new position using
body.position.x = newX without resetting its internal
velocity vectors or force buffers will cause the engine to interpret the
teleportation as massive instantaneous velocity, launching the object
unexpectedly.
Key Properties to Clear
To return a dynamic body to a neutral resting state, you must clear:
- Linear Velocity: Set current linear movement in both the X and Y axes to zero.
- Angular Velocity: Set rotational speed to zero.
- Forces: Clear direct force accumulators applied during the previous lifecycle.
- Torque: Clear accumulated rotational force.
- Position History: Synchronize previous positions to prevent velocity calculation artifacts.
The Reset Function
Use the built-in Matter.Body methods combined with
manual force clearance to ensure all state variables are fully
purged:
function resetBody(body, x, y, angle = 0) {
// 1. Clear linear and angular velocity
Matter.Body.setVelocity(body, { x: 0, y: 0 });
Matter.Body.setAngularVelocity(body, 0);
// 2. Clear accumulated forces and torques
body.force.x = 0;
body.force.y = 0;
body.torque = 0;
// 3. Update position and angle
Matter.Body.setPosition(body, { x: x, y: y });
Matter.Body.setAngle(body, angle);
// 4. Synchronize previous positions to eliminate Verlet artifacts
body.positionPrev.x = x;
body.positionPrev.y = y;
body.anglePrev = angle;
// 5. Wake the body if sleep management is enabled
if (body.isSleeping) {
Matter.Sleeping.set(body, false);
}
}Deactivating and Re-inserting Bodies
When moving a body into the inactive pool:
- Remove it from the active
CompositeorWorldusingMatter.Composite.remove(engine.world, body). - Alternatively, set
body.isSensor = true,body.render.visible = false, andbody.collisionFilter.mask = 0if retaining the body in the world hierarchy without physical interactions.
When pulling the body out of the pool:
- Execute the
resetBody()function with the target spawn coordinates. - Re-add the body to
engine.worldviaMatter.Composite.add(engine.world, body)(if removed earlier) or restore its collision masks and rendering flags.