rhusics_core/physics/
mod.rs

1//! Physics related functionality
2//!
3
4pub use self::force::ForceAccumulator;
5pub use self::mass::{Inertia, Mass};
6pub use self::resolution::{resolve_contact, ResolveData, SingleChangeSet};
7pub use self::util::PartialCrossProduct;
8pub use self::velocity::{ApplyAngular, Velocity};
9pub use self::volumes::Volume;
10
11pub mod simple;
12
13mod resolution;
14
15mod force;
16mod mass;
17mod util;
18mod velocity;
19mod volumes;
20
21use cgmath::{BaseFloat, VectorSpace};
22
23/// Global parameters for the physics world
24#[derive(Debug, Clone)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub struct WorldParameters<V, S> {
27    gravity: V,
28    damping: S,
29}
30
31impl<V, S> Default for WorldParameters<V, S>
32where
33    V: VectorSpace,
34    S: BaseFloat,
35{
36    fn default() -> Self {
37        WorldParameters::new(V::zero())
38    }
39}
40
41impl<V, S> WorldParameters<V, S>
42where
43    V: VectorSpace,
44    S: BaseFloat,
45{
46    /// Setup global parameters for the physics world
47    pub fn new(gravity: V) -> Self {
48        WorldParameters {
49            gravity,
50            damping: S::from(0.99).unwrap(),
51        }
52    }
53
54    /// Set global damping, can be overriden by individual physical entities
55    pub fn with_damping(mut self, damping: S) -> Self {
56        self.damping = damping;
57        self
58    }
59
60    /// Get gravity
61    pub fn gravity(&self) -> V {
62        self.gravity
63    }
64
65    /// Get global damping
66    pub fn damping(&self) -> S {
67        self.damping
68    }
69
70    /// Get damping for a specific physics entity
71    pub fn entity_damping(&self, body: Option<S>) -> S {
72        body.unwrap_or(self.damping)
73    }
74}
75
76/// Physics material
77///
78/// Used to describe physical properties of physical entities, such as density and restitution.
79///
80/// The default material has density 1, such that only the volume affects its mass, and restitution
81/// 1, such that all energy is preserved in collisions.
82#[derive(Debug, Clone)]
83#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
84pub struct Material {
85    density: f32,
86    restitution: f32,
87}
88
89impl Default for Material {
90    fn default() -> Self {
91        Material::new(1., 1.)
92    }
93}
94
95impl Material {
96    /// Rock
97    pub const ROCK: Material = Material {
98        density: 0.6,
99        restitution: 0.1,
100    };
101    /// Wood
102    pub const WOOD: Material = Material {
103        density: 0.3,
104        restitution: 0.2,
105    };
106    /// Metal
107    pub const METAL: Material = Material {
108        density: 1.2,
109        restitution: 0.05,
110    };
111    /// Bouncy Ball
112    pub const BOUNCY_BALL: Material = Material {
113        density: 0.3,
114        restitution: 0.8,
115    };
116    /// Super Ball
117    pub const SUPER_BALL: Material = Material {
118        density: 0.3,
119        restitution: 0.95,
120    };
121    /// Pillow
122    pub const PILLOW: Material = Material {
123        density: 0.1,
124        restitution: 0.2,
125    };
126    /// Static
127    pub const STATIC: Material = Material {
128        density: 0.0,
129        restitution: 0.4,
130    };
131
132    /// Create new material
133    pub fn new(density: f32, restitution: f32) -> Self {
134        Self {
135            density,
136            restitution,
137        }
138    }
139
140    /// Get density
141    pub fn density<S>(&self) -> S
142    where
143        S: BaseFloat,
144    {
145        S::from(self.density).unwrap()
146    }
147
148    /// Get restitution
149    pub fn restitution<S>(&self) -> S
150    where
151        S: BaseFloat,
152    {
153        S::from(self.restitution).unwrap()
154    }
155}
156
157/// Physical entity
158#[derive(Debug, Clone)]
159#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
160pub struct PhysicalEntity<S> {
161    material: Material,
162    gravity_scale: S,
163    damping: Option<S>,
164    active: bool,
165}
166
167impl<S> Default for PhysicalEntity<S>
168where
169    S: BaseFloat,
170{
171    fn default() -> Self {
172        PhysicalEntity::new(Material::default())
173    }
174}
175
176impl<S> PhysicalEntity<S>
177where
178    S: BaseFloat,
179{
180    /// Create new physical entity
181    ///
182    /// ## Parameters:
183    ///
184    /// - material: physical material (`Material`)
185    pub fn new(material: Material) -> Self {
186        Self {
187            material,
188            gravity_scale: S::one(),
189            damping: None,
190            active: true,
191        }
192    }
193
194    /// Set the amount that gravity will affect this entity
195    /// The gravity constant is set globally for the physics world.
196    pub fn with_gravity_scale(mut self, gravity_scale: S) -> Self {
197        self.gravity_scale = gravity_scale;
198        self
199    }
200
201    /// Override the velocity damping for the entity
202    /// The physics world control have a global damping set which is overriden by this.
203    pub fn with_damping(mut self, damping: S) -> Self {
204        self.damping = Some(damping);
205        self
206    }
207
208    /// Get material
209    pub fn material(&self) -> &Material {
210        &self.material
211    }
212
213    /// Get gravity scale
214    pub fn gravity_scale(&self) -> S {
215        self.gravity_scale
216    }
217
218    /// Get entity specific damping
219    pub fn damping(&self) -> Option<S> {
220        self.damping
221    }
222
223    /// Is entity active ?
224    pub fn active(&self) -> bool {
225        self.active
226    }
227
228    /// Set entity to active, meaning physics will act on it
229    pub fn activate(&mut self) {
230        self.active = true;
231    }
232
233    /// Set entity to inactive, meaning physics will not act on it
234    pub fn deactivate(&mut self) {
235        self.active = false;
236    }
237}