ncollide3d/query/contact/
contact_composite_shape_shape.rs

1use 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
8/// Best contact between a composite shape (`Mesh`, `Compound`) and any other shape.
9pub 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    // Find new collisions
20    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
47/// Best contact between a shape and a composite (`Mesh`, `Compound`) shape.
48pub 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}