linear-sim 0.6.9

Minimal linear 3D simulation library
Documentation
//! Components for use by entities.

use {std, enumflags2};
use derive_more::From;
#[cfg(feature = "derive_serdes")]
use serde::{Deserialize, Serialize};

use crate::{force, geometry, math};

#[allow(clippy::excessive_precision)]
pub const MATERIAL_WOOD    : Material  = Material {
  restitution: 0.6, friction: 0.63245553203367586639
  //restitution: 0.6, friction: 0.4
};
#[allow(clippy::excessive_precision)]
pub const MATERIAL_STONE   : Material = Material {
  restitution: 0.8, friction: 0.77459666924148337703
  //restitution: 0.8, friction: 0.6
};
#[allow(clippy::excessive_precision)]
pub const MATERIAL_COPPER  : Material = Material {
  restitution: 0.6, friction: 0.63245553203367586639
  //restitution: 0.15, friction: 0.4
};
#[allow(clippy::excessive_precision)]
pub const MATERIAL_BRONZE  : Material = Material {
  restitution: 0.6, friction: 0.54772255750516611345
  //restitution: 0.6, friction: 0.3
};
pub const MATERIAL_LEATHER : Material = Material {
  restitution: 0.1, friction: std::f64::consts::FRAC_1_SQRT_2
  //restitution: 0.1, friction: 0.5
};

/// A point in 3D space
#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, PartialEq, From)]
pub struct Position (pub math::Point3 <f64>);

/// First (velocity) and second (acceleration) time derivatives of position
#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Derivatives {
  /// First time derivative of position
  pub velocity     : math::Vector3 <f64>,
  /// Second time derivative of position
  pub acceleration : math::Vector3 <f64>,
  /// First time derivative of momentum.
  ///
  /// This vector is intended to be cleared and then accumulated each step.
  pub force        : math::Vector3 <f64>,
  pub force_flags  : enumflags2::BitFlags <force::Flag>
}

/// A drag coefficient for dynamic objects
#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Drag (pub f64);

/// A bounding volume
#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, PartialEq, From)]
pub struct Bound (pub geometry::shape::Variant <f64>);

/// A point mass; does *not* currently enforce that mass is nonzero or positive
#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Mass {
  mass            : f64,
  mass_reciprocal : f64
}

/// Surface material properties
#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, PartialEq)]
pub struct Material {
  /// A generic restitution is in [0.0,1.0] with 1.0 being perfectly elastic and
  /// 0.0 perfectly inelastic.
  ///
  /// When a pair of material objects collide, their respective restitution
  /// coefficients are multiplied to give the restitution coefficient for that
  /// collision.
  pub restitution : f64,
  /// A generic friction coefficient is in [0.0,\infty] with 0.0 being perfectly
  /// frictionless and 1.0 being about equivalent to concrete on rubber.
  ///
  /// When a pair of material objects have contact, the average of their
  /// respective friction coefficients is computed to give the friction
  /// coefficient for that contact.
  pub friction    : f64
}

impl Position {
  #[inline]
  pub fn origin() -> Self {
    Position ([0.0, 0.0, 0.0].into())
  }
}

impl Mass {
  #[inline]
  pub fn new (mass : f64) -> Self {
    let mass_reciprocal = 1.0 / mass;
    Self { mass, mass_reciprocal }
  }
  #[inline]
  pub fn mass (&self) -> f64 {
    self.mass
  }
  #[inline]
  pub fn mass_reciprocal (&self) -> f64 {
    self.mass_reciprocal
  }
  #[inline]
  pub fn set_mass (&mut self, mass : f64) {
    self.mass = mass;
    self.mass_reciprocal = 1.0 / self.mass;
  }
}
impl std::ops::Add <Self> for Mass {
  type Output = Self;
  fn add (self, rhs : Self) -> Self {
    let mass = self.mass + rhs.mass;
    let mass_reciprocal = 1.0 / mass;
    Mass { mass, mass_reciprocal }
  }
}

impl Derivatives {
  #[inline]
  pub fn zero() -> Self {
    let velocity     = math::Vector3::zero();
    let acceleration = math::Vector3::zero();
    let force        = math::Vector3::zero();
    let force_flags  = enumflags2::BitFlags::all();
    Derivatives { velocity, acceleration, force, force_flags }
  }
}

impl Drag {
  #[inline]
  pub fn zero() -> Self {
    Drag (0.0)
  }
}