jcornaz / heron

[DISCONTINUED] An ergonomic physics API for bevy games
MIT License
292 stars 44 forks source link

KinematicVelocityBased rotation is applied in world-space instead of object-local-space #261

Closed Kulasko closed 2 years ago

Kulasko commented 2 years ago

Hello there, I noticed a problem which currently forces me to use dynamic RigidBodys for turnable turrets, which isn't ideal. I wrote this test program:

use bevy::prelude::*;
use heron::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(PhysicsPlugin::default())
        .add_startup_system(spawn)
        .add_system(turn)
        .run();
}

fn spawn(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands.spawn_bundle(PerspectiveCameraBundle {
        transform: Transform::from_xyz(0.0, 8.0, -12.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });

    commands
        .spawn_bundle(PbrBundle {
            mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
            material: materials.add(Color::WHITE.into()),
            transform: Transform::from_xyz(2.0, 0.0, 1.0),
            ..default()
        })
        .insert(RigidBody::KinematicVelocityBased)
        .insert(Velocity::default());
}

fn turn(mut cube: Query<(&Transform, &mut Velocity)>) {
    let (transform, mut velocity) = cube.single_mut();
    let target = Vec3::new(10.0, 0.0, 10.0);
    let target_direction = (target - transform.translation).normalize();
    velocity.angular = Quat::from_rotation_arc(transform.forward(), target_direction).into();
}

When a RigidBody::Dynamic is used, the cube correctly turns in the direction of the target position. When a KinematicVelocityBased body is used, the cube additionally moves in an elliptical pattern until it arrives at its target rotation. Note that the KinematicVelocityBased body actually turns correctly when placed at the origin of the world [0, 0, 0].

I could be that I just understood this type of RigidBody incorrectly or I did something wrong in my rotation code, if so, please let me know.

jcornaz commented 2 years ago

Thanks for the report. I suspect it may be more a problem in rapier than in heron.

Can you try to see what behavior you get when using directly rapier, or when using bevy_rapier?

Kulasko commented 2 years ago

I have tried reproducing the behaviour using bevy_rapier3d by just converting the rotation quaternion to a scaled axis. I did not observe the erroneous behaviour in that version.

jcornaz commented 2 years ago

@Kulasko can you tell me if the problem is still present on heron version 4.0.0-alpha.1?

Kulasko commented 2 years ago

Both my test case and my actual project now work like intended. Thank you for your work!