parry3d/query/closest_points/
closest_points_composite_shape_shape.rs1use crate::bounding_volume::Aabb;
2use crate::math::{Isometry, Real};
3use crate::partitioning::BvhNode;
4use crate::query::{ClosestPoints, QueryDispatcher};
5use crate::shape::{CompositeShapeRef, Shape, TypedCompositeShape};
6use crate::utils::IsometryOpt;
7use na;
8
9impl<S: ?Sized + TypedCompositeShape> CompositeShapeRef<'_, S> {
10 pub fn closest_points_to_shape<D: ?Sized + QueryDispatcher>(
22 &self,
23 dispatcher: &D,
24 pose12: &Isometry<Real>,
25 shape2: &dyn Shape,
26 margin: Real,
27 ) -> Option<(u32, ClosestPoints)> {
28 let ls_aabb2 = shape2.compute_aabb(pose12);
29 let msum_shift = -ls_aabb2.center().coords;
30 let msum_margin = ls_aabb2.half_extents();
31
32 self.0
33 .bvh()
34 .find_best(
35 margin,
36 |node: &BvhNode, _| {
37 let msum = Aabb {
39 mins: node.mins() + msum_shift - msum_margin,
40 maxs: node.maxs() + msum_shift + msum_margin,
41 };
42 msum.distance_to_origin()
43 },
44 |part_id, _| {
45 self.0
46 .map_untyped_part_at(part_id, |part_pos1, part_g1, _| {
47 if let Ok(mut pts) = dispatcher.closest_points(
48 &part_pos1.inv_mul(pose12),
49 part_g1,
50 shape2,
51 margin,
52 ) {
53 let cost = match &mut pts {
54 ClosestPoints::WithinMargin(p1, p2) => {
55 *p1 = part_pos1.transform_point(&*p1);
56 let p2_1 = pose12 * *p2;
57 na::distance(&*p1, &p2_1)
58 }
59 ClosestPoints::Intersecting => -Real::MAX,
60 ClosestPoints::Disjoint => Real::MAX,
61 };
62 (cost, pts)
63 } else {
64 (Real::MAX, ClosestPoints::Disjoint)
65 }
66 })
67 },
68 )
69 .map(|(part_id, (_, pts))| (part_id, pts))
70 }
71}
72
73pub fn closest_points_composite_shape_shape<D, G1>(
75 dispatcher: &D,
76 pos12: &Isometry<Real>,
77 g1: &G1,
78 g2: &dyn Shape,
79 margin: Real,
80) -> ClosestPoints
81where
82 D: ?Sized + QueryDispatcher,
83 G1: ?Sized + TypedCompositeShape,
84{
85 CompositeShapeRef(g1)
86 .closest_points_to_shape(dispatcher, pos12, g2, margin)
87 .map(|cp| cp.1)
88 .unwrap_or(ClosestPoints::Disjoint)
89}
90
91pub fn closest_points_shape_composite_shape<D, G2>(
93 dispatcher: &D,
94 pos12: &Isometry<Real>,
95 g1: &dyn Shape,
96 g2: &G2,
97 margin: Real,
98) -> ClosestPoints
99where
100 D: ?Sized + QueryDispatcher,
101 G2: ?Sized + TypedCompositeShape,
102{
103 closest_points_composite_shape_shape(dispatcher, &pos12.inverse(), g2, g1, margin).flipped()
104}