How to Toggle CCD Dynamically in Ammo.js
This article explains how to dynamically enable and disable Continuous Collision Detection (CCD) for a specific rigid body in Ammo.js. You will learn how to use the built-in Bullet physics API methods to toggle this feature on the fly, allowing you to prevent fast-moving objects from passing through barriers while optimizing performance when high-precision collision detection is no longer required.
Understanding CCD in Ammo.js
Continuous Collision Detection (CCD) prevents fast-moving physics bodies from passing through other geometry (a glitch known as “tunneling”). Ammo.js handles CCD by sweeping a sphere along the object’s motion path.
To control CCD on a btRigidBody, Ammo.js utilizes two
key properties: 1. Motion Threshold: The minimum
distance an object must travel in a single simulation step to trigger
CCD. 2. Swept Sphere Radius: The radius of the bounding
sphere used to test for swept collisions.
Setting both of these values to greater than zero enables CCD. Setting them to zero disables it.
Toggling CCD Code Example
To dynamically toggle CCD, you can define a helper function that
modifies these properties on a specific Ammo.btRigidBody
instance.
/**
* Dynamically toggles CCD on a specific Ammo.js rigid body.
* @param {Ammo.btRigidBody} rigidBody - The target rigid body.
* @param {boolean} enable - True to enable CCD, false to disable.
* @param {number} [sphereRadius=0.5] - The radius of the swept sphere (used when enabling).
* @param {number} [motionThreshold=1e-7] - The motion threshold (used when enabling).
*/
function toggleCCD(rigidBody, enable, sphereRadius = 0.5, motionThreshold = 0.0001) {
if (enable) {
// Enable CCD by setting positive values
rigidBody.setCcdMotionThreshold(motionThreshold);
rigidBody.setCcdSweptSphereRadius(sphereRadius);
} else {
// Disable CCD by setting both values to zero
rigidBody.setCcdMotionThreshold(0);
rigidBody.setCcdSweptSphereRadius(0);
}
}How the Parameters Work
Enabling CCD
To activate CCD, pass a motion threshold and a swept sphere radius.
setCcdMotionThreshold: This should represent the size of your object. For example, if your object is a sphere with a radius of0.5, setting the motion threshold to0.5ensures CCD only kicks in if the object moves more than its own radius in a single frame.setCcdSweptSphereRadius: This represents the radius of the embedded sphere used for the swept volume collision test. This value is typically set slightly smaller than the object’s actual radius (e.g.,0.2for an object of size0.5) to avoid false positive collisions at rest.
Disabling CCD
To turn off CCD dynamically, set both
setCcdMotionThreshold and
setCcdSweptSphereRadius to 0. Ammo.js will
immediately fall back to discrete collision detection for that specific
body on the next physics step, saving CPU cycles.