Expand description
boxdd: Safe, ergonomic Rust bindings for Box2D (v3 C API)
Highlights
- Thin safe layer on top of the official Box2D v3 C API.
- Modular API: world, bodies, shapes, joints, queries, events, debug draw.
- Ergonomics: builder patterns, world-space helpers, mint integration.
- Two usage styles:
- RAII wrappers (Rust lifetimes, Drop auto-destroys ids).
- ID-style (return raw ids; easy to store and pass around without borrow issues).
Quickstart (RAII)
use boxdd::{World, WorldDef, BodyBuilder, ShapeDef, shapes, Vec2};
let def = WorldDef::builder().gravity(Vec2::new(0.0, -9.8)).build();
let mut world = World::new(def).unwrap();
{
// Limit the borrow of `world` by scoping the body wrapper.
let mut body = world.create_body(BodyBuilder::new().position([0.0, 2.0]).build());
let sdef = ShapeDef::builder().density(1.0).build();
let poly = shapes::box_polygon(0.5, 0.5);
let _shape = body.create_polygon_shape(&sdef, &poly);
}
world.step(1.0/60.0, 4);
Quickstart (ID-style)
use boxdd::{World, WorldDef, BodyBuilder, ShapeDef, shapes, Vec2};
let def = WorldDef::builder().gravity(Vec2::new(0.0, -9.8)).build();
let mut world = World::new(def).unwrap();
let body_id = world.create_body_id(BodyBuilder::new().position([0.0, 2.0]).build());
let sdef = ShapeDef::builder().density(1.0).build();
let poly = shapes::box_polygon(0.5, 0.5);
let _shape_id = world.create_polygon_shape_for(body_id, &sdef, &poly);
world.step(1.0/60.0, 4);
mint integration
b2Vec2
acceptsmint::Vector2<f32>
,mint::Point2<f32>
,[f32; 2]
,(f32, f32)
anywhereInto<b2Vec2>
is used.- Returned vectors can be converted back using
From
to mint types.
Modules
world
,body
,shapes
,joints
,query
,events
,debug_draw
,prelude
. Importboxdd::prelude::*
for the most common types.
Queries (AABB + Ray Cast)
use boxdd::{World, WorldDef, BodyBuilder, ShapeDef, shapes, Vec2, Aabb, QueryFilter};
let mut world = World::new(WorldDef::builder().gravity([0.0,-9.8]).build()).unwrap();
let b = world.create_body_id(BodyBuilder::new().position([0.0, 2.0]).build());
let sdef = ShapeDef::builder().density(1.0).build();
world.create_polygon_shape_for(b, &sdef, &shapes::box_polygon(0.5, 0.5));
// AABB overlap
let hits = world.overlap_aabb(Aabb::from_center_half_extents([0.0, 1.0], [1.0, 1.5]), QueryFilter::default());
assert!(!hits.is_empty());
// Ray (closest)
let r = world.cast_ray_closest(Vec2::new(0.0, 5.0), Vec2::new(0.0, -10.0), QueryFilter::default());
if r.hit { let _ = (r.point, r.normal, r.fraction); }
Feature Flags
serialize
: scene snapshot helpers (save/apply world config; build/restore minimal full-scene snapshot).pkg-config
: allow linking against a systembox2d
via pkg-config.cgmath
/nalgebra
/glam
: conversions with their 2D math types.
Events
- Three access styles:
- By value:
world.contact_events()
/sensor_events()
/body_events()
/joint_events()
return owned data for storage or cross‑frame use. - Zero‑copy views:
with_*_events_view(...)
iterate without exposing FFI types and without allocations (recommended per‑frame). - Raw slices:
with_*_events(...)
expose FFI slices (advanced); data valid only within the callback.
- By value:
Example (zero‑copy views)
use boxdd::prelude::*;
let mut world = World::new(WorldDef::default()).unwrap();
world.with_contact_events_view(|begin, end, hit| {
let _ = (begin.count(), end.count(), hit.count());
});
world.with_sensor_events_view(|beg, end| { let _ = (beg.count(), end.count()); });
world.with_body_events_view(|moves| { for m in moves { let _ = (m.body_id(), m.fell_asleep()); } });
world.with_joint_events_view(|j| { let _ = j.count(); });
Re-exports§
pub use body::Body;
pub use body::BodyBuilder;
pub use body::BodyDef;
pub use body::BodyType;
pub use core::math::Rot;
pub use core::math::Transform;
pub use debug_draw::DebugDraw;
pub use debug_draw::DebugDrawOptions;
pub use events::BodyMoveEvent;
pub use events::ContactBeginTouchEvent;
pub use events::ContactEndTouchEvent;
pub use events::ContactEvents;
pub use events::ContactHitEvent;
pub use events::JointEvent;
pub use events::SensorBeginTouchEvent;
pub use events::SensorEndTouchEvent;
pub use events::SensorEvents;
pub use filter::Filter;
pub use joints::DistanceJointBuilder;
pub use joints::DistanceJointDef;
pub use joints::FilterJointBuilder;
pub use joints::FilterJointDef;
pub use joints::Joint;
pub use joints::JointBase;
pub use joints::JointBaseBuilder;
pub use joints::MotorJointBuilder;
pub use joints::MotorJointDef;
pub use joints::PrismaticJointBuilder;
pub use joints::PrismaticJointDef;
pub use joints::RevoluteJointBuilder;
pub use joints::RevoluteJointDef;
pub use joints::WeldJointBuilder;
pub use joints::WeldJointDef;
pub use joints::WheelJointBuilder;
pub use joints::WheelJointDef;
pub use query::Aabb;
pub use query::QueryFilter;
pub use query::RayResult;
pub use shapes::chain::Chain;
pub use shapes::chain::ChainDef;
pub use shapes::chain::ChainDefBuilder;
pub use shapes::Shape;
pub use shapes::ShapeDef;
pub use shapes::ShapeDefBuilder;
pub use shapes::SurfaceMaterial;
pub use types::Vec2;
pub use world::World;
pub use world::WorldBuilder;
pub use world::WorldDef;
Modules§
- body
- core
- debug_
draw - Debug Draw bridge to Box2D v3 callbacks.
- events
- Event snapshots and zero-copy visitors.
- filter
- joints
- Joint builders and creation helpers (modularized).
- prelude
- query
- Broad-phase queries and casting helpers.
- shapes
- Shapes API
- tuning
- Tuning Notes and Upstream Constants
- types
- world
- world_
extras - Optional world extensions that are not core to the safe API surface.