Define a Cylinder Collision Shape in Ammo.js
This article provides a straightforward guide on how to correctly define and implement a cylinder collision shape using ammo.js, the JavaScript port of the Bullet physics engine. You will learn how to configure the dimensions, select the correct alignment axis, and manage memory properly to create accurate cylinder colliders for your 3D physics simulations.
Understanding Half-Extents
In ammo.js, collision shapes are defined using “half-extents” rather than full dimensions. Half-extents represent half of the total width, height, and depth of the bounding box that encloses the shape.
For a cylinder with a total height of \(H\) and a radius of \(R\): * Half-width (X): \(R\) * Half-height (Y): \(H / 2\) * Half-depth (Z): \(R\)
Step-by-Step Implementation
By default, the standard btCylinderShape class in
ammo.js creates a cylinder aligned along the
Y-axis.
Here is the JavaScript code required to define it:
// 1. Define the physical dimensions of the cylinder
const radius = 2.0;
const height = 5.0;
// 2. Create a btVector3 representing the half-extents
// For a Y-aligned cylinder, the vector is (radius, half-height, radius)
const halfExtents = new Ammo.btVector3(radius, height / 2, radius);
// 3. Instantiate the cylinder collision shape
const cylinderShape = new Ammo.btCylinderShape(halfExtents);
// 4. Clean up the temporary vector from memory
Ammo.destroy(halfExtents);Aligning the Cylinder to Other Axes
Bullet physics provides specific classes if your cylinder needs to lie along a different axis by default. Using these classes eliminates the need to manually rotate the shape’s local transform:
X-Axis Alignment (
btCylinderShapeX): The cylinder’s length runs along the X-axis.const halfExtents = new Ammo.btVector3(height / 2, radius, radius); const cylinderShape = new Ammo.btCylinderShapeX(halfExtents);Z-Axis Alignment (
btCylinderShapeZ): The cylinder’s length runs along the Z-axis.const halfExtents = new Ammo.btVector3(radius, radius, height / 2); const cylinderShape = new Ammo.btCylinderShapeZ(halfExtents);
Memory Management Note
Because ammo.js is a WebAssembly/Emscripten port of C++, it does not
automatically garbage-collect physics objects. Whenever you instantiate
an Ammo object using the new keyword (such as
btVector3), you must call Ammo.destroy(object)
once it is no longer needed to prevent memory leaks. The collision shape
itself (cylinderShape) should also be destroyed when the
physics world is cleaned up.