How to Apply Force to Ammo.js Soft Body Vertex
This article explains how to apply a localized physical force to a specific vertex (node) of an Ammo.js soft body. You will learn how to identify the target vertex index, create the force vector using the Ammo.js API, apply the force directly to the node, and manage memory allocation to ensure smooth performance in your 3D physics simulation.
In Ammo.js (the Emscripten port of the Bullet Physics engine), soft
bodies are composed of a collection of interconnected nodes (vertices).
To apply a localized force to a single point on a soft body, you must
target its specific node index using the addForce method of
the btSoftBody class.
Step 1: Identify the Target Vertex Index
Before applying force, you need the index of the vertex you want to manipulate. This index corresponds to the vertex’s position in the geometry array used to generate the soft body.
If you are determining the vertex dynamically (for example, via a user click or collision), you can perform a raycast to find the intersection point, loop through the soft body’s nodes, and identify the node closest to the collision point.
Step 2: Create the Force Vector
Define the direction and magnitude of the localized force using a
btVector3 object.
// Define a force vector (e.g., applying 15 units of force along the Y-axis)
const forceVector = new Ammo.btVector3(0, 15, 0);Step 3: Apply the Force to the Soft Body Node
Use the addForce method on your soft body instance. This
method takes two arguments: the btVector3 force vector and
the integer index of the target vertex.
const vertexIndex = 42; // The specific index of the vertex
// Apply the localized force to the vertex
softBody.addForce(forceVector, vertexIndex);This force will be processed during the next physics step simulation
(physicsWorld.stepSimulation()). Because it is a force and
not an impulse, you may need to apply it continuously over multiple
animation frames if you want a sustained push rather than a momentary
nudge.
Step 4: Clean Up Memory
Since Ammo.js is written in C++ and compiled to
WebAssembly/JavaScript, objects created with the new
keyword must be manually deallocated to prevent memory leaks.
// Destroy the vector once it has been applied to the physics engine
Ammo.destroy(forceVector);Complete Code Example
Below is a complete implementation showing how to apply a one-time localized force to a specific vertex within your render or physics update loop:
function applyLocalizedForce(softBody, vertexIndex, forceX, forceY, forceZ) {
// 1. Create the Ammo.js vector
const force = new Ammo.btVector3(forceX, forceY, forceZ);
// 2. Apply the force to the specified node index
softBody.addForce(force, vertexIndex);
// 3. Clean up the allocated vector memory
Ammo.destroy(force);
}
// Example usage: Apply an upward and outward force to vertex 105
applyLocalizedForce(mySoftBody, 105, 5.0, 20.0, -2.0);