Skip to main content

box3d_rust/
lib.rs

1//! Pure Rust port of [Box3D](https://github.com/erincatto/box3d), Erin Catto's 3D physics
2//! engine for games.
3//!
4//! The port targets exact behavioral match with the C source pinned in the
5//! `box3d-cpp-reference/` submodule: same algorithms, same `f32` arithmetic, same edge
6//! cases, including Box3D's hand-rolled cross-platform-deterministic trigonometry.
7//!
8//! # API style
9//!
10//! For 0.1 the public API is a direct C-mirror (same shapes, defs, and call patterns as
11//! Box3D / box2d-rust), not a Rust-ergonomic wrapper. A thin ergonomic layer may be
12//! considered after 0.1 if downstream users ask for one.
13//!
14//! # Quick start
15//!
16//! Add the crate, create a [`world::World`], attach bodies and shapes, then step:
17//!
18//! ```rust
19//! use box3d_rust::body::create_body;
20//! use box3d_rust::geometry::Sphere;
21//! use box3d_rust::hull::make_box_hull;
22//! use box3d_rust::shape::{create_hull_shape, create_sphere_shape};
23//! use box3d_rust::types::{default_body_def, default_shape_def, default_world_def, BodyType};
24//! use box3d_rust::world::World;
25//! use box3d_rust::{Pos, VEC3_ZERO};
26//!
27//! let mut world = World::new(&default_world_def());
28//!
29//! let mut ground_def = default_body_def();
30//! ground_def.type_ = BodyType::Static;
31//! let ground = create_body(&mut world, &ground_def);
32//!
33//! let mut ball_def = default_body_def();
34//! ball_def.type_ = BodyType::Dynamic;
35//! ball_def.position = Pos {
36//!     x: 0.0 as _,
37//!     y: 0.5 as _,
38//!     z: 0.0 as _,
39//! };
40//! let ball = create_body(&mut world, &ball_def);
41//!
42//! let shape_def = default_shape_def();
43//! let ground_hull = make_box_hull(5.0, 0.5, 5.0);
44//! create_hull_shape(&mut world, ground, &shape_def, &ground_hull.base);
45//!
46//! let mut ball_shape = default_shape_def();
47//! ball_shape.density = 1.0;
48//! create_sphere_shape(
49//!     &mut world,
50//!     ball,
51//!     &ball_shape,
52//!     &Sphere {
53//!         center: VEC3_ZERO,
54//!         radius: 0.5,
55//!     },
56//! );
57//!
58//! // 60 Hz, 1 sub-step
59//! world.step(1.0 / 60.0, 1);
60//! ```
61//!
62//! # Features
63//!
64//! Enable **`double-precision`** to mirror upstream `BOX3D_DOUBLE_PRECISION`
65//! (large-world mode). World positions use a wider scalar while collision math
66//! stays `f32`; both configurations are tested against the C reference.
67//!
68//! # Determinism
69//!
70//! Box3D is designed for cross-platform determinism. This port keeps the
71//! hand-rolled approximations (for example `atan2` / `cos`/`sin`) bit-for-bit
72//! with the C scalar path — do not replace them with `std` trig. The
73//! [`determinism`] module and the falling-ragdoll scene gate bit-exact match
74//! with the pinned reference build.
75//!
76//! # Key modules
77//!
78//! | Module | Role |
79//! |---|---|
80//! | [`world`] | Own a simulation, step it, run queries and casts |
81//! | [`body`] | Create and configure rigid bodies |
82//! | [`shape`] | Attach collision geometry to bodies |
83//! | [`joint`] | Constraints between bodies |
84//! | [`types`] | Public defs/defaults (`WorldDef`, `BodyDef`, `ShapeDef`, …) |
85//! | [`math_functions`] | `Vec3`, `Quat`, `Transform`, and deterministic math |
86//!
87//! See the repository README for port status and the live wasm demo.
88
89pub mod aabb;
90pub mod bitset;
91pub mod body;
92pub mod broad_phase;
93pub mod compound;
94pub mod constants;
95pub mod constraint_graph;
96pub mod contact;
97pub mod contact_solver;
98pub mod core;
99pub mod debug_draw;
100pub mod determinism;
101pub mod distance;
102pub mod dynamic_tree;
103pub mod events;
104pub mod geometry;
105pub mod height_field;
106pub mod hull;
107pub mod human;
108pub mod id;
109pub mod id_pool;
110pub mod island;
111pub mod joint;
112pub mod manifold;
113pub mod math_functions;
114pub mod mesh;
115pub mod mover;
116pub mod name_cache;
117pub mod recording;
118pub mod sensor;
119pub mod shape;
120pub mod solver;
121pub mod solver_set;
122pub mod table;
123pub mod types;
124pub mod world;
125
126pub use debug_draw::{
127    make_debug_color, CreateDebugShapeCallback, DebugDraw, DebugMaterial, DebugShape,
128    DestroyDebugShapeCallback, HexColor,
129};
130pub use id::{BodyId, ContactId, JointId, ShapeId, WorldId};
131pub use math_functions::{
132    Aabb, CosSin, Matrix3, Plane, Pos, Quat, SegmentDistanceResult, Transform, Triangle, Vec2,
133    Vec3, WorldTransform, MAT3_IDENTITY, MAT3_ZERO, PI, POS_ZERO, QUAT_IDENTITY,
134    TRANSFORM_IDENTITY, VEC3_AXIS_X, VEC3_AXIS_Y, VEC3_AXIS_Z, VEC3_ONE, VEC3_ZERO,
135    WORLD_TRANSFORM_IDENTITY,
136};
137pub use types::{
138    default_body_def, default_distance_joint_def, default_explosion_def, default_filter,
139    default_filter_joint_def, default_motor_joint_def, default_parallel_joint_def,
140    default_prismatic_joint_def, default_query_filter, default_revolute_joint_def,
141    default_shape_def, default_spherical_joint_def, default_weld_joint_def,
142    default_wheel_joint_def, default_world_def, BodyDef, BodyType, Capacity, Counters,
143    DistanceJointDef, ExplosionDef, Filter, FilterJointDef, JointDef, MotionLocks, MotorJointDef,
144    ParallelJointDef, PrismaticJointDef, QueryFilter, RayResult, RevoluteJointDef, ShapeDef,
145    SphericalJointDef, WeldJointDef, WheelJointDef, WorldCastOutput, WorldDef, BODY_TYPE_COUNT,
146};
147
148/// Crate version, exposed so demos and downstream tools can report the exact port build.
149pub const VERSION: &str = env!("CARGO_PKG_VERSION");
150
151#[cfg(test)]
152mod aabb_tests;
153
154#[cfg(test)]
155mod bitset_tests;
156
157#[cfg(test)]
158mod body_tests;
159
160#[cfg(test)]
161mod body_api_tests;
162
163#[cfg(test)]
164mod body_query_tests;
165
166#[cfg(test)]
167mod broad_phase_tests;
168
169#[cfg(test)]
170mod compound_tests;
171
172#[cfg(test)]
173mod contact_tests;
174
175#[cfg(test)]
176mod debug_draw_tests;
177
178#[cfg(test)]
179mod distance_tests;
180
181#[cfg(test)]
182mod dynamic_tree_tests;
183
184#[cfg(test)]
185mod geometry_tests;
186
187#[cfg(test)]
188mod height_field_tests;
189
190#[cfg(test)]
191mod hull_tests;
192
193#[cfg(test)]
194mod id_tests;
195
196#[cfg(test)]
197mod joint_tests;
198
199#[cfg(test)]
200mod manifold_tests;
201
202#[cfg(test)]
203mod math_functions_tests;
204
205#[cfg(test)]
206mod mesh_tests;
207
208#[cfg(test)]
209mod mover_tests;
210
211#[cfg(test)]
212mod shape_tests;
213
214#[cfg(test)]
215mod shape_api_tests;
216
217#[cfg(test)]
218mod table_tests;
219
220#[cfg(test)]
221mod world_tests;
222
223#[cfg(test)]
224mod world_api_tests;
225
226#[cfg(test)]
227mod large_world_tests;
228
229#[cfg(test)]
230mod determinism_tests;
231
232#[cfg(test)]
233mod recording_tests;
234
235#[cfg(test)]
236mod recording_replay_tests;
237
238#[cfg(test)]
239mod tests {
240    use super::*;
241
242    #[test]
243    fn version_matches_cargo_manifest() {
244        assert_eq!(VERSION, env!("CARGO_PKG_VERSION"));
245    }
246}