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;
#[enum_dispatch]
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(Constraint)]
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 {
pub(crate) fn impulse_a (&self) -> Vector3 <f64> {
self.impulse_normal_a + self.impulse_tangent_a
}
pub(crate) fn impulse_b (&self) -> Vector3 <f64> {
self.impulse_normal_b + self.impulse_tangent_b
}
}