Create and Manipulate btVector3 in Ammo.js

This guide explains how to properly create, read, modify, and destroy btVector3 spatial objects in Ammo.js, the WebAssembly port of the Bullet physics engine. You will learn the correct syntax for vector operations and crucial memory management techniques required to prevent memory leaks in your 3D applications.

Creating a btVector3 Object

To instantiate a new 3D vector in Ammo.js, use the Ammo.btVector3 constructor. You can initialize it with specific X, Y, and Z coordinates, or default to zero.

// Create a vector with default values (0, 0, 0)
const defaultVector = new Ammo.btVector3();

// Create a vector with specific coordinates (x, y, z)
const positionVector = new Ammo.btVector3(1.0, 5.5, -2.0);

Reading Vector Values

In Ammo.js, X, Y, and Z are accessed using getter methods rather than direct properties. Calling these functions returns standard JavaScript numbers.

const x = positionVector.x();
const y = positionVector.y();
const z = positionVector.z();

console.log(`Coordinates: X: ${x}, Y: ${y}, Z: ${z}`);

Manipulating Vector Values

To change the coordinates of an existing btVector3, you can update individual axes or set all three values simultaneously.

const vector = new Ammo.btVector3();

// Modify individual components
vector.setX(10.0);
vector.setY(20.0);
vector.setZ(30.0);

// Modify all components at once
vector.setValue(5.0, 15.0, 25.0);

Performing Vector Mathematics

Ammo.js provides built-in methods for common mathematical operations, allowing you to scale, add, or calculate dot and cross products.

const vecA = new Ammo.btVector3(1, 2, 3);
const vecB = new Ammo.btVector3(4, 5, 6);

// Addition (modifies vecA in place)
vecA.op_add(vecB); 

// Scaling (multiplies vecA by a scalar value in place)
vecA.op_mul(2.0);

// Dot Product
const dotProduct = vecA.dot(vecB);

// Cross Product (returns a new btVector3)
const crossProduct = vecA.cross(vecB);

Crucial Memory Management

Because Ammo.js is a WebAssembly/C++ wrapper, JavaScript’s automatic garbage collector does not release the memory allocated for btVector3 objects. To prevent severe memory leaks, you must manually destroy every vector you create once it is no longer needed.

// Create the vector
const tempVector = new Ammo.btVector3(0, 10, 0);

// Use the vector in your physics calculations
rigidBody.setLinearVelocity(tempVector);

// Deallocate the memory
Ammo.destroy(tempVector);