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}