diff options
| author | Crozet Sébastien <developer@crozet.re> | 2021-02-23 11:24:54 +0100 |
|---|---|---|
| committer | Crozet Sébastien <developer@crozet.re> | 2021-02-23 11:24:54 +0100 |
| commit | 00706e8b360e132cb88a7b393dcedadf35403379 (patch) | |
| tree | e2ab40056da30c614dc94fc0cb852d6207c19043 /src/geometry/narrow_phase.rs | |
| parent | ad5c10672e36f47fbdb0667bccd79c59ff3a97cc (diff) | |
| download | rapier-00706e8b360e132cb88a7b393dcedadf35403379.tar.gz rapier-00706e8b360e132cb88a7b393dcedadf35403379.tar.bz2 rapier-00706e8b360e132cb88a7b393dcedadf35403379.zip | |
Introduce the PhysicsHook trait used for both contact filtering and contact modification.
Diffstat (limited to 'src/geometry/narrow_phase.rs')
| -rw-r--r-- | src/geometry/narrow_phase.rs | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/src/geometry/narrow_phase.rs b/src/geometry/narrow_phase.rs index 9513fef..e929e0f 100644 --- a/src/geometry/narrow_phase.rs +++ b/src/geometry/narrow_phase.rs @@ -4,10 +4,11 @@ use rayon::prelude::*; use crate::data::pubsub::Subscription; use crate::data::Coarena; use crate::dynamics::{BodyPair, CoefficientCombineRule, RigidBodySet}; +use crate::geometry::pair_filter::{ContactModificationContext, PhysicsHooksFlags}; use crate::geometry::{ BroadPhasePairEvent, ColliderGraphIndex, ColliderHandle, ContactData, ContactEvent, - ContactManifoldData, ContactPairFilter, IntersectionEvent, IntersectionPairFilter, - PairFilterContext, RemovedCollider, SolverContact, SolverFlags, + ContactManifoldData, IntersectionEvent, PairFilterContext, PhysicsHooks, RemovedCollider, + SolverContact, SolverFlags, }; use crate::geometry::{ColliderSet, ContactManifold, ContactPair, InteractionGraph}; use crate::math::{Real, Vector}; @@ -387,11 +388,13 @@ impl NarrowPhase { &mut self, bodies: &RigidBodySet, colliders: &ColliderSet, - pair_filter: Option<&dyn IntersectionPairFilter>, + hooks: &dyn PhysicsHooks, events: &dyn EventHandler, ) { let nodes = &self.intersection_graph.graph.nodes; let query_dispatcher = &*self.query_dispatcher; + let active_hooks = hooks.active_hooks(); + par_iter_mut!(&mut self.intersection_graph.graph.edges).for_each(|edge| { let handle1 = nodes[edge.source().index()].weight; let handle2 = nodes[edge.target().index()].weight; @@ -415,12 +418,15 @@ impl NarrowPhase { return; } - if pair_filter.is_none() && !rb1.is_dynamic() && !rb2.is_dynamic() { + if !active_hooks.contains(PhysicsHooksFlags::FILTER_INTERSECTION_PAIR) + && !rb1.is_dynamic() + && !rb2.is_dynamic() + { // Default filtering rule: no intersection between two non-dynamic bodies. return; } - if let Some(filter) = pair_filter { + if active_hooks.contains(PhysicsHooksFlags::FILTER_INTERSECTION_PAIR) { let context = PairFilterContext { rigid_body1: rb1, rigid_body2: rb2, @@ -430,7 +436,7 @@ impl NarrowPhase { collider2: co2, }; - if !filter.filter_intersection_pair(&context) { + if !hooks.filter_intersection_pair(&context) { // No intersection allowed. return; } @@ -458,10 +464,11 @@ impl NarrowPhase { prediction_distance: Real, bodies: &RigidBodySet, colliders: &ColliderSet, - pair_filter: Option<&dyn ContactPairFilter>, + hooks: &dyn PhysicsHooks, events: &dyn EventHandler, ) { let query_dispatcher = &*self.query_dispatcher; + let active_hooks = hooks.active_hooks(); par_iter_mut!(&mut self.contact_graph.graph.edges).for_each(|edge| { let pair = &mut edge.weight; @@ -485,12 +492,16 @@ impl NarrowPhase { return; } - if pair_filter.is_none() && !rb1.is_dynamic() && !rb2.is_dynamic() { + if !active_hooks.contains(PhysicsHooksFlags::FILTER_CONTACT_PAIR) + && !rb1.is_dynamic() + && !rb2.is_dynamic() + { // Default filtering rule: no contact between two non-dynamic bodies. return; } - let mut solver_flags = if let Some(filter) = pair_filter { + let mut solver_flags = if active_hooks.contains(PhysicsHooksFlags::FILTER_CONTACT_PAIR) + { let context = PairFilterContext { rigid_body1: rb1, rigid_body2: rb2, @@ -500,7 +511,7 @@ impl NarrowPhase { collider2: co2, }; - if let Some(solver_flags) = filter.filter_contact_pair(&context) { + if let Some(solver_flags) = hooks.filter_contact_pair(&context) { solver_flags } else { // No contact allowed. @@ -566,13 +577,39 @@ impl NarrowPhase { data: contact.data, }; - // TODO: apply the user-defined contact modification/removal, if needed. - manifold.data.solver_contacts.push(solver_contact); has_any_active_contact = true; - continue; } } + + // Apply the user-defined contact modification. + if active_hooks.contains(PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS) + && manifold + .data + .solver_flags + .contains(SolverFlags::MODIFY_SOLVER_CONTACTS) + { + let mut modifiable_solver_contacts = + std::mem::replace(&mut manifold.data.solver_contacts, Vec::new()); + let mut modifiable_user_data = manifold.data.user_data; + + let mut context = ContactModificationContext { + rigid_body1: rb1, + rigid_body2: rb2, + collider_handle1: pair.pair.collider1, + collider_handle2: pair.pair.collider2, + collider1: co1, + collider2: co2, + manifold, + solver_contacts: &mut modifiable_solver_contacts, + user_data: &mut modifiable_user_data, + }; + + hooks.modify_solver_contacts(&mut context); + + manifold.data.solver_contacts = modifiable_solver_contacts; + manifold.data.user_data = modifiable_user_data; + } } if has_any_active_contact != pair.has_any_active_contact { |
