diff options
| author | Sébastien Crozet <developer@crozet.re> | 2020-10-27 16:10:10 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-27 16:10:10 +0100 |
| commit | a52fb8d7e4649dce02e2131d848b84166df82d64 (patch) | |
| tree | dc6b38ebd73ca5fd62b200417dcc0b114a894572 /src/geometry/narrow_phase.rs | |
| parent | c336ae64557a4981b9cfbd2f6fbe7b7a9d383493 (diff) | |
| parent | 7cafc5471c7fb22b4034b8fe90e848cd0912204d (diff) | |
| download | rapier-a52fb8d7e4649dce02e2131d848b84166df82d64.tar.gz rapier-a52fb8d7e4649dce02e2131d848b84166df82d64.tar.bz2 rapier-a52fb8d7e4649dce02e2131d848b84166df82d64.zip | |
Merge pull request #43 from dimforge/interaction_groups
Add collision filtering based in bit masks
Diffstat (limited to 'src/geometry/narrow_phase.rs')
| -rw-r--r-- | src/geometry/narrow_phase.rs | 148 |
1 files changed, 20 insertions, 128 deletions
diff --git a/src/geometry/narrow_phase.rs b/src/geometry/narrow_phase.rs index e95709c..f5517ba 100644 --- a/src/geometry/narrow_phase.rs +++ b/src/geometry/narrow_phase.rs @@ -15,7 +15,7 @@ use crate::geometry::proximity_detector::{ //}; use crate::geometry::{ BroadPhasePairEvent, ColliderGraphIndex, ColliderHandle, ContactEvent, ProximityEvent, - ProximityPair, RemovedCollider, + ProximityPair, RemovedCollider, SolverFlags, }; use crate::geometry::{ColliderSet, ContactManifold, ContactPair, InteractionGraph}; //#[cfg(feature = "simd-is-enabled")] @@ -306,6 +306,11 @@ impl NarrowPhase { return; } + if !co1.collision_groups.test(co2.collision_groups) { + // The collision is not allowed. + return; + } + let dispatcher = DefaultProximityDispatcher; if pair.detector.is_none() { // We need a redispatch for this detector. @@ -329,69 +334,6 @@ impl NarrowPhase { .unwrap() .detect_proximity(context, events); }); - - /* - // First, group pairs. - // NOTE: the transmutes here are OK because the Vec are all cleared - // before we leave this method. - // We do this in order to avoid reallocating those vecs each time - // we compute the contacts. Unsafe is necessary because we can't just - // store a Vec<&mut ProximityPair> into the NarrowPhase struct without - // polluting the World with lifetimes. - let ball_ball_prox: &mut Vec<&mut ProximityPair> = - unsafe { std::mem::transmute(&mut self.ball_ball_prox) }; - let shape_shape_prox: &mut Vec<&mut ProximityPair> = - unsafe { std::mem::transmute(&mut self.shape_shape_prox) }; - - let bodies = &bodies.bodies; - - // FIXME: don't iterate through all the interactions. - for pair in &mut self.proximity_graph.interactions { - let co1 = &colliders[pair.pair.collider1]; - let co2 = &colliders[pair.pair.collider2]; - - // FIXME: avoid lookup into bodies. - let rb1 = &bodies[co1.parent]; - let rb2 = &bodies[co2.parent]; - - if (rb1.is_sleeping() || !rb1.is_dynamic()) && (rb2.is_sleeping() || !rb2.is_dynamic()) - { - // No need to update this proximity because nothing moved. - continue; - } - - match (co1.shape(), co2.shape()) { - (Shape::Ball(_), Shape::Ball(_)) => ball_ball_prox.push(pair), - _ => shape_shape_prox.push(pair), - } - } - - par_chunks_mut!(ball_ball_prox, SIMD_WIDTH).for_each(|pairs| { - let context = ProximityDetectionContextSimd { - dispatcher: &DefaultProximityDispatcher, - prediction_distance, - colliders, - pairs, - }; - context.pairs[0] - .detector - .detect_proximity_simd(context, events); - }); - - par_iter_mut!(shape_shape_prox).for_each(|pair| { - let context = ProximityDetectionContext { - dispatcher: &DefaultProximityDispatcher, - prediction_distance, - colliders, - pair, - }; - - context.pair.detector.detect_proximity(context, events); - }); - - ball_ball_prox.clear(); - shape_shape_prox.clear(); - */ } pub(crate) fn compute_contacts( @@ -417,6 +359,11 @@ impl NarrowPhase { return; } + if !co1.collision_groups.test(co2.collision_groups) { + // The collision is not allowed. + return; + } + let dispatcher = DefaultContactDispatcher; if pair.generator.is_none() { // We need a redispatch for this generator. @@ -427,11 +374,18 @@ impl NarrowPhase { pair.generator_workspace = workspace; } + let solver_flags = if co1.solver_groups.test(co2.solver_groups) { + SolverFlags::COMPUTE_FORCES + } else { + SolverFlags::empty() + }; + let context = ContactGenerationContext { dispatcher: &dispatcher, prediction_distance, colliders, pair, + solver_flags, }; context @@ -440,69 +394,6 @@ impl NarrowPhase { .unwrap() .generate_contacts(context, events); }); - - /* - // First, group pairs. - // NOTE: the transmutes here are OK because the Vec are all cleared - // before we leave this method. - // We do this in order to avoid reallocating those vecs each time - // we compute the contacts. Unsafe is necessary because we can't just - // store a Vec<&mut ContactPair> into the NarrowPhase struct without - // polluting the World with lifetimes. - let ball_ball: &mut Vec<&mut ContactPair> = - unsafe { std::mem::transmute(&mut self.ball_ball) }; - let shape_shape: &mut Vec<&mut ContactPair> = - unsafe { std::mem::transmute(&mut self.shape_shape) }; - - let bodies = &bodies.bodies; - - // FIXME: don't iterate through all the interactions. - for pair in &mut self.contact_graph.interactions { - let co1 = &colliders[pair.pair.collider1]; - let co2 = &colliders[pair.pair.collider2]; - - // FIXME: avoid lookup into bodies. - let rb1 = &bodies[co1.parent]; - let rb2 = &bodies[co2.parent]; - - if (rb1.is_sleeping() || !rb1.is_dynamic()) && (rb2.is_sleeping() || !rb2.is_dynamic()) - { - // No need to update this contact because nothing moved. - continue; - } - - match (co1.shape(), co2.shape()) { - (Shape::Ball(_), Shape::Ball(_)) => ball_ball.push(pair), - _ => shape_shape.push(pair), - } - } - - par_chunks_mut!(ball_ball, SIMD_WIDTH).for_each(|pairs| { - let context = ContactGenerationContextSimd { - dispatcher: &DefaultContactDispatcher, - prediction_distance, - colliders, - pairs, - }; - context.pairs[0] - .generator - .generate_contacts_simd(context, events); - }); - - par_iter_mut!(shape_shape).for_each(|pair| { - let context = ContactGenerationContext { - dispatcher: &DefaultContactDispatcher, - prediction_distance, - colliders, - pair, - }; - - context.pair.generator.generate_contacts(context, events); - }); - - ball_ball.clear(); - shape_shape.clear(); - */ } /// Retrieve all the interactions with at least one contact point, happening between two active bodies. @@ -522,7 +413,8 @@ impl NarrowPhase { for manifold in &mut inter.weight.manifolds { let rb1 = &bodies[manifold.body_pair.body1]; let rb2 = &bodies[manifold.body_pair.body2]; - if manifold.num_active_contacts() != 0 + if manifold.solver_flags.contains(SolverFlags::COMPUTE_FORCES) + && manifold.num_active_contacts() != 0 && (!rb1.is_dynamic() || !rb1.is_sleeping()) && (!rb2.is_dynamic() || !rb2.is_sleeping()) { |
