anput_physics/
components.rs

1use crate::{PhysicsAccessView, Scalar};
2use anput::{
3    entity::Entity,
4    query::TypedLookupFetch,
5    world::{Relation, World},
6};
7use serde::{Deserialize, Serialize};
8use vek::{Quaternion, Vec3};
9
10#[derive(Clone)]
11pub struct BodyAccessInfo {
12    pub entity: Entity,
13    pub view: PhysicsAccessView,
14}
15
16impl BodyAccessInfo {
17    pub fn new(entity: Entity, view: PhysicsAccessView) -> Self {
18        Self { entity, view }
19    }
20
21    pub fn of_world(entity: Entity, world: &World) -> Self {
22        Self::new(entity, PhysicsAccessView::new(world))
23    }
24
25    pub fn particles<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING> + 'a>(
26        &'a self,
27    ) -> impl Iterator<Item = Fetch::Value> + 'a {
28        self.view
29            .entity::<LOCKING, &Relation<BodyParticleRelation>>(self.entity)
30            .map(|relations| {
31                self.view
32                    .lookup::<LOCKING, Fetch>(relations.iter().map(|(_, entity)| entity))
33            })
34            .into_iter()
35            .flatten()
36    }
37
38    pub fn density_fields<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING> + 'a>(
39        &'a self,
40    ) -> impl Iterator<Item = Fetch::Value> + 'a {
41        self.view
42            .entity::<LOCKING, &Relation<BodyDensityFieldRelation>>(self.entity)
43            .map(|relations| {
44                self.view
45                    .lookup::<LOCKING, Fetch>(relations.iter().map(|(_, entity)| entity))
46            })
47            .into_iter()
48            .flatten()
49    }
50}
51
52pub struct PhysicsBody;
53pub struct PhysicsParticle;
54pub struct BodyParticleRelation;
55pub struct BodyDensityFieldRelation;
56pub struct ParticleConstraintRelation;
57pub struct BodyParentRelation;
58
59#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
60pub struct Mass {
61    value: Scalar,
62    inverse: Scalar,
63}
64
65impl Mass {
66    pub fn new(value: Scalar) -> Self {
67        Self {
68            value,
69            inverse: if value != 0.0 { 1.0 / value } else { 0.0 },
70        }
71    }
72
73    pub fn new_inverse(inverse: Scalar) -> Self {
74        Self {
75            value: if inverse != 0.0 { 1.0 / inverse } else { 0.0 },
76            inverse,
77        }
78    }
79
80    pub fn value(&self) -> Scalar {
81        self.value
82    }
83
84    pub fn inverse(&self) -> Scalar {
85        self.inverse
86    }
87}
88
89impl PartialEq for Mass {
90    fn eq(&self, other: &Self) -> bool {
91        self.value == other.value
92    }
93}
94
95#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize)]
96pub struct Position {
97    pub current: Vec3<Scalar>,
98    previous: Vec3<Scalar>,
99}
100
101impl Position {
102    pub fn new(current: impl Into<Vec3<Scalar>>) -> Self {
103        let current = current.into();
104        Self {
105            current,
106            previous: current,
107        }
108    }
109
110    pub fn previous(&self) -> Vec3<Scalar> {
111        self.previous
112    }
113
114    pub fn change(&self) -> Vec3<Scalar> {
115        self.current - self.previous
116    }
117
118    pub fn cache_current_as_previous(&mut self) {
119        self.previous = self.current;
120    }
121}
122
123impl PartialEq for Position {
124    fn eq(&self, other: &Self) -> bool {
125        self.current == other.current
126    }
127}
128
129#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
130pub struct Rotation {
131    pub current: Quaternion<Scalar>,
132    previous: Quaternion<Scalar>,
133}
134
135impl Rotation {
136    pub fn new(current: impl Into<Quaternion<Scalar>>) -> Self {
137        let current = current.into();
138        Self {
139            current,
140            previous: current,
141        }
142    }
143
144    pub fn previous(&self) -> Quaternion<Scalar> {
145        self.previous
146    }
147
148    pub fn change(&self) -> Quaternion<Scalar> {
149        self.current * self.previous.conjugate()
150    }
151
152    pub fn cache_current_as_previous(&mut self) {
153        self.previous = self.current;
154    }
155}
156
157#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
158#[repr(transparent)]
159pub struct LinearVelocity {
160    pub value: Vec3<Scalar>,
161}
162
163impl LinearVelocity {
164    pub fn new(value: Vec3<Scalar>) -> Self {
165        Self { value }
166    }
167}
168
169#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
170#[repr(transparent)]
171pub struct AngularVelocity {
172    pub value: Vec3<Scalar>,
173}
174
175impl AngularVelocity {
176    pub fn new(value: Vec3<Scalar>) -> Self {
177        Self { value }
178    }
179}
180
181#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
182pub struct ExternalForces {
183    pub force: Vec3<Scalar>,
184    pub torque: Vec3<Scalar>,
185    pub linear_impulse: Vec3<Scalar>,
186    pub angular_impulse: Vec3<Scalar>,
187}
188
189impl ExternalForces {
190    pub fn accumulate_force(&mut self, force: Vec3<Scalar>) {
191        self.force += force;
192    }
193
194    pub fn accumulate_torque(&mut self, torque: Vec3<Scalar>) {
195        self.torque += torque;
196    }
197
198    pub fn accumulate_linear_impulse(&mut self, impulse: Vec3<Scalar>) {
199        self.linear_impulse += impulse;
200    }
201
202    pub fn accumulate_angular_impulse(&mut self, impulse: Vec3<Scalar>) {
203        self.angular_impulse += impulse;
204    }
205
206    pub fn clear_continuous(&mut self) {
207        self.force = Vec3::zero();
208        self.torque = Vec3::zero();
209    }
210
211    pub fn clear_instantaneous(&mut self) {
212        self.linear_impulse = Vec3::zero();
213        self.angular_impulse = Vec3::zero();
214    }
215
216    pub fn clear(&mut self) {
217        self.clear_continuous();
218        self.clear_instantaneous();
219    }
220}
221
222#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
223pub struct Gravity {
224    pub value: Vec3<Scalar>,
225}
226
227#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
228pub struct BodyMaterial {
229    pub friction: Scalar,
230    pub restitution: Scalar,
231}
232
233impl Default for BodyMaterial {
234    fn default() -> Self {
235        Self {
236            friction: 0.5,
237            restitution: 0.0,
238        }
239    }
240}
241
242#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
243pub struct ParticleMaterial {
244    pub linear_damping: Scalar,
245    pub angular_damping: Scalar,
246    pub linear_rest_threshold: Scalar,
247    pub angular_rest_threshold: Scalar,
248}
249
250impl Default for ParticleMaterial {
251    fn default() -> Self {
252        Self {
253            linear_damping: 0.9,
254            angular_damping: 0.9,
255            linear_rest_threshold: 0.05,
256            angular_rest_threshold: 0.05,
257        }
258    }
259}