Skip to main content

Getting started

Setting up Rapier with Cargo​

rapier relies on the official Rust package manager Cargo for dependency resolution and compilation. Therefore, making rapier ready to use in your project is simply a matter of adding a new dependency to your Cargo.toml file. You can either use the rapier2d crate for 2D physics simulation or the rapier3d crate for 3D physics simulation. For high-precision simulation using 64-bits floats, use the rapier2d-f64 crate or the rapier3d-f64 crate.

Until rapier reaches 1.0, it is strongly recommended to always use its latest published version, though you may encounter breaking changes from time to time.

To get the best of rapier multiple features can be enabled optionally:

  • parallel: enables parallelism of the physics pipeline with the rayon crate.
  • serde-serialize: enables serialization of the physics components with serde.
  • enhanced-determinism: enables cross-platform determinism (assuming the rest of your code is also deterministic) across all 32-bit and 64-bit platforms that implements the IEEE 754-2008 standard strictly. This includes most modern processors as well as WASM targets.
  • simd8: widens the SIMD of the solver from 4 to 8 lanes (32-bit floats only). Note that the compiler only emits actual 256-bit instructions on an AVX-enabled target (e.g. with RUSTFLAGS="-C target-cpu=native"); otherwise the 8-lanes path will be much slower (it will be emulated as two 128-bit halves).
  • block-solver: couples the two normal constraints of a contact pair into a single 2x2 solve. This is enabled by default in 2D, and disabled by default in 3D where it is less effective.
  • fem: adds an alternative FEM solver for the soft-bodies, selected body by body.
  • unsync-callbacks: drops the Sync requirement from the physics hooks and the event handlers. As a side effect, this removes the thread-pool API of the physics pipeline.
  • debug-render: enables the debug-renderer of Rapier.
  • profiler: enables the internal profiler, which gives the time spent by each stage of a timestep.

SIMD optimizations (based on the wide crate) are always enabled: the solver processes 4 contact manifolds per instruction (8 with the simd8 feature), and falls back to scalar code on targets without SIMD support.

Currently, the enhanced-determinism feature cannot be enabled at the same time as the simd8 feature, which changes the SIMD lane width and therefore the simulation results compared to when simd8 isn’t enabled.

Cargo example​

[package]
name = "example-using-rapier"
version = "0.0.0"
authors = [ "You" ]

[dependencies]
# TODO: Replace the * by the latest version number.
rapier2d = { version = "*" }

[[bin]]
name = "example"
path = "./example.rs"

Basic simulation example​

Here is a basic example of main.rs file. This creates a ball bouncing on a fixed ground. Details about the elements used in this examples are given in subsequent pages of this guide.

use rapier2d::prelude::*;

fn main() {
// The world owns every structure needed by the simulation.
let mut world = PhysicsWorld::new();
world.gravity = Vector::new(0.0, -9.81);

/* Create the ground. */
world.insert_collider(ColliderBuilder::cuboid(100.0, 0.1), None);

/* Create the bouncing ball. */
let (ball_body_handle, _) = world.insert(
RigidBodyBuilder::dynamic().translation(Vector::new(0.0, 10.0)),
ColliderBuilder::ball(0.5).restitution(0.7),
);

/* Run the game loop, stepping the simulation once per frame. */
for _ in 0..200 {
world.step();

let ball_body = &world.bodies[ball_body_handle];
println!("Ball altitude: {}", ball_body.translation().y);
}
}
info

This example lets the PhysicsWorld own every structure of the simulation. These structures, as well as the way of stepping them by hand without the world, are described in the simulation structures page.