1use std;
7use std::borrow::{Borrow, BorrowMut};
8use derive_more::From;
9
10#[cfg(feature = "derive_serdes")]
11use serde::{Deserialize, Serialize};
12
13use crate::{collision, component};
14use crate::geometry::{self, shape, Shape};
15use crate::math::*;
16
17pub type KeyType = u32;
27pub const KEY_MAX : KeyType = collision::OBJECT_KEY_MAX;
28
29pub trait Object : Clone + std::fmt::Debug {
35 fn kind() -> Kind;
37 fn position (&self) -> &component::Position;
38 fn position_mut (&mut self) -> &mut component::Position;
39}
40
41pub trait Bounded : Object {
43 fn bound (&self) -> &component::Bound;
44 fn bound_mut (&mut self) -> &mut component::Bound;
45 fn hit_test (&self, line_segment : geometry::Segment3 <f64>)
48 -> Option <(Normalized <f64>, Point3 <f64>)>
49 {
50 use geometry::Primitive;
51 let position = self.position().0;
52 match &self.bound().0 {
53 shape::Variant::Bounded (bounded) => match bounded {
54 shape::Bounded::Sphere (sphere) =>
55 line_segment.intersect_sphere (sphere.sphere3 (position)),
56 shape::Bounded::Capsule (capsule) =>
57 line_segment.intersect_capsule (capsule.capsule3 (position)),
58 shape::Bounded::Cylinder (cylinder) =>
59 line_segment.intersect_cylinder (cylinder.cylinder3 (position)),
60 shape::Bounded::Cuboid (cuboid) =>
61 line_segment.intersect_aabb (cuboid.aabb3 (position)),
62 shape::Bounded::Hull (hull) => {
63 let mut hull = hull.clone();
64 hull.translate (position.0);
65 line_segment.intersect_hull (&hull)
66 }
67 shape::Bounded::Cone (_cone) => unimplemented!(),
68 shape::Bounded::Cube (_cube) => unimplemented!(),
69 }
70 shape::Variant::Unbounded (unbounded) => match unbounded {
71 shape::Unbounded::Halfspace (_halfspace) => unimplemented!(),
72 shape::Unbounded::Orthant (_orthant) => unimplemented!()
73 }
74 }.map (|(start, _)| start)
75 }
76 fn to_primitive (&self) -> Box <dyn geometry::Primitive <f64, Point3 <f64>>> {
77 self.bound().0.to_primitive (self.position().0)
78 }
79}
80
81pub trait Temporal : Object {
83 fn derivatives (&self) -> &component::Derivatives;
84 fn derivatives_mut (&mut self) -> &mut component::Derivatives;
85}
86
87pub trait Inertial : Temporal {
89 fn mass (&self) -> &component::Mass;
91 fn mass_mut (&mut self) -> &mut component::Mass;
92 fn momentum (&self) -> Vector3 <f64> {
94 self.mass().mass() * self.derivatives().velocity
95 }
96 fn compute_acceleration (&self) -> Vector3 <f64> {
98 self.mass().mass_reciprocal() * self.derivatives().force
99 }
100 fn compute_acceleration_inplace (&mut self) {
103 let acceleration = self.mass().mass_reciprocal() * self.derivatives().force;
104 self.derivatives_mut().acceleration = acceleration;
105 }
106}
107
108pub trait Massive : Bounded + Inertial {
110 fn drag (&self) -> f64;
111 fn density (&self) -> Option <f64> {
112 use geometry::shape::Stereometric;
113 if let component::Bound (shape::Variant::Bounded (bounded)) = self.bound() {
114 Some (self.mass().mass() / *bounded.volume())
115 } else {
116 None
117 }
118 }
119}
120
121pub trait Solid : Bounded {
123 fn material (&self) -> &component::Material;
124 fn material_mut (&mut self) -> &mut component::Material;
125}
126
127#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
133#[derive(Clone, Copy, Debug, Eq, PartialEq)]
134pub enum Kind {
135 Static,
136 Dynamic,
137 Nodetect
138}
139
140#[derive(Clone, Debug, PartialEq, From)]
142pub enum Variant {
143 Static (Static),
144 Dynamic (Dynamic),
145 Nodetect (Nodetect)
146}
147
148#[derive(Clone, Debug, PartialEq, From)]
150pub enum VariantRef <'a> {
151 Static (&'a Static),
152 Dynamic (&'a Dynamic),
153 Nodetect (&'a Nodetect)
154}
155
156#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
162#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
163pub struct Key (KeyType);
164
165#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
167#[derive(Clone, Debug, Eq, PartialEq)]
168pub struct Id {
169 pub kind : Kind,
170 pub key : Key
171}
172
173#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
175#[derive(Clone, Debug, PartialEq)]
176pub struct Static {
177 pub position : component::Position,
178 pub bound : component::Bound,
179 pub material : component::Material,
180 pub collidable : bool
181}
182
183#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
185#[derive(Clone, Debug, PartialEq)]
186pub struct Dynamic {
187 pub position : component::Position,
188 pub mass : component::Mass,
189 pub derivatives : component::Derivatives,
190 pub drag : component::Drag,
191 pub bound : component::Bound,
192 pub material : component::Material,
193 pub collidable : bool
194}
195
196#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
198#[derive(Clone, Debug, PartialEq)]
199pub struct Nodetect {
200 pub position : component::Position,
201 pub mass : component::Mass,
202 pub derivatives : component::Derivatives,
203 pub drag : component::Drag
204}
205
206pub fn report_sizes() {
212 use std::mem::size_of;
213 println!("object report sizes...");
214
215 println!(" size of Variant: {}", size_of::<Variant>());
216 println!(" size of Static: {}", size_of::<Static>());
217 println!(" size of Dynamic: {}", size_of::<Dynamic>());
218 println!(" size of Nodetect: {}", size_of::<Nodetect>());
219
220 println!("...object report sizes");
221}
222
223impl Variant {
231 pub const fn kind (&self) -> Kind {
232 match self {
233 Variant::Static (_) => Kind::Static,
234 Variant::Dynamic (_) => Kind::Dynamic,
235 Variant::Nodetect (_) => Kind::Nodetect
236 }
237 }
238}
239
240impl Static {
244 pub (crate) fn aabb_dilated (&self) -> geometry::Aabb3 <f64> {
246 use shape::Aabb;
247 self.aabb().dilate (0.5 * collision::CONTACT_DISTANCE).unwrap()
248 }
249}
250impl Object for Static {
251 fn kind() -> Kind { Kind::Static }
252 fn position (&self) -> &component::Position {
253 &self.position
254 }
255 fn position_mut (&mut self) -> &mut component::Position {
256 &mut self.position
257 }
258}
259impl Bounded for Static {
260 fn bound (&self) -> &component::Bound {
261 &self.bound
262 }
263 fn bound_mut (&mut self) -> &mut component::Bound {
264 &mut self.bound
265 }
266}
267impl shape::Aabb <f64> for Static {
268 fn aabb (&self) -> geometry::Aabb3 <f64> {
269 let component::Bound (variant) = &self.bound;
270 let aabb_shape = variant.aabb();
271 geometry::Aabb3::with_minmax_unchecked (
272 aabb_shape.min() + self.position().0.0,
273 aabb_shape.max() + self.position().0.0)
274 }
275}
276impl shape::Stereometric <f64> for Static {
277 fn volume (&self) -> Positive <f64> {
278 let component::Bound (variant) = &self.bound;
279 variant.volume()
280 }
281}
282
283impl Dynamic {
287 pub (crate) fn aabb_dilated (&self) -> geometry::Aabb3 <f64> {
289 use shape::Aabb;
290 self.aabb().dilate (0.5 * collision::CONTACT_DISTANCE).unwrap()
291 }
292}
293impl Object for Dynamic {
294 fn kind() -> Kind { Kind::Dynamic }
295 fn position (&self) -> &component::Position {
296 &self.position
297 }
298 fn position_mut (&mut self) -> &mut component::Position {
299 &mut self.position
300 }
301}
302impl Bounded for Dynamic {
303 fn bound (&self) -> &component::Bound {
304 &self.bound
305 }
306 fn bound_mut (&mut self) -> &mut component::Bound {
307 &mut self.bound
308 }
309}
310impl Temporal for Dynamic {
311 fn derivatives (&self) -> &component::Derivatives {
312 &self.derivatives
313 }
314 fn derivatives_mut (&mut self) -> &mut component::Derivatives {
315 &mut self.derivatives
316 }
317}
318impl Inertial for Dynamic {
319 fn mass (&self) -> &component::Mass {
320 &self.mass
321 }
322 fn mass_mut (&mut self) -> &mut component::Mass {
323 &mut self.mass
324 }
325}
326impl Borrow <component::Derivatives> for Dynamic {
327 fn borrow (&self) -> &component::Derivatives {
328 &self.derivatives
329 }
330}
331impl BorrowMut <component::Derivatives> for Dynamic {
332 fn borrow_mut (&mut self) -> &mut component::Derivatives {
333 &mut self.derivatives
334 }
335}
336impl shape::Aabb <f64> for Dynamic {
337 fn aabb (&self) -> geometry::Aabb3 <f64> {
338 let component::Bound (variant) = &self.bound;
339 let aabb_shape = variant.aabb();
340 geometry::Aabb3::with_minmax_unchecked (
341 aabb_shape.min() + self.position().0.0,
342 aabb_shape.max() + self.position().0.0)
343 }
344}
345impl shape::Stereometric <f64> for Dynamic {
346 fn volume (&self) -> Positive <f64> {
347 let component::Bound (variant) = &self.bound;
348 variant.volume()
349 }
350}
351
352impl Object for Nodetect {
356 fn kind() -> Kind { Kind::Nodetect }
357 fn position (&self) -> &component::Position {
358 &self.position
359 }
360 fn position_mut (&mut self) -> &mut component::Position {
361 &mut self.position
362 }
363}
364impl Temporal for Nodetect {
365 fn derivatives (&self) -> &component::Derivatives {
366 &self.derivatives
367 }
368 fn derivatives_mut (&mut self) -> &mut component::Derivatives {
369 &mut self.derivatives
370 }
371}
372impl Inertial for Nodetect {
373 fn mass (&self) -> &component::Mass {
374 &self.mass
375 }
376 fn mass_mut (&mut self) -> &mut component::Mass {
377 &mut self.mass
378 }
379}
380impl Borrow <component::Derivatives> for Nodetect {
381 fn borrow (&self) -> &component::Derivatives {
382 &self.derivatives
383 }
384}
385impl BorrowMut <component::Derivatives> for Nodetect {
386 fn borrow_mut (&mut self) -> &mut component::Derivatives {
387 &mut self.derivatives
388 }
389}
390
391impl Key {
395 pub const fn from_raw (key : KeyType) -> Self {
397 Key (key)
398 }
399 pub const fn value (&self) -> KeyType {
400 self.0
401 }
402 pub const fn index (&self) -> usize {
403 self.0 as usize
404 }
405}
406impl std::ops::Deref for Key {
407 type Target = KeyType;
408 fn deref (&self) -> &KeyType {
409 &self.0
410 }
411}
412impl From <KeyType> for Key {
413 fn from (key : KeyType) -> Self {
415 debug_assert!(key < KEY_MAX);
416 Key (key)
417 }
418}
419impl From <usize> for Key {
420 fn from (key : usize) -> Self {
422 debug_assert!((key as KeyType) < KEY_MAX);
423 Key (key as KeyType)
424 }
425}
426
427impl Object for (component::Position, component::Bound) {
429 fn kind() -> Kind {
430 Kind::Static
431 }
432 fn position (&self) -> &component::Position {
433 &self.0
434 }
435 fn position_mut (&mut self) -> &mut component::Position {
436 &mut self.0
437 }
438}
439impl Bounded for (component::Position, component::Bound) {
440 fn bound (&self) -> &component::Bound {
441 &self.1
442 }
443 fn bound_mut (&mut self) -> &mut component::Bound {
444 &mut self.1
445 }
446}