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
:
- Example 2D
- Example 3D
"dependencies": {
"@dimforge/rapier2d": "*", // Replace the * by the latest version number.
}
"dependencies": {
"@dimforge/rapier3d": "*", // 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.
- Example 2D
- Example 3D
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 = () => {
// Step 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();
})
import('@dimforge/rapier3d').then(RAPIER => {
// Use the RAPIER module here.
let gravity = { x: 0.0, y: -9.81, z: 0.0 };
let world = new RAPIER.World(gravity);
// Create the ground
let groundColliderDesc = RAPIER.ColliderDesc.cuboid(10.0, 0.1, 10.0);
world.createCollider(groundColliderDesc);
// Create a dynamic rigid-body.
let rigidBodyDesc = RAPIER.RigidBodyDesc.dynamic()
.setTranslation(0.0, 1.0, 0.0);
let rigidBody = world.createRigidBody(rigidBodyDesc);
// Create a cuboid collider attached to the dynamic rigidBody.
let colliderDesc = RAPIER.ColliderDesc.cuboid(0.5, 0.5, 0.5);
let collider = world.createCollider(colliderDesc, rigidBody);
// Game loop. Replace by your own game loop system.
let gameLoop = () => {
// Step 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:
- Example 2D
- Example 3D
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.
_run_simulation(RAPIER);
}
run_simulation()
import RAPIER from 'https://cdn.skypack.dev/@dimforge/rapier3d-compat';
RAPIER.init().then(() => {
// Run the simulation.
_run_simulation(RAPIER);
});
// OR using the await syntax:
async function run_simulation() {
await RAPIER.init();
// Run the simulation.
_run_simulation(RAPIER);
}
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.
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";
render(world: RAPIER.World) {
const { vertices, colors } = world.debugRender();
this.lines.clear();
for (let i = 0; i < vertices.length / 4; i += 1) {
let color = PIXI.utils.rgb2hex([
colors[i * 8],
colors[i * 8 + 1],
colors[i * 8 + 2],
]);
this.lines.lineStyle(1.0, color, colors[i * 8 + 3], 0.5, true);
this.lines.moveTo(vertices[i * 4], -vertices[i * 4 + 1]);
this.lines.lineTo(vertices[i * 4 + 2], -vertices[i * 4 + 3]);
}
this.renderer.render(this.scene);
}
An example of this in action can be see in the Rapier.js testbed code.