Restore contact events.

This commit is contained in:
Crozet Sébastien
2020-12-31 11:37:42 +01:00
parent 967145a949
commit 1feac2e02d
2 changed files with 24 additions and 16 deletions

View File

@@ -62,6 +62,7 @@ pub struct ContactPair {
/// ///
/// All contact manifold contain themselves contact points between the colliders. /// All contact manifold contain themselves contact points between the colliders.
pub manifolds: Vec<ContactManifold>, pub manifolds: Vec<ContactManifold>,
pub has_any_active_contact: bool,
pub(crate) workspace: Option<ContactManifoldsWorkspace>, pub(crate) workspace: Option<ContactManifoldsWorkspace>,
} }
@@ -69,23 +70,11 @@ impl ContactPair {
pub(crate) fn new(pair: ColliderPair) -> Self { pub(crate) fn new(pair: ColliderPair) -> Self {
Self { Self {
pair, pair,
has_any_active_contact: false,
manifolds: Vec::new(), manifolds: Vec::new(),
workspace: None, workspace: None,
} }
} }
/// Does this contact pair have any active contact?
///
/// An active contact is a contact that may result in a non-zero contact force.
pub fn has_any_active_contact(&self) -> bool {
for manifold in &self.manifolds {
if manifold.data.num_active_contacts() != 0 {
return true;
}
}
false
}
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]

View File

@@ -369,7 +369,7 @@ impl NarrowPhase {
// Emit a contact stopped event if we had a contact before removing the edge. // Emit a contact stopped event if we had a contact before removing the edge.
// Also wake up the dynamic bodies that were in contact. // Also wake up the dynamic bodies that were in contact.
if let Some(ctct) = contact_pair { if let Some(ctct) = contact_pair {
if ctct.has_any_active_contact() { if ctct.has_any_active_contact {
bodies.wake_up(co1.parent, true); bodies.wake_up(co1.parent, true);
bodies.wake_up(co2.parent, true); bodies.wake_up(co2.parent, true);
@@ -524,14 +524,16 @@ impl NarrowPhase {
&mut pair.workspace, &mut pair.workspace,
); );
// TODO: don't write this everytime? let mut has_any_active_contact = false;
for manifold in &mut pair.manifolds { for manifold in &mut pair.manifolds {
manifold.data.solver_contacts.clear(); manifold.data.solver_contacts.clear();
manifold.data.body_pair = BodyPair::new(co1.parent(), co2.parent()); manifold.data.body_pair = BodyPair::new(co1.parent(), co2.parent());
manifold.data.solver_flags = solver_flags; manifold.data.solver_flags = solver_flags;
manifold.data.normal = co1.position() * manifold.local_n1; manifold.data.normal = co1.position() * manifold.local_n1;
// Sort contacts and generate solver contacts. // Sort contacts to keep only these with distances bellow
// the prediction, and generate solver contacts.
let mut first_inactive_index = manifold.points.len(); let mut first_inactive_index = manifold.points.len();
while manifold.data.num_active_contacts() != first_inactive_index { while manifold.data.num_active_contacts() != first_inactive_index {
@@ -551,6 +553,7 @@ impl NarrowPhase {
// TODO: apply the user-defined contact modification/removal, if needed. // TODO: apply the user-defined contact modification/removal, if needed.
manifold.data.solver_contacts.push(solver_contact); manifold.data.solver_contacts.push(solver_contact);
has_any_active_contact = true;
continue; continue;
} }
@@ -563,6 +566,22 @@ impl NarrowPhase {
first_inactive_index -= 1; first_inactive_index -= 1;
} }
} }
if has_any_active_contact != pair.has_any_active_contact {
if has_any_active_contact {
events.handle_contact_event(ContactEvent::Started(
pair.pair.collider1,
pair.pair.collider2,
));
} else {
events.handle_contact_event(ContactEvent::Stopped(
pair.pair.collider1,
pair.pair.collider2,
));
}
pair.has_any_active_contact = has_any_active_contact;
}
}); });
} }