Merge pull request #362 from dimforge/active-events-contact-force-event

Add ActiveEvents::CONTACT_FORCE_EVENTS for consistency with ActiveEvents::COLLISION_EVENTS
This commit is contained in:
Sébastien Crozet
2022-07-07 11:22:14 +02:00
committed by GitHub
4 changed files with 36 additions and 6 deletions

View File

@@ -1,5 +1,10 @@
## Unreleased ## Unreleased
### Fixed ### Fixed
- Fix unpredictable broad-phase panic when using small colliders in the simulation.
- Fix collision events being incorrectly generated for any shape that produces multiple
contact manifolds (like triangle meshes).
- Fix panic in the `CollisionPipeline` if a collider is both added and removed before a call
to `CollisionPipeline::step`.
### Modified ### Modified
- The `RigidBodyBuilder::additional_mass` method will now result in the additional angular inertia - The `RigidBodyBuilder::additional_mass` method will now result in the additional angular inertia
@@ -22,6 +27,16 @@
- 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 `QueryFilter` that is now used by all the scene queries instead of the `CollisionGroups` and `Fn(ColliderHandle) -> bool`
closure. This `QueryFilter` provides easy access to most common filtering strategies (e.g. dynamic bodies only,
excluding one particular collider, etc.) for scene queries.
- Add force reporting based on contact force events. The `EventHandler` trait has been modified to include
the method `EventHandler::handle_contact_force_event`. Contact force events are generated whenever the sum of the
magnitudes of all the forces between two colliders is greater than any of their
`Collider::contact_force_event_threshold` values (only the colliders wit the `ActiveEvents::CONTACT_FORCE_EVENT` flag
set are taken into account for this threshold).
- Add the `ContactForceEvent` struct that is generated by the `ChannelEventCollector` to report
contact force events.
## 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,18 @@ 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 +424,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;