aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/contact_pair.rs
diff options
context:
space:
mode:
authorSébastien Crozet <developer@crozet.re>2022-06-24 19:00:34 +0200
committerSébastien Crozet <developer@crozet.re>2022-07-01 12:00:32 +0200
commitc9d8277377681a6c5162abe4e8f17a058eebcfd4 (patch)
treeb5c01635c6530ddcbb1453e8f9b29e3bc9a50910 /src/geometry/contact_pair.rs
parentd6b61898612d05e12b52d9636e9bb21dccdca4bb (diff)
downloadrapier-c9d8277377681a6c5162abe4e8f17a058eebcfd4.tar.gz
rapier-c9d8277377681a6c5162abe4e8f17a058eebcfd4.tar.bz2
rapier-c9d8277377681a6c5162abe4e8f17a058eebcfd4.zip
Add contact force events generated above a user-defined threshold
Diffstat (limited to 'src/geometry/contact_pair.rs')
-rw-r--r--src/geometry/contact_pair.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/geometry/contact_pair.rs b/src/geometry/contact_pair.rs
index 551ffde..37f157e 100644
--- a/src/geometry/contact_pair.rs
+++ b/src/geometry/contact_pair.rs
@@ -141,6 +141,36 @@ impl ContactPair {
self.workspace = None;
}
+ /// The sum of all the impulses applied by contacts on this contact pair.
+ pub fn total_impulse(&self) -> Vector<Real> {
+ self.manifolds
+ .iter()
+ .map(|m| m.total_impulse() * m.data.normal)
+ .sum()
+ }
+
+ /// The sum of the magnitudes of the contacts on this contact pair.
+ pub fn total_impulse_magnitude(&self) -> Real {
+ self.manifolds
+ .iter()
+ .fold(0.0, |a, m| a + m.total_impulse())
+ }
+
+ /// The magnitude and (unit) direction of the maximum impulse on this contact pair.
+ pub fn max_impulse(&self) -> (Real, Vector<Real>) {
+ let mut result = (0.0, Vector::zeros());
+
+ for m in &self.manifolds {
+ let impulse = m.total_impulse();
+
+ if impulse > result.0 {
+ result = (impulse, m.data.normal);
+ }
+ }
+
+ result
+ }
+
/// Finds the contact with the smallest signed distance.
///
/// If the colliders involved in this contact pair are penetrating, then
@@ -316,3 +346,18 @@ impl ContactManifoldData {
self.solver_contacts.len()
}
}
+
+pub trait ContactManifoldExt {
+ fn total_impulse(&self) -> Real;
+ fn max_impulse(&self) -> Real;
+}
+
+impl ContactManifoldExt for ContactManifold {
+ fn total_impulse(&self) -> Real {
+ self.points.iter().map(|pt| pt.data.impulse).sum()
+ }
+
+ fn max_impulse(&self) -> Real {
+ self.points.iter().fold(0.0, |a, pt| a.max(pt.data.impulse))
+ }
+}