parry3d_f64/query/contact/
contact_composite_shape_shape.rs1use 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
8pub 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 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
48pub 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}