parry3d/query/distance/
distance_composite_shape_shape.rs1use crate::bounding_volume::Aabb;
2use crate::math::{Isometry, Real};
3use crate::partitioning::BvhNode;
4use crate::query::QueryDispatcher;
5use crate::shape::{CompositeShapeRef, Shape, TypedCompositeShape};
6use crate::utils::IsometryOpt;
7
8impl<S: ?Sized + TypedCompositeShape> CompositeShapeRef<'_, S> {
9 pub fn distance_to_shape<D: ?Sized + QueryDispatcher>(
14 &self,
15 dispatcher: &D,
16 pose12: &Isometry<Real>,
17 shape2: &dyn Shape,
18 ) -> Option<(u32, Real)> {
19 let ls_aabb2 = shape2.compute_aabb(pose12);
20 let msum_shift = -ls_aabb2.center().coords;
21 let msum_margin = ls_aabb2.half_extents();
22
23 self.0.bvh().find_best(
24 Real::MAX,
25 |node: &BvhNode, _| {
26 let msum = Aabb {
28 mins: node.mins() + msum_shift - msum_margin,
29 maxs: node.maxs() + msum_shift + msum_margin,
30 };
31 msum.distance_to_origin()
32 },
33 |part_id, _| {
34 self.0
35 .map_untyped_part_at(part_id, |part_pos1, part_g1, _| {
36 dispatcher.distance(&part_pos1.inv_mul(pose12), part_g1, shape2)
37 })?
38 .ok()
39 },
40 )
41 }
42}
43
44pub fn distance_composite_shape_shape<D, G1>(
46 dispatcher: &D,
47 pos12: &Isometry<Real>,
48 g1: &G1,
49 g2: &dyn Shape,
50) -> Real
51where
52 D: ?Sized + QueryDispatcher,
53 G1: ?Sized + TypedCompositeShape,
54{
55 CompositeShapeRef(g1)
56 .distance_to_shape(dispatcher, pos12, g2)
57 .unwrap_or((u32::MAX, Real::MAX))
58 .1
59}
60
61pub fn distance_shape_composite_shape<D, G2>(
63 dispatcher: &D,
64 pos12: &Isometry<Real>,
65 g1: &dyn Shape,
66 g2: &G2,
67) -> Real
68where
69 D: ?Sized + QueryDispatcher,
70 G2: ?Sized + TypedCompositeShape,
71{
72 distance_composite_shape_shape(dispatcher, &pos12.inverse(), g2, g1)
73}