Changing Body Mass in Matter.js: Impact on Density
In Matter.js, changing a rigid body's mass directly alters its
density, provided you use the official engine methods. Because Matter.js
calculates density as mass divided by surface area, altering the mass
while the body's geometry remains constant causes the engine to
recalculate and update the body.density property
automatically. However, how this update occurs depends strictly on
whether you modify the body via the API or through direct property
assignment.
The Relationship Between Mass, Density, and Area
Matter.js relies on a simple geometric formula to maintain physical consistency:
\[\text{density} = \frac{\text{mass}}{\text{area}}\]
When a body is initially created, Matter.js assigns a default density
(typically 0.001) and calculates the initial mass based on
the computed area of the shape.
Updating Mass Using
Body.setMass
To safely update a body's mass, you should always use the built-in module function:
Matter.Body.setMass(body, newMass);When you call Body.setMass(), Matter.js executes an
internal routine that updates several dependent properties at once:
- Recalculates Density: The engine sets
body.density = body.mass / body.area. Increasing mass increases density proportionally; decreasing mass lowers density. - Updates Inverse Mass: It recalculates
body.inverseMass = 1 / body.mass, which the collision solver relies on for performance. - Adjusts Inertia: It scales the rotational inertia
(
body.inertiaandbody.inverseInertia) to match the new mass, preventing unnatural spinning or resistance during collisions.
Direct Mutation Pitfall
(body.mass = value)
If you manually overwrite the property directly using
body.mass = newMass, density will not
change.
Matter.js does not use active getters and setters for its core
physics properties. Directly assigning a new value to
body.mass leaves body.density,
body.inverseMass, and body.inertia at their
previous values. This desynchronization can produce erratic physics
behaviors, such as incorrect impulse responses during collisions and
unnatural rotational dynamics.
Modifying Density Instead
If your goal is to make an object behave as if it were made of a heavier material (like changing wood to metal), the recommended approach in Matter.js is to alter the density directly rather than the mass:
Matter.Body.setDensity(body, newDensity);Calling Body.setDensity() performs the inverse
operation: it recalculates body.mass as
density * area and updates all related inertia parameters
accordingly.