Ammo.js Local Inertia vs Mass Explained

In physics engines like Ammo.js, understanding the distinction between mass and local inertia is crucial for simulating realistic physical interactions. While mass dictates an object’s resistance to linear movement, local inertia determines its resistance to rotational movement. This article explains the fundamental differences between these two properties, how Ammo.js calculates them, and how they directly influence the rotational behavior of rigid bodies.

Mass vs. Local Inertia: The Core Difference

Mass and local inertia represent two sides of the same coin: resistance to acceleration. However, they apply to different types of motion.

How Ammo.js Uses Local Inertia

In Ammo.js, which is a direct port of the Bullet physics engine, you cannot simply assign an arbitrary mass without also defining the local inertia for dynamic bodies.

When creating a dynamic rigid body, you typically calculate the local inertia using the collision shape’s built-in utility helper:

let mass = 1.0;
let localInertia = new Ammo.btVector3(0, 0, 0);

// Calculate the inertia tensor based on the shape and mass
collisionShape.calculateLocalInertia(mass, localInertia);

let constructionInfo = new Ammo.btRigidBodyConstructionInfo(
    mass, 
    motionState, 
    collisionShape, 
    localInertia
);
let body = new Ammo.btRigidBody(constructionInfo);

The calculateLocalInertia method computes how difficult it is to spin the shape around each axis based on its geometry and the provided mass.

How Local Inertia Affects Rotations

The values stored in the localInertia vector dictate how a rigid body reacts when torque (rotational force) is applied:

1. Shape-Dependent Rotational Resistance

An asymmetrical object, like a long, thin cylinder, has different inertia values for each axis. * Spinning the cylinder along its long axis (like rolling a pencil) requires very little force, meaning the local inertia for that axis is low. * Spinning the cylinder end-over-end requires much more force, meaning the local inertia for those axes is high.

If you manually set an equal inertia vector (e.g., [1, 1, 1]) on a long cylinder, it will roll and tumble with unrealistic, uniform resistance, defying real-world physics.

2. The Danger of Zero Inertia on Dynamic Bodies

In Ammo.js, static objects (objects that do not move, like floors) are defined with a mass of 0 and a local inertia of (0, 0, 0).

However, if you create a dynamic object with a mass greater than 0, you must calculate and apply a non-zero local inertia. Setting a dynamic body’s local inertia to (0, 0, 0) tells the physics solver that the object has zero resistance to rotation. This causes severe simulation glitches, such as infinite angular velocity, erratic spinning, or instant crashes of the physics simulation when the object collides.

3. Locking Rotations Correctly

If you want to prevent a dynamic object from rotating entirely (for example, a player character capsule that must always stand upright), do not set the local inertia to zero. Instead, use the setAngularFactor method on the rigid body:

// Disable rotation on all axes
body.setAngularFactor(new Ammo.btVector3(0, 0, 0));

// Allow rotation only around the Y axis
body.setAngularFactor(new Ammo.btVector3(0, 1, 0));

This tells the solver to ignore rotational forces on specific axes while maintaining a mathematically stable local inertia tensor.