aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/narrow_phase.rs
diff options
context:
space:
mode:
authorCrozet Sébastien <developer@crozet.re>2021-02-23 11:24:54 +0100
committerCrozet Sébastien <developer@crozet.re>2021-02-23 11:24:54 +0100
commit00706e8b360e132cb88a7b393dcedadf35403379 (patch)
treee2ab40056da30c614dc94fc0cb852d6207c19043 /src/geometry/narrow_phase.rs
parentad5c10672e36f47fbdb0667bccd79c59ff3a97cc (diff)
downloadrapier-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.rs63
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 {