parry2d/query/closest_points/
closest_points_cuboid_cuboid.rs1use crate::math::{Pose, Real};
2use crate::query::{sat, ClosestPoints, PointQuery};
3use crate::shape::{Cuboid, SupportMap};
4
5#[inline]
7pub fn closest_points_cuboid_cuboid(
8 pos12: &Pose,
9 cuboid1: &Cuboid,
10 cuboid2: &Cuboid,
11 margin: Real,
12) -> ClosestPoints {
13 let pos21 = pos12.inverse();
14
15 let sep1 = sat::cuboid_cuboid_find_local_separating_normal_oneway(cuboid1, cuboid2, pos12);
16 if sep1.0 > margin {
17 return ClosestPoints::Disjoint;
18 }
19
20 let sep2 = sat::cuboid_cuboid_find_local_separating_normal_oneway(cuboid2, cuboid1, &pos21);
21 if sep2.0 > margin {
22 return ClosestPoints::Disjoint;
23 }
24
25 #[cfg(feature = "dim2")]
26 let sep3 = (-Real::MAX, crate::math::Vector::Y); #[cfg(feature = "dim3")]
28 let sep3 = sat::cuboid_cuboid_find_local_separating_edge_twoway(cuboid1, cuboid2, pos12);
29 if sep3.0 > margin {
30 return ClosestPoints::Disjoint;
31 }
32
33 if sep1.0 <= 0.0 && sep2.0 <= 0.0 && sep3.0 <= 0.0 {
34 return ClosestPoints::Intersecting;
35 }
36
37 if sep1.0 >= sep2.0 && sep1.0 >= sep3.0 {
39 let pt2_1 = cuboid2.support_point(pos12, -sep1.1);
42 let proj1 = cuboid1.project_local_point(pt2_1, true);
45 let proj2 = cuboid2.project_local_point(pos21 * proj1.point, true);
46 let pt2_1 = pos12 * proj2.point;
47 if (proj1.point - pt2_1).length_squared() > margin * margin {
48 return ClosestPoints::Disjoint;
49 } else {
50 return ClosestPoints::WithinMargin(proj1.point, proj2.point);
51 }
52 }
53
54 if sep2.0 >= sep1.0 && sep2.0 >= sep3.0 {
56 let pt1_2 = cuboid1.support_point(&pos21, -sep2.1);
61 let proj2 = cuboid2.project_local_point(pt1_2, true);
62 let proj1 = cuboid1.project_local_point(pos12 * proj2.point, true);
63 let pt1_2 = pos21 * proj1.point;
64
65 if (proj2.point - pt1_2).length_squared() > margin * margin {
66 return ClosestPoints::Disjoint;
67 } else {
68 return ClosestPoints::WithinMargin(proj1.point, proj2.point);
69 }
70 }
71
72 #[cfg(feature = "dim3")]
74 if sep3.0 >= sep2.0 && sep3.0 >= sep1.0 {
75 let edge1 = cuboid1.local_support_edge_segment(sep3.1);
80 let edge2 = cuboid2.local_support_edge_segment(pos21.rotation * -sep3.1);
81 let (_, loc2) = super::closest_points_segment_segment_with_locations(pos12, &edge1, &edge2);
82
83 let pt2_1 = pos12 * edge2.point_at(&loc2);
86 let proj1 = cuboid1.project_local_point(pt2_1, true);
87 let proj2 = cuboid2.project_local_point(pos21 * proj1.point, true);
88 let pt2_1 = pos12 * proj2.point;
89 if (proj1.point - pt2_1).length_squared() > margin * margin {
90 return ClosestPoints::Disjoint;
91 } else {
92 return ClosestPoints::WithinMargin(proj1.point, proj2.point);
93 }
94 }
95
96 unreachable!()
97}