diff options
| author | Crozet Sébastien <developer@crozet.re> | 2021-06-01 17:59:07 +0200 |
|---|---|---|
| committer | Crozet Sébastien <developer@crozet.re> | 2021-06-01 17:59:07 +0200 |
| commit | 7153eb7779a29853289df90f28efaac738620386 (patch) | |
| tree | 561a81b65609b60c4429c134ea474a160d70d80e /src | |
| parent | 1839f61d816af37c95889caf592b5a7cf8d89412 (diff) | |
| download | rapier-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.rs | 18 | ||||
| -rw-r--r-- | src/dynamics/ccd/toi_entry.rs | 12 | ||||
| -rw-r--r-- | src/dynamics/rigid_body_components.rs | 8 | ||||
| -rw-r--r-- | src/geometry/collider.rs | 67 | ||||
| -rw-r--r-- | src/geometry/collider_components.rs | 115 | ||||
| -rw-r--r-- | src/geometry/collider_set.rs | 5 | ||||
| -rw-r--r-- | src/geometry/narrow_phase.rs | 107 | ||||
| -rw-r--r-- | src/pipeline/collision_pipeline.rs | 6 | ||||
| -rw-r--r-- | src/pipeline/event_handler.rs | 6 | ||||
| -rw-r--r-- | src/pipeline/physics_pipeline.rs | 9 | ||||
| -rw-r--r-- | src/pipeline/query_pipeline.rs | 42 |
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) = |
