Add ActiveEvents::CONTACT_FORCE_EVENTS for consistency with ActiveEvents::COLLISION_EVENTS

This commit is contained in:
Sébastien Crozet
2022-07-07 10:58:10 +02:00
parent 06ec9a0e76
commit 73788a21ab
4 changed files with 21 additions and 6 deletions

View File

@@ -22,6 +22,10 @@
- Add `ColliderBuilder::mass` to set the mass of the collider instead of its density. Its angular - Add `ColliderBuilder::mass` to set the mass of the collider instead of its density. Its angular
inertia tensor will be automatically computed based on this mass and its shape. inertia tensor will be automatically computed based on this mass and its shape.
- Add `Collider::mass` and `Collider::volume` to retrieve the mass or volume of a collider. - Add `Collider::mass` and `Collider::volume` to retrieve the mass or volume of a collider.
- Add the `ContactForceEvent` event. This event is useful to read contact forces. A `ContactForceEvent`
is generated whenever the sum of the magnitudes of the forces applied by contacts between two colliders
exceeds the value specified by `Collider::contact_force_event_threshold` on any of the two colliders with
the `ActiveEvents::CONTACT_FORCE_EVENT` flag set.
## v0.13.0 (31 May 2022) ## v0.13.0 (31 May 2022)
### Fixed ### Fixed

View File

@@ -26,7 +26,7 @@ pub struct Collider {
pub(crate) material: ColliderMaterial, pub(crate) material: ColliderMaterial,
pub(crate) flags: ColliderFlags, pub(crate) flags: ColliderFlags,
pub(crate) bf_data: ColliderBroadPhaseData, pub(crate) bf_data: ColliderBroadPhaseData,
pub(crate) contact_force_event_threshold: Real, contact_force_event_threshold: Real,
/// User-defined data associated to this collider. /// User-defined data associated to this collider.
pub user_data: u128, pub user_data: u128,
} }
@@ -37,6 +37,14 @@ impl Collider {
self.changes = ColliderChanges::all(); self.changes = ColliderChanges::all();
} }
pub(crate) fn effective_contact_force_event_threshold(&self) -> Real {
if self.flags.active_events.contains(ActiveEvents::CONTACT_FORCE_EVENTS) {
self.contact_force_event_threshold
} else {
Real::MAX
}
}
/// The rigid body this collider is attached to. /// The rigid body this collider is attached to.
pub fn parent(&self) -> Option<RigidBodyHandle> { pub fn parent(&self) -> Option<RigidBodyHandle> {
self.parent.map(|parent| parent.handle) self.parent.map(|parent| parent.handle)
@@ -412,7 +420,7 @@ impl ColliderBuilder {
active_collision_types: ActiveCollisionTypes::default(), active_collision_types: ActiveCollisionTypes::default(),
active_hooks: ActiveHooks::empty(), active_hooks: ActiveHooks::empty(),
active_events: ActiveEvents::empty(), active_events: ActiveEvents::empty(),
contact_force_event_threshold: Real::MAX, contact_force_event_threshold: 0.0,
} }
} }

View File

@@ -7,9 +7,12 @@ bitflags::bitflags! {
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// Flags affecting the events generated for this collider. /// Flags affecting the events generated for this collider.
pub struct ActiveEvents: u32 { pub struct ActiveEvents: u32 {
/// If set, Rapier will call `EventHandler::handle_contact_event` /// If set, Rapier will call `EventHandler::handle_collision_event`
/// whenever relevant for this collider. /// whenever relevant for this collider.
const COLLISION_EVENTS = 0b0001; const COLLISION_EVENTS = 0b0001;
/// If set, Rapier will call `EventHandler::handle_contact_force_event`
/// whenever relevant for this collider.
const CONTACT_FORCE_EVENTS = 0b0010;
} }
} }
@@ -48,7 +51,7 @@ pub trait EventHandler: Send + Sync {
/// ///
/// A force event is generated whenever the total force magnitude applied between two /// A force event is generated whenever the total force magnitude applied between two
/// colliders is `> Collider::contact_force_event_threshold` value of any of these /// colliders is `> Collider::contact_force_event_threshold` value of any of these
/// colliders. /// colliders with the `ActiveEvents::CONTACT_FORCE_EVENTS` flag set.
/// ///
/// The "total force magnitude" here means "the sum of the magnitudes of the forces applied at /// The "total force magnitude" here means "the sum of the magnitudes of the forces applied at
/// all the contact points in a contact pair". Therefore, if the contact pair involves two /// all the contact points in a contact pair". Therefore, if the contact pair involves two

View File

@@ -291,8 +291,8 @@ impl PhysicsPipeline {
let co1 = &colliders[pair.collider1]; let co1 = &colliders[pair.collider1];
let co2 = &colliders[pair.collider2]; let co2 = &colliders[pair.collider2];
let threshold = co1 let threshold = co1
.contact_force_event_threshold .effective_contact_force_event_threshold()
.min(co2.contact_force_event_threshold); .min(co2.effective_contact_force_event_threshold());
if threshold < Real::MAX { if threshold < Real::MAX {
let total_magnitude = pair.total_impulse_magnitude() * inv_dt; let total_magnitude = pair.total_impulse_magnitude() * inv_dt;