-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Panic on Transform::local_?
calls
#12981
Comments
UpdateMade a few changes, after removing the 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 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,
} |
I haven't looked really deeply into this yet, but I'm guessing this is caused by repeated calls to |
Oh, on second glance, |
…`Dir3` (#12986) # Objective Related to #12981 Presently, there is a footgun where we allow non-normalized vectors to be passed in the `axis` parameters of `Transform::rotate_axis` and `Transform::rotate_local_axis`. These methods invoke `Quat::from_axis_angle` which expects the vector to be normalized. This PR aims to address this. ## Solution Require `Dir3`-valued `axis` parameters for these functions so that the vector's normalization can be enforced at type-level. --- ## Migration Guide All calls to `Transform::rotate_axis` and `Transform::rotate_local_axis` will need to be updated to use a `Dir3` for the `axis` parameter rather than a `Vec3`. For a general input, this means calling `Dir3::new` and handling the `Result`, but if the previous vector is already known to be normalized, `Dir3::new_unchecked` can be called instead. Note that literals like `Vec3::X` also have corresponding `Dir3` literals; e.g. `Dir3::X`, `Dir3::NEG_Y` and so on. --- ## Discussion This axis input is unambigiously a direction instead of a vector, and that should probably be reflected and enforced by the function signature. In previous cases where we used, e.g., `impl TryInto<Dir3>`, the associated methods already implemented (and required!) additional fall-back logic, since the input is conceptually more complicated than merely specifying an axis. In this case, I think it's fairly cut-and-dry, and I'm pretty sure these methods just predate our direction types.
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! |
Thanks guys. One question though, I still didn't get what the cause is. |
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 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. |
I'm getting a panic on this on 0.14 when I leave my game running long enough that it randomly happens.
In my code I'm just doing calls to transform.forward() but it seems there's a scenario that causes the |
Are you changing the transform incrementally? The only way that unwrap should ever fail is if the quaternion representing the rotation is extremely denormalized. |
Not.. intentionally... I'm using Avian physics and the transform of this object is being modified by impulses.. it looks like at some point the rotation gets set to this denormalized value. So this panics
I'm unsure what causes the rotation to end up |
Bevy version
The release number or commit hash of the version you're using.
[Optional] Relevant system information
What you did
I'm trying to learn bevy, and I was making a very simple scene to move a cube. Here's the code :
What went wrong
Panics on one of the
local_?
calls, Here's the backtrace from one of them :Additional information
I think it happens the moment I press a key that is the opposite of a key I pressed before. For example, if I press Left (KeyA) nothing happens, but then pressing Right (KeyS) will panic afterwards.
The text was updated successfully, but these errors were encountered: