1use crate::cell::AABBGridCell;
2use crate::storage::{cell_range, SparseStorage};
3use crate::AABB;
4use slotmapd::{new_key_type, SlotMap};
5
6pub type AABBGridObjects<O, AB> = SlotMap<AABBGridHandle, StoreObject<O, AB>>;
7
8new_key_type! {
9 pub struct AABBGridHandle;
12}
13
14#[derive(Clone, Copy)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct StoreObject<O: Copy, AB: AABB> {
18 pub obj: O,
20 pub aabb: AB,
21}
22
23#[derive(Clone)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60pub struct AABBGrid<O: Copy, AB: AABB> {
61 storage: SparseStorage<AABBGridCell>,
62 objects: AABBGridObjects<O, AB>,
63}
64
65impl<O: Copy, AB: AABB> AABBGrid<O, AB> {
66 pub fn new(cell_size: i32) -> Self {
69 Self {
70 storage: SparseStorage::new(cell_size),
71 objects: AABBGridObjects::default(),
72 }
73 }
74
75 pub fn clear(&mut self) -> impl Iterator<Item = (AB, O)> {
77 self.storage = SparseStorage::new(self.storage.cell_size());
78 let objs = std::mem::take(&mut self.objects);
79 objs.into_iter().map(|(_, o)| (o.aabb, o.obj))
80 }
81
82 pub fn insert(&mut self, aabb: AB, obj: O) -> AABBGridHandle {
85 let Self {
86 storage, objects, ..
87 } = self;
88
89 let h = objects.insert(StoreObject { obj, aabb });
90 cells_apply(storage, &aabb, |cell, sing_cell| {
91 cell.objs.push((h, sing_cell));
92 });
93 h
94 }
95
96 pub fn set_aabb(&mut self, handle: AABBGridHandle, aabb: AB) {
98 let obj = self
99 .objects
100 .get_mut(handle)
101 .expect("Object not in grid anymore");
102
103 let storage = &mut self.storage;
104
105 let old_ll = storage.cell_mut(obj.aabb.ll()).0;
106 let old_ur = storage.cell_mut(obj.aabb.ur()).0;
107
108 let ll = storage.cell_mut(aabb.ll()).0;
109 let ur = storage.cell_mut(aabb.ur()).0;
110
111 obj.aabb = aabb;
112
113 if old_ll == ll && old_ur == ur {
114 return;
115 }
116
117 for id in cell_range(old_ll, old_ur) {
118 let cell = storage.cell_mut_unchecked(id);
119 let p = match cell.objs.iter().position(|(x, _)| *x == handle) {
120 Some(x) => x,
121 None => return,
122 };
123 cell.objs.swap_remove(p);
124 }
125
126 let sing_cell = ll == ur;
127 for id in cell_range(ll, ur) {
128 let cell = storage.cell_mut_unchecked(id);
129 cell.objs.push((handle, sing_cell))
130 }
131 }
132
133 pub fn remove(&mut self, handle: AABBGridHandle) -> Option<O> {
135 let st = self.objects.remove(handle)?;
136
137 let storage = &mut self.storage;
138 cells_apply(storage, &st.aabb, |cell, _| {
139 for i in 0..cell.objs.len() {
140 if cell.objs[i].0 == handle {
141 cell.objs.swap_remove(i);
142 return;
143 }
144 }
145 });
146
147 Some(st.obj)
148 }
149
150 pub fn handles(&self) -> impl Iterator<Item = AABBGridHandle> + '_ {
152 self.objects.keys()
153 }
154
155 pub fn objects(&self) -> impl Iterator<Item = &O> + '_ {
157 self.objects.values().map(|x| &x.obj)
158 }
159
160 pub fn get(&self, id: AABBGridHandle) -> Option<&StoreObject<O, AB>> {
162 self.objects.get(id)
163 }
164
165 pub fn get_mut(&mut self, id: AABBGridHandle) -> Option<&mut StoreObject<O, AB>> {
167 self.objects.get_mut(id)
168 }
169
170 pub fn storage(&self) -> &SparseStorage<AABBGridCell> {
172 &self.storage
173 }
174
175 pub fn query(&self, aabb: AB) -> impl Iterator<Item = (AABBGridHandle, &AB, &O)> + '_ {
177 self.query_broad(aabb).filter_map(move |h| {
178 let obj = unsafe { self.objects.get_unchecked(h) };
180 if aabb.intersects(&obj.aabb) {
181 Some((h, &obj.aabb, &obj.obj))
182 } else {
183 None
184 }
185 })
186 }
187
188 pub fn query_broad(&self, bbox: AB) -> impl Iterator<Item = AABBGridHandle> + '_ {
190 let storage = &self.storage;
191
192 let ll_id = storage.cell_id(bbox.ll());
193 let ur_id = storage.cell_id(bbox.ur());
194
195 let iter = cell_range(ll_id, ur_id)
196 .flat_map(move |id| storage.cell(id))
197 .flat_map(|x| x.objs.iter().copied());
198
199 if ll_id == ur_id {
200 QueryIter::Simple(iter)
201 } else {
202 QueryIter::Dedup(
203 fnv::FnvHashSet::with_hasher(fnv::FnvBuildHasher::default()),
204 iter,
205 )
206 }
207 }
208
209 pub fn query_visitor(&self, aabb: AB, mut visitor: impl FnMut(AABBGridHandle, &AB, &O)) {
212 self.query_broad_visitor(aabb, move |h| {
213 let obj = unsafe { self.objects.get_unchecked(h) };
215 if aabb.intersects(&obj.aabb) {
216 visitor(h, &obj.aabb, &obj.obj)
217 }
218 })
219 }
220
221 pub fn query_broad_visitor(&self, bbox: AB, mut visitor: impl FnMut(AABBGridHandle)) {
224 let storage = &self.storage;
225
226 let ll_id = storage.cell_id(bbox.ll());
227 let ur_id = storage.cell_id(bbox.ur());
228
229 if ll_id == ur_id {
230 let cell = storage.cell(ll_id).unwrap();
231 for (h, _) in cell.objs.iter() {
232 visitor(*h);
233 }
234 return;
235 }
236
237 let mut dedup = fnv::FnvHashSet::with_hasher(fnv::FnvBuildHasher::default());
238
239 for celly in ll_id.1..=ur_id.1 {
240 for cellx in ll_id.0..=ur_id.0 {
241 let cell = match storage.cell((cellx, celly)) {
242 Some(x) => x,
243 None => continue,
244 };
245
246 for (h, sing_cell) in cell.objs.iter() {
247 if *sing_cell {
248 visitor(*h);
249 continue;
250 }
251 if dedup.insert(*h) {
252 visitor(*h);
253 }
254 }
255 }
256 }
257 }
258
259 pub fn len(&self) -> usize {
261 self.objects.len()
262 }
263
264 pub fn is_empty(&self) -> bool {
266 self.objects.is_empty()
267 }
268}
269
270fn cells_apply<AB: AABB>(
271 storage: &mut SparseStorage<AABBGridCell>,
272 bbox: &AB,
273 f: impl Fn(&mut AABBGridCell, bool),
274) {
275 let ll = storage.cell_mut(bbox.ll()).0;
276 let ur = storage.cell_mut(bbox.ur()).0;
277 for id in cell_range(ll, ur) {
278 f(storage.cell_mut_unchecked(id), ll == ur)
279 }
280}
281
282enum QueryIter<T: Iterator<Item = (AABBGridHandle, bool)>> {
283 Simple(T),
284 Dedup(fnv::FnvHashSet<AABBGridHandle>, T),
285}
286
287impl<T: Iterator<Item = (AABBGridHandle, bool)>> Iterator for QueryIter<T> {
288 type Item = AABBGridHandle;
289
290 fn next(&mut self) -> Option<Self::Item> {
291 match self {
292 QueryIter::Simple(x) => x.next().map(|(x, _)| x),
293 QueryIter::Dedup(seen, x) => {
294 for (v, sing_cell) in x {
295 if sing_cell {
296 return Some(v);
297 }
298 if seen.insert(v) {
299 return Some(v);
300 }
301 }
302 None
303 }
304 }
305 }
306}