From 9bdb502f8f69af12aa92b6902a591f0121bd1339 Mon Sep 17 00:00:00 2001 From: tolelom <98kimsungmin@naver.com> Date: Wed, 25 Mar 2026 10:35:16 +0900 Subject: [PATCH] feat(physics): add RigidBody component and PhysicsConfig --- crates/voltex_physics/src/lib.rs | 2 + crates/voltex_physics/src/rigid_body.rs | 86 +++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 crates/voltex_physics/src/rigid_body.rs diff --git a/crates/voltex_physics/src/lib.rs b/crates/voltex_physics/src/lib.rs index 1d34893..0762275 100644 --- a/crates/voltex_physics/src/lib.rs +++ b/crates/voltex_physics/src/lib.rs @@ -3,8 +3,10 @@ pub mod collider; pub mod contact; pub mod narrow; pub mod collision; +pub mod rigid_body; pub use bvh::BvhTree; pub use collider::Collider; pub use contact::ContactPoint; pub use collision::detect_collisions; +pub use rigid_body::{RigidBody, PhysicsConfig}; diff --git a/crates/voltex_physics/src/rigid_body.rs b/crates/voltex_physics/src/rigid_body.rs new file mode 100644 index 0000000..d77c885 --- /dev/null +++ b/crates/voltex_physics/src/rigid_body.rs @@ -0,0 +1,86 @@ +use voltex_math::Vec3; + +#[derive(Debug, Clone, Copy)] +pub struct RigidBody { + pub velocity: Vec3, + pub angular_velocity: Vec3, + pub mass: f32, + pub restitution: f32, + pub gravity_scale: f32, +} + +impl RigidBody { + pub fn dynamic(mass: f32) -> Self { + Self { + velocity: Vec3::ZERO, + angular_velocity: Vec3::ZERO, + mass, + restitution: 0.3, + gravity_scale: 1.0, + } + } + + pub fn statik() -> Self { + Self { + velocity: Vec3::ZERO, + angular_velocity: Vec3::ZERO, + mass: 0.0, + restitution: 0.3, + gravity_scale: 0.0, + } + } + + pub fn inv_mass(&self) -> f32 { + if self.mass == 0.0 { 0.0 } else { 1.0 / self.mass } + } + + pub fn is_static(&self) -> bool { + self.mass == 0.0 + } +} + +pub struct PhysicsConfig { + pub gravity: Vec3, + pub fixed_dt: f32, +} + +impl Default for PhysicsConfig { + fn default() -> Self { + Self { + gravity: Vec3::new(0.0, -9.81, 0.0), + fixed_dt: 1.0 / 60.0, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_dynamic_body() { + let rb = RigidBody::dynamic(2.0); + assert_eq!(rb.mass, 2.0); + assert!(!rb.is_static()); + assert!((rb.inv_mass() - 0.5).abs() < 1e-6); + assert_eq!(rb.velocity, Vec3::ZERO); + assert_eq!(rb.restitution, 0.3); + assert_eq!(rb.gravity_scale, 1.0); + } + + #[test] + fn test_static_body() { + let rb = RigidBody::statik(); + assert_eq!(rb.mass, 0.0); + assert!(rb.is_static()); + assert_eq!(rb.inv_mass(), 0.0); + assert_eq!(rb.gravity_scale, 0.0); + } + + #[test] + fn test_physics_config_default() { + let cfg = PhysicsConfig::default(); + assert!((cfg.gravity.y - (-9.81)).abs() < 1e-6); + assert!((cfg.fixed_dt - 1.0 / 60.0).abs() < 1e-6); + } +}