parry2d/query/contact/
contact_composite_shape_shape.rs1use crate::bounding_volume::BoundingVolume;
2use crate::math::{Pose, Real};
3use crate::query::{Contact, QueryDispatcher};
4use crate::shape::{CompositeShape, CompositeShapeRef, Shape, SubShapeId};
5use crate::utils::PoseOpt;
6
7impl<S: ?Sized + CompositeShape> CompositeShapeRef<'_, S> {
8 pub fn contact_with_shape<D: ?Sized + QueryDispatcher>(
16 &self,
17 dispatcher: &D,
18 pose12: &Pose,
19 shape2: &dyn Shape,
20 prediction: Real,
21 ) -> Option<(SubShapeId, Contact)> {
22 let ls_aabb2 = shape2.compute_aabb(pose12).loosened(prediction);
23 let mut result = None::<(SubShapeId, Contact)>;
24
25 for part_id in self.0.bvh().intersect_aabb(&ls_aabb2) {
26 self.0.map_part_at(part_id, &mut |part_pos1, part1, _| {
27 if let Ok(Some(mut c)) =
28 dispatcher.contact(&part_pos1.inv_mul(pose12), part1, shape2, prediction)
29 {
30 let replace = result.is_none_or(|(_, cbest)| c.dist < cbest.dist);
31
32 if replace {
33 if let Some(part_pos1) = part_pos1 {
34 c.transform1_by_mut(part_pos1);
35 }
36 result = Some((part_id, c))
37 }
38 }
39 });
40 }
41
42 result
43 }
44}
45
46pub fn contact_composite_shape_shape<D, G1>(
48 dispatcher: &D,
49 pose12: &Pose,
50 g1: &G1,
51 g2: &dyn Shape,
52 prediction: Real,
53) -> Option<Contact>
54where
55 D: ?Sized + QueryDispatcher,
56 G1: ?Sized + CompositeShape,
57{
58 CompositeShapeRef(g1)
61 .contact_with_shape(dispatcher, pose12, g2, prediction)
62 .map(|(part_id, mut c)| {
63 c.subshape1 = part_id;
64 c
65 })
66}
67
68pub fn contact_shape_composite_shape<D, G2>(
70 dispatcher: &D,
71 pose12: &Pose,
72 g1: &dyn Shape,
73 g2: &G2,
74 prediction: Real,
75) -> Option<Contact>
76where
77 D: ?Sized + QueryDispatcher,
78 G2: ?Sized + CompositeShape,
79{
80 contact_composite_shape_shape(dispatcher, &pose12.inverse(), g2, g1, prediction)
81 .map(|c| c.flipped())
82}