Jondolf / avian

ECS-driven 2D and 3D physics engine for the Bevy game engine.
https://crates.io/crates/avian3d
Apache License 2.0
1.28k stars 106 forks source link

Error: "the given sine and cosine produce an invalid rotation" #415

Closed hocop closed 3 weeks ago

hocop commented 4 weeks ago

Some mechanical systems produce this error:

thread 'main' panicked at /home/ruslan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.1.0/src/position.rs:252:9:
the given sine and cosine produce an invalid rotation
stack backtrace:
   0: rust_begin_unwind
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/panicking.rs:72:14
   2: <avian2d::dynamics::solver::joints::revolute::RevoluteJoint as avian2d::dynamics::solver::xpbd::XpbdConstraint<2_usize>>::solve
   3: avian2d::dynamics::solver::xpbd::solve_constraint
             at /home/ruslan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.1.0/src/dynamics/solver/xpbd/mod.rs:393:17
   4: core::ops::function::FnMut::call_mut
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:166:5
   5: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:294:13
   6: <Func as bevy_ecs::system::function_system::SystemParamFunction<fn(F0,F1,F2,F3) .> Out>>::run::call_inner
             at /home/ruslan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/system/function_system.rs:710:21
   7: <Func as bevy_ecs::system::function_system::SystemParamFunction<fn(F0,F1,F2,F3) .> Out>>::run
             at /home/ruslan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/system/function_system.rs:713:17
   8: <bevy_ecs::system::function_system::FunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run_unsafe
             at /home/ruslan/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.14.0/src/system/function_system.rs:534:19

It is hard to reproduce, but I can provide a gif of one such system:

weird collision

It is just two round_rectangle's connected with a RevoluteJoint. It consistently errors out when the system (it represents a truck) folds on itself. But only on the right side. All other collisions in my game work fine.

P.S. I totally do not exclude that this might be my fault, and i just don't see it. Will gladly provide more details/logs if needed

Khanoto commented 4 weeks ago

Hi,

There is another issue for the same problem : https://github.com/Jondolf/avian/issues/416

But thanks for the gif ^^

ps : I think your problem is coming from the fact that when you're little cube is colliding with your larger cube, it may create an angle between them that is forbidden. But I must say it's quite strange that it works on the left side :/

hocop commented 3 weeks ago

Thanks for link!

I think the problem might be here

pub fn add_angle(&self, radians: Scalar) -> Self {
    Rotation::from_sin_cos(self.sin + radians * self.cos, self.cos - radians * self.sin)
        .normalize()
}

This input to from_sin_cos can be invalid in case of big angles. And it is already validated inside the function call to be normalized.

It can explain my case: with great impact XPBD tries to apply a big update on angles and fails. It also explains 416 as clicking in this demo makes big xpbd updates.

My solution would be to implement add_angle as:

pub fn add_angle(&self, radians: Scalar) -> Self {
    Rotation::from_radians(radians) * self
}

More computation but more precise. I will try it and see if it fixes the problem