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 : 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, mesh)) => {
63 let mut hull = hull.clone();
65 hull.translate (position.0);
66 line_segment.intersect_hull (&hull, mesh)
67 }
68 shape::Bounded::Cone (_cone) => unimplemented!(),
69 shape::Bounded::Cube (_cube) => unimplemented!(),
70 }
71 shape::Variant::Unbounded (unbounded) => match unbounded {
72 shape::Unbounded::Halfspace (_halfspace) => unimplemented!(),
73 shape::Unbounded::Orthant (_orthant) => unimplemented!()
74 }
75 }.map (|(start, _)| start)
76 }
77 fn to_primitive (&self) -> Box <dyn geometry::Primitive <f64, Point3 <f64>>> {
78 self.bound().0.to_primitive (self.position().0)
79 }
80}
81
82pub trait Temporal : Object {
84 fn derivatives (&self) -> &component::Derivatives;
85 fn derivatives_mut (&mut self) -> &mut component::Derivatives;
86}
87
88pub trait Inertial : Temporal {
90 fn mass (&self) -> &component::Mass;
92 fn mass_mut (&mut self) -> &mut component::Mass;
93 fn momentum (&self) -> Vector3 <f64> {
95 self.mass().mass() * self.derivatives().velocity
96 }
97 fn compute_acceleration (&self) -> Vector3 <f64> {
99 self.mass().mass_reciprocal() * self.derivatives().force
100 }
101 fn compute_acceleration_inplace (&mut self) {
104 let acceleration = self.mass().mass_reciprocal() * self.derivatives().force;
105 self.derivatives_mut().acceleration = acceleration;
106 }
107}
108
109pub trait Massive : Bounded + Inertial {
111 fn drag (&self) -> f64;
112 fn density (&self) -> Option <f64> {
113 use geometry::shape::Stereometric;
114 if let component::Bound (shape::Variant::Bounded (bounded)) = self.bound() {
115 Some (self.mass().mass() / *bounded.volume())
116 } else {
117 None
118 }
119 }
120}
121
122pub trait Solid : Bounded {
124 fn material (&self) -> &component::Material;
125 fn material_mut (&mut self) -> &mut component::Material;
126}
127
128#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
134#[derive(Clone, Copy, Debug, Eq, PartialEq)]
135pub enum Kind {
136 Static,
137 Dynamic,
138 Nodetect
139}
140
141#[derive(Clone, Debug, PartialEq, From)]
143pub enum Variant {
144 Static (Static),
145 Dynamic (Dynamic),
146 Nodetect (Nodetect)
147}
148
149#[derive(Clone, Debug, PartialEq, From)]
151pub enum VariantRef <'a> {
152 Static (&'a Static),
153 Dynamic (&'a Dynamic),
154 Nodetect (&'a Nodetect)
155}
156
157#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
163#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
164pub struct Key (KeyType);
165
166#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
168#[derive(Clone, Debug, Eq, PartialEq)]
169pub struct Id {
170 pub kind : Kind,
171 pub key : Key
172}
173
174#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
176#[derive(Clone, Debug, PartialEq)]
177pub struct Static {
178 pub position : component::Position,
179 pub bound : component::Bound,
180 pub material : component::Material,
181 pub collidable : bool
182}
183
184#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
186#[derive(Clone, Debug, PartialEq)]
187pub struct Dynamic {
188 pub position : component::Position,
189 pub mass : component::Mass,
190 pub derivatives : component::Derivatives,
191 pub drag : component::Drag,
192 pub bound : component::Bound,
193 pub material : component::Material,
194 pub collidable : bool
195}
196
197#[cfg_attr(feature = "derive_serdes", derive(Serialize, Deserialize))]
199#[derive(Clone, Debug, PartialEq)]
200pub struct Nodetect {
201 pub position : component::Position,
202 pub mass : component::Mass,
203 pub derivatives : component::Derivatives,
204 pub drag : component::Drag
205}
206
207pub fn report_sizes() {
213 use std::mem::size_of;
214 println!("object report sizes...");
215
216 println!(" size of Variant: {}", size_of::<Variant>());
217 println!(" size of Static: {}", size_of::<Static>());
218 println!(" size of Dynamic: {}", size_of::<Dynamic>());
219 println!(" size of Nodetect: {}", size_of::<Nodetect>());
220
221 println!("...object report sizes");
222}
223
224impl Variant {
232 pub const fn kind (&self) -> Kind {
233 match self {
234 Variant::Static (_) => Kind::Static,
235 Variant::Dynamic (_) => Kind::Dynamic,
236 Variant::Nodetect (_) => Kind::Nodetect
237 }
238 }
239}
240
241impl Static {
245 pub (crate) fn aabb_dilated (&self) -> geometry::Aabb3 <f64> {
247 use shape::Aabb;
248 self.aabb().dilate (0.5 * collision::CONTACT_DISTANCE).unwrap()
249 }
250}
251impl Object for Static {
252 fn kind() -> Kind { Kind::Static }
253 fn position (&self) -> &component::Position {
254 &self.position
255 }
256 fn position_mut (&mut self) -> &mut component::Position {
257 &mut self.position
258 }
259}
260impl Bounded for Static {
261 fn bound (&self) -> &component::Bound {
262 &self.bound
263 }
264 fn bound_mut (&mut self) -> &mut component::Bound {
265 &mut self.bound
266 }
267}
268impl shape::Aabb <f64> for Static {
269 fn aabb (&self) -> geometry::Aabb3 <f64> {
270 let component::Bound (variant) = &self.bound;
271 let aabb_shape = variant.aabb();
272 geometry::Aabb3::with_minmax_unchecked (
273 aabb_shape.min() + self.position().0.0,
274 aabb_shape.max() + self.position().0.0)
275 }
276}
277impl shape::Stereometric <f64> for Static {
278 fn volume (&self) -> Positive <f64> {
279 let component::Bound (variant) = &self.bound;
280 variant.volume()
281 }
282}
283
284impl Dynamic {
288 pub (crate) fn aabb_dilated (&self) -> geometry::Aabb3 <f64> {
290 use shape::Aabb;
291 self.aabb().dilate (0.5 * collision::CONTACT_DISTANCE).unwrap()
292 }
293}
294impl Object for Dynamic {
295 fn kind() -> Kind { Kind::Dynamic }
296 fn position (&self) -> &component::Position {
297 &self.position
298 }
299 fn position_mut (&mut self) -> &mut component::Position {
300 &mut self.position
301 }
302}
303impl Bounded for Dynamic {
304 fn bound (&self) -> &component::Bound {
305 &self.bound
306 }
307 fn bound_mut (&mut self) -> &mut component::Bound {
308 &mut self.bound
309 }
310}
311impl Temporal for Dynamic {
312 fn derivatives (&self) -> &component::Derivatives {
313 &self.derivatives
314 }
315 fn derivatives_mut (&mut self) -> &mut component::Derivatives {
316 &mut self.derivatives
317 }
318}
319impl Inertial for Dynamic {
320 fn mass (&self) -> &component::Mass {
321 &self.mass
322 }
323 fn mass_mut (&mut self) -> &mut component::Mass {
324 &mut self.mass
325 }
326}
327impl Borrow <component::Derivatives> for Dynamic {
328 fn borrow (&self) -> &component::Derivatives {
329 &self.derivatives
330 }
331}
332impl BorrowMut <component::Derivatives> for Dynamic {
333 fn borrow_mut (&mut self) -> &mut component::Derivatives {
334 &mut self.derivatives
335 }
336}
337impl shape::Aabb <f64> for Dynamic {
338 fn aabb (&self) -> geometry::Aabb3 <f64> {
339 let component::Bound (variant) = &self.bound;
340 let aabb_shape = variant.aabb();
341 geometry::Aabb3::with_minmax_unchecked (
342 aabb_shape.min() + self.position().0.0,
343 aabb_shape.max() + self.position().0.0)
344 }
345}
346impl shape::Stereometric <f64> for Dynamic {
347 fn volume (&self) -> Positive <f64> {
348 let component::Bound (variant) = &self.bound;
349 variant.volume()
350 }
351}
352
353impl Object for Nodetect {
357 fn kind() -> Kind { Kind::Nodetect }
358 fn position (&self) -> &component::Position {
359 &self.position
360 }
361 fn position_mut (&mut self) -> &mut component::Position {
362 &mut self.position
363 }
364}
365impl Temporal for Nodetect {
366 fn derivatives (&self) -> &component::Derivatives {
367 &self.derivatives
368 }
369 fn derivatives_mut (&mut self) -> &mut component::Derivatives {
370 &mut self.derivatives
371 }
372}
373impl Inertial for Nodetect {
374 fn mass (&self) -> &component::Mass {
375 &self.mass
376 }
377 fn mass_mut (&mut self) -> &mut component::Mass {
378 &mut self.mass
379 }
380}
381impl Borrow <component::Derivatives> for Nodetect {
382 fn borrow (&self) -> &component::Derivatives {
383 &self.derivatives
384 }
385}
386impl BorrowMut <component::Derivatives> for Nodetect {
387 fn borrow_mut (&mut self) -> &mut component::Derivatives {
388 &mut self.derivatives
389 }
390}
391
392impl Key {
396 pub const fn from_raw (key : KeyType) -> Self {
398 Key (key)
399 }
400 pub const fn value (&self) -> KeyType {
401 self.0
402 }
403 pub const fn index (&self) -> usize {
404 self.0 as usize
405 }
406}
407impl std::ops::Deref for Key {
408 type Target = KeyType;
409 fn deref (&self) -> &KeyType {
410 &self.0
411 }
412}
413impl From <KeyType> for Key {
414 fn from (key : KeyType) -> Self {
416 debug_assert!(key < KEY_MAX);
417 Key (key)
418 }
419}
420impl From <usize> for Key {
421 fn from (key : usize) -> Self {
423 debug_assert!((key as KeyType) < KEY_MAX);
424 Key (key as KeyType)
425 }
426}
427
428impl Object for (component::Position, component::Bound) {
432 fn kind() -> Kind {
433 Kind::Static
434 }
435 fn position (&self) -> &component::Position {
436 &self.0
437 }
438 fn position_mut (&mut self) -> &mut component::Position {
439 &mut self.0
440 }
441}
442impl Bounded for (component::Position, component::Bound) {
443 fn bound (&self) -> &component::Bound {
444 &self.1
445 }
446 fn bound_mut (&mut self) -> &mut component::Bound {
447 &mut self.1
448 }
449}
450impl Object for (component::Position, &component::Bound) {
451 fn kind() -> Kind {
452 Kind::Static
453 }
454 fn position (&self) -> &component::Position {
455 &self.0
456 }
457 fn position_mut (&mut self) -> &mut component::Position {
458 &mut self.0
459 }
460}
461impl Bounded for (component::Position, &component::Bound) {
462 fn bound (&self) -> &component::Bound {
463 self.1
464 }
465 fn bound_mut (&mut self) -> &mut component::Bound {
466 unimplemented!()
467 }
468}