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