Skip to main content

PhysicsWorld

Struct PhysicsWorld 

Source
pub struct PhysicsWorld<const N: usize, const M: usize = 0> {
    pub solver_iterations: u32,
    /* private fields */
}
Expand description

The physics simulation world.

Manages a fixed-capacity set of rigid bodies and constraints, and steps the simulation forward.

§Type Parameters

  • N - Maximum number of bodies (compile-time capacity).
  • M - Maximum number of constraints/joints (compile-time capacity).

§Example

use embedded_3dgfx::physics::{PhysicsWorld, RigidBody, Constraint};
use nalgebra::Vector3;

let mut world = PhysicsWorld::<8, 4>::new();
world.set_gravity(Vector3::new(0.0, -9.81, 0.0));

let body = RigidBody::new(2.0)
    .with_position(Vector3::new(0.0, 5.0, 0.0));
let id = world.add_body(body).unwrap();

world.step::<8>(1.0 / 60.0);

Fields§

§solver_iterations: u32

Number of iterations for the constraint solver per substep.

Implementations§

Source§

impl<const N: usize, const M: usize> PhysicsWorld<N, M>

Source

pub fn new() -> Self

Create a new physics world with no gravity.

Source

pub fn set_gravity(&mut self, gravity: Vector3<f32>)

Set the gravity vector (e.g., Vector3::new(0.0, -9.81, 0.0)).

Source

pub fn gravity(&self) -> Vector3<f32>

Returns the current gravity vector.

Source

pub fn add_body(&mut self, body: RigidBody) -> Option<BodyId>

Add a body to the world. Returns its BodyId, or None if at capacity.

Source

pub fn body(&self, id: BodyId) -> Option<&RigidBody>

Get an immutable reference to a body by its ID.

Source

pub fn body_mut(&mut self, id: BodyId) -> Option<&mut RigidBody>

Get a mutable reference to a body by its ID.

Source

pub fn body_count(&self) -> usize

Returns the total number of bodies in the world (including inactive).

Source

pub fn active_body_count(&self) -> usize

Returns the number of active bodies in the world.

Source

pub fn remove_body(&mut self, id: BodyId) -> bool

Deactivate a body, effectively removing it from the simulation.

The body remains in the world (its slot is preserved) but it is skipped during integration and collision detection. This avoids invalidating existing BodyIds.

Returns true if the body was found and deactivated, false if the ID was out of bounds or the body was already inactive.

Source

pub fn set_active(&mut self, id: BodyId, active: bool) -> bool

Set whether a body is active. Inactive bodies are skipped during integration and collision detection.

Returns true if the body exists, false otherwise.

Source

pub fn bodies(&self) -> impl Iterator<Item = (BodyId, &RigidBody)>

Iterate over all bodies immutably.

Source

pub fn bodies_mut(&mut self) -> impl Iterator<Item = (BodyId, &mut RigidBody)>

Iterate over all bodies mutably.

Source

pub fn ray_cast(&self, ray: &Ray, max_distance: f32) -> Option<RayCastHit>

Cast a ray through the world and find the nearest intersection.

Returns information about the hit, or None if no bodies were hit.

§Arguments
  • ray - The ray to cast
  • max_distance - Maximum distance to check (use f32::MAX for infinite)
§Example
use embedded_3dgfx::physics::{PhysicsWorld, Ray};
use nalgebra::Vector3;

let world = PhysicsWorld::<16>::new();
let ray = Ray::new(
    Vector3::new(0.0, 10.0, 0.0),
    Vector3::new(0.0, -1.0, 0.0)
);

if let Some(hit) = world.ray_cast(&ray, 100.0) {
    println!("Hit body at distance: {}", hit.distance);
}
Source

pub fn add_constraint(&mut self, constraint: Constraint) -> Option<ConstraintId>

Add a constraint to the world. Returns its ConstraintId, or None if at capacity.

Source

pub fn constraint(&self, id: ConstraintId) -> Option<&Constraint>

Get an immutable reference to a constraint by its ID.

Source

pub fn constraint_mut(&mut self, id: ConstraintId) -> Option<&mut Constraint>

Get a mutable reference to a constraint by its ID.

Source

pub fn remove_constraint(&mut self, id: ConstraintId) -> bool

Remove a constraint by ID (swap-removes; invalidates the last ID).

Returns true if a constraint was removed, false if the ID was out of bounds.

Source

pub fn constraint_count(&self) -> usize

Returns the number of constraints in the world.

Source

pub fn add_distance_constraint( &mut self, body_a: BodyId, anchor_a: Vector3<f32>, body_b: BodyId, anchor_b: Vector3<f32>, compliance: f32, ) -> Option<ConstraintId>

Helper: create a distance constraint between two bodies.

Anchors are in body-local space. The rest length is computed automatically from the current body positions.

Source

pub fn add_ball_socket( &mut self, body_a: BodyId, anchor_a: Vector3<f32>, body_b: BodyId, anchor_b: Vector3<f32>, compliance: f32, ) -> Option<ConstraintId>

Helper: create a ball-socket joint between two bodies.

Anchors are in body-local space. The two anchor points will be constrained to coincide (distance = 0).

Source

pub fn add_fixed_joint( &mut self, body_a: BodyId, anchor_a: Vector3<f32>, body_b: BodyId, anchor_b: Vector3<f32>, compliance: f32, ) -> Option<ConstraintId>

Helper: create a fixed (weld) joint between two bodies.

Stores the current relative orientation as the target.

Source

pub fn detect_collisions<const C: usize>(&self) -> Vec<Contact, C>

Detect all collisions between bodies with colliders.

Uses a sort-and-sweep broad phase on the X axis to prune pairs that cannot possibly overlap, then runs the narrow-phase collide() test only on candidate pairs.

Returns contacts in a fixed-capacity buffer. The C const generic sets the maximum number of contacts per detection pass. For N bodies, worst case is N*(N-1)/2 pairs, so choose C accordingly.

Pairs where both bodies lack a collider are skipped.

Source

pub fn resolve_contacts(&mut self, contacts: &[Contact])

Resolve a set of contacts by applying positional correction, impulse response (linear + angular), and Coulomb friction.

Contact-point velocity includes both linear and angular contributions: v_contact = v_linear + ω × r, where r is the vector from the body center to the contact point. Impulses produce both linear velocity changes and torques via τ = r × J.

Source

pub fn solve_constraints(&mut self, dt: f32)

Solve all constraints using position-based correction.

Uses Extended Position-Based Dynamics (XPBD) style positional correction with compliance for soft constraints. Each constraint is solved solver_iterations times per call for convergence.

Source

pub fn step<const C: usize>(&mut self, dt: f32)

Advance the simulation by dt seconds.

Integrates all dynamic bodies, detects and resolves collisions, then solves constraints.

The C const generic sets the maximum number of collision contacts per step.

Source

pub fn step_fixed<const C: usize>(&mut self, dt: f32, substeps: u32)

Advance the simulation using fixed-size substeps for stability.

Divides dt into substeps equal intervals. Each substep runs integration, collision detection/response, and constraint solving.

Auto Trait Implementations§

§

impl<const N: usize, const M: usize> Freeze for PhysicsWorld<N, M>

§

impl<const N: usize, const M: usize> RefUnwindSafe for PhysicsWorld<N, M>

§

impl<const N: usize, const M: usize> Send for PhysicsWorld<N, M>

§

impl<const N: usize, const M: usize> Sync for PhysicsWorld<N, M>

§

impl<const N: usize, const M: usize> Unpin for PhysicsWorld<N, M>

§

impl<const N: usize, const M: usize> UnsafeUnpin for PhysicsWorld<N, M>

§

impl<const N: usize, const M: usize> UnwindSafe for PhysicsWorld<N, M>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.