linear-sim 0.10.3

Minimal linear 3D simulation library
Documentation
//! Simulation constraint entities

use either::Either;
use enum_dispatch::enum_dispatch;

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

use crate::object;
use crate::math::*;

pub mod contact;
pub mod distance;
pub use self::contact::Contact;
pub use self::distance::Distance;

pub(crate) mod island;
pub(crate) mod manager;
pub(crate) use self::island::Island;
pub(crate) use self::manager::Manager;

/// Constraint interface trait
#[enum_dispatch(Variant)]
pub(crate) trait Constraint {
  fn constrain_velocity (&self,
    object_a         : Either <&object::Static, &mut object::Dynamic>,
    object_b         : &mut object::Dynamic,
    pseudovelocity_a : Option <Vector3 <f64>>,
    pseudovelocity_b : Vector3 <f64>
  ) -> Option <Impulses>;

  fn constrain_position (&mut self,
    t_reverse        : f64,
    object_a         : Either <&object::Static, &mut object::Dynamic>,
    object_b         : &mut object::Dynamic,
    pseudovelocity_a : Option <&mut Vector3 <f64>>,
    pseudovelocity_b : &mut Vector3 <f64>
  ) -> Option <PostImpulses>;
}

#[cfg_attr(feature = "derive_serdes", derive(Deserialize, Serialize))]
#[derive(Clone, Debug, PartialEq)]
#[enum_dispatch]
pub enum Variant {
  Contact  (Contact),
  Distance (Distance)
}

#[derive(Debug, Default)]
pub(crate) struct Impulses {
  pub impulse_normal_a  : Vector3 <f64>,
  pub impulse_normal_b  : Vector3 <f64>,
  pub impulse_tangent_a : Vector3 <f64>,
  pub impulse_tangent_b : Vector3 <f64>
}

#[derive(Debug, Default)]
pub(crate) struct PostImpulses {
  pub pseudo_impulse_a : Vector3 <f64>,
  pub pseudo_impulse_b : Vector3 <f64>
}

impl Impulses {
  /// Combined normal + tangent impulse
  pub(crate) fn impulse_a (&self) -> Vector3 <f64> {
    self.impulse_normal_a + self.impulse_tangent_a
  }
  /// Combined normal + tangent impulse
  pub(crate) fn impulse_b (&self) -> Vector3 <f64> {
    self.impulse_normal_b + self.impulse_tangent_b
  }
}