ncollide3d/query/contact/
contact_composite_shape_shape.rs1use crate::bounding_volume::BoundingVolume;
2use crate::math::Isometry;
3use crate::query::visitors::BoundingVolumeInterferencesCollector;
4use crate::query::{self, Contact};
5use crate::shape::{CompositeShape, Shape};
6use na::{self, RealField};
7
8pub fn contact_composite_shape_shape<N: RealField + Copy, G1: ?Sized>(
10 m1: &Isometry<N>,
11 g1: &G1,
12 m2: &Isometry<N>,
13 g2: &dyn Shape<N>,
14 prediction: N,
15) -> Option<Contact<N>>
16where
17 G1: CompositeShape<N>,
18{
19 let ls_m2 = m1.inverse() * m2.clone();
21 let ls_aabb2 = g2.aabb(&ls_m2).loosened(prediction);
22
23 let mut interferences = Vec::new();
24
25 {
26 let mut visitor = BoundingVolumeInterferencesCollector::new(&ls_aabb2, &mut interferences);
27 g1.bvh().visit(&mut visitor);
28 }
29
30 let mut res = None::<Contact<N>>;
31
32 for i in interferences.into_iter() {
33 g1.map_part_at(i, m1, &mut |m, part| {
34 if let Some(c) = query::contact(m, part, m2, g2, prediction) {
35 let replace = res.map_or(true, |cbest| c.depth > cbest.depth);
36
37 if replace {
38 res = Some(c)
39 }
40 }
41 });
42 }
43
44 res
45}
46
47pub fn contact_shape_composite_shape<N: RealField + Copy, G2: ?Sized>(
49 m1: &Isometry<N>,
50 g1: &dyn Shape<N>,
51 m2: &Isometry<N>,
52 g2: &G2,
53 prediction: N,
54) -> Option<Contact<N>>
55where
56 G2: CompositeShape<N>,
57{
58 let mut res = contact_composite_shape_shape(m2, g2, m1, g1, prediction);
59 if let Some(c) = &mut res {
60 c.flip()
61 }
62 res
63}