Skip to content
Merged
376 changes: 373 additions & 3 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,6 +11,7 @@ members = [
"tools/lambda_audio",
# Demo crates (not built by default; see `default-members`).
"demos/audio",
"demos/physics",
"demos/render",
"demos/minimal",
]
Expand Down
6 changes: 6 additions & 0 deletions crates/lambda-rs-platform/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,6 +29,7 @@ symphonia = { version = "=0.5.5", optional = true, default-features = false, fea
"wav",
"pcm",
] }
rapier2d = { version = "=0.32.0", optional = true }

# Force windows crate to 0.62 to unify wgpu-hal and gpu-allocator dependencies.
# Both crates support this version range, but Cargo may resolve to different
Expand DownExpand Up@@ -65,3 +66,8 @@ audio = ["audio-device", "audio-decode-wav", "audio-decode-vorbis"]
audio-device = ["dep:cpal"]
audio-decode-wav = ["dep:symphonia"]
audio-decode-vorbis = ["dep:symphonia"]

# --------------------------------- PHYSICS -----------------------------------

# Umbrella features (disabled by default)
physics-2d = ["dep:rapier2d"]
3 changes: 3 additions & 0 deletions crates/lambda-rs-platform/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,3 +23,6 @@ pub mod winit;
feature = "audio-decode-vorbis"
))]
pub mod audio;

#[cfg(feature = "physics-2d")]
pub mod physics;
9 changes: 9 additions & 0 deletions crates/lambda-rs-platform/src/physics/mod.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
//! Internal physics backends.
//!
//! This module contains physics backend implementations that support the
//! higher-level `lambda-rs` physics APIs without exposing vendor types from
//! `lambda-rs` itself.

pub mod rapier2d;

pub use rapier2d::PhysicsBackend2D;
110 changes: 110 additions & 0 deletions crates/lambda-rs-platform/src/physics/rapier2d.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
//! Rapier-backed 2D physics backend.
//!
//! This module provides a minimal wrapper around `rapier2d` to support the
//! higher-level `lambda-rs` physics APIs without exposing vendor types outside
//! of the platform layer.

use rapier2d::prelude::*;

/// A 2D physics backend powered by `rapier2d`.
///
/// This type is an internal implementation detail used by `lambda-rs`.
pub struct PhysicsBackend2D {
gravity: Vector,
integration_parameters: IntegrationParameters,
islands: IslandManager,
broad_phase: BroadPhaseBvh,
narrow_phase: NarrowPhase,
bodies: RigidBodySet,
colliders: ColliderSet,
impulse_joints: ImpulseJointSet,
multibody_joints: MultibodyJointSet,
ccd_solver: CCDSolver,
pipeline: PhysicsPipeline,
}

impl PhysicsBackend2D {
/// Creates a new empty 2D physics backend.
///
/// # Arguments
/// - `gravity`: The gravity vector in meters per second squared.
/// - `timestep_seconds`: The fixed integration timestep in seconds.
///
/// # Returns
/// Returns a new `PhysicsBackend2D` with no bodies, colliders, or joints.
pub fn new(gravity: [f32; 2], timestep_seconds: f32) -> Self {
let gravity_vector = Vector::new(gravity[0], gravity[1]);

let integration_parameters = IntegrationParameters {
dt: timestep_seconds,
..Default::default()
};

return Self {
gravity: gravity_vector,
integration_parameters,
islands: IslandManager::new(),
broad_phase: BroadPhaseBvh::new(),
narrow_phase: NarrowPhase::new(),
bodies: RigidBodySet::new(),
colliders: ColliderSet::new(),
impulse_joints: ImpulseJointSet::new(),
multibody_joints: MultibodyJointSet::new(),
ccd_solver: CCDSolver::new(),
pipeline: PhysicsPipeline::new(),
};
}

/// Returns the gravity vector used by this backend.
///
/// # Returns
/// Returns the gravity vector in meters per second squared.
pub fn gravity(&self) -> [f32; 2] {
return [self.gravity.x, self.gravity.y];
}

/// Returns the fixed integration timestep in seconds.
///
/// # Returns
/// Returns the timestep used for each simulation step.
pub fn timestep_seconds(&self) -> f32 {
return self.integration_parameters.dt;
}

/// Advances the simulation by one fixed timestep.
///
/// # Returns
/// Returns `()` after applying integration and constraint solving for the
/// configured timestep.
pub fn step(&mut self) {
return self.step_with_timestep_seconds(self.integration_parameters.dt);
}

/// Advances the simulation by the given timestep.
///
/// # Arguments
/// - `timestep_seconds`: The timestep used for this step.
///
/// # Returns
/// Returns `()` after applying integration and constraint solving.
pub fn step_with_timestep_seconds(&mut self, timestep_seconds: f32) {
self.integration_parameters.dt = timestep_seconds;

self.pipeline.step(
self.gravity,
&self.integration_parameters,
&mut self.islands,
&mut self.broad_phase,
&mut self.narrow_phase,
&mut self.bodies,
&mut self.colliders,
&mut self.impulse_joints,
&mut self.multibody_joints,
&mut self.ccd_solver,
&(),
&(),
);

return;
}
}
5 changes: 5 additions & 0 deletions crates/lambda-rs/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -89,6 +89,11 @@ render-validation-encoder = []
render-validation-instancing = []
render-validation-render-targets = []

# --------------------------------- PHYSICS -----------------------------------

# Umbrella features (disabled by default)
physics-2d = ["lambda-rs-platform/physics-2d"]


# ---------------------------- PLATFORM DEPENDENCIES ---------------------------

Expand Down
3 changes: 3 additions & 0 deletions crates/lambda-rs/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,6 +29,9 @@ pub mod util;
))]
pub mod audio;

#[cfg(feature = "physics-2d")]
pub mod physics;

/// The logging module provides a simple logging interface for Lambda
/// applications.
pub use logging;
Loading
Loading