Added user-implementable traits for collision/proximity pair filtering.
This commit is contained in:
@@ -14,8 +14,9 @@ use crate::geometry::proximity_detector::{
|
||||
// proximity_detector::ProximityDetectionContextSimd, WBall,
|
||||
//};
|
||||
use crate::geometry::{
|
||||
BroadPhasePairEvent, ColliderGraphIndex, ColliderHandle, ContactEvent, ProximityEvent,
|
||||
ProximityPair, RemovedCollider, SolverFlags,
|
||||
BroadPhasePairEvent, ColliderGraphIndex, ColliderHandle, ContactEvent, ContactPairFilter,
|
||||
PairFilterContext, ProximityEvent, ProximityPair, ProximityPairFilter, RemovedCollider,
|
||||
SolverFlags,
|
||||
};
|
||||
use crate::geometry::{ColliderSet, ContactManifold, ContactPair, InteractionGraph};
|
||||
//#[cfg(feature = "simd-is-enabled")]
|
||||
@@ -290,6 +291,7 @@ impl NarrowPhase {
|
||||
prediction_distance: f32,
|
||||
bodies: &RigidBodySet,
|
||||
colliders: &ColliderSet,
|
||||
pair_filter: Option<&dyn ProximityPairFilter>,
|
||||
events: &dyn EventHandler,
|
||||
) {
|
||||
par_iter_mut!(&mut self.proximity_graph.graph.edges).for_each(|edge| {
|
||||
@@ -301,16 +303,35 @@ impl NarrowPhase {
|
||||
let rb1 = &bodies[co1.parent];
|
||||
let rb2 = &bodies[co2.parent];
|
||||
|
||||
if (rb1.is_sleeping() || rb1.is_static()) && (rb2.is_sleeping() || rb2.is_static()) {
|
||||
// No need to update this contact because nothing moved.
|
||||
if (rb1.is_sleeping() && rb2.is_static()) || (rb2.is_sleeping() && rb1.is_static()) {
|
||||
// No need to update this proximity because nothing moved.
|
||||
return;
|
||||
}
|
||||
|
||||
if !co1.collision_groups.test(co2.collision_groups) {
|
||||
// The collision is not allowed.
|
||||
// The proximity is not allowed.
|
||||
return;
|
||||
}
|
||||
|
||||
if pair_filter.is_none() && !rb1.is_dynamic() && !rb2.is_dynamic() {
|
||||
// Default filtering rule: no proximity between two non-dynamic bodies.
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(filter) = pair_filter {
|
||||
let context = PairFilterContext {
|
||||
collider1: co1,
|
||||
collider2: co2,
|
||||
rigid_body1: rb1,
|
||||
rigid_body2: rb2,
|
||||
};
|
||||
|
||||
if !filter.filter_proximity_pair(&context) {
|
||||
// No proximity allowed.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let dispatcher = DefaultProximityDispatcher;
|
||||
if pair.detector.is_none() {
|
||||
// We need a redispatch for this detector.
|
||||
@@ -341,6 +362,7 @@ impl NarrowPhase {
|
||||
prediction_distance: f32,
|
||||
bodies: &RigidBodySet,
|
||||
colliders: &ColliderSet,
|
||||
pair_filter: Option<&dyn ContactPairFilter>,
|
||||
events: &dyn EventHandler,
|
||||
) {
|
||||
par_iter_mut!(&mut self.contact_graph.graph.edges).for_each(|edge| {
|
||||
@@ -352,9 +374,7 @@ impl NarrowPhase {
|
||||
let rb1 = &bodies[co1.parent];
|
||||
let rb2 = &bodies[co2.parent];
|
||||
|
||||
if ((rb1.is_sleeping() || rb1.is_static()) && (rb2.is_sleeping() || rb2.is_static()))
|
||||
|| (!rb1.is_dynamic() && !rb2.is_dynamic())
|
||||
{
|
||||
if (rb1.is_sleeping() && rb2.is_static()) || (rb2.is_sleeping() && rb1.is_static()) {
|
||||
// No need to update this contact because nothing moved.
|
||||
return;
|
||||
}
|
||||
@@ -364,6 +384,33 @@ impl NarrowPhase {
|
||||
return;
|
||||
}
|
||||
|
||||
if pair_filter.is_none() && !rb1.is_dynamic() && !rb2.is_dynamic() {
|
||||
// Default filtering rule: no contact between two non-dynamic bodies.
|
||||
return;
|
||||
}
|
||||
|
||||
let solver_flags = if let Some(filter) = pair_filter {
|
||||
let context = PairFilterContext {
|
||||
collider1: co1,
|
||||
collider2: co2,
|
||||
rigid_body1: rb1,
|
||||
rigid_body2: rb2,
|
||||
};
|
||||
|
||||
if let Some(solver_flags) = filter.filter_contact_pair(&context) {
|
||||
solver_flags
|
||||
} else {
|
||||
// No contact allowed.
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if co1.solver_groups.test(co2.solver_groups) {
|
||||
SolverFlags::COMPUTE_FORCES
|
||||
} else {
|
||||
SolverFlags::empty()
|
||||
}
|
||||
};
|
||||
|
||||
let dispatcher = DefaultContactDispatcher;
|
||||
if pair.generator.is_none() {
|
||||
// We need a redispatch for this generator.
|
||||
@@ -374,12 +421,6 @@ 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,
|
||||
@@ -415,6 +456,7 @@ impl NarrowPhase {
|
||||
let rb2 = &bodies[manifold.body_pair.body2];
|
||||
if manifold.solver_flags.contains(SolverFlags::COMPUTE_FORCES)
|
||||
&& manifold.num_active_contacts() != 0
|
||||
&& (rb1.is_dynamic() || rb2.is_dynamic())
|
||||
&& (!rb1.is_dynamic() || !rb1.is_sleeping())
|
||||
&& (!rb2.is_dynamic() || !rb2.is_sleeping())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user