1use std::collections::{hash_map, HashMap};
2use std::marker::PhantomData;
3
4use na::RealField;
5
6use ncollide::bounding_volume::AABB;
7use ncollide::pipeline::{
8 self, BroadPhase, BroadPhasePairFilter, CollisionGroups, CollisionObjectSet, ContactAlgorithm,
9 ContactEvents, DBVTBroadPhase, DefaultContactDispatcher, DefaultProximityDispatcher,
10 Interaction, InteractionGraph, NarrowPhase, ProximityDetector, ProximityEvents,
11};
12use ncollide::query::{ContactManifold, Proximity, Ray};
13
14use crate::object::{
15 BodyHandle, BodySet, Collider, ColliderAnchor, ColliderHandle, ColliderSet, DefaultBodyHandle,
16 DefaultBodySet, DefaultColliderHandle, DefaultColliderSet,
17};
18use crate::volumetric::Volumetric;
19
20use crate::math::Point;
21
22pub type DefaultGeometricalWorld<N> = GeometricalWorld<N, DefaultBodyHandle, DefaultColliderHandle>;
24
25pub struct GeometricalWorld<N: RealField + Copy, Handle: BodyHandle, CollHandle: ColliderHandle> {
30 pub(crate) broad_phase: Box<dyn BroadPhase<N, AABB<N>, CollHandle>>,
32 pub(crate) narrow_phase: NarrowPhase<N, CollHandle>,
34 pub(crate) interactions: InteractionGraph<N, CollHandle>,
36 pub(crate) body_colliders: HashMap<Handle, Vec<CollHandle>>,
37}
38
39impl<N: RealField + Copy, Handle: BodyHandle, CollHandle: ColliderHandle>
40 GeometricalWorld<N, Handle, CollHandle>
41{
42 pub fn from_parts<BF>(broad_phase: BF, narrow_phase: NarrowPhase<N, CollHandle>) -> Self
44 where
45 BF: BroadPhase<N, AABB<N>, CollHandle>,
46 {
47 GeometricalWorld {
48 broad_phase: Box::new(broad_phase),
49 narrow_phase,
50 interactions: InteractionGraph::new(),
51 body_colliders: HashMap::new(),
52 }
53 }
54
55 pub fn new() -> Self {
58 let coll_dispatcher = Box::new(DefaultContactDispatcher::new());
59 let prox_dispatcher = Box::new(DefaultProximityDispatcher::new());
60 let broad_phase = DBVTBroadPhase::new(na::convert(0.01));
61 let narrow_phase = NarrowPhase::new(coll_dispatcher, prox_dispatcher);
62 Self::from_parts(broad_phase, narrow_phase)
63 }
64
65 fn register_collider(&mut self, handle: CollHandle, collider: &mut Collider<N, Handle>) {
66 assert!(
67 collider.proxy_handle().is_none(),
68 "Cannot register a collider that is already registered."
69 );
70 assert!(
71 collider.graph_index().is_none(),
72 "Cannot register a collider that is already registered."
73 );
74
75 let proxies = pipeline::create_proxies(
76 handle,
77 &mut *self.broad_phase,
78 &mut self.interactions,
79 collider.position(),
80 collider.shape(),
81 collider.query_type(),
82 );
83
84 self.body_colliders
85 .entry(collider.body())
86 .or_insert_with(Vec::new)
87 .push(handle);
88 collider.set_proxy_handle(Some(proxies.0));
89 collider.set_graph_index(Some(proxies.1));
90 }
91
92 pub fn maintain<Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
94 &mut self,
95 bodies: &mut dyn BodySet<N, Handle = Handle>,
96 colliders: &mut Colliders,
97 ) {
98 self.handle_removals(bodies, colliders);
99 self.handle_insertions(bodies, colliders);
100 }
101
102 fn handle_insertions<Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
103 &mut self,
104 bodies: &mut dyn BodySet<N, Handle = Handle>,
105 colliders: &mut Colliders,
106 ) {
107 while let Some(handle) = colliders.pop_insertion_event() {
108 if let Some(collider) = colliders.get_mut(handle) {
109 self.register_collider(handle, collider);
110
111 match collider.anchor() {
112 ColliderAnchor::OnBodyPart {
113 body_part,
114 position_wrt_body_part,
115 } => {
116 let body = bodies
117 .get_mut(body_part.0)
118 .expect("Invalid parent body part handle.");
119
120 if !collider.density().is_zero() {
122 let (com, inertia) = collider.shape().transformed_mass_properties(
123 collider.density(),
124 position_wrt_body_part,
125 );
126 body.add_local_inertia_and_com(body_part.1, com, inertia);
127 }
128
129 let ndofs = body.status_dependent_ndofs();
131 let part = body
132 .part(body_part.1)
133 .expect("Invalid parent body part handle.");
134 let pos = part.position() * position_wrt_body_part;
135
136 collider.set_body_status_dependent_ndofs(ndofs);
137 collider.set_position(pos);
138 }
139 _ => {}
140 }
141 }
142 }
143 }
144
145 fn handle_removals<Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
146 &mut self,
147 bodies: &mut dyn BodySet<N, Handle = Handle>,
148 colliders: &mut Colliders,
149 ) {
150 let mut graph_id_remapping = HashMap::new();
151
152 while let Some((removed_handle, mut removed)) = colliders.pop_removal_event() {
153 if let Some(new_id) = graph_id_remapping.get(&removed_handle) {
155 removed.graph_index = *new_id
156 }
157
158 for (coll1, coll2, _, _) in self.interactions.contacts_with(removed.graph_index, false)
160 {
161 if coll1 == removed_handle {
162 if let Some(coll) = colliders.get(coll2) {
163 if let Some(body) = bodies.get_mut(coll.body()) {
164 body.activate()
165 }
166 }
167 }
168
169 if coll2 == removed_handle {
170 if let Some(coll) = colliders.get(coll1) {
171 if let Some(body) = bodies.get_mut(coll.body()) {
172 body.activate()
173 }
174 }
175 }
176 }
177
178 if let Some(body) = bodies.get_mut(removed.anchor.body()) {
180 if !removed.density.is_zero() {
182 if let ColliderAnchor::OnBodyPart {
183 body_part,
184 position_wrt_body_part,
185 } = &removed.anchor
186 {
187 let (com, inertia) = removed
188 .shape
189 .transformed_mass_properties(removed.density, position_wrt_body_part);
190 body.add_local_inertia_and_com(body_part.1, -com, -inertia)
191 }
192 }
193
194 body.activate()
195 }
196
197 match self.body_colliders.entry(removed.anchor.body()) {
199 hash_map::Entry::Occupied(mut e) => {
200 if let Some(i) = e.get().iter().position(|h| *h == removed_handle) {
201 let _ = e.get_mut().swap_remove(i);
202 }
203
204 if e.get().is_empty() {
205 let _ = e.remove_entry();
206 }
207 }
208 hash_map::Entry::Vacant(_) => {}
209 }
210
211 if let Some(to_change) = pipeline::remove_proxies(
213 &mut *self.broad_phase,
214 &mut self.interactions,
215 removed.proxy_handle,
216 removed.graph_index,
217 ) {
218 if let Some(collider) = colliders.get_mut(to_change.0) {
219 collider.set_graph_index(Some(to_change.1))
221 } else {
222 let _ = graph_id_remapping.insert(to_change.0, to_change.1);
224 }
225 }
226 }
227 }
228
229 pub fn sync_colliders<Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
231 &mut self,
232 bodies: &dyn BodySet<N, Handle = Handle>,
233 colliders: &mut Colliders,
234 ) {
235 colliders.foreach_mut(|_collider_id, collider| {
236 let body = try_ret!(bodies.get(collider.body()));
237
238 collider.set_body_status_dependent_ndofs(body.status_dependent_ndofs());
239
240 if !body.update_status().colliders_need_update() {
241 return;
242 }
243
244 let new_pos = match collider.anchor() {
245 ColliderAnchor::OnBodyPart {
246 body_part,
247 position_wrt_body_part,
248 } => {
249 let part = try_ret!(body.part(body_part.1));
250 let part_pos1 = part.safe_position();
251 let part_pos2 = part.position();
252 Some((
253 part_pos1 * position_wrt_body_part,
254 part_pos2 * position_wrt_body_part,
255 ))
256 }
257 ColliderAnchor::OnDeformableBody { .. } => None,
258 };
259
260 match new_pos {
261 Some(pos) => collider.set_position_with_prediction(pos.0, pos.1),
262 None => collider.set_deformations(body.deformed_positions().unwrap().1),
263 }
264 });
265 }
266
267 pub fn body_colliders(&self, body: Handle) -> Option<&[CollHandle]> {
271 self.body_colliders.get(&body).map(|c| &c[..])
272 }
273
274 pub fn clear_events(&mut self) {
282 self.narrow_phase.clear_events()
283 }
284 pub fn perform_broad_phase<Bodies, Colliders, Filter>(
286 &mut self,
287 bodies: &Bodies,
288 colliders: &Colliders,
289 user_filter: &Filter,
290 ) where
291 Bodies: BodySet<N, Handle = Handle>,
292 Colliders: ColliderSet<N, Handle, Handle = CollHandle>,
293 Filter: for<'a> BroadPhasePairFilter<N, BroadPhasePairFilterSets<'a, N, Bodies, Colliders>>
294 + ?Sized,
295 {
296 let pair_filter = DefaultCollisionFilter {
297 user_filter,
298 _pd: PhantomData,
299 };
300
301 pipeline::perform_broad_phase(
302 &BroadPhasePairFilterSets {
303 bodies,
304 colliders,
305 _pd: PhantomData,
306 },
307 &mut *self.broad_phase,
308 &mut self.narrow_phase,
309 &mut self.interactions,
310 Some(&pair_filter),
311 )
312 }
313
314 pub fn perform_narrow_phase<Colliders>(&mut self, colliders: &Colliders)
316 where
317 Colliders: ColliderSet<N, Handle, Handle = CollHandle>,
318 {
319 pipeline::perform_narrow_phase(colliders, &mut self.narrow_phase, &mut self.interactions)
320 }
321
322 pub fn broad_phase(&self) -> &dyn BroadPhase<N, AABB<N>, CollHandle> {
324 &*self.broad_phase
325 }
326
327 #[inline]
329 pub fn interferences_with_ray<
330 'a,
331 'b,
332 Colliders: ColliderSet<N, Handle, Handle = CollHandle>,
333 >(
334 &'a self,
335 colliders: &'a Colliders,
336 ray: &'b Ray<N>,
337 max_toi: N,
338 groups: &'b CollisionGroups,
339 ) -> pipeline::InterferencesWithRay<'a, 'b, N, Colliders> {
340 pipeline::interferences_with_ray(&colliders, &*self.broad_phase, ray, max_toi, groups)
341 }
342
343 #[inline]
345 pub fn interferences_with_point<
346 'a,
347 'b,
348 Colliders: ColliderSet<N, Handle, Handle = CollHandle>,
349 >(
350 &'a self,
351 colliders: &'a Colliders,
352 point: &'b Point<N>,
353 groups: &'b CollisionGroups,
354 ) -> pipeline::InterferencesWithPoint<'a, 'b, N, Colliders> {
355 pipeline::interferences_with_point(&colliders, &*self.broad_phase, point, groups)
356 }
357
358 #[inline]
360 pub fn interferences_with_aabb<
361 'a,
362 'b,
363 Colliders: ColliderSet<N, Handle, Handle = CollHandle>,
364 >(
365 &'a self,
366 colliders: &'a Colliders,
367 aabb: &'b AABB<N>,
368 groups: &'b CollisionGroups,
369 ) -> pipeline::InterferencesWithAABB<'a, 'b, N, Colliders> {
370 pipeline::interferences_with_aabb(&colliders, &*self.broad_phase, aabb, groups)
371 }
372
373 pub fn contact_events(&self) -> &ContactEvents<CollHandle> {
375 self.narrow_phase.contact_events()
376 }
377
378 pub fn proximity_events(&self) -> &ProximityEvents<CollHandle> {
380 self.narrow_phase.proximity_events()
381 }
382
383 fn is_interaction_effective(
389 c1: &Collider<N, Handle>,
390 c2: &Collider<N, Handle>,
391 interaction: &Interaction<N>,
392 ) -> bool {
393 match interaction {
394 Interaction::Contact(_, manifold) => Self::is_contact_effective(c1, c2, manifold),
395 Interaction::Proximity(_, prox) => *prox == Proximity::Intersecting,
396 }
397 }
398
399 fn is_contact_effective(
400 c1: &Collider<N, Handle>,
401 c2: &Collider<N, Handle>,
402 manifold: &ContactManifold<N>,
403 ) -> bool {
404 if let Some(c) = manifold.deepest_contact() {
405 c.contact.depth >= -(c1.margin() + c2.margin())
406 } else {
407 false
408 }
409 }
410
411 #[inline(always)]
412 fn filter_interactions<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
413 colliders: &'a Colliders,
414 iter: impl Iterator<Item = (CollHandle, CollHandle, &'a Interaction<N>)>,
415 effective_only: bool,
416 ) -> impl Iterator<
417 Item = (
418 CollHandle,
419 &'a Collider<N, Handle>,
420 CollHandle,
421 &'a Collider<N, Handle>,
422 &'a Interaction<N>,
423 ),
424 > {
425 iter.filter_map(move |inter| {
426 let c1 = colliders.get(inter.0)?;
427 let c2 = colliders.get(inter.1)?;
428 if !effective_only || Self::is_interaction_effective(c1, c2, inter.2) {
429 Some((inter.0, c1, inter.1, c2, inter.2))
430 } else {
431 None
432 }
433 })
434 }
435
436 #[inline(always)]
437 fn filter_contacts<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
438 colliders: &'a Colliders,
439 iter: impl Iterator<
440 Item = (
441 CollHandle,
442 CollHandle,
443 &'a ContactAlgorithm<N>,
444 &'a ContactManifold<N>,
445 ),
446 >,
447 effective_only: bool,
448 ) -> impl Iterator<
449 Item = (
450 CollHandle,
451 &'a Collider<N, Handle>,
452 CollHandle,
453 &'a Collider<N, Handle>,
454 &'a ContactAlgorithm<N>,
455 &'a ContactManifold<N>,
456 ),
457 > {
458 iter.filter_map(move |inter| {
459 let c1 = colliders.get(inter.0)?;
460 let c2 = colliders.get(inter.1)?;
461 if !effective_only || Self::is_contact_effective(c1, c2, inter.3) {
462 Some((inter.0, c1, inter.1, c2, inter.2, inter.3))
463 } else {
464 None
465 }
466 })
467 }
468
469 #[inline(always)]
470 fn filter_proximities<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
471 colliders: &'a Colliders,
472 iter: impl Iterator<
473 Item = (
474 CollHandle,
475 CollHandle,
476 &'a dyn ProximityDetector<N>,
477 Proximity,
478 ),
479 >,
480 ) -> impl Iterator<
481 Item = (
482 CollHandle,
483 &'a Collider<N, Handle>,
484 CollHandle,
485 &'a Collider<N, Handle>,
486 &'a dyn ProximityDetector<N>,
487 Proximity,
488 ),
489 > {
490 iter.filter_map(move |prox| {
491 Some((
492 prox.0,
493 colliders.get(prox.0)?,
494 prox.1,
495 colliders.get(prox.1)?,
496 prox.2,
497 prox.3,
498 ))
499 })
500 }
501
502 pub fn interaction_pairs<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
511 &'a self,
512 colliders: &'a Colliders,
513 effective_only: bool,
514 ) -> impl Iterator<
515 Item = (
516 CollHandle,
517 &'a Collider<N, Handle>,
518 CollHandle,
519 &'a Collider<N, Handle>,
520 &'a Interaction<N>,
521 ),
522 > {
523 Self::filter_interactions(
524 colliders,
525 self.interactions.interaction_pairs(false),
526 effective_only,
527 )
528 }
529
530 pub fn contact_pairs<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
535 &'a self,
536 colliders: &'a Colliders,
537 effective_only: bool,
538 ) -> impl Iterator<
539 Item = (
540 CollHandle,
541 &'a Collider<N, Handle>,
542 CollHandle,
543 &'a Collider<N, Handle>,
544 &'a ContactAlgorithm<N>,
545 &'a ContactManifold<N>,
546 ),
547 > {
548 Self::filter_contacts(
549 colliders,
550 self.interactions.contact_pairs(false),
551 effective_only,
552 )
553 }
554
555 pub fn proximity_pairs<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
560 &'a self,
561 colliders: &'a Colliders,
562 effective_only: bool,
563 ) -> impl Iterator<
564 Item = (
565 CollHandle,
566 &'a Collider<N, Handle>,
567 CollHandle,
568 &'a Collider<N, Handle>,
569 &'a dyn ProximityDetector<N>,
570 Proximity,
571 ),
572 > {
573 Self::filter_proximities(colliders, self.interactions.proximity_pairs(effective_only))
574 }
575
576 pub fn interaction_pair<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
581 &'a self,
582 colliders: &'a Colliders,
583 handle1: CollHandle,
584 handle2: CollHandle,
585 effective_only: bool,
586 ) -> Option<(
587 CollHandle,
588 &'a Collider<N, Handle>,
589 CollHandle,
590 &'a Collider<N, Handle>,
591 &'a Interaction<N>,
592 )> {
593 let id1 = colliders
594 .get(handle1)?
595 .graph_index()
596 .expect(crate::NOT_REGISTERED_ERROR);
597 let id2 = colliders
598 .get(handle2)?
599 .graph_index()
600 .expect(crate::NOT_REGISTERED_ERROR);
601
602 self.interactions
603 .interaction_pair(id1, id2, false)
604 .and_then(move |inter| {
605 let c1 = colliders.get(inter.0)?;
606 let c2 = colliders.get(inter.1)?;
607
608 if !effective_only || Self::is_interaction_effective(c1, c2, inter.2) {
609 Some((inter.0, c1, inter.1, c2, inter.2))
610 } else {
611 None
612 }
613 })
614 }
615
616 pub fn contact_pair<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
621 &'a self,
622 colliders: &'a Colliders,
623 handle1: CollHandle,
624 handle2: CollHandle,
625 effective_only: bool,
626 ) -> Option<(
627 CollHandle,
628 &'a Collider<N, Handle>,
629 CollHandle,
630 &'a Collider<N, Handle>,
631 &'a ContactAlgorithm<N>,
632 &'a ContactManifold<N>,
633 )> {
634 let id1 = colliders
635 .get(handle1)?
636 .graph_index()
637 .expect(crate::NOT_REGISTERED_ERROR);
638 let id2 = colliders
639 .get(handle2)?
640 .graph_index()
641 .expect(crate::NOT_REGISTERED_ERROR);
642
643 self.interactions
644 .contact_pair(id1, id2, false)
645 .and_then(move |inter| {
646 let c1 = colliders.get(inter.0)?;
647 let c2 = colliders.get(inter.1)?;
648 if !effective_only || Self::is_contact_effective(c1, c2, inter.3) {
649 Some((inter.0, c1, inter.1, c2, inter.2, inter.3))
650 } else {
651 None
652 }
653 })
654 }
655
656 pub fn proximity_pair<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
661 &'a self,
662 colliders: &'a Colliders,
663 handle1: CollHandle,
664 handle2: CollHandle,
665 effective_only: bool,
666 ) -> Option<(
667 CollHandle,
668 &'a Collider<N, Handle>,
669 CollHandle,
670 &'a Collider<N, Handle>,
671 &'a dyn ProximityDetector<N>,
672 Proximity,
673 )> {
674 let id1 = colliders
675 .get(handle1)?
676 .graph_index()
677 .expect(crate::NOT_REGISTERED_ERROR);
678 let id2 = colliders
679 .get(handle2)?
680 .graph_index()
681 .expect(crate::NOT_REGISTERED_ERROR);
682
683 self.interactions
684 .proximity_pair(id1, id2, effective_only)
685 .and_then(move |prox| {
686 Some((
687 prox.0,
688 colliders.get(prox.0)?,
689 prox.1,
690 colliders.get(prox.1)?,
691 prox.2,
692 prox.3,
693 ))
694 })
695 }
696
697 pub fn interactions_with<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
702 &'a self,
703 colliders: &'a Colliders,
704 handle: CollHandle,
705 effective_only: bool,
706 ) -> Option<
707 impl Iterator<
708 Item = (
709 CollHandle,
710 &'a Collider<N, Handle>,
711 CollHandle,
712 &'a Collider<N, Handle>,
713 &'a Interaction<N>,
714 ),
715 >,
716 > {
717 let idx = colliders
718 .get(handle)?
719 .graph_index()
720 .expect(crate::NOT_REGISTERED_ERROR);
721 Some(Self::filter_interactions(
722 colliders,
723 self.interactions.interactions_with(idx, false),
724 effective_only,
725 ))
726 }
727
728 pub fn contacts_with<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
733 &'a self,
734 colliders: &'a Colliders,
735 handle: CollHandle,
736 effective_only: bool,
737 ) -> Option<
738 impl Iterator<
739 Item = (
740 CollHandle,
741 &'a Collider<N, Handle>,
742 CollHandle,
743 &'a Collider<N, Handle>,
744 &'a ContactAlgorithm<N>,
745 &'a ContactManifold<N>,
746 ),
747 >,
748 > {
749 let idx = colliders
750 .get(handle)?
751 .graph_index()
752 .expect(crate::NOT_REGISTERED_ERROR);
753 Some(Self::filter_contacts(
754 colliders,
755 self.interactions.contacts_with(idx, false),
756 effective_only,
757 ))
758 }
759
760 pub fn proximities_with<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
765 &'a self,
766 colliders: &'a Colliders,
767 handle: CollHandle,
768 effective_only: bool,
769 ) -> Option<
770 impl Iterator<
771 Item = (
772 CollHandle,
773 &'a Collider<N, Handle>,
774 CollHandle,
775 &'a Collider<N, Handle>,
776 &'a dyn ProximityDetector<N>,
777 Proximity,
778 ),
779 >,
780 > {
781 let idx = colliders
782 .get(handle)?
783 .graph_index()
784 .expect(crate::NOT_REGISTERED_ERROR);
785 Some(Self::filter_proximities(
786 colliders,
787 self.interactions.proximities_with(idx, effective_only),
788 ))
789 }
790
791 pub fn colliders_interacting_with<
796 'a,
797 Colliders: ColliderSet<N, Handle, Handle = CollHandle>,
798 >(
799 &'a self,
800 colliders: &'a Colliders,
801 handle: CollHandle,
802 ) -> Option<impl Iterator<Item = (CollHandle, &'a Collider<N, Handle>)>> {
803 Some(
804 self.interactions_with(colliders, handle, true)?
805 .map(
806 move |(h1, c1, h2, c2, _)| {
807 if h1 == handle {
808 (h2, c2)
809 } else {
810 (h1, c1)
811 }
812 },
813 ),
814 )
815 }
816
817 pub fn colliders_in_contact_with<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
823 &'a self,
824 colliders: &'a Colliders,
825 handle: CollHandle,
826 ) -> Option<impl Iterator<Item = (CollHandle, &'a Collider<N, Handle>)>> {
827 Some(
828 self.contacts_with(colliders, handle, true)?
829 .map(
830 move |(h1, c1, h2, c2, _, _)| {
831 if h1 == handle {
832 (h2, c2)
833 } else {
834 (h1, c1)
835 }
836 },
837 ),
838 )
839 }
840
841 pub fn colliders_in_proximity_of<'a, Colliders: ColliderSet<N, Handle, Handle = CollHandle>>(
847 &'a self,
848 colliders: &'a Colliders,
849 handle: CollHandle,
850 ) -> Option<impl Iterator<Item = (CollHandle, &'a Collider<N, Handle>)>> {
851 Some(
852 self.proximities_with(colliders, handle, true)?
853 .map(
854 move |(h1, c1, h2, c2, _, _)| {
855 if h1 == handle {
856 (h2, c2)
857 } else {
858 (h1, c1)
859 }
860 },
861 ),
862 )
863 }
864}
865
866pub type DefaultBroadPhasePairFilterSets<'a, N> =
868 BroadPhasePairFilterSets<'a, N, DefaultBodySet<N>, DefaultColliderSet<N>>;
869
870pub struct BroadPhasePairFilterSets<'a, N, Bodies, Colliders>
872where
873 N: RealField + Copy,
874 Bodies: BodySet<N>,
875 Colliders: ColliderSet<N, Bodies::Handle>,
876{
877 colliders: &'a Colliders,
879
880 bodies: &'a Bodies,
882
883 _pd: PhantomData<N>,
885}
886
887impl<'a, N, Bodies, Colliders> BroadPhasePairFilterSets<'a, N, Bodies, Colliders>
888where
889 N: RealField + Copy,
890 Bodies: BodySet<N>,
891 Colliders: ColliderSet<N, Bodies::Handle>,
892{
893 pub fn bodies(&self) -> &Bodies {
895 self.bodies
896 }
897
898 pub fn colliders(&self) -> &Colliders {
900 self.colliders
901 }
902}
903
904impl<'a, N, Bodies, Colliders> CollisionObjectSet<N>
905 for BroadPhasePairFilterSets<'a, N, Bodies, Colliders>
906where
907 N: RealField + Copy,
908 Bodies: BodySet<N>,
909 Colliders: ColliderSet<N, Bodies::Handle>,
910{
911 type CollisionObject = Collider<N, Bodies::Handle>;
912 type CollisionObjectHandle = Colliders::Handle;
913
914 fn collision_object(
915 &self,
916 handle: Self::CollisionObjectHandle,
917 ) -> Option<&Self::CollisionObject> {
918 self.colliders.get(handle)
919 }
920
921 fn foreach(&self, f: impl FnMut(Self::CollisionObjectHandle, &Self::CollisionObject)) {
922 CollisionObjectSet::foreach(self.colliders, f)
923 }
924}
925
926struct DefaultCollisionFilter<'a, Filter: ?Sized, Handle> {
927 user_filter: &'a Filter,
928
929 _pd: PhantomData<Handle>,
931}
932
933impl<'a, N, Handle, Set, Filter> BroadPhasePairFilter<N, Set>
934 for DefaultCollisionFilter<'a, Filter, Handle>
935where
936 N: RealField + Copy,
937 Handle: BodyHandle,
938 Set: CollisionObjectSet<N, CollisionObject = Collider<N, Handle>>,
939 Filter: BroadPhasePairFilter<N, Set> + ?Sized,
940{
941 fn is_pair_valid(
942 &self,
943 h1: Set::CollisionObjectHandle,
944 h2: Set::CollisionObjectHandle,
945 set: &Set,
946 ) -> bool {
947 let (c1, c2) = match (set.collision_object(h1), set.collision_object(h2)) {
948 (Some(c1), Some(c2)) => (c1, c2),
949 _ => return false,
950 };
951
952 match (c1.anchor(), c2.anchor()) {
953 (
954 ColliderAnchor::OnBodyPart {
955 body_part: part1, ..
956 },
957 ColliderAnchor::OnBodyPart {
958 body_part: part2, ..
959 },
960 ) => {
961 if part1 == part2 {
962 return false;
963 }
964 }
965 _ => {}
966 }
967
968 (c1.body_status_dependent_ndofs() != 0 || c2.body_status_dependent_ndofs() != 0)
969 && self.user_filter.is_pair_valid(h1, h2, set)
970 }
971}