1use crate::bitset::BitSet;
9use crate::body::get_body_transform;
10use crate::core::NULL_INDEX;
11use crate::dynamic_tree::{DynamicTree, DEFAULT_MASK_BITS};
12use crate::geometry::ShapeType;
13use crate::id::ShapeId;
14use crate::math_functions::{
15 aabb_overlaps, aabb_transform, invert_transform, max_int, to_relative_transform, Aabb, POS_ZERO,
16};
17use crate::shape::{shape_flags, ShapeGeometry};
18use crate::table::{shape_pair_key, HashSet};
19use crate::types::{BodyType, Capacity, BODY_TYPE_COUNT};
20use crate::world::World;
21
22pub fn proxy_type(key: i32) -> BodyType {
24 match key & 3 {
25 0 => BodyType::Static,
26 1 => BodyType::Kinematic,
27 _ => BodyType::Dynamic,
28 }
29}
30
31pub fn proxy_id(key: i32) -> i32 {
33 key >> 2
34}
35
36pub fn proxy_key(id: i32, type_: BodyType) -> i32 {
38 (id << 2) | (type_ as i32)
39}
40
41#[derive(Debug)]
45pub struct BroadPhase {
46 pub trees: [DynamicTree; BODY_TYPE_COUNT],
47
48 pub moved_proxies: [BitSet; BODY_TYPE_COUNT],
52 pub move_array: Vec<i32>,
53
54 pub pair_set: HashSet,
56}
57
58impl BroadPhase {
59 pub fn new(capacity: &Capacity) -> BroadPhase {
61 debug_assert!(BODY_TYPE_COUNT == 3);
62
63 let static_capacity = max_int(16, capacity.static_shape_count);
64 let kinematic_capacity = 16;
65 let dynamic_capacity = max_int(16, capacity.dynamic_shape_count);
66
67 let mut move_array = Vec::new();
68 move_array.reserve(capacity.dynamic_shape_count.max(0) as usize);
69
70 BroadPhase {
71 trees: [
72 DynamicTree::new(static_capacity),
73 DynamicTree::new(kinematic_capacity),
74 DynamicTree::new(dynamic_capacity),
75 ],
76 moved_proxies: [
77 BitSet::new(max_int(16, capacity.static_shape_count) as u32),
78 BitSet::new(16),
79 BitSet::new(max_int(16, capacity.dynamic_shape_count) as u32),
80 ],
81 move_array,
82 pair_set: HashSet::new(2 * capacity.contact_count),
84 }
85 }
86
87 pub fn destroy(&mut self) {
89 *self = BroadPhase {
90 trees: [
91 DynamicTree::new(0),
92 DynamicTree::new(0),
93 DynamicTree::new(0),
94 ],
95 moved_proxies: [BitSet::new(0), BitSet::new(0), BitSet::new(0)],
96 move_array: Vec::new(),
97 pair_set: HashSet::new(16),
98 };
99 }
100
101 pub fn buffer_move(&mut self, query_proxy: i32) {
104 let proxy_type_ = proxy_type(query_proxy);
105 let proxy_id_ = proxy_id(query_proxy);
106 let set = &mut self.moved_proxies[proxy_type_ as usize];
107 if !set.get_bit(proxy_id_ as u32) {
108 set.set_bit_grow(proxy_id_ as u32);
109 self.move_array.push(query_proxy);
110 }
111 }
112
113 pub fn create_proxy(
115 &mut self,
116 proxy_type_: BodyType,
117 aabb: Aabb,
118 category_bits: u64,
119 shape_index: i32,
120 force_pair_creation: bool,
121 ) -> i32 {
122 debug_assert!((proxy_type_ as usize) < BODY_TYPE_COUNT);
123 let proxy_id_ =
124 self.trees[proxy_type_ as usize].create_proxy(aabb, category_bits, shape_index as u64);
125 let proxy_key_ = proxy_key(proxy_id_, proxy_type_);
126 if proxy_type_ != BodyType::Static || force_pair_creation {
127 self.buffer_move(proxy_key_);
128 }
129 proxy_key_
130 }
131
132 fn unbuffer_move(&mut self, proxy_key_: i32) {
134 let proxy_type_ = proxy_type(proxy_key_);
135 let proxy_id_ = proxy_id(proxy_key_);
136 let set = &mut self.moved_proxies[proxy_type_ as usize];
137
138 if set.get_bit(proxy_id_ as u32) {
139 set.clear_bit(proxy_id_ as u32);
140
141 if let Some(index) = self.move_array.iter().position(|&k| k == proxy_key_) {
143 self.move_array.swap_remove(index);
144 }
145 }
146 }
147
148 pub fn destroy_proxy(&mut self, proxy_key_: i32) {
150 self.unbuffer_move(proxy_key_);
151
152 let proxy_type_ = proxy_type(proxy_key_);
153 let proxy_id_ = proxy_id(proxy_key_);
154
155 debug_assert!((proxy_type_ as usize) <= BODY_TYPE_COUNT);
156 self.trees[proxy_type_ as usize].destroy_proxy(proxy_id_);
157 }
158
159 pub fn move_proxy(&mut self, proxy_key_: i32, aabb: Aabb) {
161 let proxy_type_ = proxy_type(proxy_key_);
162 let proxy_id_ = proxy_id(proxy_key_);
163
164 self.trees[proxy_type_ as usize].move_proxy(proxy_id_, aabb);
165 self.buffer_move(proxy_key_);
166 }
167
168 pub fn enlarge_proxy(&mut self, proxy_key_: i32, aabb: Aabb) {
170 debug_assert!(proxy_key_ != crate::core::NULL_INDEX);
171 let proxy_type_ = proxy_type(proxy_key_);
172 let proxy_id_ = proxy_id(proxy_key_);
173
174 debug_assert!(proxy_type_ != BodyType::Static);
175
176 self.trees[proxy_type_ as usize].enlarge_proxy(proxy_id_, aabb);
177 self.buffer_move(proxy_key_);
178 }
179
180 pub fn shape_index(&self, proxy_key_: i32) -> i32 {
182 let proxy_type_ = proxy_type(proxy_key_);
183 let proxy_id_ = proxy_id(proxy_key_);
184
185 self.trees[proxy_type_ as usize].user_data(proxy_id_) as i32
186 }
187
188 pub fn test_overlap(&self, proxy_key_a: i32, proxy_key_b: i32) -> bool {
190 let type_a = proxy_type(proxy_key_a);
191 let id_a = proxy_id(proxy_key_a);
192 let type_b = proxy_type(proxy_key_b);
193 let id_b = proxy_id(proxy_key_b);
194
195 let aabb_a = self.trees[type_a as usize].aabb(id_a);
196 let aabb_b = self.trees[type_b as usize].aabb(id_b);
197 aabb_overlaps(aabb_a, aabb_b)
198 }
199
200 pub fn validate(&self) {
202 self.trees[BodyType::Dynamic as usize].validate();
203 self.trees[BodyType::Kinematic as usize].validate();
204 }
205
206 pub fn validate_no_enlarged(&self) {
209 if cfg!(debug_assertions) {
210 for tree in &self.trees {
211 tree.validate_no_enlarged();
212 }
213 }
214 }
215
216 pub fn validate_moved_proxies(&self) {
218 if cfg!(debug_assertions) {
219 for &proxy_key_ in &self.move_array {
220 let proxy_type_ = proxy_type(proxy_key_);
221 let proxy_id_ = proxy_id(proxy_key_);
222 debug_assert!(self.moved_proxies[proxy_type_ as usize].get_bit(proxy_id_ as u32));
223 }
224
225 let mut total_set_bits = 0;
226 for i in 0..BODY_TYPE_COUNT {
227 total_set_bits += self.moved_proxies[i].count_set_bits();
228 }
229 debug_assert!(total_set_bits == self.move_array.len() as i32);
230 }
231 }
232}
233
234fn consider_move_pair(
237 world: &World,
238 tree_type: BodyType,
239 query_proxy_key: i32,
240 query_shape_index: i32,
241 shape_index: i32,
242 proxy_id_: i32,
243 child_index: i32,
244 pair_list: &mut Vec<(i32, i32, i32)>,
245) {
246 let proxy_key_ = proxy_key(proxy_id_, tree_type);
247 debug_assert!(proxy_key_ != query_proxy_key);
248
249 let query_proxy_type = proxy_type(query_proxy_key);
250 let bp = &world.broad_phase;
251
252 if query_proxy_type == BodyType::Dynamic {
254 if tree_type == BodyType::Dynamic && proxy_key_ < query_proxy_key {
255 if bp.moved_proxies[tree_type as usize].get_bit(proxy_id_ as u32) {
256 return;
257 }
258 }
259 } else {
260 debug_assert!(tree_type == BodyType::Dynamic);
261 if bp.moved_proxies[tree_type as usize].get_bit(proxy_id_ as u32) {
262 return;
263 }
264 }
265
266 let pair_key = shape_pair_key(shape_index, query_shape_index, child_index);
267 if bp.pair_set.contains_key(pair_key) {
268 return;
269 }
270
271 let shape_id_a = shape_index;
272 let shape_id_b = query_shape_index;
273 let shape_a = &world.shapes[shape_id_a as usize];
274 let shape_b = &world.shapes[shape_id_b as usize];
275 let body_id_a = shape_a.body_id;
276 let body_id_b = shape_b.body_id;
277
278 if body_id_a == body_id_b {
279 return;
280 }
281
282 if shape_a.sensor_index != NULL_INDEX || shape_b.sensor_index != NULL_INDEX {
283 return;
284 }
285
286 if !crate::shape::should_shapes_collide(shape_a.filter, shape_b.filter) {
287 return;
288 }
289
290 if !crate::body::should_bodies_collide(world, body_id_a, body_id_b) {
291 return;
292 }
293
294 if (shape_a.flags & shape_flags::ENABLE_CUSTOM_FILTERING) != 0
295 || (shape_b.flags & shape_flags::ENABLE_CUSTOM_FILTERING) != 0
296 {
297 if let Some(custom_filter_fcn) = world.custom_filter_fcn {
298 let id_a = ShapeId {
299 index1: shape_id_a + 1,
300 world0: world.world_id,
301 generation: shape_a.generation,
302 };
303 let id_b = ShapeId {
304 index1: shape_id_b + 1,
305 world0: world.world_id,
306 generation: shape_b.generation,
307 };
308 if !custom_filter_fcn(world, id_a, id_b, world.custom_filter_context) {
309 return;
310 }
311 }
312 }
313
314 if !crate::contact::can_collide(shape_a.shape_type(), shape_b.shape_type()) {
315 return;
316 }
317
318 pair_list.push((shape_id_a, shape_id_b, child_index));
319}
320
321fn query_tree_for_pairs(
324 world: &World,
325 tree_type: BodyType,
326 query_proxy_key: i32,
327 query_shape_index: i32,
328 fat_aabb: Aabb,
329 pair_list: &mut Vec<(i32, i32, i32)>,
330) {
331 world.broad_phase.trees[tree_type as usize].query(
332 fat_aabb,
333 DEFAULT_MASK_BITS,
334 false,
335 |proxy_id_, user_data| {
336 let shape_index = user_data as i32;
337 if shape_index == query_shape_index {
338 return true;
339 }
340
341 if world.shapes[shape_index as usize].shape_type() == ShapeType::Compound {
342 let body_id = world.shapes[shape_index as usize].body_id;
345 let compound_transform =
346 to_relative_transform(get_body_transform(world, body_id), POS_ZERO);
347 let local_aabb = aabb_transform(invert_transform(compound_transform), fat_aabb);
348
349 let mut child_indices = Vec::new();
350 if let ShapeGeometry::Compound(compound) =
351 &world.shapes[shape_index as usize].geometry
352 {
353 compound.tree.query(
354 local_aabb,
355 DEFAULT_MASK_BITS,
356 false,
357 |_child_proxy, child_user_data| {
358 child_indices.push(child_user_data as i32);
359 true
360 },
361 );
362 }
363
364 for child_index in child_indices {
365 consider_move_pair(
366 world,
367 tree_type,
368 query_proxy_key,
369 query_shape_index,
370 shape_index,
371 proxy_id_,
372 child_index,
373 pair_list,
374 );
375 }
376 return true;
377 }
378
379 consider_move_pair(
380 world,
381 tree_type,
382 query_proxy_key,
383 query_shape_index,
384 shape_index,
385 proxy_id_,
386 0,
387 pair_list,
388 );
389 true
390 },
391 );
392}
393
394pub fn update_broad_phase_pairs(world: &mut World) {
397 world.broad_phase.validate_moved_proxies();
398
399 let move_count = world.broad_phase.move_array.len();
400 if move_count == 0 {
401 return;
402 }
403
404 let mut move_results: Vec<Vec<(i32, i32, i32)>> = Vec::with_capacity(move_count);
405 for i in 0..move_count {
406 let mut pair_list: Vec<(i32, i32, i32)> = Vec::new();
407 let proxy_key_ = world.broad_phase.move_array[i];
408 if proxy_key_ == NULL_INDEX {
409 move_results.push(pair_list);
410 continue;
411 }
412
413 let proxy_type_ = proxy_type(proxy_key_);
414 let proxy_id_ = proxy_id(proxy_key_);
415 let base_tree = &world.broad_phase.trees[proxy_type_ as usize];
416 let fat_aabb = base_tree.aabb(proxy_id_);
417 let query_shape_index = base_tree.user_data(proxy_id_) as i32;
418
419 debug_assert!(world.shapes[query_shape_index as usize].shape_type() != ShapeType::Compound);
420
421 if proxy_type_ == BodyType::Dynamic {
422 query_tree_for_pairs(
423 world,
424 BodyType::Kinematic,
425 proxy_key_,
426 query_shape_index,
427 fat_aabb,
428 &mut pair_list,
429 );
430 query_tree_for_pairs(
431 world,
432 BodyType::Static,
433 proxy_key_,
434 query_shape_index,
435 fat_aabb,
436 &mut pair_list,
437 );
438 }
439
440 query_tree_for_pairs(
441 world,
442 BodyType::Dynamic,
443 proxy_key_,
444 query_shape_index,
445 fat_aabb,
446 &mut pair_list,
447 );
448
449 move_results.push(pair_list);
450 }
451
452 world.broad_phase.trees[BodyType::Dynamic as usize].rebuild(false);
453 world.broad_phase.trees[BodyType::Kinematic as usize].rebuild(false);
454
455 for pair_list in &move_results {
457 for &(shape_id_a, shape_id_b, child_index) in pair_list.iter().rev() {
458 crate::contact::create_contact(world, shape_id_a, shape_id_b, child_index);
459 }
460 }
461
462 for i in 0..world.broad_phase.move_array.len() {
463 let proxy_key_ = world.broad_phase.move_array[i];
464 let proxy_type_ = proxy_type(proxy_key_);
465 let proxy_id_ = proxy_id(proxy_key_);
466 world.broad_phase.moved_proxies[proxy_type_ as usize].clear_bit(proxy_id_ as u32);
467 }
468 world.broad_phase.move_array.clear();
469
470 world.validate_solver_sets();
471}