Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

non-normalized rotations #618

Open
matjlars opened this issue Jan 9, 2025 · 2 comments · May be fixed by #620
Open

non-normalized rotations #618

matjlars opened this issue Jan 9, 2025 · 2 comments · May be fixed by #620
Labels
A-Transform Relates to transforms or physics positions C-Bug Something isn't working

Comments

@matjlars
Copy link

matjlars commented Jan 9, 2025

I am getting an error in my game that seems like Avian is creating some non-normalized rotations. Specifically, bevy panics when calling transform.forward() when the rotation somehow becomes un-normalized. To explain what I mean, everywhere a rotation is set within Avian, if there was an assert!(rotation.is_normalized());, I think it may fail somewhere sometimes.

They key thing I wanted to demonstrate in this MRE below is that I am never setting a non-normalized rotation, and yet the rotations become non-normalized somehow somewhere.

I want to explain myself a little bit because it's tempting to think this is not a bug because I could just normalize the rotations, but that is not the case. I am making a spaceship rail shoot (like Star Fox for example) and my laser beams copy transform.forward() from the spaceship to know which direction to fly in. I have tried simply detecting non-normalized rotations and calling normalize() on those, and while this does resolve bevy panicking on transform.forward(), it also leads to about 5-10% of my lasers flying off in a random direction. Which, although funny, that does not work for the game :) I hope you understand. Thank you very much for making Avian!

use bevy::prelude::*;
use avian3d::prelude::*;

fn main() {
    App::new()
    .add_plugins(DefaultPlugins)
    .add_plugins(PhysicsPlugins::default())
    .add_systems(Startup, setup_scene)
    .add_systems(Update, rotate_cubes)
    .run();
}

#[derive(Component)]
struct TestCube;

/// spawn a bunch of cubes to test
fn setup_scene(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
){
    commands.spawn(
        DirectionalLight::default(),
    );
    commands.spawn((
        Camera3d::default(),
        Transform::from_xyz(50.0, 10.0, 50.0).looking_at(Vec3::new(50.0, 0.0, 0.0), Dir3::Y),
    ));

    // floor
    commands.spawn((
        RigidBody::Static,
        Collider::cylinder(100.0, 0.1),
        Mesh3d(meshes.add(Cylinder::new(100.0, 0.1))),
        MeshMaterial3d(materials.add(Color::WHITE)),
    ));

    // spawn some physics cubes
    for i in 0..100 {
        let x = i as f32;

        commands.spawn((
            Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
            Transform::from_xyz(x * 1.2, 0.0, -4.0),
            //RigidBody::Dynamic,  // NOTE: I never got a non-normalized rotation with a dynamic body. maybe this issue only exists for kinematic bodies?
            RigidBody::Kinematic,
            Collider::cuboid(1.0, 1.0, 1.0),
            MeshMaterial3d(materials.add(Color::WHITE)),
            TestCube,
        ));
    }
}


fn rotate_cubes(
    mut q: Query<&mut Transform, With<TestCube>>,
){
    for mut transform in q.iter_mut() {
        assert!(transform.rotation.is_normalized(), "A cube has a non-normalized rotation!");

        let pos = transform.translation;
        transform.rotation *= Quat::from_euler(EulerRot::XYZ, pos.x * 1.0, pos.x * 2.0, pos.x * 3.0);
        assert!(transform.rotation.is_normalized(), "I just set the rotation and it's not normalized. (This never happens)");
    }
}

(edit: simpler MRE)

@Jondolf Jondolf added C-Bug Something isn't working A-Transform Relates to transforms or physics positions labels Jan 10, 2025
@Jondolf
Copy link
Owner

Jondolf commented Jan 10, 2025

Thanks for the great example! #620 seems to fix the problem at least for the MRE in my testing.

@matjlars
Copy link
Author

Excellent! Thank you so much!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Transform Relates to transforms or physics positions C-Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants