Setting Body Mass Instead of Density in Matter.js

In Matter.js, physics bodies automatically calculate their mass based on their area and a default density value. However, you can manually set the mass of a body instead of relying on density calculations. This article explains how to explicitly define mass during body creation or update it dynamically at runtime, as well as how Matter.js reconciles the relationship between mass, density, and inertia.

Setting Mass During Body Creation

You can override the default automatic calculation by passing a mass property inside the options object when creating a body.

const { Bodies } = Matter;

// Create a body with an explicit mass of 50
const box = Bodies.rectangle(400, 200, 80, 80, {
  mass: 50
});

When you pass an explicit mass value at instantiation, Matter.js accepts the value and automatically recalculates the body's density behind the scenes using the formula:

\[\text{density} = \frac{\text{mass}}{\text{area}}\]

Updating Mass Dynamically

If the body has already been instantiated, you should not set body.mass = newMass directly. Directly modifying properties can cause physics calculation errors because internal properties such as inverseMass, inertia, and inverseInertia will not update.

Instead, use the built-in Body.setMass method:

const { Body } = Matter;

// Correct way to update mass dynamically
Body.setMass(box, 100);

Using Body.setMass() ensures that:

How Matter.js Balances Mass and Density

Matter.js always keeps mass, density, and area synchronized. They are not independent variables:

  1. Changing Density: If you call Body.setDensity(body, newDensity), Matter.js updates the mass (mass = newDensity * area).
  2. Changing Mass: If you call Body.setMass(body, newMass), Matter.js updates the density (density = newMass / area).
  3. Scaling Dimensions: If you scale a body using Body.scale(body, scaleX, scaleY), its area changes. By default, Matter.js preserves the body's density and recalculates the mass to reflect the new size. If you want the body to retain its exact mass after scaling, you must call Body.setMass() again after the scale operation.

Considerations for Static Bodies

Static bodies (bodies created with isStatic: true) are treated as having infinite mass and zero inverse mass:

Attempting to set a finite mass on a static body will not make it dynamic. To apply a manual mass to a previously static body, you must first convert it to a dynamic body using Body.setStatic(body, false) before defining its mass.