use rapier3d::prelude::*;
fn has_active_contact(world: &PhysicsWorld, c1: ColliderHandle, c2: ColliderHandle) -> bool {
world
.contact_pair(c1, c2)
.is_some_and(|pair| pair.has_any_active_contact())
}
#[test]
fn reparenting_updates_narrow_phase_state() {
let mut world = PhysicsWorld::new();
world.gravity = Vector::new(0.0, 0.0, 0.0);
let body1 = world.insert_body(RigidBodyBuilder::dynamic());
let c1 = world.insert_collider(
ColliderBuilder::ball(1.0).solver_groups(InteractionGroups::none()),
Some(body1),
);
let body2 = world.insert_body(RigidBodyBuilder::fixed());
let c2 = world.insert_collider(
ColliderBuilder::ball(1.0).translation(Vector::new(0.5, 0.0, 0.0)),
Some(body2),
);
for _ in 0..3 {
world.step();
}
assert!(
has_active_contact(&world, c1, c2),
"overlapping colliders on different bodies must collide"
);
world
.colliders
.set_parent(c2, Some(body1), &mut world.bodies);
world.step();
assert!(
!has_active_contact(&world, c1, c2),
"same-parent colliders must not collide after reparenting"
);
for _ in 0..3 {
world.step();
}
assert!(!has_active_contact(&world, c1, c2));
world
.colliders
.set_parent(c2, Some(body2), &mut world.bodies);
for _ in 0..2 {
world.step();
}
assert!(
has_active_contact(&world, c1, c2),
"contact not re-discovered after reparenting back onto separate bodies"
);
}