aboutsummaryrefslogtreecommitdiff
path: root/src/pipeline
diff options
context:
space:
mode:
Diffstat (limited to 'src/pipeline')
-rw-r--r--src/pipeline/collision_pipeline.rs10
-rw-r--r--src/pipeline/event_handler.rs25
-rw-r--r--src/pipeline/mod.rs6
-rw-r--r--src/pipeline/physics_hooks.rs69
-rw-r--r--src/pipeline/physics_pipeline.rs56
-rw-r--r--src/pipeline/query_pipeline.rs42
-rw-r--r--src/pipeline/user_changes.rs3
7 files changed, 139 insertions, 72 deletions
diff --git a/src/pipeline/collision_pipeline.rs b/src/pipeline/collision_pipeline.rs
index 455e75d..d789da7 100644
--- a/src/pipeline/collision_pipeline.rs
+++ b/src/pipeline/collision_pipeline.rs
@@ -6,7 +6,7 @@ use crate::dynamics::{
RigidBodyIds, RigidBodyPosition, RigidBodyType, RigidBodyVelocity,
};
use crate::geometry::{
- BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderGroups,
+ BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderFlags,
ColliderHandle, ColliderMaterial, ColliderPair, ColliderParent, ColliderPosition,
ColliderShape, ColliderType, NarrowPhase,
};
@@ -65,8 +65,8 @@ impl CollisionPipeline {
+ ComponentSet<ColliderShape>
+ ComponentSetOption<ColliderParent>
+ ComponentSet<ColliderType>
- + ComponentSet<ColliderGroups>
- + ComponentSet<ColliderMaterial>,
+ + ComponentSet<ColliderMaterial>
+ + ComponentSet<ColliderFlags>,
{
// Update broad-phase.
self.broad_phase_events.clear();
@@ -172,8 +172,8 @@ impl CollisionPipeline {
+ ComponentSet<ColliderShape>
+ ComponentSetOption<ColliderParent>
+ ComponentSet<ColliderType>
- + ComponentSet<ColliderGroups>
- + ComponentSet<ColliderMaterial>,
+ + ComponentSet<ColliderMaterial>
+ + ComponentSet<ColliderFlags>,
{
super::user_changes::handle_user_changes_to_colliders(
bodies,
diff --git a/src/pipeline/event_handler.rs b/src/pipeline/event_handler.rs
index 9d7b17a..c54acc2 100644
--- a/src/pipeline/event_handler.rs
+++ b/src/pipeline/event_handler.rs
@@ -1,6 +1,23 @@
-use crate::geometry::{ContactEvent, IntersectionEvent};
+use crate::geometry::{ContactEvent, ContactPair, IntersectionEvent};
use crossbeam::channel::Sender;
+bitflags::bitflags! {
+ #[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
+ /// Flags affecting the events generated for this collider.
+ pub struct ActiveEvents: u32 {
+ /// If set, Rapier will call `EventHandler::handle_intersection_event` whenever relevant for this collider.
+ const INTERSECTION_EVENTS = 0b0001;
+ /// If set, Rapier will call `PhysicsHooks::handle_contact_event` whenever relevant for this collider.
+ const CONTACT_EVENTS = 0b0010;
+ }
+}
+
+impl Default for ActiveEvents {
+ fn default() -> Self {
+ ActiveEvents::empty()
+ }
+}
+
/// Trait implemented by structures responsible for handling events generated by the physics engine.
///
/// Implementors of this trait will typically collect these events for future processing.
@@ -13,12 +30,12 @@ pub trait EventHandler: Send + Sync {
///
/// A contact event is emitted when two collider start or stop touching, independently from the
/// number of contact points involved.
- fn handle_contact_event(&self, event: ContactEvent);
+ fn handle_contact_event(&self, event: ContactEvent, contact_pair: &ContactPair);
}
impl EventHandler for () {
fn handle_intersection_event(&self, _event: IntersectionEvent) {}
- fn handle_contact_event(&self, _event: ContactEvent) {}
+ fn handle_contact_event(&self, _event: ContactEvent, _contact_pair: &ContactPair) {}
}
/// A physics event handler that collects events into a crossbeam channel.
@@ -45,7 +62,7 @@ impl EventHandler for ChannelEventCollector {
let _ = self.intersection_event_sender.send(event);
}
- fn handle_contact_event(&self, event: ContactEvent) {
+ fn handle_contact_event(&self, event: ContactEvent, _: &ContactPair) {
let _ = self.contact_event_sender.send(event);
}
}
diff --git a/src/pipeline/mod.rs b/src/pipeline/mod.rs
index ad288d6..2c0393e 100644
--- a/src/pipeline/mod.rs
+++ b/src/pipeline/mod.rs
@@ -1,10 +1,8 @@
//! Structure for combining the various physics components to perform an actual simulation.
pub use collision_pipeline::CollisionPipeline;
-pub use event_handler::{ChannelEventCollector, EventHandler};
-pub use physics_hooks::{
- ContactModificationContext, PairFilterContext, PhysicsHooks, PhysicsHooksFlags,
-};
+pub use event_handler::{ActiveEvents, ChannelEventCollector, EventHandler};
+pub use physics_hooks::{ActiveHooks, ContactModificationContext, PairFilterContext, PhysicsHooks};
pub use physics_pipeline::PhysicsPipeline;
pub use query_pipeline::{QueryPipeline, QueryPipelineMode};
diff --git a/src/pipeline/physics_hooks.rs b/src/pipeline/physics_hooks.rs
index c4ef245..68a05d1 100644
--- a/src/pipeline/physics_hooks.rs
+++ b/src/pipeline/physics_hooks.rs
@@ -118,30 +118,54 @@ impl<'a, Bodies, Colliders> ContactModificationContext<'a, Bodies, Colliders> {
bitflags::bitflags! {
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
/// Flags affecting the behavior of the constraints solver for a given contact manifold.
- pub struct PhysicsHooksFlags: u32 {
+ pub struct ActiveHooks: u32 {
/// If set, Rapier will call `PhysicsHooks::filter_contact_pair` whenever relevant.
- const FILTER_CONTACT_PAIR = 0b0001;
+ const FILTER_CONTACT_PAIRS = 0b0001;
/// If set, Rapier will call `PhysicsHooks::filter_intersection_pair` whenever relevant.
const FILTER_INTERSECTION_PAIR = 0b0010;
/// If set, Rapier will call `PhysicsHooks::modify_solver_contact` whenever relevant.
const MODIFY_SOLVER_CONTACTS = 0b0100;
}
}
-impl Default for PhysicsHooksFlags {
+impl Default for ActiveHooks {
fn default() -> Self {
- PhysicsHooksFlags::empty()
+ ActiveHooks::empty()
}
}
+// TODO: right now, the wasm version don't have the Send+Sync bounds.
+// This is because these bounds are very difficult to fulfill if we want to
+// call JS closures. Also, parallelism cannot be enabled for wasm targets, so
+// not having Send+Sync isn't a problem.
/// User-defined functions called by the physics engines during one timestep in order to customize its behavior.
-pub trait PhysicsHooks<Bodies, Colliders>: Send + Sync {
- /// The sets of hooks that must be taken into account.
- fn active_hooks(&self) -> PhysicsHooksFlags;
+#[cfg(target_arch = "wasm32")]
+pub trait PhysicsHooks<Bodies, Colliders> {
+ /// Applies the contact pair filter.
+ fn filter_contact_pair(
+ &self,
+ _context: &PairFilterContext<Bodies, Colliders>,
+ ) -> Option<SolverFlags> {
+ None
+ }
+
+ /// Applies the intersection pair filter.
+ fn filter_intersection_pair(&self, _context: &PairFilterContext<Bodies, Colliders>) -> bool {
+ false
+ }
+
+ /// Modifies the set of contacts seen by the constraints solver.
+ fn modify_solver_contacts(&self, _context: &mut ContactModificationContext<Bodies, Colliders>) {
+ }
+}
+/// User-defined functions called by the physics engines during one timestep in order to customize its behavior.
+#[cfg(not(target_arch = "wasm32"))]
+pub trait PhysicsHooks<Bodies, Colliders>: Send + Sync {
/// Applies the contact pair filter.
///
- /// Note that this method will only be called if `self.active_hooks()`
- /// contains the `PhysicsHooksFlags::FILTER_CONTACT_PAIR` flags.
+ /// Note that this method will only be called if at least one of the colliders
+ /// involved in the contact contains the `ActiveHooks::FILTER_CONTACT_PAIRS` flags
+ /// in its physics hooks flags.
///
/// User-defined filter for potential contact pairs detected by the broad-phase.
/// This can be used to apply custom logic in order to decide whether two colliders
@@ -165,13 +189,14 @@ pub trait PhysicsHooks<Bodies, Colliders>: Send + Sync {
&self,
_context: &PairFilterContext<Bodies, Colliders>,
) -> Option<SolverFlags> {
- None
+ Some(SolverFlags::COMPUTE_IMPULSES)
}
/// Applies the intersection pair filter.
///
- /// Note that this method will only be called if `self.active_hooks()`
- /// contains the `PhysicsHooksFlags::FILTER_INTERSECTION_PAIR` flags.
+ /// Note that this method will only be called if at least one of the colliders
+ /// involved in the contact contains the `ActiveHooks::FILTER_INTERSECTION_PAIR` flags
+ /// in its physics hooks flags.
///
/// User-defined filter for potential intersection pairs detected by the broad-phase.
///
@@ -188,13 +213,14 @@ pub trait PhysicsHooks<Bodies, Colliders>: Send + Sync {
/// If this return `true` then the narrow-phase will compute intersection
/// information for this pair.
fn filter_intersection_pair(&self, _context: &PairFilterContext<Bodies, Colliders>) -> bool {
- false
+ true
}
/// Modifies the set of contacts seen by the constraints solver.
///
- /// Note that this method will only be called if `self.active_hooks()`
- /// contains the `PhysicsHooksFlags::MODIFY_SOLVER_CONTACTS` flags.
+ /// Note that this method will only be called if at least one of the colliders
+ /// involved in the contact contains the `ActiveHooks::MODIFY_SOLVER_CONTACTS` flags
+ /// in its physics hooks flags.
///
/// By default, the content of `solver_contacts` is computed from `manifold.points`.
/// This method will be called on each contact manifold which have the flag `SolverFlags::modify_solver_contacts` set.
@@ -220,16 +246,15 @@ pub trait PhysicsHooks<Bodies, Colliders>: Send + Sync {
}
impl<Bodies, Colliders> PhysicsHooks<Bodies, Colliders> for () {
- fn active_hooks(&self) -> PhysicsHooksFlags {
- PhysicsHooksFlags::empty()
- }
-
- fn filter_contact_pair(&self, _: &PairFilterContext<Bodies, Colliders>) -> Option<SolverFlags> {
- None
+ fn filter_contact_pair(
+ &self,
+ _context: &PairFilterContext<Bodies, Colliders>,
+ ) -> Option<SolverFlags> {
+ Some(SolverFlags::default())
}
fn filter_intersection_pair(&self, _: &PairFilterContext<Bodies, Colliders>) -> bool {
- false
+ true
}
fn modify_solver_contacts(&self, _: &mut ContactModificationContext<Bodies, Colliders>) {}
diff --git a/src/pipeline/physics_pipeline.rs b/src/pipeline/physics_pipeline.rs
index 2f2a95d..a83240e 100644
--- a/src/pipeline/physics_pipeline.rs
+++ b/src/pipeline/physics_pipeline.rs
@@ -13,7 +13,7 @@ use crate::dynamics::{
#[cfg(feature = "parallel")]
use crate::dynamics::{JointGraphEdge, ParallelIslandSolver as IslandSolver};
use crate::geometry::{
- BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderGroups,
+ BroadPhase, BroadPhasePairEvent, ColliderBroadPhaseData, ColliderChanges, ColliderFlags,
ColliderHandle, ColliderMaterial, ColliderPair, ColliderParent, ColliderPosition,
ColliderShape, ColliderType, ContactManifoldIndex, NarrowPhase,
};
@@ -103,8 +103,8 @@ impl PhysicsPipeline {
+ ComponentSet<ColliderShape>
+ ComponentSetOption<ColliderParent>
+ ComponentSet<ColliderType>
- + ComponentSet<ColliderGroups>
- + ComponentSet<ColliderMaterial>,
+ + ComponentSet<ColliderMaterial>
+ + ComponentSet<ColliderFlags>,
{
self.counters.stages.collision_detection_time.resume();
self.counters.cd.broad_phase_time.resume();
@@ -365,7 +365,8 @@ impl PhysicsPipeline {
Colliders: ComponentSetOption<ColliderParent>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>
- + ComponentSet<ColliderType>,
+ + ComponentSet<ColliderType>
+ + ComponentSet<ColliderFlags>,
{
self.counters.ccd.toi_computation_time.start();
// Handle CCD
@@ -428,7 +429,10 @@ impl PhysicsPipeline {
islands: &IslandManager,
bodies: &mut Bodies,
) where
- Bodies: ComponentSetMut<RigidBodyVelocity> + ComponentSet<RigidBodyPosition>,
+ Bodies: ComponentSetMut<RigidBodyVelocity>
+ + ComponentSetMut<RigidBodyPosition>
+ + ComponentSet<RigidBodyType>
+ + ComponentSet<RigidBodyMassProps>,
{
// Update kinematic bodies velocities.
// TODO: what is the best place for this? It should at least be
@@ -436,9 +440,31 @@ impl PhysicsPipeline {
// there to determine if this kinematic body should wake-up dynamic
// bodies it is touching.
for handle in islands.active_kinematic_bodies() {
- let ppos: &RigidBodyPosition = bodies.index(handle.0);
- let new_vel = ppos.interpolate_velocity(integration_parameters.inv_dt());
- bodies.set_internal(handle.0, new_vel);
+ let (rb_type, rb_pos, rb_vel, rb_mprops): (
+ &RigidBodyType,
+ &RigidBodyPosition,
+ &RigidBodyVelocity,
+ &RigidBodyMassProps,
+ ) = bodies.index_bundle(handle.0);
+
+ match rb_type {
+ RigidBodyType::KinematicPositionBased => {
+ let rb_pos: &RigidBodyPosition = bodies.index(handle.0);
+ let new_vel = rb_pos.interpolate_velocity(integration_parameters.inv_dt());
+ bodies.set_internal(handle.0, new_vel);
+ }
+ RigidBodyType::KinematicVelocityBased => {
+ let new_pos = rb_vel.integrate(
+ integration_parameters.dt,
+ &rb_pos.position,
+ // NOTE: we don't use the `world_com` here because it is not
+ // really updated for kinematic bodies.
+ &(rb_pos.position * rb_mprops.local_mprops.local_com),
+ );
+ bodies.set_internal(handle.0, RigidBodyPosition::from(new_pos));
+ }
+ _ => {}
+ }
}
}
@@ -519,8 +545,8 @@ impl PhysicsPipeline {
+ ComponentSet<ColliderShape>
+ ComponentSetOption<ColliderParent>
+ ComponentSet<ColliderType>
- + ComponentSet<ColliderGroups>
- + ComponentSet<ColliderMaterial>,
+ + ComponentSet<ColliderMaterial>
+ + ComponentSet<ColliderFlags>,
{
self.counters.reset();
self.counters.step_started();
@@ -719,12 +745,12 @@ mod test {
let rb = RigidBodyBuilder::new_static().build();
let h1 = bodies.insert(rb.clone());
let co = ColliderBuilder::ball(10.0).build();
- colliders.insert(co.clone(), h1, &mut bodies);
+ colliders.insert_with_parent(co.clone(), h1, &mut bodies);
// The same but with a kinematic body.
- let rb = RigidBodyBuilder::new_kinematic().build();
+ let rb = RigidBodyBuilder::new_kinematic_position_based().build();
let h2 = bodies.insert(rb.clone());
- colliders.insert(co, h2, &mut bodies);
+ colliders.insert_with_parent(co, h2, &mut bodies);
pipeline.step(
&Vector::zeros(),
@@ -760,7 +786,7 @@ mod test {
let h2 = bodies.insert(rb.clone());
// The same but with a kinematic body.
- let rb = RigidBodyBuilder::new_kinematic().build();
+ let rb = RigidBodyBuilder::new_kinematic_position_based().build();
let h3 = bodies.insert(rb.clone());
// The same but with a static body.
@@ -838,7 +864,7 @@ mod test {
let body = RigidBodyBuilder::new_dynamic().build();
let b_handle = bodies.insert(body);
let collider = ColliderBuilder::ball(1.0).build();
- let c_handle = colliders.insert(collider, b_handle, &mut bodies);
+ let c_handle = colliders.insert_with_parent(collider, b_handle, &mut bodies);
colliders.remove(c_handle, &mut islands, &mut bodies, true);
bodies.remove(b_handle, &mut islands, &mut colliders, &mut joints);
diff --git a/src/pipeline/query_pipeline.rs b/src/pipeline/query_pipeline.rs
index 31bf3a4..733d767 100644
--- a/src/pipeline/query_pipeline.rs
+++ b/src/pipeline/query_pipeline.rs
@@ -4,7 +4,7 @@ use crate::dynamics::{
RigidBodyVelocity,
};
use crate::geometry::{
- ColliderGroups, ColliderHandle, ColliderParent, ColliderPosition, ColliderShape,
+ ColliderFlags, ColliderHandle, ColliderParent, ColliderPosition, ColliderShape,
InteractionGroups, PointProjection, Ray, RayIntersection, AABB, QBVH,
};
use crate::math::{Isometry, Point, Real, Vector};
@@ -67,7 +67,7 @@ impl<'a, Colliders> TypedSimdCompositeShape for QueryPipelineAsCompositeShape<'a
where
// TODO ECS: make everything optional but the shape?
Colliders:
- ComponentSet<ColliderGroups> + ComponentSet<ColliderPosition> + ComponentSet<ColliderShape>,
+ ComponentSet<ColliderFlags> + ComponentSet<ColliderPosition> + ComponentSet<ColliderShape>,
{
type PartShape = dyn Shape;
type PartId = ColliderHandle;
@@ -77,10 +77,10 @@ where
shape_id: Self::PartId,
mut f: impl FnMut(Option<&Isometry<Real>>, &Self::PartShape),
) {
- let co_groups: Option<&ColliderGroups> = self.colliders.get(shape_id.0);
+ let co_flags: Option<&ColliderFlags> = self.colliders.get(shape_id.0);
- if let Some(co_groups) = co_groups {
- if co_groups.collision_groups.test(self.query_groups)
+ if let Some(co_flags) = co_flags {
+ if co_flags.collision_groups.test(self.query_groups)
&& self.filter.map(|f| f(shape_id)).unwrap_or(true)
{
let (co_pos, co_shape): (&ColliderPosition, &ColliderShape) =
@@ -384,7 +384,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
) -> Option<(ColliderHandle, Real)>
where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -420,7 +420,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
) -> Option<(ColliderHandle, RayIntersection)>
where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -463,16 +463,16 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
mut callback: impl FnMut(ColliderHandle, RayIntersection) -> bool,
) where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
let mut leaf_callback = &mut |handle: &ColliderHandle| {
let co_shape: Option<&ColliderShape> = colliders.get(handle.0);
if let Some(co_shape) = co_shape {
- let (co_groups, co_pos): (&ColliderGroups, &ColliderPosition) =
+ let (co_flags, co_pos): (&ColliderFlags, &ColliderPosition) =
colliders.index_bundle(handle.0);
- if co_groups.collision_groups.test(query_groups)
+ if co_flags.collision_groups.test(query_groups)
&& filter.map(|f| f(*handle)).unwrap_or(true)
{
if let Some(hit) = co_shape.cast_ray_and_get_normal(co_pos, ray, max_toi, solid)
@@ -509,7 +509,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
) -> Option<ColliderHandle>
where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -550,7 +550,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
) -> Option<(ColliderHandle, PointProjection)>
where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -583,7 +583,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
mut callback: impl FnMut(ColliderHandle) -> bool,
) where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -591,10 +591,10 @@ impl QueryPipeline {
let co_shape: Option<&ColliderShape> = colliders.get(handle.0);
if let Some(co_shape) = co_shape {
- let (co_groups, co_pos): (&ColliderGroups, &ColliderPosition) =
+ let (co_flags, co_pos): (&ColliderFlags, &ColliderPosition) =
colliders.index_bundle(handle.0);
- if co_groups.collision_groups.test(query_groups)
+ if co_flags.collision_groups.test(query_groups)
&& filter.map(|f| f(*handle)).unwrap_or(true)
&& co_shape.contains_point(co_pos, point)
{
@@ -635,7 +635,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
) -> Option<(ColliderHandle, PointProjection, FeatureId)>
where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -685,7 +685,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
) -> Option<(ColliderHandle, TOI)>
where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -733,7 +733,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
) -> Option<(ColliderHandle, TOI)>
where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -774,7 +774,7 @@ impl QueryPipeline {
filter: Option<&dyn Fn(ColliderHandle) -> bool>,
mut callback: impl FnMut(ColliderHandle) -> bool,
) where
- Colliders: ComponentSet<ColliderGroups>
+ Colliders: ComponentSet<ColliderFlags>
+ ComponentSet<ColliderPosition>
+ ComponentSet<ColliderShape>,
{
@@ -785,10 +785,10 @@ impl QueryPipeline {
let co_shape: Option<&ColliderShape> = colliders.get(handle.0);
if let Some(co_shape) = co_shape {
- let (co_groups, co_pos): (&ColliderGroups, &ColliderPosition) =
+ let (co_flags, co_pos): (&ColliderFlags, &ColliderPosition) =
colliders.index_bundle(handle.0);
- if co_groups.collision_groups.test(query_groups)
+ if co_flags.collision_groups.test(query_groups)
&& filter.map(|f| f(*handle)).unwrap_or(true)
{
let pos12 = inv_shape_pos * co_pos.as_ref();
diff --git a/src/pipeline/user_changes.rs b/src/pipeline/user_changes.rs
index 99c5cfe..699361c 100644
--- a/src/pipeline/user_changes.rs
+++ b/src/pipeline/user_changes.rs
@@ -100,7 +100,8 @@ pub(crate) fn handle_user_changes_to_rigid_bodies<Bodies, Colliders>(
// the active_dynamic_set.
changes.set(RigidBodyChanges::SLEEP, true);
}
- RigidBodyType::Kinematic => {
+ RigidBodyType::KinematicVelocityBased
+ | RigidBodyType::KinematicPositionBased => {
// Remove from the active dynamic set if it was there.
if islands.active_dynamic_set.get(ids.active_set_id) == Some(&handle) {
islands.active_dynamic_set.swap_remove(ids.active_set_id);