Getting started

Installing Rapier from NPM#

Rapier is available as the @dimforge/rapier2d and @dimforge/rapier3d NPM packages. You may add the following to your package.json:

"dependencies": {
"@dimforge/rapier2d": "*", // Replace the * by the latest version number.
}

Because Rapier is actually a WebAssembly module, it has to be loaded asynchronously. The following shows a basic example with a dynamic rigid-body falling on the ground.

import('@dimforge/rapier2d').then(RAPIER => {
// Use the RAPIER module here.
let gravity = { x: 0.0, y: -9.81 };
let world = new RAPIER.World(gravity);
// Create the ground
let groundColliderDesc = RAPIER.ColliderDesc.cuboid(10.0, 0.1);
world.createCollider(groundColliderDesc);
// Create a dynamic rigid-body.
let rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic()
.setTranslation(0.0, 1.0);
let rigidBody = world.createRigidBody(rigidBodyDesc);
// Create a cuboid collider attached to the dynamic rigidBody.
let colliderDesc = RAPIER.ColliderDesc.cuboid(0.5, 0.5);
let collider = world.createCollider(colliderDesc, rigidBody);
// Game loop. Replace by your own game loop system.
let gameLoop = () => {
// Ste the simulation forward.
world.step();
// Get and print the rigid-body's position.
let position = rigidBody.translation();
console.log("Rigid-body position: ", position.x, position.y);
setTimeout(gameLoop, 16);
};
gameLoop();
})

See the testbed3d/src/demos and testbed2d/src/demos folders for examples on how to initialize a Rapier physics world using these bindings.

Using Rapier without a bundler#

If you are attempting to use Rapier without a bundler, or if you are using a bundler that doesn't support WASM files properly, the previous solution will be difficult to get working. The alternative is to use our compatibility UMD packages @dimforge/rapier2d-compat or @dimforge/rapier3d-compat. These packages embed the WASM file (encoded in base64) into the main JS file. This results in a slightly different initialization process:

import RAPIER from 'https://cdn.skypack.dev/@dimforge/rapier2d-compat';
RAPIER.init().then(() => {
// Run the simulation.
});
// OR using the await syntax:
async function run_simulation() {
await RAPIER.init();
// Run the simulation.
}

A complete example can be found on codepen.

Rendering Debug Shapes#

Rapier does not come with any built-in rendering capabilities, so you must do the rendering yourself. However, the debug shape data can be accessed directly from the physics world instance by calling debugRender().

const { vertices, colors } = world.debugRender()

These are each flat arrays filled with shape and color data for every body and collider in the physics world.

The vertices array contains point data of where to draw lines while the colors array contains the RGBA values to associate with each line.

info

The colors of each body are not configurable in the current version of Rapier. The colors given will be based on the type of the given rigid body or collider and the current kinematic state of it.

Below is an example of rendering this data using Pixi.js and Pixi Viewport.

import PIXI from 'pixi.js';
import { Viewport } from 'pixi-viewport';
// ...
let GRAPHICS = [];
function renderDebug (pixiViewport, physicsWorld) {
const { vertices, colors } = physicsWorld.debugRender();
GRAPHICS.forEach(g => g.destroy());
GRAPHICS = [];
for (let i = 0; i < vtx.length / 4; i += 1) {
const g = new PIXI.Graphics();
const c = new PIXI.Color({
r: colors[i * 4] * 255,
g: colors[i * 4 + 1] * 255,
b: colors[i * 4 + 2] * 255,
a: colors[i * 4 + 3] * 255
});
g.lineStyle(0.5, c, 1);
g.moveTo(vertices[i * 4], vertices[i * 4 + 1]);
g.lineTo(vertices[i * 4 + 2], vertices[i * 4 + 3]);
g.closePath();
GRAPHICS.push(g);
pixiViewport.addChild(g);
}
}

An example of this in action can be see in the Rapier.js testbed code.