1use crate::bitset::BitSet;
15use crate::core::NULL_INDEX;
16use crate::dynamic_tree::{DynamicTree, DEFAULT_MASK_BITS};
17use crate::id::ShapeId;
18use crate::math_functions::Aabb;
19use crate::table::{shape_pair_key, HashSet};
20use crate::types::{BodyType, Capacity, BODY_TYPE_COUNT};
21use crate::world::World;
22
23pub fn proxy_type(key: i32) -> BodyType {
28 match key & 3 {
29 0 => BodyType::Static,
30 1 => BodyType::Kinematic,
31 _ => BodyType::Dynamic,
32 }
33}
34
35pub fn proxy_id(key: i32) -> i32 {
37 key >> 2
38}
39
40pub fn proxy_key(id: i32, type_: BodyType) -> i32 {
42 (id << 2) | (type_ as i32)
43}
44
45#[derive(Debug)]
50pub struct BroadPhase {
51 pub trees: [DynamicTree; BODY_TYPE_COUNT],
52
53 pub moved_proxies: [BitSet; BODY_TYPE_COUNT],
57 pub move_array: Vec<i32>,
58
59 pub pair_set: HashSet,
61}
62
63impl BroadPhase {
64 pub fn new(capacity: &Capacity) -> BroadPhase {
66 BroadPhase {
70 trees: [
71 DynamicTree::new(capacity.static_shape_count),
72 DynamicTree::new(capacity.dynamic_shape_count),
73 DynamicTree::new(capacity.dynamic_shape_count),
74 ],
75 moved_proxies: [BitSet::new(16), BitSet::new(16), BitSet::new(16)],
76 move_array: Vec::new(),
77 pair_set: HashSet::new(crate::math_functions::max_int(16, capacity.contact_count)),
78 }
79 }
80
81 pub fn destroy(&mut self) {
83 *self = BroadPhase {
84 trees: [
85 DynamicTree::new(0),
86 DynamicTree::new(0),
87 DynamicTree::new(0),
88 ],
89 moved_proxies: Default::default(),
90 move_array: Vec::new(),
91 pair_set: HashSet::new(16),
92 };
93 }
94
95 pub fn buffer_move(&mut self, query_proxy: i32) {
98 let proxy_type_ = proxy_type(query_proxy);
99 let proxy_id_ = proxy_id(query_proxy);
100 let set = &mut self.moved_proxies[proxy_type_ as usize];
101 if !set.get_bit(proxy_id_ as u32) {
102 set.set_bit_grow(proxy_id_ as u32);
103 self.move_array.push(query_proxy);
104 }
105 }
106
107 pub fn create_proxy(
109 &mut self,
110 proxy_type_: BodyType,
111 aabb: Aabb,
112 category_bits: u64,
113 shape_index: i32,
114 force_pair_creation: bool,
115 ) -> i32 {
116 let proxy_id_ =
117 self.trees[proxy_type_ as usize].create_proxy(aabb, category_bits, shape_index as u64);
118 let proxy_key_ = proxy_key(proxy_id_, proxy_type_);
119 if proxy_type_ != BodyType::Static || force_pair_creation {
120 self.buffer_move(proxy_key_);
121 }
122 proxy_key_
123 }
124
125 fn unbuffer_move(&mut self, proxy_key: i32) {
127 let proxy_type_ = proxy_type(proxy_key);
128 let proxy_id_ = proxy_id(proxy_key);
129 let set = &mut self.moved_proxies[proxy_type_ as usize];
130
131 if set.get_bit(proxy_id_ as u32) {
132 set.clear_bit(proxy_id_ as u32);
133
134 if let Some(index) = self.move_array.iter().position(|&k| k == proxy_key) {
136 self.move_array.swap_remove(index);
138 }
139 }
140 }
141
142 pub fn destroy_proxy(&mut self, proxy_key: i32) {
144 self.unbuffer_move(proxy_key);
145
146 let proxy_type_ = proxy_type(proxy_key);
147 let proxy_id_ = proxy_id(proxy_key);
148
149 self.trees[proxy_type_ as usize].destroy_proxy(proxy_id_);
150 }
151
152 pub fn move_proxy(&mut self, proxy_key: i32, aabb: Aabb) {
154 let proxy_type_ = proxy_type(proxy_key);
155 let proxy_id_ = proxy_id(proxy_key);
156
157 self.trees[proxy_type_ as usize].move_proxy(proxy_id_, aabb);
158 self.buffer_move(proxy_key);
159 }
160
161 pub fn enlarge_proxy(&mut self, proxy_key: i32, aabb: Aabb) {
163 debug_assert!(proxy_key != crate::core::NULL_INDEX);
164 let proxy_type_ = proxy_type(proxy_key);
165 let proxy_id_ = proxy_id(proxy_key);
166
167 debug_assert!(proxy_type_ != BodyType::Static);
169
170 self.trees[proxy_type_ as usize].enlarge_proxy(proxy_id_, aabb);
171 self.buffer_move(proxy_key);
172 }
173
174 pub fn shape_index(&self, proxy_key: i32) -> i32 {
176 let proxy_type_ = proxy_type(proxy_key);
177 let proxy_id_ = proxy_id(proxy_key);
178
179 self.trees[proxy_type_ as usize].user_data(proxy_id_) as i32
180 }
181
182 pub fn test_overlap(&self, proxy_key_a: i32, proxy_key_b: i32) -> bool {
184 let type_a = proxy_type(proxy_key_a);
185 let id_a = proxy_id(proxy_key_a);
186 let type_b = proxy_type(proxy_key_b);
187 let id_b = proxy_id(proxy_key_b);
188
189 let aabb_a = self.trees[type_a as usize].aabb(id_a);
190 let aabb_b = self.trees[type_b as usize].aabb(id_b);
191 crate::math_functions::aabb_overlaps(aabb_a, aabb_b)
192 }
193
194 pub fn validate(&self) {
196 self.trees[BodyType::Dynamic as usize].validate();
197 self.trees[BodyType::Kinematic as usize].validate();
198 }
199
200 pub fn validate_no_enlarged(&self) {
203 if cfg!(debug_assertions) {
204 for tree in &self.trees {
205 tree.validate_no_enlarged();
206 }
207 }
208 }
209
210 pub fn validate_moved_proxies(&self) {
213 if cfg!(debug_assertions) {
214 for &proxy_key_ in &self.move_array {
217 let proxy_type_ = proxy_type(proxy_key_);
218 let proxy_id_ = proxy_id(proxy_key_);
219 debug_assert!(self.moved_proxies[proxy_type_ as usize].get_bit(proxy_id_ as u32));
220 }
221
222 let mut total_set_bits = 0;
223 for i in 0..BODY_TYPE_COUNT {
224 total_set_bits += self.moved_proxies[i].count_set_bits();
225 }
226 debug_assert!(total_set_bits == self.move_array.len() as i32);
227 }
228 }
229}
230
231fn query_tree_for_pairs(
235 world: &World,
236 tree_type: BodyType,
237 query_proxy_key: i32,
238 query_shape_index: i32,
239 fat_aabb: Aabb,
240 pair_list: &mut Vec<(i32, i32)>,
241) {
242 let bp = &world.broad_phase;
243 let query_proxy_type = proxy_type(query_proxy_key);
244
245 bp.trees[tree_type as usize].query(fat_aabb, DEFAULT_MASK_BITS, |tree_proxy_id, user_data| {
246 let shape_id = user_data as i32;
247 let proxy_key_ = proxy_key(tree_proxy_id, tree_type);
248
249 if proxy_key_ == query_proxy_key {
251 return true;
252 }
253
254 if query_proxy_type == BodyType::Dynamic {
264 if tree_type == BodyType::Dynamic && proxy_key_ < query_proxy_key {
265 let moved = bp.moved_proxies[tree_type as usize].get_bit(tree_proxy_id as u32);
266 if moved {
267 return true;
269 }
270 }
271 } else {
272 debug_assert!(tree_type == BodyType::Dynamic);
273 let moved = bp.moved_proxies[tree_type as usize].get_bit(tree_proxy_id as u32);
274 if moved {
275 return true;
277 }
278 }
279
280 let pair_key = shape_pair_key(shape_id, query_shape_index);
281 if bp.pair_set.contains_key(pair_key) {
282 return true;
284 }
285
286 let (shape_id_a, shape_id_b) = if proxy_key_ < query_proxy_key {
287 (shape_id, query_shape_index)
288 } else {
289 (query_shape_index, shape_id)
290 };
291
292 let shape_a = &world.shapes[shape_id_a as usize];
293 let shape_b = &world.shapes[shape_id_b as usize];
294
295 let body_id_a = shape_a.body_id;
296 let body_id_b = shape_b.body_id;
297
298 if body_id_a == body_id_b {
300 return true;
301 }
302
303 if shape_a.sensor_index != NULL_INDEX || shape_b.sensor_index != NULL_INDEX {
305 return true;
306 }
307
308 if !crate::shape::should_shapes_collide(shape_a.filter, shape_b.filter) {
309 return true;
310 }
311
312 if !crate::contact::can_collide(shape_a.shape_type(), shape_b.shape_type()) {
313 return true;
315 }
316
317 if !crate::body::should_bodies_collide(world, body_id_a, body_id_b) {
319 return true;
320 }
321
322 if shape_a.enable_custom_filtering || shape_b.enable_custom_filtering {
324 if let Some(custom_filter_fcn) = world.custom_filter_fcn {
325 let id_a = ShapeId {
326 index1: shape_id_a + 1,
327 world0: world.world_id,
328 generation: shape_a.generation,
329 };
330 let id_b = ShapeId {
331 index1: shape_id_b + 1,
332 world0: world.world_id,
333 generation: shape_b.generation,
334 };
335 let should_collide = custom_filter_fcn(id_a, id_b, world.custom_filter_context);
336 if !should_collide {
337 return true;
338 }
339 }
340 }
341
342 pair_list.push((shape_id_a, shape_id_b));
343
344 true
346 });
347}
348
349pub fn update_broad_phase_pairs(world: &mut World) {
354 world.broad_phase.validate_moved_proxies();
355
356 let move_count = world.broad_phase.move_array.len();
357
358 if move_count == 0 {
359 return;
360 }
361
362 let mut move_results: Vec<Vec<(i32, i32)>> = Vec::with_capacity(move_count);
364 for i in 0..move_count {
365 let mut pair_list: Vec<(i32, i32)> = Vec::new();
366
367 let proxy_key_ = world.broad_phase.move_array[i];
368 if proxy_key_ == NULL_INDEX {
369 move_results.push(pair_list);
371 continue;
372 }
373
374 let proxy_type_ = proxy_type(proxy_key_);
375 let proxy_id_ = proxy_id(proxy_key_);
376
377 let base_tree = &world.broad_phase.trees[proxy_type_ as usize];
380 let fat_aabb = base_tree.aabb(proxy_id_);
381 let query_shape_index = base_tree.user_data(proxy_id_) as i32;
382
383 if proxy_type_ == BodyType::Dynamic {
387 query_tree_for_pairs(
388 world,
389 BodyType::Kinematic,
390 proxy_key_,
391 query_shape_index,
392 fat_aabb,
393 &mut pair_list,
394 );
395 query_tree_for_pairs(
396 world,
397 BodyType::Static,
398 proxy_key_,
399 query_shape_index,
400 fat_aabb,
401 &mut pair_list,
402 );
403 }
404
405 query_tree_for_pairs(
407 world,
408 BodyType::Dynamic,
409 proxy_key_,
410 query_shape_index,
411 fat_aabb,
412 &mut pair_list,
413 );
414
415 move_results.push(pair_list);
416 }
417
418 world.broad_phase.trees[BodyType::Dynamic as usize].rebuild(false);
422 world.broad_phase.trees[BodyType::Kinematic as usize].rebuild(false);
423
424 for pair_list in &move_results {
430 for &(shape_id_a, shape_id_b) in pair_list.iter().rev() {
431 crate::contact::create_contact(world, shape_id_a, shape_id_b);
432 }
433 }
434
435 for i in 0..world.broad_phase.move_array.len() {
439 let proxy_key_ = world.broad_phase.move_array[i];
440 let proxy_type_ = proxy_type(proxy_key_);
441 let proxy_id_ = proxy_id(proxy_key_);
442 world.broad_phase.moved_proxies[proxy_type_ as usize].clear_bit(proxy_id_ as u32);
443 }
444 world.broad_phase.move_array.clear();
445
446 world.validate_solver_sets();
447}
448
449#[cfg(test)]
450mod tests {
451 use super::*;
452 use crate::math_functions::Vec2;
453
454 fn aabb(lx: f32, ly: f32, ux: f32, uy: f32) -> Aabb {
455 Aabb {
456 lower_bound: Vec2 { x: lx, y: ly },
457 upper_bound: Vec2 { x: ux, y: uy },
458 }
459 }
460
461 #[test]
462 fn proxy_key_round_trip() {
463 for (id, t) in [
464 (0, BodyType::Static),
465 (7, BodyType::Kinematic),
466 (123456, BodyType::Dynamic),
467 ] {
468 let key = proxy_key(id, t);
469 assert_eq!(proxy_id(key), id);
470 assert_eq!(proxy_type(key), t);
471 }
472 }
473
474 #[test]
475 fn create_move_destroy_and_overlap() {
476 let mut bp = BroadPhase::new(&Capacity::default());
477
478 let k_static = bp.create_proxy(BodyType::Static, aabb(0.0, 0.0, 1.0, 1.0), 1, 10, false);
480 assert!(bp.move_array.is_empty());
481
482 let k_dyn = bp.create_proxy(BodyType::Dynamic, aabb(0.5, 0.5, 1.5, 1.5), 1, 11, false);
483 assert_eq!(bp.move_array.len(), 1);
484
485 bp.buffer_move(k_dyn);
487 assert_eq!(bp.move_array.len(), 1);
488
489 assert!(bp.test_overlap(k_static, k_dyn));
490 assert_eq!(bp.shape_index(k_static), 10);
491 assert_eq!(bp.shape_index(k_dyn), 11);
492
493 bp.move_proxy(k_dyn, aabb(10.0, 10.0, 11.0, 11.0));
495 assert!(!bp.test_overlap(k_static, k_dyn));
496
497 bp.destroy_proxy(k_dyn);
499 assert!(bp.move_array.is_empty());
500 assert_eq!(bp.trees[BodyType::Dynamic as usize].proxy_count(), 0);
501 }
502}