Giter VIP home page Giter VIP logo

Comments (7)

mweatherley avatar mweatherley commented on June 3, 2024 1

Oh, on second glance, Quat::from_axis_angle, which is called in Transform::rotate_local_axis, expects the input vector to be normalized. It looks like our API doesn't explain this, but the first input to rotate_local_axis is definitely supposed to be a unit vector.

from bevy.

pablo-lua avatar pablo-lua commented on June 3, 2024 1

Well, this is a user error that is now solved by #12986, So I'm closing this as completed, feel free to open this again if you see something wrong!

from bevy.

pablo-lua avatar pablo-lua commented on June 3, 2024 1

The problem is that the Vec is not normalized. If you have a look at the internal function, it uses a function Quat::from_axis (IIRC) that will panic if you use a denormalized vec. So, to solve this, you just need to normalize your final vec. Now, using Dir3, we will assert that everything is normalized.

from bevy.

DanteMarshal avatar DanteMarshal commented on June 3, 2024

Update

Made a few changes, after removing the for loop on mouse.read() I don't get the panics anymore.

I don't know if I'm doing something wrong or if this is really a bug !

Here's the new code, I still get the panics when I uncomment the mouse.read() loop.

use bevy::{
    input::{keyboard::KeyboardInput, mouse::MouseMotion, ButtonState},
    prelude::*,
};
fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(bevy_framepace::FramepacePlugin)
        .add_systems(Startup, setup)
        .add_systems(Update, update)
        .run();
}
fn update(
    mut cube: Query<(&mut Player, &mut Transform)>,
    mut keys: EventReader<KeyboardInput>,
    mut mouse: EventReader<MouseMotion>,
    time: Res<Time>,
) {
    let mut player = cube.single_mut();
    for event in keys.read() {
        if event.key_code == KeyCode::KeyR {
            match event.state {
                ButtonState::Pressed => player.0.move_direction.y = 1.0,
                ButtonState::Released => player.0.move_direction.y = 0.0,
            }
        }
        if event.key_code == KeyCode::KeyF {
            match event.state {
                ButtonState::Pressed => player.0.move_direction.y = -1.0,
                ButtonState::Released => player.0.move_direction.y = 0.0,
            }
        }
        if event.key_code == KeyCode::KeyW {
            match event.state {
                ButtonState::Pressed => player.0.move_direction.z = -1.0,
                ButtonState::Released => player.0.move_direction.z = 0.0,
            }
        }
        if event.key_code == KeyCode::KeyS {
            match event.state {
                ButtonState::Pressed => player.0.move_direction.z = 1.0,
                ButtonState::Released => player.0.move_direction.z = 0.0,
            }
        }
        if event.key_code == KeyCode::KeyD {
            match event.state {
                ButtonState::Pressed => player.0.move_direction.x = 1.0,
                ButtonState::Released => player.0.move_direction.x = 0.0,
            }
        }
        if event.key_code == KeyCode::KeyA {
            match event.state {
                ButtonState::Pressed => player.0.move_direction.x = -1.0,
                ButtonState::Released => player.0.move_direction.x = 0.0,
            }
        }
    }
    let translation = time.delta_seconds()
        * Vec3::new(
            player.1.local_x().dot(player.0.move_direction),
            player.1.local_y().dot(player.0.move_direction),
            player.1.local_z().dot(player.0.move_direction),
        );
    player.1.translation += translation;
    // for event in mouse.read() {
    //     player
    //         .1
    //         .rotate_local_axis(time.delta_seconds() * Vec3::X, event.delta.y);
    //     player
    //         .1
    //         .rotate_local_axis(time.delta_seconds() * Vec3::Y, event.delta.x);
    // }
    player.1.set_changed();
}
fn setup(
    mut framepace: ResMut<bevy_framepace::FramepaceSettings>,
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    framepace.limiter = bevy_framepace::Limiter::from_framerate(30.0);
    // circular base
    commands.spawn(PbrBundle {
        mesh: meshes.add(Circle::new(4.0)),
        material: materials.add(Color::WHITE),
        transform: Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
        ..default()
    });
    // cube
    commands.spawn(PbrBundle {
        mesh: meshes.add(Cuboid::new(1.0, 1.0, 1.0)),
        material: materials.add(Color::rgb_u8(124, 144, 255)),
        transform: Transform::from_xyz(0.0, 0.5, 0.0),
        ..default()
    });
    // light
    commands.spawn(PointLightBundle {
        point_light: PointLight {
            shadows_enabled: true,
            ..default()
        },
        transform: Transform::from_xyz(4.0, 8.0, 4.0),
        ..default()
    });
    // camera
    commands.spawn((
        Player::default(),
        Camera3dBundle {
            transform: Transform::from_xyz(-2.5, 4.5, 9.0).looking_at(Vec3::ZERO, Vec3::Y),
            ..default()
        },
    ));
}
#[derive(Default, Component)]
struct Player {
    move_direction: Vec3,
}

from bevy.

mweatherley avatar mweatherley commented on June 3, 2024

I haven't looked really deeply into this yet, but I'm guessing this is caused by repeated calls to rotate_local_axis causing the rotation quaternion to denormalize, since Transform::rotate_local just multiplies the current rotation quaternion by another one (so errors accumulate).

from bevy.

DanteMarshal avatar DanteMarshal commented on June 3, 2024

Thanks guys. One question though, I still didn't get what the cause is.
I'm guessing it's because I wrote time.delta_seconds() * Vec3::X which is not a unit vector, so in that case will it be fixed by rotate_local_axis(Vec3::X, time.delta_seconds() * event.delta.y) ?
Just wanna make sure I understood correctly.

from bevy.

mweatherley avatar mweatherley commented on June 3, 2024

The problem is that the Vec is not normalized. If you have a look at the internal function, it uses a function Quat::from_axis (IIRC) that will panic if you use a denormalized vec. So, to solve this, you just need to normalize your final vec. Now, using Dir3, we will assert that everything is normalized.

I don't think it actually panics unless glam_assert is enabled, but it would still cause other weird behaviors which could easily be at the root of the problem (e.g. causing the quaternion to denormalize).

That being said, do try using a normalized vector as input and seeing if the crash still occurs; if it does, you might need to renormalize the rotation quaternion every so often.

from bevy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.