Skip to main content

collide/
lib.rs

1#![deny(missing_docs)]
2
3/*!
4A generic collider trait designed for use by collision detection libraries.
5
6You can define new colliders and implement the `Collider` trait, making them usable with different collision detection libraries that adopt this trait.
7
8Collision detection libraries can be generic over vector types, scalar types, and dimensions, or specialized for specific ones.
9
10## Example
11
12```rust
13use collide::{Collider, CollisionInfo};
14
15#[derive(Copy, Clone, Debug, PartialEq)]
16struct Vec2(f32, f32);
17
18// Basic operation implementations here
19
20struct Sphere {
21    center: Vec2,
22    radius: f32,
23}
24
25impl Collider for Sphere {
26    type Vector = Vec2;
27
28    fn collision_info(&self, other: &Self) -> Option<CollisionInfo<Vec2>> {
29        // Collision logic here
30        None
31    }
32}
33```
34*/
35
36use std::{hash::Hash, ops::Neg};
37
38/// Information about a detected collision between collider objects.
39/// The data is stored in the specified vector type.
40#[derive(Copy, Clone, Debug)]
41pub struct CollisionInfo<V> {
42    /// Contact point on the first collider.
43    pub self_contact: V,
44    /// Contact point on the other collider.
45    pub other_contact: V,
46    /// Smallest displacement vector to move the first collider so objects no longer touch.
47    pub vector: V,
48}
49
50impl<V: Neg<Output = V>> Neg for CollisionInfo<V> {
51    type Output = Self;
52    fn neg(self) -> Self {
53        let Self {
54            self_contact,
55            other_contact,
56            vector,
57        } = self;
58        Self {
59            self_contact: other_contact,
60            other_contact: self_contact,
61            vector: -vector,
62        }
63    }
64}
65
66/// The collider trait that all colliders must implement.
67pub trait Collider<OtherCollider = Self> {
68    /// The underlying vector type.
69    type Vector;
70
71    /// Checks if two colliders collide.
72    /// By default just checks if a collision info is found, so implementing this manually might be more effcient.
73    fn check_collision(&self, other: &OtherCollider) -> bool {
74        self.collision_info(other).is_some()
75    }
76
77    /// Returns collision info if colliders intersect, otherwise `None`.
78    fn collision_info(&self, other: &OtherCollider) -> Option<CollisionInfo<Self::Vector>>;
79}
80
81/// Maps a collider to spatial cells for broad-phase acceleration.
82///
83/// Collision managers can use this to build a spatial index and only check
84/// pairs that share at least one cell, reducing O(n²) to O(n×k) where k
85/// is the average number of colliders per cell.
86pub trait SpatialPartition {
87    /// The cell type used for spatial indexing.
88    type Cell: Hash + Eq;
89
90    /// Returns the cells this collider occupies.
91    fn cells(&self) -> impl Iterator<Item = Self::Cell>;
92}