-
-
Notifications
You must be signed in to change notification settings - Fork 302
Open
Description
From the code in NarrowPhase::compute_contacts
, I get the impression that if there's more than one joint between two objects, it's supposed to disregard the contact if any of the joints have contacts_enabled
set to false. However, that isn't how it behaves in practice; it seems to only check contacts_enabled
for the most recently added joint.
My best guess is that something is wrong with ImpulseJointSet::joints_between
: even if there's more than one joint connecting two objects, it always returns only 1 element. ImpulseJointSet::attached_joints
, however, returns the correct result.
All of this is demonstrated with the repro code below. Since one of the joints has contacts_enabled
set to false, I would expect it to ignore the contact.
use rapier2d::prelude::*;
#[derive(Default)]
struct GamePhysics {
physics: PhysicsPipeline,
island_manager: IslandManager,
broad_phase: DefaultBroadPhase,
narrow_phase: NarrowPhase,
bodies: RigidBodySet,
colliders: ColliderSet,
impulse_joints: ImpulseJointSet,
multibody_joints: MultibodyJointSet,
ccd_solver: CCDSolver,
}
impl GamePhysics {
fn step(&mut self) {
self.physics.step(&Vector::new(0.0, 9.8), &Default::default(), &mut self.island_manager, &mut self.broad_phase, &mut self.narrow_phase, &mut self.bodies, &mut self.colliders, &mut self.impulse_joints, &mut self.multibody_joints, &mut self.ccd_solver, None, &(), &MyEventHandler);
}
}
struct MyEventHandler;
impl EventHandler for MyEventHandler {
fn handle_collision_event(&self, _: &RigidBodySet, _: &ColliderSet, _: CollisionEvent, _: Option<&ContactPair>) {
println!("Collision");
}
fn handle_contact_force_event(&self, _: f32, _: &RigidBodySet, _: &ColliderSet, _: &ContactPair, _: f32) {}
}
fn main() {
let mut physics = GamePhysics::default();
let a = physics.bodies.insert(RigidBodyBuilder::dynamic());
let b = physics.bodies.insert(RigidBodyBuilder::dynamic());
physics.colliders.insert_with_parent(ColliderBuilder::ball(1.0)
.active_events(ActiveEvents::COLLISION_EVENTS), a, &mut physics.bodies);
physics.colliders.insert_with_parent(ColliderBuilder::ball(1.0)
.active_events(ActiveEvents::COLLISION_EVENTS), b, &mut physics.bodies);
// If the following two lines are switched, it correctly doesn't detect a collision
physics.impulse_joints.insert(a, b, RevoluteJointBuilder::new().contacts_enabled(false), true);
physics.impulse_joints.insert(a, b, RevoluteJointBuilder::new().contacts_enabled(true), true);
// Should be 2, but instead is 1
println!("Joints between a and b: {}", physics.impulse_joints.joints_between(a, b).count());
// This one is correct
println!("Joints for a: {}", physics.impulse_joints.attached_joints(a).count());
// This incorrectly detects a collision
physics.step();
}
Metadata
Metadata
Assignees
Labels
No labels