aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/dynamics/ccd/ccd_solver.rs18
-rw-r--r--src/dynamics/ccd/toi_entry.rs12
-rw-r--r--src/dynamics/rigid_body_components.rs8
-rw-r--r--src/geometry/collider.rs67
-rw-r--r--src/geometry/collider_components.rs115
-rw-r--r--src/geometry/collider_set.rs5
-rw-r--r--src/geometry/narrow_phase.rs107
-rw-r--r--src/pipeline/collision_pipeline.rs6
-rw-r--r--src/pipeline/event_handler.rs6
-rw-r--r--src/pipeline/physics_pipeline.rs9
-rw-r--r--src/pipeline/query_pipeline.rs42
11 files changed, 214 insertions, 181 deletions
diff --git a/src/dynamics/ccd/ccd_solver.rs b/src/dynamics/ccd/ccd_solver.rs
index dab4f73..7e95f08 100644
--- a/src/dynamics/ccd/ccd_solver.rs
+++ b/src/dynamics/ccd/ccd_solver.rs
@@ -10,7 +10,7 @@ use crate::geometry::{
use crate::math::Real;
use crate::parry::utils::SortedPair;
use crate::pipeline::{EventHandler, QueryPipeline, QueryPipelineMode};
-use crate::prelude::{ActiveEvents, ColliderFlags, ColliderGroups};
+use crate::prelude::{ActiveEvents, ColliderFlags};
use parry::query::{DefaultQueryDispatcher, QueryDispatcher};
use parry::utils::hashmap::HashMap;
use std::collections::BinaryHeap;
@@ -141,7 +141,7 @@ impl CCDSolver {
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>
+ ComponentSet<ColliderType>
- + ComponentSet<ColliderGroups>,
+ + ComponentSet<ColliderFlags>,
{
// Update the query pipeline.
self.query_pipeline.update_with_mode(
@@ -202,8 +202,8 @@ impl CCDSolver {
{
let co_parent1: Option<&ColliderParent> = colliders.get(ch1.0);
let co_parent2: Option<&ColliderParent> = colliders.get(ch2.0);
- let c1: (_, _, _, &ColliderGroups) = colliders.index_bundle(ch1.0);
- let c2: (_, _, _, &ColliderGroups) = colliders.index_bundle(ch2.0);
+ let c1: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch1.0);
+ let c2: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch2.0);
let co_type1: &ColliderType = colliders.index(ch1.0);
let co_type2: &ColliderType = colliders.index(ch1.0);
@@ -281,7 +281,7 @@ impl CCDSolver {
+ ComponentSet<ColliderShape>
+ ComponentSet<ColliderType>
+ ComponentSet<ColliderFlags>
- + ComponentSet<ColliderGroups>,
+ + ComponentSet<ColliderFlags>,
{
let mut frozen = HashMap::<_, Real>::default();
let mut all_toi = BinaryHeap::new();
@@ -343,8 +343,8 @@ impl CCDSolver {
{
let co_parent1: Option<&ColliderParent> = colliders.get(ch1.0);
let co_parent2: Option<&ColliderParent> = colliders.get(ch2.0);
- let c1: (_, _, _, &ColliderGroups) = colliders.index_bundle(ch1.0);
- let c2: (_, _, _, &ColliderGroups) = colliders.index_bundle(ch2.0);
+ let c1: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch1.0);
+ let c2: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch2.0);
let bh1 = co_parent1.map(|p| p.handle);
let bh2 = co_parent2.map(|p| p.handle);
@@ -470,8 +470,8 @@ impl CCDSolver {
.colliders_with_aabb_intersecting_aabb(&aabb, |ch2| {
let co_parent1: Option<&ColliderParent> = colliders.get(ch1.0);
let co_parent2: Option<&ColliderParent> = colliders.get(ch2.0);
- let c1: (_, _, _, &ColliderGroups) = colliders.index_bundle(ch1.0);
- let c2: (_, _, _, &ColliderGroups) = colliders.index_bundle(ch2.0);
+ let c1: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch1.0);
+ let c2: (_, _, _, &ColliderFlags) = colliders.index_bundle(ch2.0);
let bh1 = co_parent1.map(|p| p.handle);
let bh2 = co_parent2.map(|p| p.handle);
diff --git a/src/dynamics/ccd/toi_entry.rs b/src/dynamics/ccd/toi_entry.rs
index 918e7c4..f937979 100644
--- a/src/dynamics/ccd/toi_entry.rs
+++ b/src/dynamics/ccd/toi_entry.rs
@@ -2,7 +2,7 @@ use crate::dynamics::{
RigidBodyCcd, RigidBodyHandle, RigidBodyMassProps, RigidBodyPosition, RigidBodyVelocity,
};
use crate::geometry::{
- ColliderGroups, ColliderHandle, ColliderParent, ColliderPosition, ColliderShape, ColliderType,
+ ColliderFlags, ColliderHandle, ColliderParent, ColliderPosition, ColliderShape, ColliderType,
};
use crate::math::Real;
use parry::query::{NonlinearRigidMotion, QueryDispatcher};
@@ -49,14 +49,14 @@ impl TOIEntry {
&ColliderType,
&ColliderShape,
&ColliderPosition,
- &ColliderGroups,
+ &ColliderFlags,
Option<&ColliderParent>,
),
c2: (
&ColliderType,
&ColliderShape,
&ColliderPosition,
- &ColliderGroups,
+ &ColliderFlags,
Option<&ColliderParent>,
),
b1: Option<(
@@ -82,8 +82,8 @@ impl TOIEntry {
return None;
}
- let (co_type1, co_shape1, co_pos1, co_groups1, co_parent1) = c1;
- let (co_type2, co_shape2, co_pos2, co_groups2, co_parent2) = c2;
+ let (co_type1, co_shape1, co_pos1, co_flags1, co_parent1) = c1;
+ let (co_type2, co_shape2, co_pos2, co_flags2, co_parent2) = c2;
let linvel1 =
frozen1.is_none() as u32 as Real * b1.map(|b| b.1.linvel).unwrap_or(na::zero());
@@ -110,7 +110,7 @@ impl TOIEntry {
+ smallest_contact_dist.max(0.0);
let is_pseudo_intersection_test = co_type1.is_sensor()
|| co_type2.is_sensor()
- || !co_groups1.solver_groups.test(co_groups2.solver_groups);
+ || !co_flags1.solver_groups.test(co_flags2.solver_groups);
if (end_time - start_time) * vel12 < thickness {
return None;
diff --git a/src/dynamics/rigid_body_components.rs b/src/dynamics/rigid_body_components.rs
index d1a00ce..ec67b66 100644
--- a/src/dynamics/rigid_body_components.rs
+++ b/src/dynamics/rigid_body_components.rs
@@ -54,23 +54,23 @@ pub type BodyStatus = RigidBodyType;
/// The status of a body, governing the way it is affected by external forces.
pub enum RigidBodyType {
/// A `RigidBodyType::Dynamic` body can be affected by all external forces.
- Dynamic,
+ Dynamic = 0,
/// A `RigidBodyType::Static` body cannot be affected by external forces.
- Static,
+ Static = 1,
/// A `RigidBodyType::KinematicPositionBased` body cannot be affected by any external forces but can be controlled
/// by the user at the position level while keeping realistic one-way interaction with dynamic bodies.
///
/// One-way interaction means that a kinematic body can push a dynamic body, but a kinematic body
/// cannot be pushed by anything. In other words, the trajectory of a kinematic body can only be
/// modified by the user and is independent from any contact or joint it is involved in.
- KinematicPositionBased,
+ KinematicPositionBased = 2,
/// A `RigidBodyType::KinematicVelocityBased` body cannot be affected by any external forces but can be controlled
/// by the user at the velocity level while keeping realistic one-way interaction with dynamic bodies.
///
/// One-way interaction means that a kinematic body can push a dynamic body, but a kinematic body
/// cannot be pushed by anything. In other words, the trajectory of a kinematic body can only be
/// modified by the user and is independent from any contact or joint it is involved in.
- KinematicVelocityBased,
+ KinematicVelocityBased = 3,
// Semikinematic, // A kinematic that performs automatic CCD with the static environment to avoid traversing it?
// Disabled,
}
diff --git a/src/geometry/collider.rs b/src/geometry/collider.rs
index b9007bf..0101a09 100644
--- a/src/geometry/collider.rs
+++ b/src/geometry/collider.rs
@@ -1,8 +1,8 @@
use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle};
use crate::geometry::{
- ColliderBroadPhaseData, ColliderChanges, ColliderFlags, ColliderGroups, ColliderMassProps,
- ColliderMaterial, ColliderParent, ColliderPosition, ColliderShape, ColliderType,
- InteractionGroups, SharedShape,
+ ActiveCollisionTypes, ColliderBroadPhaseData, ColliderChanges, ColliderFlags,
+ ColliderMassProps, ColliderMaterial, ColliderParent, ColliderPosition, ColliderShape,
+ ColliderType, InteractionGroups, SharedShape,
};
use crate::math::{AngVector, Isometry, Point, Real, Rotation, Vector, DIM};
use crate::parry::transformation::vhacd::VHACDParameters;
@@ -25,7 +25,6 @@ pub struct Collider {
pub(crate) co_pos: ColliderPosition,
pub(crate) co_material: ColliderMaterial,
pub(crate) co_flags: ColliderFlags,
- pub(crate) co_groups: ColliderGroups,
pub(crate) co_bf_data: ColliderBroadPhaseData,
/// User-defined data associated to this rigid-body.
pub user_data: u128,
@@ -57,16 +56,26 @@ impl Collider {
self.co_flags.active_hooks = active_hooks;
}
- /// The physics hooks enabled for this collider.
+ /// The events enabled for this collider.
pub fn active_events(&self) -> ActiveEvents {
self.co_flags.active_events
}
- /// Sets the physics hooks enabled for this collider.
+ /// Sets the events enabled for this collider.
pub fn set_active_events(&mut self, active_events: ActiveEvents) {
self.co_flags.active_events = active_events;
}
+ /// The collision types enabled for this collider.
+ pub fn active_collision_types(&self) -> ActiveCollisionTypes {
+ self.co_flags.active_collision_types
+ }
+
+ /// Sets the collision types enabled for this collider.
+ pub fn set_active_collision_types(&mut self, active_collision_types: ActiveCollisionTypes) {
+ self.co_flags.active_collision_types = active_collision_types;
+ }
+
/// The friction coefficient of this collider.
pub fn friction(&self) -> Real {
self.co_material.friction
@@ -179,27 +188,27 @@ impl Collider {
/// The collision groups used by this collider.
pub fn collision_groups(&self) -> InteractionGroups {
- self.co_groups.collision_groups
+ self.co_flags.collision_groups
}
/// Sets the collision groups of this collider.
pub fn set_collision_groups(&mut self, groups: InteractionGroups) {
- if self.co_groups.collision_groups != groups {
+ if self.co_flags.collision_groups != groups {
self.co_changes.insert(ColliderChanges::GROUPS);
- self.co_groups.collision_groups = groups;
+ self.co_flags.collision_groups = groups;
}
}
/// The solver groups used by this collider.
pub fn solver_groups(&self) -> InteractionGroups {
- self.co_groups.solver_groups
+ self.co_flags.solver_groups
}
/// Sets the solver groups of this collider.
pub fn set_solver_groups(&mut self, groups: InteractionGroups) {
- if self.co_groups.solver_groups != groups {
+ if self.co_flags.solver_groups != groups {
self.co_changes.insert(ColliderChanges::GROUPS);
- self.co_groups.solver_groups = groups;
+ self.co_flags.solver_groups = groups;
}
}
@@ -281,6 +290,8 @@ pub struct ColliderBuilder {
pub position: Isometry<Real>,
/// Is this collider a sensor?
pub is_sensor: bool,
+ /// Contact pairs enabled for this collider.
+ pub active_collision_types: ActiveCollisionTypes,
/// Physics hooks enabled for this collider.
pub active_hooks: ActiveHooks,
/// Events enabled for this collider.
@@ -309,6 +320,7 @@ impl ColliderBuilder {
solver_groups: InteractionGroups::all(),
friction_combine_rule: CoefficientCombineRule::Average,
restitution_combine_rule: CoefficientCombineRule::Average,
+ active_collision_types: ActiveCollisionTypes::default(),
active_hooks: ActiveHooks::empty(),
active_events: ActiveEvents::empty(),
}
@@ -605,6 +617,12 @@ impl ColliderBuilder {
self
}
+ /// The set of active collision types for this collider.
+ pub fn active_collision_types(mut self, active_collision_types: ActiveCollisionTypes) -> Self {
+ self.active_collision_types = active_collision_types;
+ self
+ }
+
/// Sets the friction coefficient of the collider this builder will build.
pub fn friction(mut self, friction: Real) -> Self {
self.friction = friction;
@@ -691,27 +709,17 @@ impl ColliderBuilder {
/// Builds a new collider attached to the given rigid-body.
pub fn build(&self) -> Collider {
- let (
- co_changes,
- co_pos,
- co_bf_data,
- co_shape,
- co_type,
- co_groups,
- co_material,
- co_flags,
- co_mprops,
- ) = self.components();
+ let (co_changes, co_pos, co_bf_data, co_shape, co_type, co_material, co_flags, co_mprops) =
+ self.components();
Collider {
co_shape,
co_mprops,
co_material,
- co_flags,
co_parent: None,
co_changes,
co_pos,
co_bf_data,
- co_groups,
+ co_flags,
co_type,
user_data: self.user_data,
}
@@ -726,7 +734,6 @@ impl ColliderBuilder {
ColliderBroadPhaseData,
ColliderShape,
ColliderType,
- ColliderGroups,
ColliderMaterial,
ColliderFlags,
ColliderMassProps,
@@ -748,16 +755,15 @@ impl ColliderBuilder {
restitution_combine_rule: self.restitution_combine_rule,
};
let co_flags = ColliderFlags {
+ collision_groups: self.collision_groups,
+ solver_groups: self.solver_groups,
+ active_collision_types: self.active_collision_types,
active_hooks: self.active_hooks,
active_events: self.active_events,
};
let co_changes = ColliderChanges::all();
let co_pos = ColliderPosition(self.position);
let co_bf_data = ColliderBroadPhaseData::default();
- let co_groups = ColliderGroups {
- collision_groups: self.collision_groups,
- solver_groups: self.solver_groups,
- };
let co_type = if self.is_sensor {
ColliderType::Sensor
} else {
@@ -770,7 +776,6 @@ impl ColliderBuilder {
co_bf_data,
co_shape,
co_type,
- co_groups,
co_material,
co_flags,
co_mprops,
diff --git a/src/geometry/collider_components.rs b/src/geometry/collider_components.rs
index 5923a42..111f527 100644
--- a/src/geometry/collider_components.rs
+++ b/src/geometry/collider_components.rs
@@ -1,4 +1,4 @@
-use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle};
+use crate::dynamics::{CoefficientCombineRule, MassProperties, RigidBodyHandle, RigidBodyType};
use crate::geometry::{InteractionGroups, SAPProxyIndex, Shape, SharedShape};
use crate::math::{Isometry, Real};
use crate::parry::partitioning::IndexedData;
@@ -210,27 +210,6 @@ where
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
-/// The groups of this collider, for filtering contact and solver pairs.
-pub struct ColliderGroups {
- /// The groups controlling the pairs of colliders that can interact (generate
- /// interaction events or contacts).
- pub collision_groups: InteractionGroups,
- /// The groups controlling the pairs of collider that have their contact
- /// points taken into account for force computation.
- pub solver_groups: InteractionGroups,
-}
-
-impl Default for ColliderGroups {
- fn default() -> Self {
- Self {
- collision_groups: InteractionGroups::default(),
- solver_groups: InteractionGroups::default(),
- }
- }
-}
-
-#[derive(Copy, Clone, Debug)]
-#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// The constraints solver-related properties of this collider (friction, restitution, etc.)
pub struct ColliderMaterial {
/// The friction coefficient of this collider.
@@ -272,10 +251,97 @@ impl Default for ColliderMaterial {
}
}
+bitflags::bitflags! {
+ #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
+ /// Flags affecting whether or not collision-detection happens between two colliders
+ /// depending on the type of rigid-bodies they are attached to.
+ pub struct ActiveCollisionTypes: u16 {
+ /// Enable collision-detection between a collider attached to a dynamic body
+ /// and another collider attached to a dynamic body.
+ const DYNAMIC_DYNAMIC = 0b0000_0000_0000_0001;
+ /// Enable collision-detection between a collider attached to a dynamic body
+ /// and another collider attached to a kinematic body.
+ const DYNAMIC_KINEMATIC = 0b0000_0000_0000_1100;
+ /// Enable collision-detection between a collider attached to a dynamic body
+ /// and another collider attached to a static body (or not attached to any body).
+ const DYNAMIC_STATIC = 0b0000_0000_0000_0010;
+ /// Enable collision-detection between a collider attached to a kinematic body
+ /// and another collider attached to a kinematic body.
+ const KINEMATIC_KINEMATIC = 0b1100_1100_0000_0000;
+
+ /// Enable collision-detection between a collider attached to a kinematic body
+ /// and another collider attached to a static body (or not attached to any body).
+ const KINEMATIC_STATIC = 0b0010_0010_0000_0000;
+
+ /// Enable collision-detection between a collider attached to a static body (or
+ /// not attached to any body) and another collider attached to a static body (or
+ /// not attached to any body).
+ const STATIC_STATIC = 0b0000_0000_0010_0000;
+ }
+}
+
+impl ActiveCollisionTypes {
+ /// Test whether contact should be computed between two rigid-bodies with the given types.
+ pub fn test(self, rb_type1: RigidBodyType, rb_type2: RigidBodyType) -> bool {
+ // NOTE: This test is quite complicated so here is an explanation.
+ // First, we associate the following bit masks:
+ // - DYNAMIC = 0001
+ // - STATIC = 0010
+ // - KINEMATIC = 1100
+ // These are equal to the bits indexed by `RigidBodyType as u32`.
+ // The bit masks defined by ActiveCollisionTypes are defined is such a way
+ // that the first part of the variant name (e.g. DYNAMIC_*) indicates which
+ // groups of four bits should be considered:
+ // - DYNAMIC_* = the first group of four bits.
+ // - STATIC_* = the second group of four bits.
+ // - KINEMATIC_* = the third and fourth groups of four bits.
+ // The second part of the variant name (e.g. *_DYNAMIC) indicates the value
+ // of the aforementioned groups of four bits.
+ // For example, DYNAMIC_STATIC means that the first group of four bits (because
+ // of DYNAMIC_*) must have the value 0010 (because of *_STATIC). That gives
+ // us 0b0000_0000_0000_0010 for the DYNAMIC_STATIC_VARIANT.
+ //
+ // The KINEMATIC_* is special because it occupies two groups of four bits. This is
+ // because it combines both KinematicPositionBased and KinematicVelocityBased.
+ //
+ // Now that we have a way of building these bit masks, let's see how we use them.
+ // Given a pair of rigid-body types, the first rigid-body type is used to select
+ // the group of four bits we want to test (the selection is done by to the
+ // `>> (rb_type1 as u32 * 4) & 0b0000_1111`) and the second rigid-body type is
+ // used to form the bit mask we test this group of four bits against.
+ // In other word, the selection of the group of four bits tells us "for this type
+ // of rigid-body I can have collision with rigid-body types with these bit representation".
+ // Then the `(1 << rb_type2)` gives us the bit-representation of the rigid-body type,
+ // which needs to be checked.
+ //
+ // Because that test must be symmetric, we perform two similar tests by swapping
+ // rb_type1 and rb_type2.
+ ((self.bits >> (rb_type1 as u32 * 4)) & 0b0000_1111) & (1 << rb_type2 as u32) != 0
+ || ((self.bits >> (rb_type2 as u32 * 4)) & 0b0000_1111) & (1 << rb_type1 as u32) != 0
+ }
+}
+
+impl Default for ActiveCollisionTypes {
+ fn default() -> Self {
+ ActiveCollisionTypes::DYNAMIC_DYNAMIC
+ | ActiveCollisionTypes::DYNAMIC_KINEMATIC
+ | ActiveCollisionTypes::DYNAMIC_STATIC
+ }
+}
+
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
-/// A set of flags controlling the active hooks and events for this colliders.
+/// A set of flags for controlling collision/intersection filtering, modification, and events.
pub struct ColliderFlags {
+ /// Controls whether collision-detection happens between two colliders depending on
+ /// the type of the rigid-bodies they are attached to.
+ pub active_collision_types: ActiveCollisionTypes,
+ /// The groups controlling the pairs of colliders that can interact (generate
+ /// interaction events or contacts).
+ pub collision_groups: InteractionGroups,
+ /// The groups controlling the pairs of collider that have their contact
+ /// points taken into account for force computation.
+ pub solver_groups: InteractionGroups,
/// The physics hooks enabled for contact pairs and intersection pairs involving this collider.
pub active_hooks: ActiveHooks,
/// The events enabled for this collider.
@@ -285,6 +351,9 @@ pub struct ColliderFlags {
impl Default for ColliderFlags {
fn default() -> Self {
Self {
+ active_collision_types: ActiveCollisionTypes::default(),
+ collision_groups: InteractionGroups::all(),
+ solver_groups: InteractionGroups::all(),
active_hooks: ActiveHooks::empty(),
active_events: ActiveEvents::empty(),
}
diff --git a/src/geometry/collider_set.rs b/src/geometry/collider_set.rs
index dc0abdc..9584015 100644
--- a/src/geometry/collider_set.rs
+++ b/src/geometry/collider_set.rs
@@ -2,8 +2,8 @@ use crate::data::arena::Arena;
use crate::data::{ComponentSet, ComponentSetMut, ComponentSetOption};
use crate::dynamics::{IslandManager, RigidBodyHandle, RigidBodySet};
use crate::geometry::{
- Collider, ColliderBroadPhaseData, ColliderFlags, ColliderGroups, ColliderMassProps,
- ColliderMaterial, ColliderParent, ColliderPosition, ColliderShape, ColliderType,
+ Collider, ColliderBroadPhaseData, ColliderFlags, ColliderMassProps, ColliderMaterial,
+ ColliderParent, ColliderPosition, ColliderShape, ColliderType,
};
use crate::geometry::{ColliderChanges, ColliderHandle};
use std::ops::{Index, IndexMut};
@@ -64,7 +64,6 @@ impl_field_component_set!(ColliderChanges, co_changes);
impl_field_component_set!(ColliderPosition, co_pos);
impl_field_component_set!(ColliderMaterial, co_material);
impl_field_component_set!(ColliderFlags, co_flags);
-impl_field_component_set!(ColliderGroups, co_groups);
impl_field_component_set!(ColliderBroadPhaseData, co_bf_data);
impl ComponentSetOption<ColliderParent> for ColliderSet {
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) =