rapier icon indicating copy to clipboard operation
rapier copied to clipboard

[2D] BallJoint looses momentum

Open truchi opened this issue 4 years ago • 1 comments

Hello Monsieur,

I am playing with Rapier 2D for fun. I am trying to simulate grappling hooks, I use BallJoint for that. All my colliders have no friction (0.) and full restitution (1.). Top-down, no gravity.

The white ball have initial position [WIDTH / 4., HEIGHT / 2.] and linvel [300., 400.]. The hook is at [WIDTH / 2., HEIGHT / 4.].

Without joint, everything works OK:

https://user-images.githubusercontent.com/9745474/123634811-32a01280-d81b-11eb-8279-c3358c7b7d0e.mp4

With joint, the angvel and linvel slow down, and on impact drop significantly:

let joint = BallJoint::new(point![0.0, 0.0], point![WIDTH / 4., 0.]);
physics
    .joints
    .insert(&mut physics.bodies, pendulum, ball, joint);

https://user-images.githubusercontent.com/9745474/123635417-f1f4c900-d81b-11eb-87cf-0d4f2518cf28.mp4

I think I don't want motor behavior. I'd like a circular trajectory, just like when grappling. Am I doing something wrong? Is this a bug? Should I set angvel with configure_motor_velocity on every impact?

for [x, y, w, h] in WALLS {
    walls.push(
        physics.colliders.insert(
            ColliderBuilder::cuboid(w / 2., h / 2.)
                .friction(0.)
                .restitution(1.)
                .translation(vector![x + w / 2., y + h / 2.])
                .build(),
        ),
    );
}

for &[x, y, r1, r2] in HOOKS {
    hooks.push(
        physics.colliders.insert(
            ColliderBuilder::ball(r1)
                .friction(0.)
                .restitution(1.)
                .translation(vector![x, y])
                .build(),
        ),
    );
}

let ball = physics.bodies.insert(
    RigidBodyBuilder::new_dynamic()
        .translation(vector![WIDTH / 4., HEIGHT / 2.])
        .linvel(vector![300.0, 400.0])
        .build(),
);
physics.colliders.insert_with_parent(
    ColliderBuilder::ball(10.)
        .active_events(ActiveEvents::CONTACT_EVENTS | ActiveEvents::INTERSECTION_EVENTS)
        .friction(0.)
        .restitution(1.)
        .build(),
    ball,
    &mut physics.bodies,
);

// Adding grappling
let pendulum = physics.bodies.insert(
    RigidBodyBuilder::new_static()
        .translation(vector![WIDTH / 2., HEIGHT / 2.])
        .build(),
);
let joint = BallJoint::new(point![0.0, 0.0], point![WIDTH / 4., 0.]);
physics
    .joints
    .insert(&mut physics.bodies, pendulum, ball, joint);

Thanks for the help!

truchi avatar Jun 28 '21 12:06 truchi

It seems like setting SpringModel doesn't do anything. Shouldn't it, esp. Disabled do something different?

truchi avatar Jun 29 '21 05:06 truchi

I would recommend switching to the new rope or spring joints. Closing this for now, but please reopen if the rope or spring joint isn’t behaving as expected.

sebcrozet avatar Mar 23 '24 11:03 sebcrozet