diff options
| author | Sébastien Crozet <developer@crozet.re> | 2022-06-24 19:00:34 +0200 |
|---|---|---|
| committer | Sébastien Crozet <developer@crozet.re> | 2022-07-01 12:00:32 +0200 |
| commit | c9d8277377681a6c5162abe4e8f17a058eebcfd4 (patch) | |
| tree | b5c01635c6530ddcbb1453e8f9b29e3bc9a50910 /src/geometry/contact_pair.rs | |
| parent | d6b61898612d05e12b52d9636e9bb21dccdca4bb (diff) | |
| download | rapier-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.rs | 45 |
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)) + } +} |
