-
-
Notifications
You must be signed in to change notification settings - Fork 273
Open
Description
Let's talk about adding send collision events and contact force to observers.
I think this can be added into src/plugin/context/mod.rs in RapierContextSimulation::send_bevy_events.
We can declare new events, maybe something like this:
/// Event occurring when two colliders start colliding
/// This will only get triggered if the entity has the
/// [`ActiveEvents::COLLISION_EVENTS`] flag enabled.
#[derive(Event, Copy, Clone, Debug, PartialEq, Eq)]
pub struct CollisionStarted {
pub collider: Entity,
pub flags: CollisionEventFlags,
}
/// Event occurring when two colliders stop colliding
/// This will only get triggered if the entity has the
/// [`ActiveEvents::COLLISION_EVENTS`] flag enabled.
#[derive(Event, Copy, Clone, Debug, PartialEq, Eq)]
pub struct CollisionStopped {
pub collider: Entity,
pub flags: CollisionEventFlags,
}
/// Event occurring when the sum of the magnitudes of the contact forces
/// between two colliders exceed a threshold ([`ContactForceEventThreshold`]).
///
/// This will only get triggered if the entity has the
/// [`ActiveEvents::CONTACT_FORCE_EVENTS`] flag enabled.
#[derive(Event, Copy, Clone, Debug, PartialEq)]
pub struct ContactForce {
/// Collider involved in the contact.
pub collider: Entity,
/// The sum of all the forces between the two colliders.
pub total_force: Vect,
/// The sum of the magnitudes of each force between the two colliders.
///
/// Note that this is **not** the same as the magnitude of `self.total_force`.
/// Here we are summing the magnitude of all the forces, instead of taking
/// the magnitude of their sum.
pub total_force_magnitude: Real,
/// The world-space (unit) direction of the force with strongest magnitude.
pub max_force_direction: Vect,
/// The magnitude of the largest force at a contact point of this contact pair.
pub max_force_magnitude: Real,
}Then use this new events in src/plugin/context/mod.rs in RapierContextSimulation::send_bevy_events:
/// Generates bevy events for any physics interactions that have happened
/// that are stored in the events list
pub fn send_bevy_events(
&mut self,
commands: &mut Commands,
collision_event_writer: &mut EventWriter<CollisionEvent>,
contact_force_event_writer: &mut EventWriter<ContactForceEvent>,
) {
for collision_event in self.collision_events_to_send.drain(..) {
collision_event_writer.send(collision_event);
match collision_event {
CollisionEvent::Started(entity1, entity2, flags) => {
commands.trigger_targets(
CollisionStarted {
collider: entity2,
flags,
},
entity1,
);
commands.trigger_targets(
CollisionStarted {
collider: entity1,
flags,
},
entity2,
);
}
CollisionEvent::Stopped(entity1, entity2, flags) => {
commands.trigger_targets(
CollisionStopped {
collider: entity2,
flags,
},
entity1,
);
commands.trigger_targets(
CollisionStopped {
collider: entity1,
flags,
},
entity2,
);
}
}
}
for contact_force_event in self.contact_force_events_to_send.drain(..) {
contact_force_event_writer.send(contact_force_event);
commands.trigger_targets(
ContactForce {
collider: contact_force_event.collider2,
total_force: contact_force_event.total_force,
total_force_magnitude: contact_force_event.total_force_magnitude,
max_force_direction: contact_force_event.max_force_direction,
max_force_magnitude: contact_force_event.max_force_magnitude,
},
contact_force_event.collider1,
);
commands.trigger_targets(
ContactForce {
collider: contact_force_event.collider1,
total_force: contact_force_event.total_force,
total_force_magnitude: contact_force_event.total_force_magnitude,
max_force_direction: contact_force_event.max_force_direction,
max_force_magnitude: contact_force_event.max_force_magnitude,
},
contact_force_event.collider2,
);
}
}This may not be the best place to do it, but we need to start this discussion.
ThierryBerger
Metadata
Metadata
Assignees
Labels
No labels