dimforge / bevy_rapier

Official Rapier plugin for the Bevy game engine.
https://rapier.rs
Apache License 2.0
1.23k stars 259 forks source link

ExternalForce/Impulse not working as expected #500

Open Xirbizos opened 4 months ago

Xirbizos commented 4 months ago

Since updating to 0.26, ExternalForce and ExternalImpulse do not seem to work correctly for me. I've tried the same code with 0.25 and it works fine there. As far as I can tell, it has to do with the unit conversion between game and physics world but I'm pretty new here so I don't know for certain. Oddly enough, gravity still works as expected.

The setup I tested with uses 100 pixels per meter and applies a force to a 100x100 cube. In 0.25, an impulse of 100 resulted in a velocity of 100 (this seems reasonable, as it should always be game world units being written to impulses/read from velocity from what I understand). In 0.26, an impulse of 1000000 resulted in a Velocity of 100.

Relevant code snippets: Adding the plugin and ppm:

.add_plugins(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))

Spawning the rigidbody:

commands
        .spawn(RigidBody::Dynamic)
        .insert(GravityScale(0.0))
        .insert(Collider::round_cuboid(50.0, 50.0, 0.1))
        .insert(Velocity::default())
        .insert(ExternalImpulse {
                  impulse: Vec2 { x: 0.0, y: 100.0 },
                  ..Default::default()
        })
        .insert(TransformBundle::from(Transform::from_xyz(0.0, 400.0, 0.0)));

Reading the velocity:

fn print_velocity(q: Query<(&Velocity)>) {
    for q in q.iter() {
        println!("V: {}", q.linvel);
    }
}

If this is a mistake on my end, I would appreciate any help on understanding what I was doing wrong :)

sebcrozet commented 4 months ago

Hey! This was a bug in 0.25. The version 0.26 is being correct here. Since you cube is 100x100 with the default density of 1, it has a mass of 10_000. So in order to obtain a velocity of 100 from an impulse, you need 100 * mass = 100 * 10_000 = 1_000_000.

The reason why gravity remained the the same is because gravity is specified as an acceleration (instead of an actual force). So it is independent from mass.

Xirbizos commented 4 months ago

Thanks a lot for the clarification! I wrongly used the mass of the cuboid in physics world units, resulting in a value of 1(which is wrong, since it mixes the physics/game world units). It all makes sense now that I read your explanation.

I'm not sure if this is the right place to ask, but it may be nice to add this to the CHANGELOG.md and update the docs with more realistic values relative to the getting started section to avoid confusing new users and those who migrate to 0.26.

Vrixyz commented 3 months ago

update the docs with more realistic values relative to the getting started section to avoid confusing new users and those who migrate to 0.26.

The getting started uses Collider::ball(0.5), which is reasonable and should work fine with an impulse of 100 ; I imagine you changed the floor and went from there.

The fix should be visible in the changelog indeed though.