1use crate::query::{Contact, ContactKinematic};
2use na::RealField;
34/// Pre-process a contact before it is added to a contact manifold.
5pub trait ContactPreprocessor<N: RealField + Copy> {
6/// Process a contact before it is stored into a contact manifold.
7 ///
8 /// Returns `false` if the contact should be ignored.
9fn process_contact(
10&self,
11 c: &mut Contact<N>,
12 kinematic: &mut ContactKinematic<N>,
13 is_first: bool,
14 ) -> bool;
15}
1617// FIXME: not sure if there is a more efficient way of doing this.
18// In particular, this induces some overhead (additional indirection and possibly one
19// more virtual call) when the first member is `None`.
20impl<'a, 'b, N, A, B> ContactPreprocessor<N> for (Option<&'a A>, &'b B)
21where
22N: RealField + Copy,
23 A: ?Sized + ContactPreprocessor<N>,
24 B: ?Sized + ContactPreprocessor<N>,
25{
26fn process_contact(
27&self,
28 c: &mut Contact<N>,
29 kinematic: &mut ContactKinematic<N>,
30 is_first: bool,
31 ) -> bool {
32if let Some(p) = self.0 {
33 p.process_contact(c, kinematic, is_first)
34 && self.1.process_contact(c, kinematic, is_first)
35 } else {
36self.1.process_contact(c, kinematic, is_first)
37 }
38 }
39}