aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/narrow_phase.rs
diff options
context:
space:
mode:
authorCrozet Sébastien <developer@crozet.re>2021-06-01 17:59:07 +0200
committerCrozet Sébastien <developer@crozet.re>2021-06-01 17:59:07 +0200
commit7153eb7779a29853289df90f28efaac738620386 (patch)
tree561a81b65609b60c4429c134ea474a160d70d80e /src/geometry/narrow_phase.rs
parent1839f61d816af37c95889caf592b5a7cf8d89412 (diff)
downloadrapier-7153eb7779a29853289df90f28efaac738620386.tar.gz
rapier-7153eb7779a29853289df90f28efaac738620386.tar.bz2
rapier-7153eb7779a29853289df90f28efaac738620386.zip
Add ActiveCollisionTypes to easily enable collision-detection between two non-static rigid-body.
Diffstat (limited to 'src/geometry/narrow_phase.rs')
-rw-r--r--src/geometry/narrow_phase.rs107
1 files changed, 36 insertions, 71 deletions
diff --git a/src/geometry/narrow_phase.rs b/src/geometry/narrow_phase.rs
index 61bb4c0..185cf0c 100644
--- a/src/geometry/narrow_phase.rs
+++ b/src/geometry/narrow_phase.rs
@@ -7,9 +7,9 @@ use crate::dynamics::{
IslandManager, RigidBodyActivation, RigidBodyDominance, RigidBodyIds, RigidBodyType,
};
use crate::geometry::{
- BroadPhasePairEvent, ColliderChanges, ColliderGraphIndex, ColliderGroups, ColliderHandle,
- ColliderMaterial, ColliderPair, ColliderParent, ColliderPosition, ColliderShape, ColliderType,
- ContactData, ContactEvent, ContactManifold, ContactManifoldData, ContactPair, InteractionGraph,
+ BroadPhasePairEvent, ColliderChanges, ColliderGraphIndex, ColliderHandle, ColliderMaterial,
+ ColliderPair, ColliderParent, ColliderPosition, ColliderShape, ColliderType, ContactData,
+ ContactEvent, ContactManifold, ContactManifoldData, ContactPair, InteractionGraph,
IntersectionEvent, SolverContact, SolverFlags,
};
use crate::math::{Real, Vector};
@@ -675,7 +675,6 @@ impl NarrowPhase {
+ ComponentSet<RigidBodyDominance>,
Colliders: ComponentSet<ColliderChanges>
+ ComponentSetOption<ColliderParent>
- + ComponentSet<ColliderGroups>
+ ComponentSet<ColliderShape>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderMaterial>
@@ -694,18 +693,16 @@ impl NarrowPhase {
let handle2 = nodes[edge.target().index()].weight;
let co_parent1: Option<&ColliderParent> = colliders.get(handle1.0);
- let (co_changes1, co_groups1, co_shape1, co_pos1, co_flags1): (
+ let (co_changes1, co_shape1, co_pos1, co_flags1): (
&ColliderChanges,
- &ColliderGroups,
&ColliderShape,
&ColliderPosition,
&ColliderFlags,
) = colliders.index_bundle(handle1.0);
let co_parent2: Option<&ColliderParent> = colliders.get(handle2.0);
- let (co_changes2, co_groups2, co_shape2, co_pos2, co_flags2): (
+ let (co_changes2, co_shape2, co_pos2, co_flags2): (
&ColliderChanges,
- &ColliderGroups,
&ColliderShape,
&ColliderPosition,
&ColliderFlags,
@@ -718,47 +715,36 @@ impl NarrowPhase {
}
// TODO: avoid lookup into bodies.
- let (mut sleeping1, mut status1) = (true, RigidBodyType::Static);
- let (mut sleeping2, mut status2) = (true, RigidBodyType::Static);
+ let mut rb_type1 = RigidBodyType::Static;
+ let mut rb_type2 = RigidBodyType::Static;
if let Some(co_parent1) = co_parent1 {
- let (rb_type1, rb_activation1): (&RigidBodyType, &RigidBodyActivation) =
- bodies.index_bundle(co_parent1.handle.0);
- status1 = *rb_type1;
- sleeping1 = rb_activation1.sleeping;
+ rb_type1 = *bodies.index(co_parent1.handle.0);
}
if let Some(co_parent2) = co_parent2 {
- let (rb_type2, rb_activation2): (&RigidBodyType, &RigidBodyActivation) =
- bodies.index_bundle(co_parent2.handle.0);
- status2 = *rb_type2;
- sleeping2 = rb_activation2.sleeping;
+ rb_type2 = *bodies.index(co_parent2.handle.0);
}
- if (sleeping1 && status2.is_static())
- || (sleeping2 && status1.is_static())
- || (sleeping1 && sleeping2)
+ // Filter based on the rigid-body types.
+ if !co_flags1.active_collision_types.test(rb_type1, rb_type2)
+ && !co_flags2.active_collision_types.test(rb_type1, rb_type2)
{
- // No need to update this intersection because nothing moved.
return;
}
- if !co_groups1
- .collision_groups
- .test(co_groups2.collision_groups)
- {
- // The intersection is not allowed.
+ // Filter based on collision groups.
+ if !co_flags1.collision_groups.test(co_flags2.collision_groups) {
return;
}
let active_hooks = co_flags1.active_hooks | co_flags2.active_hooks;
let active_events = co_flags1.active_events | co_flags2.active_events;
- if !active_hooks.contains(ActiveHooks::FILTER_INTERSECTION_PAIR)
- && !status1.is_dynamic()
- && !status2.is_dynamic()
+ // Filter based on rigid-body types.
+ if !co_flags1.active_collision_types.test(rb_type1, rb_type2)
+ && !co_flags2.active_collision_types.test(rb_type1, rb_type2)
{
- // Default filtering rule: no intersection between two non-dynamic bodies.
return;
}
@@ -811,7 +797,6 @@ impl NarrowPhase {
+ ComponentSet<RigidBodyDominance>,
Colliders: ComponentSet<ColliderChanges>
+ ComponentSetOption<ColliderParent>
- + ComponentSet<ColliderGroups>
+ ComponentSet<ColliderShape>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderMaterial>
@@ -828,9 +813,8 @@ impl NarrowPhase {
let pair = &mut edge.weight;
let co_parent1: Option<&ColliderParent> = colliders.get(pair.collider1.0);
- let (co_changes1, co_groups1, co_shape1, co_pos1, co_material1, co_flags1): (
+ let (co_changes1, co_shape1, co_pos1, co_material1, co_flags1): (
&ColliderChanges,
- &ColliderGroups,
&ColliderShape,
&ColliderPosition,
&ColliderMaterial,
@@ -838,9 +822,8 @@ impl NarrowPhase {
) = colliders.index_bundle(pair.collider1.0);
let co_parent2: Option<&ColliderParent> = colliders.get(pair.collider2.0);
- let (co_changes2, co_groups2, co_shape2, co_pos2, co_material2, co_flags2): (
+ let (co_changes2, co_shape2, co_pos2, co_material2, co_flags2): (
&ColliderChanges,
- &ColliderGroups,
&ColliderShape,
&ColliderPosition,
&ColliderMaterial,
@@ -854,50 +837,32 @@ impl NarrowPhase {
}
// TODO: avoid lookup into bodies.
- let (mut sleeping1, mut status1) = (true, RigidBodyType::Static);
- let (mut sleeping2, mut status2) = (true, RigidBodyType::Static);
+ let mut rb_type1 = RigidBodyType::Static;
+ let mut rb_type2 = RigidBodyType::Static;
if let Some(co_parent1) = co_parent1 {
- let (rb_type1, rb_activation1): (&RigidBodyType, &RigidBodyActivation) =
- bodies.index_bundle(co_parent1.handle.0);
- status1 = *rb_type1;
- sleeping1 = rb_activation1.sleeping;
+ rb_type1 = *bodies.index(co_parent1.handle.0);
}
if let Some(co_parent2) = co_parent2 {
- let (rb_type2, rb_activation2): (&RigidBodyType, &RigidBodyActivation) =
- bodies.index_bundle(co_parent2.handle.0);
- status2 = *rb_type2;
- sleeping2 = rb_activation2.sleeping;
+ rb_type2 = *bodies.index(co_parent2.handle.0);
}
- if (sleeping1 && status2.is_static())
- || (sleeping2 && status1.is_static())
- || (sleeping1 && sleeping2)
+ // Filter based on the rigid-body types.
+ if !co_flags1.active_collision_types.test(rb_type1, rb_type2)
+ && !co_flags2.active_collision_types.test(rb_type1, rb_type2)
{
- // No need to update this intersection because nothing moved.
return;
}
- if !co_groups1
- .collision_groups
- .test(co_groups2.collision_groups)
- {
- // The collision is not allowed.
+ // Filter based on collision groups.
+ if !co_flags1.collision_groups.test(co_flags2.collision_groups) {
return;
}
let active_hooks = co_flags1.active_hooks | co_flags2.active_hooks;
let active_events = co_flags1.active_events | co_flags2.active_events;
- if !active_hooks.contains(ActiveHooks::FILTER_CONTACT_PAIRS)
- && !status1.is_dynamic()
- && !status2.is_dynamic()
- {
- // Default filtering rule: no contact between two non-dynamic bodies.
- return;
- }
-
let mut solver_flags = if active_hooks.contains(ActiveHooks::FILTER_CONTACT_PAIRS) {
let context = PairFilterContext {
bodies,
@@ -918,7 +883,7 @@ impl NarrowPhase {
SolverFlags::default()
};
- if !co_groups1.solver_groups.test(co_groups2.solver_groups) {
+ if !co_flags1.solver_groups.test(co_flags2.solver_groups) {
solver_flags.remove(SolverFlags::COMPUTE_IMPULSES);
}
@@ -969,7 +934,7 @@ impl NarrowPhase {
manifold.data.rigid_body2 = co_parent2.map(|p| p.handle);
manifold.data.solver_flags = solver_flags;
manifold.data.relative_dominance =
- dominance1.effective_group(&status1) - dominance2.effective_group(&status2);
+ dominance1.effective_group(&rb_type1) - dominance2.effective_group(&rb_type2);
manifold.data.normal = world_pos1 * manifold.local_n1;
// Generate solver contacts.
@@ -1073,7 +1038,7 @@ impl NarrowPhase {
.contains(SolverFlags::COMPUTE_IMPULSES)
&& manifold.data.num_active_contacts() != 0
{
- let (active_island_id1, status1, sleeping1) =
+ let (active_island_id1, rb_type1, sleeping1) =
if let Some(handle1) = manifold.data.rigid_body1 {
let data: (&RigidBodyIds, &RigidBodyType, &RigidBodyActivation) =
bodies.index_bundle(handle1.0);
@@ -1082,7 +1047,7 @@ impl NarrowPhase {
(0, RigidBodyType::Static, true)
};
- let (active_island_id2, status2, sleeping2) =
+ let (active_island_id2, rb_type2, sleeping2) =
if let Some(handle2) = manifold.data.rigid_body2 {
let data: (&RigidBodyIds, &RigidBodyType, &RigidBodyActivation) =
bodies.index_bundle(handle2.0);
@@ -1091,11 +1056,11 @@ impl NarrowPhase {
(0, RigidBodyType::Static, true)
};
- if (status1.is_dynamic() || status2.is_dynamic())
- && (!status1.is_dynamic() || !sleeping1)
- && (!status2.is_dynamic() || !sleeping2)
+ if (rb_type1.is_dynamic() || rb_type2.is_dynamic())
+ && (!rb_type1.is_dynamic() || !sleeping1)
+ && (!rb_type2.is_dynamic() || !sleeping2)
{
- let island_index = if !status1.is_dynamic() {
+ let island_index = if !rb_type1.is_dynamic() {
active_island_id2
} else {
active_island_id1