To use Ammo.js on the server side, you must install it with the following commands:
mkdir my-game
cd my-game
npm init -y (to create the package.json
file)
npm i github:kripken/ammo.js (to install ammo to the node_modules
file)
nul > app.js (to create the app.js
file)
Copy the source example below into app.js and run it using node app.js
. This will create a ground and a cube. The cube coordinates will be printed to the console. Stop the program using Ctrl+C
. These articles will help you get started using Ammo.js: Tutorial on JavaScript Physics Using AmmoJS and ThreeJS
app.js
const AmmoLib = require("ammo.js");
let world, tmpTrans, Ammo;
const rigidBodies = [];
function setupPhysicsWorld()
{
const collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
const dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
const overlappingPairCache = new Ammo.btDbvtBroadphase();
const solver = new Ammo.btSequentialImpulseConstraintSolver();
world = new Ammo.btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);
world.setGravity(new Ammo.btVector3(0, -10, 0));
tmpTrans = new Ammo.btTransform();
}
function createGround()
{
const pos = { x: 0, y: 0, z: 0 };
const scale = { x: 50, y: 2, z: 50 };
const quat = { x: 0, y: 0, z: 0, w: 1 };
const mass = 0;
const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z));
transform.setRotation(new Ammo.btQuaternion(quat.x, quat.y, quat.z, quat.w));
const motionState = new Ammo.btDefaultMotionState(transform);
const colShape = new Ammo.btBoxShape(new Ammo.btVector3(scale.x / 2, scale.y / 2, scale.z / 2));
colShape.setMargin(0.05);
const localInertia = new Ammo.btVector3(0, 0, 0);
colShape.calculateLocalInertia(mass, localInertia);
const rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, colShape, localInertia);
const body = new Ammo.btRigidBody(rbInfo);
world.addRigidBody(body);
}
function createBox(pos)
{
const scale = { x: 1, y: 1, z: 1 };
const quat = { x: 0, y: 0, z: 0, w: 1 };
const mass = 10;
const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z));
transform.setRotation(new Ammo.btQuaternion(quat.x, quat.y, quat.z, quat.w));
const motionState = new Ammo.btDefaultMotionState(transform);
const colShape = new Ammo.btBoxShape(new Ammo.btVector3(scale.x / 2, scale.y / 2, scale.z / 2));
colShape.setMargin(0.05);
const localInertia = new Ammo.btVector3(0, 0, 0);
colShape.calculateLocalInertia(mass, localInertia);
const rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, colShape, localInertia);
const body = new Ammo.btRigidBody(rbInfo);
world.addRigidBody(body);
rigidBodies.push(body);
}
function updatePhysics()
{
world.stepSimulation(0.05, 10);
for (let i = 0; i < rigidBodies.length; i++)
{
let objAmmo = rigidBodies[i];
let ms = objAmmo.getMotionState();
if (ms)
{
ms.getWorldTransform(tmpTrans);
const p = tmpTrans.getOrigin();
const q = tmpTrans.getRotation();
console.log(p.x(), p.y(), p.z());
}
}
}
function start()
{
setupPhysicsWorld();
createGround();
createBox({ x: 0, y: 3, z: 0 });
setInterval(updatePhysics, 1000 / 20);
}
AmmoLib().then((re) => {
Ammo = re;
start();
});