1use crate::math::{Isometry, Real, Vector};
2use crate::query::details::ShapeCastOptions;
3#[cfg(feature = "alloc")]
4use crate::query::{
5 contact_manifolds::{ContactManifoldsWorkspace, NormalConstraints},
6 ContactManifold,
7};
8use crate::query::{ClosestPoints, Contact, NonlinearRigidMotion, ShapeCastHit, Unsupported};
9use crate::shape::Shape;
10#[cfg(feature = "alloc")]
11use alloc::vec::Vec;
12
13#[cfg(feature = "alloc")]
14pub trait PersistentQueryDispatcher<ManifoldData = (), ContactData = ()>: QueryDispatcher {
16 fn contact_manifolds(
24 &self,
25 pos12: &Isometry<Real>,
26 g1: &dyn Shape,
27 g2: &dyn Shape,
28 prediction: Real,
29 manifolds: &mut Vec<ContactManifold<ManifoldData, ContactData>>,
30 workspace: &mut Option<ContactManifoldsWorkspace>,
31 ) -> Result<(), Unsupported>;
32
33 fn contact_manifold_convex_convex(
35 &self,
36 pos12: &Isometry<Real>,
37 g1: &dyn Shape,
38 g2: &dyn Shape,
39 normal_constraints1: Option<&dyn NormalConstraints>,
40 normal_constraints2: Option<&dyn NormalConstraints>,
41 prediction: Real,
42 manifold: &mut ContactManifold<ManifoldData, ContactData>,
43 ) -> Result<(), Unsupported>;
44}
45
46pub trait QueryDispatcher: Send + Sync {
54 fn intersection_test(
56 &self,
57 pos12: &Isometry<Real>,
58 g1: &dyn Shape,
59 g2: &dyn Shape,
60 ) -> Result<bool, Unsupported>;
61
62 fn distance(
66 &self,
67 pos12: &Isometry<Real>,
68 g1: &dyn Shape,
69 g2: &dyn Shape,
70 ) -> Result<Real, Unsupported>;
71
72 fn contact(
76 &self,
77 pos12: &Isometry<Real>,
78 g1: &dyn Shape,
79 g2: &dyn Shape,
80 prediction: Real,
81 ) -> Result<Option<Contact>, Unsupported>;
82
83 fn closest_points(
87 &self,
88 pos12: &Isometry<Real>,
89 g1: &dyn Shape,
90 g2: &dyn Shape,
91 max_dist: Real,
92 ) -> Result<ClosestPoints, Unsupported>;
93
94 fn cast_shapes(
109 &self,
110 pos12: &Isometry<Real>,
111 local_vel12: &Vector<Real>,
112 g1: &dyn Shape,
113 g2: &dyn Shape,
114 options: ShapeCastOptions,
115 ) -> Result<Option<ShapeCastHit>, Unsupported>;
116
117 fn chain<U: QueryDispatcher>(self, other: U) -> QueryDispatcherChain<Self, U>
119 where
120 Self: Sized,
121 {
122 QueryDispatcherChain(self, other)
123 }
124
125 fn cast_shapes_nonlinear(
142 &self,
143 motion1: &NonlinearRigidMotion,
144 g1: &dyn Shape,
145 motion2: &NonlinearRigidMotion,
146 g2: &dyn Shape,
147 start_time: Real,
148 end_time: Real,
149 stop_at_penetration: bool,
150 ) -> Result<Option<ShapeCastHit>, Unsupported>;
151}
152
153pub struct QueryDispatcherChain<T, U>(T, U);
155
156macro_rules! chain_method {
157 ($name:ident ( $( $arg:ident : $ty:ty,)*) -> $result:ty) => {
158 fn $name(&self, $($arg : $ty,)*
159 ) -> Result<$result, Unsupported> {
160 (self.0).$name($($arg,)*)
161 .or_else(|Unsupported| (self.1).$name($($arg,)*))
162 }
163 }
164}
165
166impl<T, U> QueryDispatcher for QueryDispatcherChain<T, U>
167where
168 T: QueryDispatcher,
169 U: QueryDispatcher,
170{
171 chain_method!(intersection_test(
172 pos12: &Isometry<Real>,
173 g1: &dyn Shape,
174 g2: &dyn Shape,
175 ) -> bool);
176
177 chain_method!(distance(pos12: &Isometry<Real>, g1: &dyn Shape, g2: &dyn Shape,) -> Real);
178
179 chain_method!(contact(
180 pos12: &Isometry<Real>,
181 g1: &dyn Shape,
182 g2: &dyn Shape,
183 prediction: Real,
184 ) -> Option<Contact>);
185
186 chain_method!(closest_points(
187 pos12: &Isometry<Real>,
188 g1: &dyn Shape,
189 g2: &dyn Shape,
190 max_dist: Real,
191 ) -> ClosestPoints);
192
193 chain_method!(cast_shapes(
194 pos12: &Isometry<Real>,
195 vel12: &Vector<Real>,
196 g1: &dyn Shape,
197 g2: &dyn Shape,
198 options: ShapeCastOptions,
199 ) -> Option<ShapeCastHit>);
200
201 chain_method!(cast_shapes_nonlinear(
202 motion1: &NonlinearRigidMotion,
203 g1: &dyn Shape,
204 motion2: &NonlinearRigidMotion,
205 g2: &dyn Shape,
206 start_time: Real,
207 end_time: Real,
208 stop_at_penetration: bool,
209 ) -> Option<ShapeCastHit>);
210}
211
212#[cfg(feature = "alloc")]
213impl<ManifoldData, ContactData, T, U> PersistentQueryDispatcher<ManifoldData, ContactData>
214 for QueryDispatcherChain<T, U>
215where
216 T: PersistentQueryDispatcher<ManifoldData, ContactData>,
217 U: PersistentQueryDispatcher<ManifoldData, ContactData>,
218{
219 chain_method!(contact_manifolds(
220 pos12: &Isometry<Real>,
221 g1: &dyn Shape,
222 g2: &dyn Shape,
223 prediction: Real,
224 manifolds: &mut Vec<ContactManifold<ManifoldData, ContactData>>,
225 workspace: &mut Option<ContactManifoldsWorkspace>,
226 ) -> ());
227
228 chain_method!(contact_manifold_convex_convex(
229 pos12: &Isometry<Real>,
230 g1: &dyn Shape,
231 g2: &dyn Shape,
232 normal_constraints1: Option<&dyn NormalConstraints>,
233 normal_constraints2: Option<&dyn NormalConstraints>,
234 prediction: Real,
235 manifold: &mut ContactManifold<ManifoldData, ContactData>,
236 ) -> ());
237}