parry3d_f64/query/contact/
contact_composite_shape_shape.rs

1use crate::bounding_volume::BoundingVolume;
2use crate::math::{Isometry, Real};
3use crate::query::visitors::BoundingVolumeIntersectionsVisitor;
4use crate::query::{Contact, QueryDispatcher};
5use crate::shape::{Shape, SimdCompositeShape};
6use crate::utils::IsometryOpt;
7
8/// Best contact between a composite shape (`Mesh`, `Compound`) and any other shape.
9pub fn contact_composite_shape_shape<D, G1>(
10    dispatcher: &D,
11    pos12: &Isometry<Real>,
12    g1: &G1,
13    g2: &dyn Shape,
14    prediction: Real,
15) -> Option<Contact>
16where
17    D: ?Sized + QueryDispatcher,
18    G1: ?Sized + SimdCompositeShape,
19{
20    // Find new collisions
21    let ls_aabb2 = g2.compute_aabb(pos12).loosened(prediction);
22    let mut res = None::<Contact>;
23
24    let mut leaf_callback = |i: &_| {
25        g1.map_part_at(*i, &mut |part_pos1, part1, _| {
26            if let Ok(Some(mut c)) =
27                dispatcher.contact(&part_pos1.inv_mul(pos12), part1, g2, prediction)
28            {
29                let replace = res.is_none_or(|cbest| c.dist < cbest.dist);
30
31                if replace {
32                    if let Some(part_pos1) = part_pos1 {
33                        c.transform1_by_mut(part_pos1);
34                    }
35                    res = Some(c)
36                }
37            }
38        });
39
40        true
41    };
42
43    let mut visitor = BoundingVolumeIntersectionsVisitor::new(&ls_aabb2, &mut leaf_callback);
44    let _ = g1.qbvh().traverse_depth_first(&mut visitor);
45    res
46}
47
48/// Best contact between a shape and a composite (`Mesh`, `Compound`) shape.
49pub fn contact_shape_composite_shape<D, G2>(
50    dispatcher: &D,
51    pos12: &Isometry<Real>,
52    g1: &dyn Shape,
53    g2: &G2,
54    prediction: Real,
55) -> Option<Contact>
56where
57    D: ?Sized + QueryDispatcher,
58    G2: ?Sized + SimdCompositeShape,
59{
60    contact_composite_shape_shape(dispatcher, &pos12.inverse(), g2, g1, prediction)
61        .map(|c| c.flipped())
62}