Soft Body Cluster Collision in Ammo.js
This article explains soft body cluster collision in the ammo.js physics engine, detailing what it is, why it is used for performance optimization, and the exact steps required to enable it in your JavaScript-based 3D applications.
Understanding Soft Body Cluster Collision
In physics simulation, a soft body is a deformable object—such as gelatin, cloth, or rubber—whose shape changes upon impact. Simulating these objects realistically requires representing them as a network of vertices (nodes) and links. By default, calculating collisions for every individual vertex against other physical objects is computationally expensive and can severely degrade performance.
Cluster collision solves this performance bottleneck. Instead of checking every node, the physics engine groups the soft body’s vertices into localized “clusters.” The engine then calculates collisions between these clusters and other rigid or soft bodies. This approximation dramatically reduces the number of collision checks, allowing for real-time simulation of complex deformable objects while still maintaining a highly realistic appearance.
How to Enable Cluster Collision in Ammo.js
To use cluster collision in ammo.js (the Emscripten port of the Bullet Physics engine), you must configure both the soft body’s structure and its collision configuration flags.
Step 1: Initialize the Soft Body World
Ensure you are using btSoftRigidDynamicsWorld as your
physics world, as standard rigid-only dynamics worlds do not support
soft bodies.
const collisionConfiguration = new Ammo.btSoftBodyRigidBodyCollisionConfiguration();
const dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
const broadphase = new Ammo.btDbvtBroadphase();
const solver = new Ammo.btSequentialImpulseConstraintSolver();
const softBodySolver = new Ammo.btDefaultSoftBodySolver();
const physicsWorld = new Ammo.btSoftRigidDynamicsWorld(
dispatcher,
broadphase,
solver,
collisionConfiguration,
softBodySolver
);Step 2: Create the Soft Body and Generate Clusters
When creating your soft body (for example, from a mesh helper), you
must explicitly tell Ammo.js to generate the collision clusters. This is
done using the generateClusters method, passing the number
of clusters you want to create.
// Assuming 'softBody' has been created via Ammo.btSoftBodyHelpers
const numClusters = 64; // Adjust based on complexity and performance needs
softBody.generateClusters(numClusters);Step 3: Configure Collision Flags
Once the clusters are generated, you must update the soft body’s
configuration (m_cfg) to instruct the engine to use
cluster-based collision detection instead of vertex-based detection.
You can enable cluster-to-rigid-body collisions, cluster-to-soft-body collisions, or both by using bitwise operations on the collision flags:
const sbConfig = softBody.get_m_cfg();
// Clear default collisions and enable cluster-based collisions
sbConfig.set_collisions(0x0000);
// Enable Cluster vs. Rigid Body collisions (CL_RS)
sbConfig.set_collisions(sbConfig.get_collisions() | 0x0001);
// Enable Cluster vs. Soft Body collisions (CL_SS)
sbConfig.set_collisions(sbConfig.get_collisions() | 0x0002);Step 4: Set Solver Iterations
Because cluster collisions rely on joint-like constraints between clusters, you may need to increase the cluster solver iterations to prevent objects from clipping or passing through one another.
// Increase cluster solver iterations for stability (default is usually 1)
sbConfig.set_citerations(4); Once these configurations are applied, add the soft body to your
physics world using physicsWorld.addSoftBody(softBody). The
engine will now handle all physical interactions using the optimized
cluster collision method.