Dynamic vs Kinematic Rigid Bodies in Ammo.js

This article explains the technical differences between dynamic and kinematic rigid bodies in the ammo.js physics engine. You will learn how each body type is simulated, how they interact with the physics world, and the specific API calls and flags required to implement them in your JavaScript applications.

Dynamic Rigid Bodies

Dynamic rigid bodies are fully simulated by the ammo.js physics engine. They react to forces, gravity, collisions, and impulses according to the laws of classical mechanics.

Technical Characteristics

Code Implementation

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

let startTransform = new Ammo.btTransform();
startTransform.setIdentity();
startTransform.setOrigin(new Ammo.btVector3(0, 10, 0));

let motionState = new Ammo.btDefaultMotionState(startTransform);
let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, geometryShape, localInertia);
let body = new Ammo.btRigidBody(rbInfo);

physicsWorld.addRigidBody(body);

Kinematic Rigid Bodies

Kinematic rigid bodies are hybrid objects that are not affected by physics forces, gravity, or collisions, yet they can collide with and push dynamic bodies. They are typically used for moving platforms, doors, or character controllers.

Technical Characteristics

Code Implementation

To convert a static body (mass = 0) into a kinematic body in ammo.js, you must explicitly set the kinematic collision flag and disable the sleep state.

let mass = 0; // Must be zero
let localInertia = new Ammo.btVector3(0, 0, 0);

let startTransform = new Ammo.btTransform();
startTransform.setIdentity();

let motionState = new Ammo.btDefaultMotionState(startTransform);
let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, geometryShape, localInertia);
let body = new Ammo.btRigidBody(rbInfo);

// Set kinematic flag (CF_KINEMATIC_OBJECT = 2)
body.setCollisionFlags(body.getCollisionFlags() | 2);

// Prevent the body from going to sleep (DISABLE_DEACTIVATION = 4)
body.setActivationState(4);

physicsWorld.addRigidBody(body);

To move the kinematic body during your render loop:

let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(newX, newY, newZ));

// Update the motion state; ammo.js will read this on the next stepSimulation
body.getMotionState().setWorldTransform(transform);

Direct Technical Comparison

Feature Dynamic Rigid Body Kinematic Rigid Body
Mass Value Greater than zero (> 0) Must be zero (0)
Primary Driver Physics engine (gravity, forces, collisions) User code (direct transform updates)
Affected by Gravity Yes No
Can Push Dynamic Bodies Yes Yes (with infinite simulated mass)
Can Be Pushed by Dynamic Bodies Yes No
Ammo.js Flags Required Default flags CF_KINEMATIC_OBJECT & DISABLE_DEACTIVATION
Motion State Pipeline Physics engine updates the Motion State User updates the Motion State; Engine reads it