-
-
Notifications
You must be signed in to change notification settings - Fork 208
Description
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)