Configure Anisotropic Friction in Ammo.js
This article explains how to configure anisotropic friction for specialized surfaces using ammo.js, the JavaScript port of the Bullet physics engine. You will learn how to define directional friction coefficients, enable the necessary collision flags, and apply these settings to rigid bodies to simulate realistic physical materials like ice skate blades, skis, or textured conveyor belts.
Understanding Anisotropic Friction
Standard (isotropic) friction resists motion equally in all directions across a surface. Anisotropic friction allows you to define different friction coefficients along the local coordinate axes (X, Y, and Z) of a rigid body. This is essential for simulating surfaces where sliding is easier in one direction than another.
Step-by-Step Configuration in Ammo.js
To implement anisotropic friction on a rigid body in ammo.js, follow these three steps:
1. Define the Friction Directional Coefficients
First, create a btVector3 that defines the friction
multiplier for the local X, Y, and Z axes. A value of 1.0
maintains the default friction of the body, while lower values reduce
friction along that specific axis.
// Create a vector representing friction scaling along local axes (X, Y, Z)
// In this example, friction is significantly reduced along the Y-axis
var frictionScale = new Ammo.btVector3(1.0, 0.1, 1.0);2. Apply the Coefficients to the Rigid Body
Use the setAnisotropicFriction method on your
btRigidBody instance. This method takes the friction scale
vector and an optional friction mode flag as arguments.
// Assuming 'rigidBody' is an already initialized Ammo.btRigidBody
var frictionMode = 1; // 1 enables anisotropic friction, 2 enables anisotropic rolling friction
rigidBody.setAnisotropicFriction(frictionScale, frictionMode);3. Enable the Anisotropic Collision Flag
For the physics solver to process directional friction, you must explicitly enable the anisotropic friction flag on the collision object. Retrieve the current collision flags, perform a bitwise OR operation with the anisotropic flag, and write the new flags back to the body.
// Get current collision flags
var flags = rigidBody.getCollisionFlags();
// Enable anisotropic friction flag (CF_ANISOTROPIC_FRICTION has a value of 1)
var CF_ANISOTROPIC_FRICTION = 1;
rigidBody.setCollisionFlags(flags | CF_ANISOTROPIC_FRICTION);Practical Example
Below is a complete implementation helper function to configure anisotropic friction on any existing Ammo.js rigid body:
function enableAnisotropicFriction(rigidBody, xScl, yScl, zScl) {
// 1. Create the vector for axis scaling
var scaleVec = new Ammo.btVector3(xScl, yScl, zScl);
// 2. Set the anisotropic friction on the body with mode 1 (Anisotropic Friction)
rigidBody.setAnisotropicFriction(scaleVec, 1);
// 3. Update the collision flags to notify the solver
var currentFlags = rigidBody.getCollisionFlags();
var CF_ANISOTROPIC_FRICTION = 1;
rigidBody.setCollisionFlags(currentFlags | CF_ANISOTROPIC_FRICTION);
// Clean up memory allocated for the vector
Ammo.destroy(scaleVec);
}
// Usage: Ease movement along the Z-axis of a ski object
enableAnisotropicFriction(skiRigidBody, 1.0, 1.0, 0.05);Key Considerations
- Local Coordinates: Anisotropic friction axes are bound to the local coordinate system of the rigid body, not the global world space. As the body rotates, the direction of low friction rotates with it.
- Memory Management: Always destroy temporary helper
vectors like
btVector3usingAmmo.destroy()if they are created inside a loop or frequently called function to prevent memory leaks in the WebAssembly heap.