linear_sim/
component.rs

1//! Components for use by entities.
2
3use {std, enumflags2};
4use derive_more::From;
5#[cfg(feature = "derive_serdes")]
6use serde::{Deserialize, Serialize};
7
8use crate::{force, geometry, math};
9
10pub const MATERIAL_WOOD    : Material  = Material {
11  restitution: 0.6, friction: 0.63245553203367586639
12  //restitution: 0.6, friction: 0.4
13};
14pub const MATERIAL_STONE   : Material = Material {
15  restitution: 0.8, friction: 0.77459666924148337703
16  //restitution: 0.8, friction: 0.6
17};
18pub const MATERIAL_COPPER  : Material = Material {
19  restitution: 0.6, friction: 0.63245553203367586639
20  //restitution: 0.15, friction: 0.4
21};
22pub const MATERIAL_BRONZE  : Material = Material {
23  restitution: 0.6, friction: 0.54772255750516611345
24  //restitution: 0.6, friction: 0.3
25};
26pub const MATERIAL_LEATHER : Material = Material {
27  restitution: 0.1, friction: std::f64::consts::FRAC_1_SQRT_2
28  //restitution: 0.1, friction: 0.5
29};
30
31/// A point in 3D space
32#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
33#[derive(Clone, Debug, PartialEq, From)]
34pub struct Position (pub math::Point3 <f64>);
35
36/// First (velocity) and second (acceleration) time derivatives of position
37#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
38#[derive(Clone, Debug, PartialEq)]
39pub struct Derivatives {
40  /// First time derivative of position
41  pub velocity     : math::Vector3 <f64>,
42  /// Second time derivative of position
43  pub acceleration : math::Vector3 <f64>,
44  /// First time derivative of momentum.
45  ///
46  /// This vector is intended to be cleared and then accumulated each step.
47  pub force        : math::Vector3 <f64>,
48  pub force_flags  : enumflags2::BitFlags <force::Flag>
49}
50
51/// A drag coefficient for dynamic objects
52#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
53#[derive(Clone, Debug, PartialEq)]
54pub struct Drag (pub f64);
55
56/// A bounding volume
57#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
58#[derive(Clone, Debug, PartialEq, From)]
59pub struct Bound (pub geometry::shape::Variant <f64>);
60
61/// A point mass; does *not* currently enforce that mass is nonzero or positive
62#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
63#[derive(Clone, Debug, PartialEq)]
64pub struct Mass {
65  mass            : f64,
66  mass_reciprocal : f64
67}
68
69/// Surface material properties
70#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
71#[derive(Clone, Debug, PartialEq)]
72pub struct Material {
73  /// A generic restitution is in [0.0,1.0] with 1.0 being perfectly elastic and
74  /// 0.0 perfectly inelastic.
75  ///
76  /// When a pair of material objects collide, their respective restitution
77  /// coefficients are multiplied to give the restitution coefficient for that
78  /// collision.
79  pub restitution : f64,
80  /// A generic friction coefficient is in [0.0,\infty] with 0.0 being perfectly
81  /// frictionless and 1.0 being about equivalent to concrete on rubber.
82  ///
83  /// When a pair of material objects have contact, the average of their
84  /// respective friction coefficients is computed to give the friction
85  /// coefficient for that contact.
86  pub friction    : f64
87}
88
89impl Position {
90  #[inline]
91  pub fn origin() -> Self {
92    Position ([0.0, 0.0, 0.0].into())
93  }
94}
95
96impl Mass {
97  #[inline]
98  pub fn new (mass : f64) -> Self {
99    let mass_reciprocal = 1.0 / mass;
100    Self { mass, mass_reciprocal }
101  }
102  #[inline]
103  pub fn mass (&self) -> f64 {
104    self.mass
105  }
106  #[inline]
107  pub fn mass_reciprocal (&self) -> f64 {
108    self.mass_reciprocal
109  }
110  #[inline]
111  pub fn set_mass (&mut self, mass : f64) {
112    self.mass = mass;
113    self.mass_reciprocal = 1.0 / self.mass;
114  }
115}
116impl std::ops::Add <Self> for Mass {
117  type Output = Self;
118  fn add (self, rhs : Self) -> Self {
119    let mass = self.mass + rhs.mass;
120    let mass_reciprocal = 1.0 / mass;
121    Mass { mass, mass_reciprocal }
122  }
123}
124
125impl Derivatives {
126  #[inline]
127  pub fn zero() -> Self {
128    let velocity     = math::Vector3::zero();
129    let acceleration = math::Vector3::zero();
130    let force        = math::Vector3::zero();
131    let force_flags  = enumflags2::BitFlags::all();
132    Derivatives { velocity, acceleration, force, force_flags }
133  }
134}
135
136impl Drag {
137  #[inline]
138  pub fn zero() -> Self {
139    Drag (0.0)
140  }
141}