Collision Detection Frontend / Backend

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();
});
1 Like