Skip to content

Panic when pausing physics time #619

@claudijo

Description

@claudijo

The code example below panics intermittently with message "the given sine and cosine produce an invalid rotation" when pausing physics time. The values of the sin and cos arguments in the from_sin_cos function where the panic originates will be NaN. This seems to be an regression with version 0.2, as I did not have this issue in version 0.1.

Backtrace

claudijo@Claudijos-MacBook-Pro avian_error_replication % RUST_BACKTRACE=1 cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
     Running `target/debug/avian_error_replication`
2025-01-10T20:41:31.970501Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "MacOS 14.6.1 ", kernel: "23.6.0", cpu: "Apple M3 Pro", core_count: "12", memory: "18.0 GiB" }
2025-01-10T20:41:32.040908Z  INFO bevy_render::renderer: AdapterInfo { name: "Apple M3 Pro", vendor: 0, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Metal }
2025-01-10T20:41:32.531532Z  INFO bevy_winit::system: Creating new window "App" (0v1#4294967296)
thread 'main' panicked at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/position.rs:254:9:
the given sine and cosine produce an invalid rotation
stack backtrace:
   0: rust_begin_unwind
             at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf/library/core/src/panicking.rs:74:14
   2: avian2d::position::Rotation::from_sin_cos
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/position.rs:254:9
   3: avian2d::position::Rotation::add_angle
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/position.rs:436:9
   4: avian2d::dynamics::solver::xpbd::positional_constraint::PositionConstraint::apply_positional_impulse
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/dynamics/solver/xpbd/positional_constraint.rs:52:35
   5: avian2d::dynamics::solver::xpbd::positional_constraint::PositionConstraint::apply_positional_lagrange_update
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/dynamics/solver/xpbd/positional_constraint.rs:26:9
   6: avian2d::dynamics::solver::joints::prismatic::PrismaticJoint::constrain_positions
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/dynamics/solver/joints/prismatic.rs:220:9
   7: <avian2d::dynamics::solver::joints::prismatic::PrismaticJoint as avian2d::dynamics::solver::xpbd::XpbdConstraint<2_usize>>::solve
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/dynamics/solver/joints/prismatic.rs:70:22
   8: avian2d::dynamics::solver::xpbd::solve_constraint
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/avian2d-0.2.0/src/dynamics/solver/xpbd/mod.rs:393:17
   9: core::ops::function::FnMut::call_mut
             at /Users/claudijo/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:166:5
  10: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /Users/claudijo/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:294:13
  11: <Func as bevy_ecs::system::function_system::SystemParamFunction<fn(F0,F1,F2,F3) .> Out>>::run::call_inner
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.15.1/src/system/function_system.rs:1002:21
  12: <Func as bevy_ecs::system::function_system::SystemParamFunction<fn(F0,F1,F2,F3) .> Out>>::run
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.15.1/src/system/function_system.rs:1005:17
  13: <bevy_ecs::system::function_system::FunctionSystem<Marker,F> as bevy_ecs::system::system::System>::run_unsafe
             at /Users/claudijo/.cargo/registry/src/index.crates.io-6f17d22bba15001f/bevy_ecs-0.15.1/src/system/function_system.rs:800:19
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Encountered a panic in system `avian2d::dynamics::solver::xpbd::solve_constraint<avian2d::dynamics::solver::joints::prismatic::PrismaticJoint, 2>`!
Encountered a panic in system `avian2d::dynamics::solver::schedule::run_substep_schedule`!
Encountered a panic in system `avian2d::schedule::run_physics_schedule`!
Encountered a panic in system `bevy_app::main_schedule::FixedMain::run_fixed_main`!
Encountered a panic in system `bevy_time::fixed::run_fixed_main_schedule`!
Encountered a panic in system `bevy_app::main_schedule::Main::run_main`!

The smallest setup I have found that reproduces the problem includes two colliders connected with a prismatic joint and having one of the colliders rotating. The panic will occur (intermittently) when pressing the button that pauses the physics time.

use avian2d::prelude::*;
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugins(PhysicsPlugins::default())
        .add_plugins(PhysicsDebugPlugin::default())
        .add_systems(Startup, (setup, spawn_button))
        .add_systems(Update, button_interaction)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d);

    let first_collider = commands
        .spawn((AngularVelocity(1.), RigidBody::Dynamic, Collider::rectangle(10., 20.)))
        .id();

    let second_collider = commands
        .spawn((RigidBody::Dynamic, Collider::circle(10.)))
        .id();

    commands.spawn(PrismaticJoint::new(first_collider, second_collider));
}

fn spawn_button(mut commands: Commands) {
    commands
        .spawn((
            Button,
            Node {
                width: Val::Px(150.0),
                height: Val::Px(65.0),
                border: UiRect::all(Val::Px(5.0)),
                justify_content: JustifyContent::Center,
                align_items: AlignItems::Center,
                ..default()
            },
            BorderColor(Color::BLACK),
            BorderRadius::MAX,
        ))
        .with_child((
            Text::new("Pause"),
            TextFont {
                font_size: 33.0,
                ..default()
            },
            TextColor(Color::srgb(0.9, 0.9, 0.9)),
        ));
}

fn button_interaction(
    mut interaction_query: Query<&Interaction, (Changed<Interaction>, With<Button>)>,
    mut time: ResMut<Time<Physics>>
) {
    for interaction in &mut interaction_query {
        if *interaction == Interaction::Pressed {
            time.pause();
        }
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-SchedulingRelates to scheduling or system setsP-RegressionBehaviour that was working before is now worse or broken.Add a test for this!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions