1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
use crate::math::{Isometry, Point, Real, Vector};
use na::{self, Unit};
use std::mem;
#[cfg(feature = "rkyv")]
use rkyv::{bytecheck, CheckBytes};
/// Geometric description of a contact.
#[derive(Debug, PartialEq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(
feature = "rkyv",
derive(rkyv::Archive, rkyv::Deserialize, rkyv::Serialize, CheckBytes),
archive(as = "Self")
)]
pub struct Contact {
/// Position of the contact on the first object.
pub point1: Point<Real>,
/// Position of the contact on the second object.
pub point2: Point<Real>,
/// Contact normal, pointing towards the exterior of the first shape.
pub normal1: Unit<Vector<Real>>,
/// Contact normal, pointing towards the exterior of the second shape.
///
/// If these contact data are expressed in world-space, this normal is equal to `-normal1`.
pub normal2: Unit<Vector<Real>>,
/// Distance between the two contact points.
///
/// If this is negative, this contact represents a penetration.
pub dist: Real,
}
impl Contact {
/// Creates a new contact.
#[inline]
pub fn new(
point1: Point<Real>,
point2: Point<Real>,
normal1: Unit<Vector<Real>>,
normal2: Unit<Vector<Real>>,
dist: Real,
) -> Self {
Contact {
point1,
point2,
normal1,
normal2,
dist,
}
}
}
impl Contact {
/// Swaps the points and normals of this contact.
#[inline]
pub fn flip(&mut self) {
mem::swap(&mut self.point1, &mut self.point2);
mem::swap(&mut self.normal1, &mut self.normal2);
}
/// Returns a new contact containing the swapped points and normals of `self`.
#[inline]
pub fn flipped(mut self) -> Self {
self.flip();
self
}
/// Transform the points and normals from this contact by
/// the given transformations.
#[inline]
pub fn transform_by_mut(&mut self, pos1: &Isometry<Real>, pos2: &Isometry<Real>) {
self.point1 = pos1 * self.point1;
self.point2 = pos2 * self.point2;
self.normal1 = pos1 * self.normal1;
self.normal2 = pos2 * self.normal2;
}
/// Transform `self.point1` and `self.normal1` by the `pos`.
pub fn transform1_by_mut(&mut self, pos: &Isometry<Real>) {
self.point1 = pos * self.point1;
self.normal1 = pos * self.normal1;
}
}