ferravex_physics/
lib.rs

1//! Original rigid-body simulation for the recovered Ferravex games.
2//!
3//! Circles/spheres and oriented boxes have dynamic mass and angular inertia.
4//! Capsules (2D) and cylinders (3D) are static or kinematic ball obstacles.
5//! This is a small native solver, not a compatibility implementation of Rapier.
6mod body;
7mod geometry;
8mod world;
9pub use body::{BodySet, Collider, ColliderHandle, ColliderSet, RigidBodyHandle};
10use ferravex_math::{Quat, Vec2, Vec3};
11pub use world::{ContactEvent, ContactPair, StepStats};
12
13/// A planar rotation, measured in radians.
14#[derive(Clone, Copy, Debug, Default, PartialEq)]
15pub struct Rotation2(f32);
16impl Rotation2 {
17    pub fn from_angle(angle: f32) -> Self {
18        assert!(angle.is_finite());
19        Self(angle)
20    }
21    pub fn angle(self) -> f32 {
22        self.0
23    }
24}
25impl std::ops::Mul<Vec2> for Rotation2 {
26    type Output = Vec2;
27    fn mul(self, p: Vec2) -> Vec2 {
28        let (s, c) = self.0.sin_cos();
29        Vec2::new(c * p.x - s * p.y, s * p.x + c * p.y)
30    }
31}
32
33#[cfg(feature = "dim2")]
34pub mod d2 {
35    use super::*;
36    pub type Vector = Vec2;
37    pub type Rotation = Rotation2;
38    pub type Angular = f32;
39    fn to3(v: Vector) -> Vec3 {
40        Vec3::new(v.x, v.y, 0.)
41    }
42    fn from3(v: Vec3) -> Vector {
43        Vec2::new(v.x, v.y)
44    }
45    fn angular_to3(v: Angular) -> Vec3 {
46        Vec3::Z * v
47    }
48    fn angular_from3(v: Vec3) -> Angular {
49        v.z
50    }
51    fn rotation(core: &body::Core) -> &Rotation {
52        &core.rotation2
53    }
54    fn rotation_to3(r: Rotation) -> Quat {
55        Quat::from_rotation_z(r.angle())
56    }
57    const PLANAR: bool = true;
58    include!("api.rs");
59    impl ColliderBuilder {
60        pub fn cuboid(x: f32, y: f32) -> Self {
61            Self::shape(body::Shape::Box(Vec3::new(x, y, 0.5)))
62        }
63        pub fn capsule_from_endpoints(a: Vector, b: Vector, radius: f32) -> Self {
64            Self::shape(body::Shape::Capsule {
65                a: to3(a),
66                b: to3(b),
67                radius,
68            })
69        }
70    }
71}
72#[cfg(feature = "dim3")]
73pub mod d3 {
74    use super::*;
75    pub type Vector = Vec3;
76    pub type Rotation = Quat;
77    pub type Angular = Vec3;
78    fn to3(v: Vector) -> Vec3 {
79        v
80    }
81    fn from3(v: Vec3) -> Vector {
82        v
83    }
84    fn angular_to3(v: Angular) -> Vec3 {
85        v
86    }
87    fn angular_from3(v: Vec3) -> Angular {
88        v
89    }
90    fn rotation(core: &body::Core) -> &Rotation {
91        &core.rotation
92    }
93    fn rotation_to3(r: Rotation) -> Quat {
94        r
95    }
96    const PLANAR: bool = false;
97    include!("api.rs");
98    impl ColliderBuilder {
99        pub fn cuboid(x: f32, y: f32, z: f32) -> Self {
100            Self::shape(body::Shape::Box(Vec3::new(x, y, z)))
101        }
102        pub fn cylinder(half_height: f32, radius: f32) -> Self {
103            Self::shape(body::Shape::Cylinder {
104                half_height,
105                radius,
106            })
107        }
108    }
109}