From 25a3fbe8123d81e3c6ee16e5a01714b6539fdabd Mon Sep 17 00:00:00 2001 From: i551115 Date: Wed, 30 Apr 2025 09:08:41 +0200 Subject: [PATCH 1/3] fixed bug where collission pipeline doesn't update children colliders of a body --- src/pipeline/collision_pipeline.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/pipeline/collision_pipeline.rs b/src/pipeline/collision_pipeline.rs index b75ca5cd6..0807eb312 100644 --- a/src/pipeline/collision_pipeline.rs +++ b/src/pipeline/collision_pipeline.rs @@ -7,6 +7,7 @@ use crate::geometry::{ }; use crate::math::Real; use crate::pipeline::{EventHandler, PhysicsHooks, QueryPipeline}; +use crate::prelude::{ModifiedRigidBodies, RigidBodyChanges, RigidBodyHandle}; use crate::{dynamics::RigidBodySet, geometry::ColliderSet}; /// The collision pipeline, responsible for performing collision detection between colliders. @@ -109,6 +110,18 @@ impl CollisionPipeline { modified_colliders.clear(); } + fn clear_modified_bodies( + &mut self, + bodies: &mut RigidBodySet, + modified_bodies: &mut ModifiedRigidBodies, + ) { + for handle in modified_bodies.iter() { + if let Some(rb) = bodies.get_mut_internal(*handle) { + rb.changes = RigidBodyChanges::empty(); + } + } + } + /// Executes one step of the collision detection. pub fn step( &mut self, @@ -121,7 +134,7 @@ impl CollisionPipeline { hooks: &dyn PhysicsHooks, events: &dyn EventHandler, ) { - let modified_bodies = bodies.take_modified(); + let mut modified_bodies = bodies.take_modified(); let mut modified_colliders = colliders.take_modified(); let mut removed_colliders = colliders.take_removed(); @@ -166,6 +179,7 @@ impl CollisionPipeline { } self.clear_modified_colliders(colliders, &mut modified_colliders); + self.clear_modified_bodies(bodies, &mut modified_bodies); removed_colliders.clear(); } } From 591d0e841b602a25c4fe707447932b661ffcd0c8 Mon Sep 17 00:00:00 2001 From: i551115 Date: Tue, 13 May 2025 10:02:00 +0200 Subject: [PATCH 2/3] added test for fix --- src/pipeline/collision_pipeline.rs | 48 +++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/pipeline/collision_pipeline.rs b/src/pipeline/collision_pipeline.rs index 0807eb312..c6d1612fb 100644 --- a/src/pipeline/collision_pipeline.rs +++ b/src/pipeline/collision_pipeline.rs @@ -7,7 +7,7 @@ use crate::geometry::{ }; use crate::math::Real; use crate::pipeline::{EventHandler, PhysicsHooks, QueryPipeline}; -use crate::prelude::{ModifiedRigidBodies, RigidBodyChanges, RigidBodyHandle}; +use crate::prelude::{ModifiedRigidBodies, RigidBodyChanges}; use crate::{dynamics::RigidBodySet, geometry::ColliderSet}; /// The collision pipeline, responsible for performing collision detection between colliders. @@ -290,4 +290,50 @@ mod tests { assert!(hit, "No hit found"); } + + #[cfg(feature = "dim2")] + #[test] + fn test_collider_move_with_parent_body_updates_collissions() { + use na::{Isometry2, Rotation2, Translation2}; + + use crate::prelude::*; + let mut rigid_body_set = RigidBodySet::new(); + let mut collider_set = ColliderSet::new(); + + let body = RigidBodyBuilder::fixed().build(); + let body_handle = rigid_body_set.insert(body); + + let collider = ColliderBuilder::ball(1.).build(); + let collider_handle = + collider_set.insert_with_parent(collider, body_handle, &mut rigid_body_set); + + let integration_parameters = IntegrationParameters::default(); + let mut broad_phase = BroadPhaseMultiSap::new(); + let mut narrow_phase = NarrowPhase::new(); + let mut collision_pipeline = CollisionPipeline::default(); + + for i in 1..3 { + let next_position = Translation2::new(i as Real, 0.).vector; + rigid_body_set.get_mut(body_handle).unwrap().set_translation(next_position, false); + + collision_pipeline.step( + integration_parameters.prediction_distance(), + &mut broad_phase, + &mut narrow_phase, + &mut rigid_body_set, + &mut collider_set, + None, + &(), + &(), + ); + + assert_eq!( + collider_set.get(collider_handle).unwrap().position(), + rigid_body_set.get(body_handle).unwrap().position(), + "Collider should be at the same position as the parent body after {i} step" + ); + assert_eq!(collider_set.get(collider_handle).unwrap().position(), &Isometry2::new(next_position, Rotation2::identity().angle())); + } + + } } From 412d1bcfaedc930841165aff8eb83332d9c0e7c2 Mon Sep 17 00:00:00 2001 From: i551115 Date: Thu, 15 May 2025 08:43:57 +0200 Subject: [PATCH 3/3] fixed typo and formatted code --- src/pipeline/collision_pipeline.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pipeline/collision_pipeline.rs b/src/pipeline/collision_pipeline.rs index c6d1612fb..82fbe5512 100644 --- a/src/pipeline/collision_pipeline.rs +++ b/src/pipeline/collision_pipeline.rs @@ -293,7 +293,7 @@ mod tests { #[cfg(feature = "dim2")] #[test] - fn test_collider_move_with_parent_body_updates_collissions() { + fn test_collider_move_with_parent_body_updates_collisions() { use na::{Isometry2, Rotation2, Translation2}; use crate::prelude::*; @@ -314,7 +314,10 @@ mod tests { for i in 1..3 { let next_position = Translation2::new(i as Real, 0.).vector; - rigid_body_set.get_mut(body_handle).unwrap().set_translation(next_position, false); + rigid_body_set + .get_mut(body_handle) + .unwrap() + .set_translation(next_position, false); collision_pipeline.step( integration_parameters.prediction_distance(), @@ -332,8 +335,10 @@ mod tests { rigid_body_set.get(body_handle).unwrap().position(), "Collider should be at the same position as the parent body after {i} step" ); - assert_eq!(collider_set.get(collider_handle).unwrap().position(), &Isometry2::new(next_position, Rotation2::identity().angle())); + assert_eq!( + collider_set.get(collider_handle).unwrap().position(), + &Isometry2::new(next_position, Rotation2::identity().angle()) + ); } - } }