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