box3d-rs — Deterministic Sub-Stepping 3D Rigid-Body Physics in Pure Rust
box3d-rs is a safe, zero-FFI Rust port of Erin Catto's Box3D physics engine designed for games, robotics simulation, and WebAssembly. It pairs a dynamic BVH broadphase and GJK/SAT narrowphase with a Soft TGS sub-stepping constraint solver that keeps tall stacks and jointed mechanisms stable.
$ cargo add box3d-rs
Architected for Speed & Reliability
Engineered from the ground up in memory-safe Rust with zero unnecessary dependencies.
Soft Step Integrator
Erin Catto's cutting-edge sub-stepping solver providing unprecedented stacking stability and soft constraint compliance without explosive divergence.
Separating Axis Theorem (SAT)
Full polyhedral convex hull SAT narrow-phase collision with Sutherland-Hodgman contact polygon clipping for micro-accurate contacts.
Dual Dynamic AABB Trees
Surface Area Heuristic (SAH) spatial partitioning with automatic rebalancing tree rotations for high-speed broad-phase queries.
Two-Axis Coulomb Friction
Genuine 3D Coulomb friction cone solved via 2x2 block tangent matrices, preventing sliding artifacts.
Generational IDs
Handle-based memory allocation (WorldId, BodyId, ShapeId, JointId) eliminating dangling pointers and borrow checker battles.
Tested & Benchmarked
Passes Erin Catto's drop and stack benchmark tests with verified 1:1 mathematical accuracy (y ≈ 1.00022m settlement on standard 2-meter drop).
Get Started in Seconds
Install via Cargo and run immediately on macOS, Linux, or Windows.
# Add box3d to your Cargo.toml
[dependencies]
box3d = { git = "https://github.com/bhubbard/box3d-rs" }
# In your Rust code:
use box3d::prelude::*;
fn main() {
let mut world = World::new(WorldDef {
gravity: Vec3::new(0.0, -9.81, 0.0),
..Default::default()
});
let ground = world.create_body(&BodyDef::static_body());
let dynamic_box = world.create_body(&BodyDef::dynamic_body(Vec3::new(0.0, 5.0, 0.0)));
for _ in 0..60 {
world.step(1.0 / 60.0, 4); // 4 sub-steps
}
}
Engine Architecture
Streamlined execution pipeline with deterministic memory isolation and zero runtime overhead.
┌───────────────────────────────────────────────────────────┐
│ User Simulation Loop │
└─────────────────────────────┬─────────────────────────────┘
│ world.step(dt, sub_steps)
┌─────────────────────────────▼─────────────────────────────┐
│ Broad-Phase: Dual Dynamic AABB Trees (SAH) │
└─────────────────────────────┬─────────────────────────────┘
│ Candidate Overlaps
┌─────────────────────────────▼─────────────────────────────┐
│ Narrow-Phase: Polyhedral SAT + Contact Clipping │
└─────────────────────────────┬─────────────────────────────┘
│ Manifold Points
┌─────────────────────────────▼─────────────────────────────┐
│ Soft Step Solver: 2-Axis Friction Cone + Sub-stepping │
└───────────────────────────────────────────────────────────┘