feat(physics): add RigidBody component and PhysicsConfig

This commit is contained in:
2026-03-25 10:35:16 +09:00
parent 7d91e204cc
commit 9bdb502f8f
2 changed files with 88 additions and 0 deletions

View File

@@ -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};

View File

@@ -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);
}
}