mod broad_phase_interop;
mod epa;
mod gjk;
mod math;
mod minkowski;
#[cfg(test)]
mod ray;
pub mod shapes;
mod transform;
use shapes::ShapeData;
pub use transform::Transform;
#[derive(Debug, Clone)]
pub struct CollisionShape {
transform: Transform,
data: ShapeData,
}
impl<S: Into<ShapeData>> From<S> for CollisionShape {
fn from(shape: S) -> Self {
Self {
transform: Transform::default(),
data: shape.into(),
}
}
}
impl CollisionShape {
#[inline]
#[must_use]
pub fn new_circle(radius: f32) -> Self {
shapes::Circle::new(radius).into()
}
#[inline]
#[must_use]
pub fn new_rectangle(width: f32, height: f32) -> Self {
shapes::Rectangle::new(width, height).into()
}
#[inline]
#[must_use]
pub fn new_segment(p1: impl Into<[f32; 2]>, p2: impl Into<[f32; 2]>) -> Self {
shapes::Segment::new(p1, p2).into()
}
#[inline]
#[must_use]
pub fn with_transform(mut self, transform: impl Into<Transform>) -> Self {
self.set_transform(transform);
self
}
#[inline]
pub fn set_transform(&mut self, transform: impl Into<Transform>) {
self.transform = transform.into();
}
#[must_use]
pub fn is_collided_with(&self, other: &Self) -> bool {
let difference = minkowski::Difference {
shape1: self,
shape2: other,
};
let initial_axis = other.transform.position() - self.transform.position();
gjk::find_simplex_enclosing_origin(&difference, initial_axis).is_some()
}
#[must_use]
pub fn contact_with(&self, other: &Self) -> Option<Contact> {
let difference = minkowski::Difference {
shape1: self,
shape2: other,
};
let initial_axis = other.transform.position() - self.transform.position();
let simplex = gjk::find_simplex_enclosing_origin(&difference, initial_axis)?;
let Contact {
normal,
penetration,
} = epa::generate_contact(&difference, simplex);
Some(Contact::<f32, [f32; 2]> {
normal: normal.into(),
penetration,
})
}
#[must_use]
pub fn shape_data(&self) -> &ShapeData {
&self.data
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub struct Contact<S = f32, V = [S; 2]> {
pub normal: V,
pub penetration: S,
}
trait Support<V> {
fn support(&self, direction: V) -> V;
}