From 6370ce68d7fce54e5e0be3deec12c1ff2511e245 Mon Sep 17 00:00:00 2001 From: Joona Aalto Date: Tue, 12 Nov 2024 17:57:13 +0200 Subject: [PATCH] Add helpers for `ContactData` and `SingleContact` to flip contact data (#557) # Objective Sometimes it can be useful to flip contact data, for example when you want to guarantee that `contact.point1` is always the point on the desired entity when iterating over its contacts. ## Solution Add `flip` and `flipped` helpers for `ContactData` and `SingleContact`. --- src/collision/mod.rs | 45 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/collision/mod.rs b/src/collision/mod.rs index 4e562ad5..6a37fece 100644 --- a/src/collision/mod.rs +++ b/src/collision/mod.rs @@ -511,6 +511,23 @@ impl SingleContact { pub fn global_normal2(&self, rotation: &Rotation) -> Vector { rotation * self.normal2 } + + /// Flips the contact data, swapping the points and normals. + pub fn flip(&mut self) { + std::mem::swap(&mut self.point1, &mut self.point2); + std::mem::swap(&mut self.normal1, &mut self.normal2); + } + + /// Returns a flipped copy of the contact data, swapping the points and normals. + pub fn flipped(&self) -> Self { + Self { + point1: self.point2, + point2: self.point1, + normal1: self.normal2, + normal2: self.normal1, + penetration: self.penetration, + } + } } /// Data related to a contact between two bodies. @@ -546,7 +563,7 @@ pub struct ContactData { /// The contact feature ID on the first shape. This indicates the ID of /// the vertex, edge, or face of the contact, if one can be determined. pub feature_id1: PackedFeatureId, - /// The contact feature ID on the first shape. This indicates the ID of + /// The contact feature ID on the second shape. This indicates the ID of /// the vertex, edge, or face of the contact, if one can be determined. pub feature_id2: PackedFeatureId, } @@ -632,4 +649,30 @@ impl ContactData { pub fn global_normal2(&self, rotation: &Rotation) -> Vector { rotation * self.normal2 } + + /// Flips the contact data, swapping the points, normals, and feature IDs, + /// and negating the impulses. + pub fn flip(&mut self) { + std::mem::swap(&mut self.point1, &mut self.point2); + std::mem::swap(&mut self.normal1, &mut self.normal2); + std::mem::swap(&mut self.feature_id1, &mut self.feature_id2); + self.normal_impulse = -self.normal_impulse; + self.tangent_impulse = -self.tangent_impulse; + } + + /// Returns a flipped copy of the contact data, swapping the points, normals, and feature IDs, + /// and negating the impulses. + pub fn flipped(&self) -> Self { + Self { + point1: self.point2, + point2: self.point1, + normal1: self.normal2, + normal2: self.normal1, + penetration: self.penetration, + normal_impulse: -self.normal_impulse, + tangent_impulse: -self.tangent_impulse, + feature_id1: self.feature_id2, + feature_id2: self.feature_id1, + } + } }