aboutsummaryrefslogtreecommitdiff
path: root/src/geometry/collider_components.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/collider_components.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/collider_components.rs')
-rw-r--r--src/geometry/collider_components.rs115
1 files changed, 92 insertions, 23 deletions
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(),
}