use crate::math::{Point, Vector};
use crate::query::ContactKinematic;
use na::{self, RealField, Unit};
use slotmap::Key;
use std::mem;
slotmap::new_key_type! {
pub struct ContactId;
}
#[derive(Debug, PartialEq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Contact<N: RealField + Copy> {
pub world1: Point<N>,
pub world2: Point<N>,
pub normal: Unit<Vector<N>>,
pub depth: N,
}
impl<N: RealField + Copy> Contact<N> {
#[inline]
pub fn new(world1: Point<N>, world2: Point<N>, normal: Unit<Vector<N>>, depth: N) -> Self {
Contact {
world1,
world2,
normal,
depth,
}
}
#[inline]
pub fn new_wo_depth(world1: Point<N>, world2: Point<N>, normal: Unit<Vector<N>>) -> Contact<N> {
let depth = -normal.dot(&(world2 - world1));
Self::new(world1, world2, normal, depth)
}
}
impl<N: RealField + Copy> Contact<N> {
#[inline]
pub fn flip(&mut self) {
mem::swap(&mut self.world1, &mut self.world2);
self.normal = -self.normal;
}
}
#[derive(Copy, Clone, Debug)]
pub struct TrackedContact<N: RealField + Copy> {
pub contact: Contact<N>,
pub kinematic: ContactKinematic<N>,
pub id: ContactId,
}
impl<N: RealField + Copy> TrackedContact<N> {
pub fn new(contact: Contact<N>, kinematic: ContactKinematic<N>) -> Self {
TrackedContact {
contact,
kinematic,
id: ContactId::null(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct ContactPrediction<N: RealField + Copy> {
linear: N,
angular1: N,
angular2: N,
cos_angular1: N,
cos_angular2: N,
sin_angular1: N,
sin_angular2: N,
}
impl<N: RealField + Copy> ContactPrediction<N> {
pub fn new(linear: N, angular1: N, angular2: N) -> Self {
ContactPrediction {
linear,
angular1,
angular2,
cos_angular1: angular1.cos(),
cos_angular2: angular2.cos(),
sin_angular1: angular1.sin(),
sin_angular2: angular2.sin(),
}
}
#[inline]
pub fn linear(&self) -> N {
self.linear
}
#[inline]
pub fn set_linear(&mut self, val: N) {
self.linear = val
}
#[inline]
pub fn angular1(&self) -> N {
self.angular1
}
#[inline]
pub fn angular2(&self) -> N {
self.angular2
}
#[inline]
pub fn cos_angular1(&self) -> N {
self.cos_angular1
}
#[inline]
pub fn cos_angular2(&self) -> N {
self.cos_angular2
}
#[inline]
pub fn sin_angular1(&self) -> N {
self.sin_angular1
}
#[inline]
pub fn sin_angular2(&self) -> N {
self.sin_angular2
}
}