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
#![deny(missing_docs)]
/*!
This crate defines a generic collider trait, which is meant to be used by collision detection libraries.
You can define new colliders and implement the `Collider` trait, so this collider can be used with different collision detection libraries, which use this trait.
If you create a collision detection library, it can use different collider traits.
A collision detection library might be generic over vector types, scalar types and dimensions, or specialized for specific vector types, scalar types and dimensions.
**/
use std::ops::Neg;
use vector_space::VectorSpace;
/// Information of a detected collision between colliders objects.
/// The information is stored as elements of the specified vector space.
#[derive(Copy, Clone, Debug)]
pub struct CollisionInfo<V: VectorSpace> {
/// The contact point at the first collider.
pub self_contact: V,
/// The contact point at the other collider.
pub other_contact: V,
/// The smallest vector by which the first collider needs to be moved, so the objects won't touch each other anymore.
pub vector: V,
}
impl<V: VectorSpace> Neg for CollisionInfo<V> {
type Output = Self;
fn neg(self) -> Self {
let Self {
self_contact,
other_contact,
vector,
} = self;
Self {
self_contact: other_contact,
other_contact: self_contact,
vector: -vector,
}
}
}
/// The collider trait, all colliders need to implement.
pub trait Collider<Other = Self> {
/// The vector type of this collider.
type Vector: VectorSpace;
/// Checks the collision between two colliders.
/// Defaults to a check of the return value of collision info.
fn check_collision(&self, other: &Other) -> bool {
self.collision_info(other).is_some()
}
/// If both colliders collide, returns some collision info, else returns none.
fn collision_info(&self, other: &Other) -> Option<CollisionInfo<Self::Vector>>;
}