Extract Vertex Data from Ammo.js Convex Hull
This article explains how to retrieve raw vertex coordinates from an
internal btConvexHullShape in ammo.js (the Emscripten port
of the Bullet physics engine). You will learn how to access the
underlying shape representation, iterate through its points using
WebAssembly-compatible methods, and safely manage the allocated memory
in JavaScript.
To extract vertex data from an ammo.js convex hull shape, you must
utilize the methods inherited from btPolyhedralConvexShape.
Although btConvexHullShape stores the points internally in
a compressed or optimized format, the WebAssembly interface exposes
helper functions to retrieve them individually without needing to access
raw heap memory directly.
The Extraction Process
The extraction relies on two key methods exposed by the
btConvexHullShape object: 1. getNumVertices():
Returns the total number of vertices in the hull. 2.
getVertex(index, vertexOut): Populates a passed
btVector3 object with the coordinates of the vertex at the
specified index.
Step-by-Step Code Implementation
Below is a clean JavaScript implementation demonstrating how to extract the vertices into a flat array of floats:
function getConvexHullVertices(convexHullShape) {
const vertices = [];
// 1. Get the total count of vertices in the hull
const numVertices = convexHullShape.getNumVertices();
// 2. Create a temporary btVector3 to store the output of each iteration
const tempVertex = new Ammo.btVector3();
try {
// 3. Loop through and extract each vertex's coordinates
for (let i = 0; i < numVertices; i++) {
convexHullShape.getVertex(i, tempVertex);
vertices.push(
tempVertex.x(),
tempVertex.y(),
tempVertex.z()
);
}
} finally {
// 4. Always destroy temporary Ammo objects to prevent WebAssembly memory leaks
Ammo.destroy(tempVertex);
}
return vertices;
}Memory Management Considerations
Because ammo.js runs inside WebAssembly, any object created with the
new keyword (like new Ammo.btVector3())
allocates memory on the Emscripten heap.
To prevent memory leaks: * Instantiated helper vectors must be freed
explicitly using Ammo.destroy(vector). * Do not instantiate
a new btVector3 inside the loop. Instead, allocate a single
temporary btVector3 outside the loop, reuse it for each
iteration, and destroy it once the loop completes.
Utilizing the Extracted Data
The resulting flat array [x1, y1, z1, x2, y2, z2, ...]
can be easily wrapped into a standard JavaScript
Float32Array. This format is ideal for: * Reconstructing
visual geometry in rendering engines like Three.js using
BufferAttribute. * Debugging physics collision boundaries
by drawing wireframes. * Serializing collision shapes for storage or
network transmission.