Initialize Soft Body Physics in Ammo.js

This article provides a direct, step-by-step guide on how to initialize a specialized soft body physics world in Ammo.js, the JavaScript port of the Bullet Physics engine. You will learn about the specific classes required to support soft body dynamics—such as clothes, ropes, and deformable volumes—and how to configure them in JavaScript.

To simulate soft bodies in Ammo.js, you cannot use the standard rigid body dynamics world. Instead, you must initialize a btSoftRigidDynamicsWorld and configure it with a dedicated soft body solver and collision configuration.

Here is the step-by-step process and the code required to set up the environment.

1. Collision Configuration

Standard rigid body simulations use btDefaultCollisionConfiguration. For soft bodies, you must use btSoftBodyRigidBodyCollisionConfiguration. This allows the collision dispatcher to handle interactions between soft bodies, rigid bodies, and other soft bodies.

const collisionConfiguration = new Ammo.btSoftBodyRigidBodyCollisionConfiguration();

2. Dispatcher and Broadphase

The collision dispatcher and broadphase algorithm detect when objects are close to or touching each other. These remain similar to a standard setup, but they operate using the soft body collision configuration defined above.

const dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
const broadphase = new Ammo.btDbvtBroadphase();

3. Constraint Solver

The solver handles the forces and constraints (like joints and contacts) between objects. A sequential impulse constraint solver is standard.

const solver = new Ammo.btSequentialImpulseConstraintSolver();

4. Soft Body Solver

You must instantiate a dedicated solver to calculate the deformation and internal forces of the soft bodies.

const softBodySolver = new Ammo.btDefaultSoftBodySolver();

5. Instantiating the World

With all components ready, instantiate the btSoftRigidDynamicsWorld. Pass the dispatcher, broadphase, solver, collision configuration, and soft body solver as arguments.

const physicsWorld = new Ammo.btSoftRigidDynamicsWorld(
    dispatcher,
    broadphase,
    solver,
    collisionConfiguration,
    softBodySolver
);

6. Configuring Gravity

Soft bodies require gravity to be set in two places: the physics world itself (for rigid bodies) and the world information object (specifically for soft bodies).

const gravity = new Ammo.btVector3(0, -9.81, 0);

// Set gravity for rigid bodies
physicsWorld.setGravity(gravity);

// Set gravity for soft bodies
const worldInfo = physicsWorld.getWorldInfo();
worldInfo.set_m_gravity(gravity);

Complete Initialization Example

Below is the complete initialization block wrapped inside the Ammo asynchronous initializer:

Ammo().then(function(Ammo) {
    // 1. Setup collision configuration
    const collisionConfiguration = new Ammo.btSoftBodyRigidBodyCollisionConfiguration();

    // 2. Setup dispatcher
    const dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);

    // 3. Setup broadphase
    const broadphase = new Ammo.btDbvtBroadphase();

    // 4. Setup solver
    const solver = new Ammo.btSequentialImpulseConstraintSolver();

    // 5. Setup soft body solver
    const softBodySolver = new Ammo.btDefaultSoftBodySolver();

    // 6. Create the specialized world
    const physicsWorld = new Ammo.btSoftRigidDynamicsWorld(
        dispatcher,
        broadphase,
        solver,
        collisionConfiguration,
        softBodySolver
    );

    // 7. Apply gravity
    const gravity = new Ammo.btVector3(0, -9.8, 0);
    physicsWorld.setGravity(gravity);
    physicsWorld.getWorldInfo().set_m_gravity(gravity);

    console.log("Ammo.js soft body physics world initialized successfully.");
});