Skip to content

Commit

Permalink
Fix contact hooks.
Browse files Browse the repository at this point in the history
They're now per-collider instead of per-pipeline. This may allows some
extra optimizations, which should be looked into.
  • Loading branch information
Demindiro committed Jun 24, 2021
1 parent b13d78a commit 5603456
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 19 deletions.
7 changes: 6 additions & 1 deletion rapier3d/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::space::Space;
use crate::util::*;
use core::convert::{TryFrom, TryInto};
use gdnative::core_types::*;
use rapier3d::prelude::*;
use rapier3d::dynamics::{MassProperties, RigidBody, RigidBodyHandle, RigidBodySet, RigidBodyType};
use rapier3d::geometry::{
Collider, ColliderBuilder, ColliderHandle, InteractionGroups, SharedShape,
Expand Down Expand Up @@ -177,7 +178,9 @@ impl Body {
let shape_scale = iso.rotation * vec_gd_to_na(scl);
let shape_scale = vec_gd_to_na(self_scale).component_mul(&shape_scale);
let shape_scale = vec_na_to_gd(shape_scale);
let collider = shape.build(body_shape.transform, shape_scale, false);
let mut collider = shape.build(body_shape.transform, shape_scale, false);
collider.set_active_hooks(ActiveHooks::FILTER_CONTACT_PAIRS | ActiveHooks::MODIFY_SOLVER_CONTACTS);
collider.set_active_events(ActiveEvents::INTERSECTION_EVENTS);
let collider = space.add_collider(collider, *rb);
colliders.push(Some(collider));
})
Expand Down Expand Up @@ -246,6 +249,8 @@ impl Body {
.collision_groups(self.collision_groups)
.restitution(self.restitution)
.friction(self.friction)
.active_hooks(ActiveHooks::FILTER_CONTACT_PAIRS | ActiveHooks::MODIFY_SOLVER_CONTACTS)
.active_events(ActiveEvents::INTERSECTION_EVENTS)
.build();
collider.user_data = ColliderUserdata::new(
index,
Expand Down
20 changes: 9 additions & 11 deletions rapier3d/src/server/joint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ fn create_hinge(
body_b: Index,
transform_b: &Transform,
) -> Option<Index> {
dbg!("CREATE MEEEEE");
let body_a = if let Index::Body(index) = body_a {
index
} else {
Expand Down Expand Up @@ -191,8 +192,11 @@ fn create_hinge(
}

fn disable_collisions_between_bodies(joint: Index, disable: bool) {
let enable = !disable;
dbg!("I live you shit");
// *disable* collisions = *enable* exclusion
let enable = disable;
map_or_err!(joint, map_joint_mut, |joint, _| {
dbg!(joint.exclude_bodies, enable);
if joint.exclude_bodies != enable {
joint.exclude_bodies = enable;
if let Instance::Attached(joint, space) = joint.joint {
Expand All @@ -204,17 +208,11 @@ fn disable_collisions_between_bodies(joint: Index, disable: bool) {
let b = space.bodies().get(joint.body2).expect("Invalid body B");
let a = body::RigidBodyUserdata::try_from(a).unwrap().index();
let b = body::RigidBodyUserdata::try_from(b).unwrap().index();
let result = if enable {
space.add_body_exclusion(a, b)
// Adding an exclusion multiple times is valid.
if enable {
let _ = space.add_body_exclusion(a, b);
} else {
space.remove_body_exclusion(a, b)
};
if let Err(e) = result {
if enable {
godot_error!("Failed to add bodies: {:?}", e);
} else {
godot_error!("Failed to remove bodies: {:?}", e);
}
let _ = space.remove_body_exclusion(a, b);
}
});
}
Expand Down
20 changes: 13 additions & 7 deletions rapier3d/src/space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ impl Space {

/// Make two bodies not interact with each other.
/// Returns `Ok` if the bodies did not exclude each other already, `Err` otherwise.
pub fn add_body_exclusion(&mut self, index_a: BodyIndex, index_b: BodyIndex) -> Result<(), ()> {
pub fn add_body_exclusion(&mut self, index_a: BodyIndex, index_b: BodyIndex) -> Result<(), ExclusionAlreadyExists> {
self.body_exclusions.add_exclusion(index_a, index_b)
}

Expand All @@ -304,7 +304,7 @@ impl Space {
&mut self,
index_a: BodyIndex,
index_b: BodyIndex,
) -> Result<(), ()> {
) -> Result<(), ExclusionDoesntExist> {
self.body_exclusions.remove_exclusion(index_a, index_b)
}

Expand Down Expand Up @@ -524,6 +524,12 @@ impl Space {
}
}

#[derive(Debug)]
pub struct ExclusionAlreadyExists;

#[derive(Debug)]
pub struct ExclusionDoesntExist;

impl BodyExclusionHooks {
fn new(contacts_sender: Sender<(BodyIndex, body::ContactEvent)>) -> Self {
Self {
Expand All @@ -532,7 +538,7 @@ impl BodyExclusionHooks {
}
}

fn add_exclusion(&mut self, index_a: BodyIndex, index_b: BodyIndex) -> Result<(), ()> {
fn add_exclusion(&mut self, index_a: BodyIndex, index_b: BodyIndex) -> Result<(), ExclusionAlreadyExists> {
// TODO how should we handle self-exclusions? (index_a == index_b)
let (a, b) = (index_a, index_b);
let (a, b) = if a.index() < b.index() {
Expand All @@ -542,7 +548,7 @@ impl BodyExclusionHooks {
};
if let Some(vec) = self.exclusions.get_mut(a.index() as usize) {
if vec.contains(&b) {
Err(())
Err(ExclusionAlreadyExists)
} else {
vec.push(b);
Ok(())
Expand All @@ -557,18 +563,18 @@ impl BodyExclusionHooks {

// TODO implement body_remove_exception and remove the allow
#[allow(dead_code)]
fn remove_exclusion(&mut self, index_a: BodyIndex, index_b: BodyIndex) -> Result<(), ()> {
fn remove_exclusion(&mut self, index_a: BodyIndex, index_b: BodyIndex) -> Result<(), ExclusionDoesntExist> {
let (a, b) = (index_a, index_b);
let (a, b) = if a.index() < b.index() {
(a, b)
} else {
(b, a)
};
if let Some(vec) = self.exclusions.get_mut(a.index() as usize) {
vec.swap_remove(vec.iter().position(|&e| e == b).ok_or(())?);
vec.swap_remove(vec.iter().position(|&e| e == b).ok_or(ExclusionDoesntExist)?);
Ok(())
} else {
Err(())
Err(ExclusionDoesntExist)
}
}
}
Expand Down

0 comments on commit 5603456

Please sign in to comment.