New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug with CollisionEvent::Stopped events after removal if a sensor is involved #330
Comments
Hi! Do you have an example for us to reproduce this inconsistency? |
Hi! Not yet, I observed it in a larger project only. I'll try to construct a minimal example using the testbed. |
I quickly hacked something together based on the sensor3 example that should do the job - see below. The green marked cubes have the handle indices: 34, 44, 54, 64, 74.
The sensor has body handle index 101 / collider index 102:
After 3 seconds, the above green marked cubes are removed. The resulting 3 STOPPED events are strange:
While the first one seems correct, the other ones have wrong handles of bodies that weren't removed (78, 56). Also, two STOPPED events are missing completely. use rapier3d::prelude::*;
use rapier_testbed3d::{Testbed, TestbedApp};
pub fn init_world(testbed: &mut Testbed) {
/*
* World
*/
let mut bodies = RigidBodySet::new();
let mut colliders = ColliderSet::new();
let impulse_joints = ImpulseJointSet::new();
let multibody_joints = MultibodyJointSet::new();
/*
* Ground.
*/
let ground_size = 200.1;
let ground_height = 0.1;
let rigid_body = RigidBodyBuilder::fixed().translation(vector![0.0, -ground_height, 0.0]);
let ground_handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(ground_size, ground_height, ground_size);
colliders.insert_with_parent(collider, ground_handle, &mut bodies);
/*
* Create some boxes.
*/
let num = 10;
let rad = 0.2;
let shift = rad * 2.0;
let centerx = shift * num as f32 / 2.0;
let centerz = shift * num as f32 / 2.0;
let mut test_cubes = Vec::new();
for i in 0usize..num {
for k in 0usize..num {
let x = i as f32 * shift - centerx;
let y = 3.0;
let z = k as f32 * shift - centerz;
// Build the rigid body.
let rigid_body = RigidBodyBuilder::dynamic().translation(vector![x, y, z]);
let handle = bodies.insert(rigid_body);
let collider = ColliderBuilder::cuboid(rad, rad, rad);
let collider_handle = colliders.insert_with_parent(collider, handle, &mut bodies);
testbed.set_initial_body_color(handle, [0.5, 0.5, 1.0]);
if i >= 3 && i <= 7 && k == 3 {
println!("cube body handle: {:?}", handle);
println!("cube collider handle: {:?}", collider_handle);
test_cubes.push(handle);
testbed.set_initial_body_color(handle, [0.0, 1.0, 0.0]);
}
}
}
println!("============");
/*
* Create a cube that will have a ball-shaped sensor attached.
*/
// Rigid body so that the sensor can move.
let sensor = RigidBodyBuilder::dynamic().translation(vector![0.0, 5.0, 0.0]);
let sensor_handle = bodies.insert(sensor);
println!("sensor handle: {:?}", sensor_handle);
// Solid cube attached to the sensor which
// other colliders can touch.
let collider = ColliderBuilder::cuboid(rad, rad, rad);
colliders.insert_with_parent(collider, sensor_handle, &mut bodies);
// We create a collider desc without density because we don't
// want it to contribute to the rigid body mass.
let sensor_collider = ColliderBuilder::ball(rad * 5.0)
.density(0.0)
.sensor(true)
.active_events(ActiveEvents::COLLISION_EVENTS);
let sensor_collider_handle =
colliders.insert_with_parent(sensor_collider, sensor_handle, &mut bodies);
println!("sensor collider handle: {:?}", sensor_collider_handle);
println!("==============");
testbed.set_initial_body_color(sensor_handle, [0.5, 1.0, 1.0]);
let mut done = false;
// Callback that will be executed on the main loop to handle proximities.
testbed.add_callback(move |_, physics, events, run_state| {
while let Ok(prox) = events.events.try_recv() {
if prox.removed() {
println!("removed!");
println!("collider handle 1: {:?}", prox.collider1());
println!("collider handle 2: {:?}", prox.collider2());
}
}
if run_state.time >= 3.0 && !done {
done = true;
for test_cube in &test_cubes {
physics.bodies.remove(
*test_cube,
&mut physics.islands,
&mut physics.colliders,
&mut physics.impulse_joints,
&mut physics.multibody_joints,
true,
);
}
}
});
/*
* Set up the testbed.
*/
testbed.set_world(bodies, colliders, impulse_joints, multibody_joints);
testbed.look_at(point![-6.0, 4.0, -6.0], point![0.0, 1.0, 0.0]);
}
pub fn main() {
let testbedapp = TestbedApp::from_builders(0, vec![("test", init_world)]);
testbedapp.run()
} |
Thank you for the code reproducing the bug. This will be fixed by #337. |
Rapier 0.12.0 introduced the emission of
CollisionEvent::Stopped
events after a collider is removed.This seems to work for non-sensor collisions. But for contacts where the other (non-removed) collider is a sensor, stopped events are either missing or wrong.
By wrong I mean: the stopped events point to uninvolved contacts and to collider handles that haven't been removed at all, while the
CollisionEventFlags::REMOVED
flag still being set in these events.The text was updated successfully, but these errors were encountered: