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 PhysicsMaterial {
229 pub friction: Scalar,
230 pub restitution: Scalar,
231}
232
233impl Default for PhysicsMaterial {
234 fn default() -> Self {
235 Self {
236 friction: 0.5,
237 restitution: 0.0,
238 }
239 }
240}