parry3d/query/contact_manifolds/
contact_manifolds_cuboid_triangle.rs1#[cfg(feature = "dim2")]
2use crate::math::Vector;
3use crate::math::{Isometry, Real};
4use crate::query::contact_manifolds::{NormalConstraints, NormalConstraintsPair};
5use crate::query::{sat, ContactManifold};
6use crate::shape::PolygonalFeature;
7use crate::shape::{Cuboid, Shape, Triangle};
8
9pub fn contact_manifold_cuboid_triangle_shapes<ManifoldData, ContactData>(
11 pos12: &Isometry<Real>,
12 shape1: &dyn Shape,
13 shape2: &dyn Shape,
14 normal_constraints1: Option<&dyn NormalConstraints>,
15 normal_constraints2: Option<&dyn NormalConstraints>,
16 prediction: Real,
17 manifold: &mut ContactManifold<ManifoldData, ContactData>,
18) where
19 ContactData: Default + Copy,
20{
21 if let (Some(cuboid1), Some(triangle2)) = (shape1.as_cuboid(), shape2.as_triangle()) {
22 contact_manifold_cuboid_triangle(
23 pos12,
24 &pos12.inverse(),
25 cuboid1,
26 triangle2,
27 normal_constraints1,
28 normal_constraints2,
29 prediction,
30 manifold,
31 false,
32 );
33 } else if let (Some(triangle1), Some(cuboid2)) = (shape1.as_triangle(), shape2.as_cuboid()) {
34 contact_manifold_cuboid_triangle(
35 &pos12.inverse(),
36 pos12,
37 cuboid2,
38 triangle1,
39 normal_constraints2,
40 normal_constraints1,
41 prediction,
42 manifold,
43 true,
44 );
45 }
46}
47
48pub fn contact_manifold_cuboid_triangle<'a, ManifoldData, ContactData>(
50 pos12: &Isometry<Real>,
51 pos21: &Isometry<Real>,
52 cuboid1: &'a Cuboid,
53 triangle2: &'a Triangle,
54 normal_constraints1: Option<&dyn NormalConstraints>,
55 normal_constraints2: Option<&dyn NormalConstraints>,
56 prediction: Real,
57 manifold: &mut ContactManifold<ManifoldData, ContactData>,
58 flipped: bool,
59) where
60 ContactData: Default + Copy,
61{
62 if (!flipped && manifold.try_update_contacts(pos12))
63 || (flipped && manifold.try_update_contacts(pos21))
64 {
65 return;
66 }
67
68 let sep1 =
74 sat::cuboid_support_map_find_local_separating_normal_oneway(cuboid1, triangle2, pos12);
75 if sep1.0 > prediction {
76 manifold.clear();
77 return;
78 }
79
80 let sep2 = sat::triangle_cuboid_find_local_separating_normal_oneway(triangle2, cuboid1, pos21);
81 if sep2.0 > prediction {
82 manifold.clear();
83 return;
84 }
85
86 #[cfg(feature = "dim2")]
92 let sep3 = (-Real::MAX, Vector::x()); #[cfg(feature = "dim3")]
94 let sep3 = sat::cuboid_triangle_find_local_separating_edge_twoway(cuboid1, triangle2, pos12);
95 if sep3.0 > prediction {
96 manifold.clear();
97 return;
98 }
99
100 let mut normal1 = sep1.1;
107 let mut dist = sep1.0;
108
109 if sep2.0 > sep1.0 && sep2.0 > sep3.0 {
110 normal1 = pos12 * -sep2.1;
111 dist = sep2.0;
112 } else if sep3.0 > sep1.0 {
113 normal1 = sep3.1;
114 dist = sep3.0;
115 }
116
117 let mut normal2 = pos21 * -normal1;
119
120 if !(normal_constraints1, normal_constraints2).project_local_normals(
121 pos12,
122 &mut normal1,
123 &mut normal2,
124 ) {
125 manifold.clear();
126 return; }
128
129 let feature1;
130 let feature2;
131
132 #[cfg(feature = "dim2")]
133 {
134 feature1 = cuboid1.support_face(normal1);
135 feature2 = triangle2.support_face(normal2);
136 }
137 #[cfg(feature = "dim3")]
138 {
139 feature1 = cuboid1.support_face(normal1);
140 feature2 = PolygonalFeature::from(*triangle2);
141 }
142
143 let old_manifold_points = manifold.points.clone();
146 manifold.clear();
147
148 PolygonalFeature::contacts(
149 pos12, pos21, &normal1, &normal2, &feature1, &feature2, manifold, flipped,
150 );
151
152 if normal_constraints1.is_some() || normal_constraints2.is_some() {
153 manifold
160 .points
161 .retain(|pt| dist >= 0.0 || pt.dist >= 0.0 || pt.dist >= dist * 5.0);
162 }
163
164 if flipped {
165 manifold.local_n1 = normal2;
166 manifold.local_n2 = normal1;
167 } else {
168 manifold.local_n1 = normal1;
169 manifold.local_n2 = normal2;
170 }
171
172 manifold.match_contacts(&old_manifold_points);
174}