1use std;
7use std::borrow::{Borrow, BorrowMut};
8use derive_more::{From, Into};
9
10#[cfg(feature = "derive_serdes")]
11use serde::{Deserialize, Serialize};
12
13use crate::component;
14use crate::constraint::contact::CONTACT_DISTANCE;
15use crate::geometry::{shape, Shape};
16use crate::math::*;
17
18pub type KeyType = u32;
28
29pub(crate) const KEY_MAX : KeyType = INTERNAL_ID_DYNAMIC_BIT - 1;
32
33pub(crate) const INTERNAL_ID_DYNAMIC_BIT : KeyType = 1 << (KeyType::BITS - 1);
37
38pub trait Object : std::fmt::Debug {
44 fn kind() -> Kind;
46 fn position (&self) -> &component::Position;
47 fn position_mut (&mut self) -> &mut component::Position;
48}
49
50pub trait Bounded : Object {
52 fn bound (&self) -> &component::Bound;
53 fn bound_mut (&mut self) -> &mut component::Bound;
54 fn hit_test (&self, line_segment : geometry::Segment3 <f64>)
57 -> Option <(Normalized <f64>, Point3 <f64>)>
58 {
59 use geometry::Primitive;
60 let position = self.position().0;
61 match &self.bound().0 {
62 shape::Variant::Bounded (bounded) => match bounded {
63 shape::Bounded::Sphere (sphere) =>
64 line_segment.intersect_sphere (sphere.sphere3 (position)),
65 shape::Bounded::Capsule (capsule) =>
66 line_segment.intersect_capsule (capsule.capsule3 (position)),
67 shape::Bounded::Cylinder (cylinder) =>
68 line_segment.intersect_cylinder (cylinder.cylinder3 (position)),
69 shape::Bounded::Cuboid (cuboid) =>
70 line_segment.intersect_aabb (cuboid.aabb3 (position)),
71 shape::Bounded::Hull ((hull, mesh)) => {
72 let mut hull = hull.clone();
74 hull.translate (position.0);
75 line_segment.intersect_hull (&hull, mesh)
76 }
77 shape::Bounded::Cone (_cone) => unimplemented!(),
78 shape::Bounded::Cube (_cube) => unimplemented!(),
79 }
80 shape::Variant::Unbounded (unbounded) => match unbounded {
81 shape::Unbounded::Halfspace (_halfspace) => unimplemented!(),
82 shape::Unbounded::Orthant (_orthant) => unimplemented!()
83 }
84 }.map (|(start, _)| start)
85 }
86 fn to_primitive (&self) -> Box <dyn geometry::Primitive <f64, Point3 <f64>>> {
87 self.bound().0.to_primitive (self.position().0)
88 }
89}
90
91pub trait Temporal : Object {
93 fn derivatives (&self) -> &component::Derivatives;
94 fn derivatives_mut (&mut self) -> &mut component::Derivatives;
95}
96
97pub trait Inertial : Temporal {
99 fn mass (&self) -> &component::Mass;
101 fn mass_mut (&mut self) -> &mut component::Mass;
102 fn momentum (&self) -> Vector3 <f64> {
104 self.mass().mass() * self.derivatives().velocity
105 }
106 fn compute_acceleration (&self) -> Vector3 <f64> {
108 self.mass().mass_reciprocal() * self.derivatives().force
109 }
110 fn compute_acceleration_inplace (&mut self) {
113 let acceleration = self.mass().mass_reciprocal() * self.derivatives().force;
114 self.derivatives_mut().acceleration = acceleration;
115 }
116}
117
118pub trait Massive : Bounded + Inertial {
120 fn drag (&self) -> f64;
121 fn density (&self) -> Option <f64> {
122 use geometry::shape::Stereometric;
123 if let component::Bound (shape::Variant::Bounded (bounded)) = self.bound() {
124 Some (self.mass().mass() / *bounded.volume())
125 } else {
126 None
127 }
128 }
129}
130
131pub trait Solid : Bounded {
133 fn material (&self) -> &component::Material;
134 fn material_mut (&mut self) -> &mut component::Material;
135}
136
137#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
139#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Into)]
140pub(crate) struct ObjectPair (pub InternalId, pub InternalId);
141
142#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
145#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
146pub(crate) struct InternalId (KeyType);
147
148#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
154#[derive(Clone, Copy, Debug, Eq, PartialEq)]
155pub enum Kind {
156 Static,
157 Dynamic,
158 Nodetect
159}
160
161#[derive(Clone, Debug, PartialEq, From)]
163pub enum Variant {
164 Static (Static),
165 Dynamic (Dynamic),
166 Nodetect (Nodetect)
167}
168
169#[derive(Clone, Debug, PartialEq, From)]
171pub enum VariantRef <'a> {
172 Static (&'a Static),
173 Dynamic (&'a Dynamic),
174 Nodetect (&'a Nodetect)
175}
176
177#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
183#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
184pub struct Key (KeyType);
185
186#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
188#[derive(Clone, Copy, Debug, Eq, PartialEq)]
189pub struct Id {
190 pub kind : Kind,
191 pub key : Key
192}
193
194#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
196#[derive(Clone, Debug, PartialEq)]
197pub struct Static {
198 pub position : component::Position,
199 pub bound : component::Bound,
200 pub material : component::Material,
201 pub collidable : bool
202}
203
204#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
206#[derive(Clone, Debug, PartialEq)]
207pub struct Dynamic {
208 pub position : component::Position,
209 pub mass : component::Mass,
210 pub derivatives : component::Derivatives,
211 pub drag : component::Drag,
212 pub bound : component::Bound,
213 pub material : component::Material,
214 pub collidable : bool
215}
216
217#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
219#[derive(Clone, Debug, PartialEq)]
220pub struct Nodetect {
221 pub position : component::Position,
222 pub mass : component::Mass,
223 pub derivatives : component::Derivatives,
224 pub drag : component::Drag
225}
226
227pub fn lerp <O : Temporal> (
233 object : &mut O, pseudovelocity : Vector3 <f64>, t_relative : f64
234) {
235 let component::Position (position) = object.position();
236 object.position_mut().0 = position + t_relative * object.derivatives().velocity
237 + t_relative * pseudovelocity;
238}
239
240pub fn report_sizes() {
242 use std::mem::size_of;
243 println!("object report sizes...");
244
245 println!(" size of Variant: {}", size_of::<Variant>());
246 println!(" size of Static: {}", size_of::<Static>());
247 println!(" size of Dynamic: {}", size_of::<Dynamic>());
248 println!(" size of Nodetect: {}", size_of::<Nodetect>());
249
250 println!("...object report sizes");
251}
252
253impl Variant {
261 pub const fn kind (&self) -> Kind {
262 match self {
263 Variant::Static (_) => Kind::Static,
264 Variant::Dynamic (_) => Kind::Dynamic,
265 Variant::Nodetect (_) => Kind::Nodetect
266 }
267 }
268}
269
270impl Static {
274 pub (crate) fn aabb_dilated (&self) -> geometry::Aabb3 <f64> {
276 use shape::Aabb;
277 self.aabb().dilate (0.5 * CONTACT_DISTANCE).unwrap()
278 }
279}
280impl Object for Static {
281 fn kind() -> Kind { Kind::Static }
282 fn position (&self) -> &component::Position {
283 &self.position
284 }
285 fn position_mut (&mut self) -> &mut component::Position {
286 &mut self.position
287 }
288}
289impl Bounded for Static {
290 fn bound (&self) -> &component::Bound {
291 &self.bound
292 }
293 fn bound_mut (&mut self) -> &mut component::Bound {
294 &mut self.bound
295 }
296}
297impl shape::Aabb <f64> for Static {
298 fn aabb (&self) -> geometry::Aabb3 <f64> {
299 let component::Bound (variant) = &self.bound;
300 let aabb_shape = variant.aabb();
301 geometry::Aabb3::with_minmax_unchecked (
302 aabb_shape.min() + self.position().0.0,
303 aabb_shape.max() + self.position().0.0)
304 }
305}
306impl shape::Stereometric <f64> for Static {
307 fn volume (&self) -> Positive <f64> {
308 let component::Bound (variant) = &self.bound;
309 variant.volume()
310 }
311}
312
313impl Dynamic {
317 pub (crate) fn aabb_dilated (&self) -> geometry::Aabb3 <f64> {
319 use shape::Aabb;
320 self.aabb().dilate (0.5 * CONTACT_DISTANCE).unwrap()
321 }
322}
323impl Object for Dynamic {
324 fn kind() -> Kind { Kind::Dynamic }
325 fn position (&self) -> &component::Position {
326 &self.position
327 }
328 fn position_mut (&mut self) -> &mut component::Position {
329 &mut self.position
330 }
331}
332impl Bounded for Dynamic {
333 fn bound (&self) -> &component::Bound {
334 &self.bound
335 }
336 fn bound_mut (&mut self) -> &mut component::Bound {
337 &mut self.bound
338 }
339}
340impl Temporal for Dynamic {
341 fn derivatives (&self) -> &component::Derivatives {
342 &self.derivatives
343 }
344 fn derivatives_mut (&mut self) -> &mut component::Derivatives {
345 &mut self.derivatives
346 }
347}
348impl Inertial for Dynamic {
349 fn mass (&self) -> &component::Mass {
350 &self.mass
351 }
352 fn mass_mut (&mut self) -> &mut component::Mass {
353 &mut self.mass
354 }
355}
356impl Borrow <component::Derivatives> for Dynamic {
357 fn borrow (&self) -> &component::Derivatives {
358 &self.derivatives
359 }
360}
361impl BorrowMut <component::Derivatives> for Dynamic {
362 fn borrow_mut (&mut self) -> &mut component::Derivatives {
363 &mut self.derivatives
364 }
365}
366impl shape::Aabb <f64> for Dynamic {
367 fn aabb (&self) -> geometry::Aabb3 <f64> {
368 let component::Bound (variant) = &self.bound;
369 let aabb_shape = variant.aabb();
370 geometry::Aabb3::with_minmax_unchecked (
371 aabb_shape.min() + self.position().0.0,
372 aabb_shape.max() + self.position().0.0)
373 }
374}
375impl shape::Stereometric <f64> for Dynamic {
376 fn volume (&self) -> Positive <f64> {
377 let component::Bound (variant) = &self.bound;
378 variant.volume()
379 }
380}
381
382impl Object for Nodetect {
386 fn kind() -> Kind { Kind::Nodetect }
387 fn position (&self) -> &component::Position {
388 &self.position
389 }
390 fn position_mut (&mut self) -> &mut component::Position {
391 &mut self.position
392 }
393}
394impl Temporal for Nodetect {
395 fn derivatives (&self) -> &component::Derivatives {
396 &self.derivatives
397 }
398 fn derivatives_mut (&mut self) -> &mut component::Derivatives {
399 &mut self.derivatives
400 }
401}
402impl Inertial for Nodetect {
403 fn mass (&self) -> &component::Mass {
404 &self.mass
405 }
406 fn mass_mut (&mut self) -> &mut component::Mass {
407 &mut self.mass
408 }
409}
410impl Borrow <component::Derivatives> for Nodetect {
411 fn borrow (&self) -> &component::Derivatives {
412 &self.derivatives
413 }
414}
415impl BorrowMut <component::Derivatives> for Nodetect {
416 fn borrow_mut (&mut self) -> &mut component::Derivatives {
417 &mut self.derivatives
418 }
419}
420
421impl Key {
425 pub const fn from_raw (key : KeyType) -> Self {
427 Key (key)
428 }
429 pub const fn value (&self) -> KeyType {
430 self.0
431 }
432 pub const fn index (&self) -> usize {
433 self.0 as usize
434 }
435}
436impl std::ops::Deref for Key {
437 type Target = KeyType;
438 fn deref (&self) -> &KeyType {
439 &self.0
440 }
441}
442impl From <KeyType> for Key {
443 fn from (key : KeyType) -> Self {
445 debug_assert!(key < KEY_MAX);
446 Key (key)
447 }
448}
449impl From <usize> for Key {
450 fn from (key : usize) -> Self {
452 debug_assert!((key as KeyType) < KEY_MAX);
453 Key (key as KeyType)
454 }
455}
456
457impl Object for (component::Position, component::Bound) {
461 fn kind() -> Kind {
462 Kind::Static
463 }
464 fn position (&self) -> &component::Position {
465 &self.0
466 }
467 fn position_mut (&mut self) -> &mut component::Position {
468 &mut self.0
469 }
470}
471impl Bounded for (component::Position, component::Bound) {
472 fn bound (&self) -> &component::Bound {
473 &self.1
474 }
475 fn bound_mut (&mut self) -> &mut component::Bound {
476 &mut self.1
477 }
478}
479impl Object for (component::Position, &component::Bound) {
480 fn kind() -> Kind {
481 Kind::Static
482 }
483 fn position (&self) -> &component::Position {
484 &self.0
485 }
486 fn position_mut (&mut self) -> &mut component::Position {
487 &mut self.0
488 }
489}
490impl Bounded for (component::Position, &component::Bound) {
491 fn bound (&self) -> &component::Bound {
492 self.1
493 }
494 fn bound_mut (&mut self) -> &mut component::Bound {
495 unimplemented!()
496 }
497}
498
499impl ObjectPair {
503 pub(crate) fn new (id_a : InternalId, id_b : InternalId) -> Self {
508 debug_assert!(id_a.kind() == Kind::Dynamic || id_b.kind() == Kind::Dynamic);
509 if id_a < id_b {
510 ObjectPair (id_a, id_b)
511 } else {
512 debug_assert!(id_a > id_b, "object pair ids should not be identical");
513 ObjectPair (id_b, id_a)
514 }
515 }
516}
517
518impl From <(InternalId, InternalId)> for ObjectPair {
519 fn from ((id_a, id_b) : (InternalId, InternalId)) -> Self {
520 ObjectPair::new (id_a, id_b)
521 }
522}
523
524impl TryFrom <(Id, Id)> for ObjectPair {
525 type Error = (Id, Id);
526 fn try_from ((id_a, id_b) : (Id, Id)) -> Result <Self, Self::Error> {
527 match [id_a, id_b].map (InternalId::try_from) {
528 [Ok (internal_id_a), Ok (internal_id_b)]
529 => Ok ((internal_id_a, internal_id_b).into()),
530 _ => Err ((id_a, id_b))
531 }
532 }
533}
534
535impl InternalId {
539 #[inline]
540 pub(crate) fn new_static (key : Key) -> Self {
541 debug_assert!(key.value() < KEY_MAX);
542 InternalId (key.value())
543 }
544 #[inline]
545 pub(crate) fn new_dynamic (key : Key) -> Self {
546 debug_assert!(key.value() < KEY_MAX);
547 InternalId (key.value() | INTERNAL_ID_DYNAMIC_BIT)
548 }
549 #[inline]
550 pub(crate) const fn kind (self) -> Kind {
551 match self.0 & INTERNAL_ID_DYNAMIC_BIT > 0 {
552 true => Kind::Dynamic,
553 false => Kind::Static
554 }
555 }
556 #[inline]
557 pub(crate) fn key (self) -> Key {
558 Key::from (self.0 & !INTERNAL_ID_DYNAMIC_BIT)
559 }
560}
561impl From <InternalId> for Id {
562 fn from (id : InternalId) -> Self {
563 Id {
564 kind: id.kind(),
565 key: id.key()
566 }
567 }
568}
569impl TryFrom <Id> for InternalId {
570 type Error = Id;
571 fn try_from (id : Id) -> Result <Self, Self::Error> {
572 let out = match id.kind {
573 Kind::Dynamic => InternalId::new_dynamic (id.key),
574 Kind::Static => InternalId::new_static (id.key),
575 Kind::Nodetect => return Err(id)
576 };
577 Ok(out)
578 }
579}