collision_detection/
lib.rs1#![deny(missing_docs)]
2
3use array_linked_list::ArrayLinkedList;
18use collide::{Collider, CollisionInfo};
19use vector_space::VectorSpace;
20
21pub struct IndexedCollisionInfo<V: VectorSpace, I> {
23 pub index: I,
25 pub info: CollisionInfo<V>,
27}
28
29struct Indexed<C: Collider, I> {
30 index: I,
31 collider: C,
32}
33
34pub struct CollisionManager<C: Collider, I> {
37 colliders: ArrayLinkedList<Indexed<C, I>>,
38}
39
40impl<C: Collider, I: Copy> Default for CollisionManager<C, I> {
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46impl<C: Collider, I: Copy> CollisionManager<C, I> {
47 pub fn new() -> Self {
49 Self {
50 colliders: ArrayLinkedList::new(),
51 }
52 }
53
54 pub fn with_capacity(capacity: usize) -> Self {
56 Self {
57 colliders: ArrayLinkedList::with_capacity(capacity),
58 }
59 }
60
61 pub fn insert_collider(&mut self, collider: C, index: I) -> usize {
64 self.colliders.push_back(Indexed { index, collider })
65 }
66
67 pub fn replace_collider(&mut self, index: usize, collider: C) {
69 self.colliders[index].as_mut().unwrap().collider = collider;
70 }
71
72 pub fn remove_collider(&mut self, index: usize) {
74 self.colliders.remove(index);
75 }
76
77 pub fn collider(&self, index: usize) -> &C {
79 &self.colliders[index].as_ref().unwrap().collider
80 }
81
82 pub fn collider_mut(&mut self, index: usize) -> &mut C {
84 &mut self.colliders[index].as_mut().unwrap().collider
85 }
86
87 pub fn check_collision(&self, check_collider: &C) -> bool {
89 for collider in &self.colliders {
90 if check_collider.check_collision(&collider.collider) {
91 return true;
92 }
93 }
94 false
95 }
96
97 pub fn find_collision(&self, check_collider: &C) -> Option<I> {
99 for collider in &self.colliders {
100 if check_collider.check_collision(&collider.collider) {
101 return Some(collider.index);
102 }
103 }
104 None
105 }
106
107 pub fn find_collisions(&self, check_collider: &C) -> Vec<I> {
109 let mut result = Vec::new();
110 for collider in &self.colliders {
111 if check_collider.check_collision(&collider.collider) {
112 result.push(collider.index);
113 }
114 }
115 result
116 }
117
118 pub fn compute_inner_collisions(
121 &self,
122 ) -> ArrayLinkedList<Vec<IndexedCollisionInfo<C::Vector, I>>> {
123 let mut result = ArrayLinkedList::with_capacity(self.colliders.capacity());
124 for collider_index in self.colliders.indices() {
125 result.replace_front(collider_index, Vec::new());
126 }
127 for (collider_index, indexed_collider) in self.colliders.indexed() {
128 let infos = result[collider_index].as_mut().unwrap() as *mut Vec<_>;
129 for (other_index, other_dynamic) in self.colliders.indexed_after(collider_index) {
131 let dynamic_collider = &other_dynamic.collider;
132 let other_infos = result[other_index].as_mut().unwrap();
133 let Some(info) = indexed_collider.collider.collision_info(dynamic_collider) else {
134 continue;
135 };
136
137 other_infos.push(IndexedCollisionInfo {
138 index: indexed_collider.index,
139 info: -info,
140 });
141 unsafe { &mut *infos }.push(IndexedCollisionInfo {
142 index: other_dynamic.index,
143 info,
144 });
145 }
146 }
147
148 result
149 }
150
151 pub fn compute_collisions_with(
154 &self,
155 other: &Self,
156 ) -> ArrayLinkedList<Vec<IndexedCollisionInfo<C::Vector, I>>> {
157 let mut result = ArrayLinkedList::with_capacity(self.colliders.capacity());
158 for collider_index in self.colliders.indices() {
159 result.replace_front(collider_index, Vec::new());
160 }
161 for (collider_index, indexed_collider) in self.colliders.indexed() {
162 let infos = result[collider_index].as_mut().unwrap();
163 for collider_static in &other.colliders {
165 let Some(info) = indexed_collider
166 .collider
167 .collision_info(&collider_static.collider)
168 else {
169 continue;
170 };
171
172 infos.push(IndexedCollisionInfo {
173 index: collider_static.index,
174 info,
175 });
176 }
177 }
178 result
179 }
180}