dimforge / rapier

2D and 3D physics engines focused on performance.
https://rapier.rs
Apache License 2.0
3.77k stars 235 forks source link

How to simulate triggers between kinematic and sensor bodies #594

Closed fabiopolimeni closed 1 month ago

fabiopolimeni commented 4 months ago

I have a character controller that is position based an moved like this

let delta = controller.move_shape(
                    dt,
                    &physics.rigid_body_set,
                    &physics.collider_set,
                    &physics.query_pipeline,
                    collider.shape(),
                    &pos.into(),
                    displacement.into(),
                    QueryFilter::new()
                        .exclude_rigid_body(self.rigid_body_handle)
                        .exclude_sensors(),
                    |collision| {
                        collisions.push((
                            self.rigid_body_handle,
                            physics
                                .collider_set
                                .get(collision.handle)
                                .unwrap()
                                .parent()
                                .unwrap(),
                        ));
                    },
                );

What I have to do to ignore the collision against a sensor, is to add the exclude_sensors() from the QueryFilter. Note that the sensor is attached to a fixed rigid body, and according to the documentation, collisions between two non-dynamic rigid bodies, such as the kinematic controller and the fixed body's sensor I have, should never occur. Nevertheless, the character controller is not capable of passing through the sensor, despite being attached to a fixed body.

This would not be a big deal if I could simply ignore sensors with exclude_sensors(), but I still need to receive a collision/intersection event when that happens, essentially to simulate a trigger behaviour. That is not happening with the current configuration I have.

So, my question is, what is the strategy to simulate a trigger behaviour? That is, my character is capable of passing through an object, while still firing some events when I entered/exited the sensor collider. Would I need to use the Intersection Graph? Would I also need to hook up into the solver to modify/ignore contacts? It all seems all a bit more complicated than I expect, I am more inclined to assume I am missing something here, as triggers should not be such a pain to setup. I would appreciated any help thanks.

fabiopolimeni commented 3 months ago

Ok, this is not receiving much love here. Should I repost in Discussions instead? Might me more appropriate?

sebcrozet commented 3 months ago

Sorry, that issue went under the radar.

The QueryFilter provided to the character controller for the character controller update is fairly independent from the logic driving collision-detection during the main physics pipeline stepping. So you could keep your QueryFilter with exclude_sensors() while updating your character controller to obtain the desired motion ignoring sensors, and at the same time set the active collision types of your character controller’s collider to ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_FIXED (or just ActiveCollisionTypes::all()), and its active events to ActiveEvents::COLLISION_EVENTS.

This will enable collision events involving your character controller and your trigger (and other static shapes).

fabiopolimeni commented 3 months ago

Cool, thank you for the hint, I will give it a try soon ;)