Giter Site home page Giter Site logo

bevy_rapier's Introduction

bevy_rapier's People

Contributors

ablexxive avatar aceeri avatar alec-deason avatar borisboutillier avatar chungwong avatar ciubix8513 avatar cleancut avatar cscorley avatar dependabot[bot] avatar extrawurst avatar fedcomp avatar guillaumegomez avatar heinousjay avatar illis avatar irate-devil avatar james-j-obrien avatar janhohenheim avatar mvlabat avatar nicopap avatar nkzawa avatar pcwalton avatar ricochet1k avatar robertdodd avatar sebcrozet avatar shatur avatar squ1rr avatar supercilex avatar superdump avatar vrixyz avatar zicklag avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bevy_rapier's Issues

Query pipeline panic

I believe there's some kind of race between the collider builders being added, updating the collision tree, and making a collision query which results in a panic like:

panicked at 'index out of bounds: the len is 0 but the index is 0', /Users/mdenchev
/.cargo/registry/src/github.com-1ecc6299db9ec823/parry2d-0.3.0/src/partitioning/wquadtree.rs:417:24

This only happens upon adding a collider and doing a collision query in the same frame. If there's no panic at the start, then things keep working fine. I can provide a buildable minimal example if helpful, but the relevant code is:

pub fn setup(
    mut commands: Commands
) {
    commands.spawn_bundle(OrthographicCameraBundle::new_2d());

    commands
        .spawn()
        .insert(RigidBodyBuilder::new_dynamic())
        .insert(ColliderBuilder::cuboid(40.0, 40.0).sensor(true));
}

pub fn detect_mouse_hover(
    mouse_pos: Res<MousePos>,
    query_pipeline: Res<QueryPipeline>,
    collider_set: Res<ColliderSet>,
    windows: ResMut<Windows>,
) {
    let window = windows.get_primary().unwrap();
    query_pipeline.intersections_with_point(
        &*collider_set,
        &Point::new(mouse_pos.x-window.width()/2., mouse_pos.y - window.height()/2.),
        InteractionGroups::all(),
        None,
        |_col_handle, _col| {
            info!("bonk, {:?}", &*mouse_pos);
            false
        },
    )
}

proximity_events specified in rapier bevy docs

In the Rapier Bevy docs section Handling contact/proximity events the docs specify a proximity_events field on EventQueue but at least in 0.8.0 there is no proximity_events field only contact_events and intersection_events. I'm guessing the docs just need to be updated? Also wasn't sure if this was the better repo to make the issue or the main rapier repo. Thanks!

Panic when `simd` and `parallel` features are enabled together

When I enable simd-nightly or simd-stable with parallel I get a panic when multiple objects collide. However this only happens when the objects have different collision shapes.

The error thrown is:
thread '<unnamed>' panicked at 'internal error: entered unreachable code',
C:\Users\name.cargo\registry\src\github.com-1ecc6299db9ec823\rapier2d-0.1.3\src\dynamics\solver\position_constraint.rs:55:45

Here is the repo for the full code:
https://github.com/mthom26/bevy-rapier-panic

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/dynamics/solver/generic_velocity_constraint.rs:48:49

I feel this is a bug, I've tried to fix my code but I can't get it to not panic on certain collisions

Code excerpts:

main

App::new()
        ...
        .add_plugins(DefaultPlugins)
        .add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
        .add_plugin(RapierRenderPlugin)
        ...
        .add_system_set(
            SystemSet::on_enter(GameState::Level)
                .with_system(setup)
                .with_system(setup_player),
        )

setup, setup_player

rapier.scale = TILE_SIZE as f32;
rapier.gravity = Vec2::new(0.0, -12.0).into();

let player_body = RigidBodyBundle {
        position: RigidBodyPositionComponent(RigidBodyPosition {
            position: Vec2::new(0.0, 10.0).into(),
            ..Default::default()
        }),
        velocity: RigidBodyVelocityComponent(RigidBodyVelocity {
            angvel: 0.0,
            linvel: Vec2::new(0.0, 3.0).into(),
        }),
        mass_properties: RigidBodyMassPropsComponent(RigidBodyMassProps {
            flags: RigidBodyMassPropsFlags::ROTATION_LOCKED,
            ..Default::default()
        }),
        ..Default::default()
    };
    let player_shape = ColliderBundle {
        collider_type: ColliderTypeComponent(ColliderType::Solid),
        shape: ColliderShapeComponent(ColliderShape::cuboid(w as f32 / 2.0, h as f32 / 2.0)),
        ..Default::default()
    };

    commands
        .spawn_bundle(SpriteSheetBundle {
            texture_atlas: graphics.p1_texture.clone(),
            ..Default::default()
        })
        ...
        .insert_bundle(player_shape)
        .insert_bundle(player_body)
        .insert(RigidBodyPositionSync::Discrete);

Tile generation

let id = commands
  .spawn()
  .insert_bundle(SpriteSheetBundle { ... })
  .insert_bundle(ColliderBundle {
      shape: ColliderShapeComponent(ColliderShape::cuboid(0.5, 0.5)),
      position: ColliderPositionComponent(ColliderPosition(
        Isometry::translation(p.x as f32, p.y as f32),
      )),
      ..Default::default()
  })
  .insert(ColliderDebugRender::with_id(3))
  .id();
children.push(id);
// -----------
commands
  .spawn()
  .insert(Chunk)
  .insert(Transform::from_translation(Vec3::new(
    p.x as f32 * CHUNK_SIZE as f32 * TILE_SIZE as f32,
    p.y as f32 * CHUNK_SIZE as f32 * TILE_SIZE as f32,
    1.0,
  )))
  .insert(GlobalTransform::default())
  .push_children(&children);

Backtrace

22-01-10T05:08:42.914884Z  INFO bevy_render::renderer: AdapterInfo { name: "AMD RADV RENOIR", vendor: 4098, device: 5686, device_type: IntegratedGpu, backend: Vulkan }
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.12.0-alpha.0/src/dynamics/solver/generic_velocity_constraint.rs:48:49
stack backtrace:
   0: rust_begin_unwind
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/panicking.rs:107:14
   2: core::panicking::panic
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/panicking.rs:48:5
   3: rapier2d::dynamics::solver::generic_velocity_constraint::GenericVelocityConstraint::generate
   4: rapier2d::dynamics::solver::solver_constraints::SolverConstraints<rapier2d::dynamics::solver::velocity_constraint::AnyVelocityConstraint,rapier2d::dynamics::solver::generic_velocity_constraint::GenericVelocityConstraint>::compute_generic_constraints
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.12.0-alpha.0/src/dynamics/solver/solver_constraints.rs:228:13
   5: rapier2d::dynamics::solver::solver_constraints::SolverConstraints<rapier2d::dynamics::solver::velocity_constraint::AnyVelocityConstraint,rapier2d::dynamics::solver::generic_velocity_constraint::GenericVelocityConstraint>::init
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.12.0-alpha.0/src/dynamics/solver/solver_constraints.rs:149:9
   6: rapier2d::dynamics::solver::island_solver::IslandSolver::init_and_solve
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.12.0-alpha.0/src/dynamics/solver/island_solver.rs:85:13
   7: rapier2d::pipeline::physics_pipeline::PhysicsPipeline::build_islands_and_solve_velocity_constraints
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.12.0-alpha.0/src/pipeline/physics_pipeline.rs:249:17
   8: rapier2d::pipeline::physics_pipeline::PhysicsPipeline::step_generic
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.12.0-alpha.0/src/pipeline/physics_pipeline.rs:636:13
   9: bevy_rapier2d::physics::systems::step_world_system
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_rapier2d-0.12.0/src/physics/systems.rs:324:17
  10: core::ops::function::FnMut::call_mut
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/ops/function.rs:150:5
  11: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/ops/function.rs:269:13
  12: <Func as bevy_ecs::system::function_system::SystemParamFunction<(),Out,(F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11),()>>::run::call_inner
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/system/function_system.rs:512:21
  13: <Func as bevy_ecs::system::function_system::SystemParamFunction<(),Out,(F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11),()>>::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/system/function_system.rs:515:17
  14: <bevy_ecs::system::function_system::FunctionSystem<In,Out,Param,Marker,F> as bevy_ecs::system::system::System>::run_unsafe
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/system/function_system.rs:442:19
  15: bevy_ecs::schedule::executor_parallel::ParallelExecutor::prepare_systems::{{closure}}
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/schedule/executor_parallel.rs:214:30
  16: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/future/mod.rs:84:19
  17: async_executor::Executor::spawn::{{closure}}
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:144:19
  18: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/future/mod.rs:84:19
  19: async_task::raw::RawTask<F,T,S>::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/raw.rs:489:20
  20: async_executor::Executor::try_tick
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:181:17
  21: bevy_tasks::task_pool::TaskPool::scope::{{closure}}
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.6.0/src/task_pool.rs:222:21
  22: std::thread::local::LocalKey<T>::try_with
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/std/src/thread/local.rs:412:16
  23: std::thread::local::LocalKey<T>::with
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/std/src/thread/local.rs:388:9
  24: bevy_tasks::task_pool::TaskPool::scope
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.6.0/src/task_pool.rs:169:9
  25: <bevy_ecs::schedule::executor_parallel::ParallelExecutor as bevy_ecs::schedule::executor::ParallelSystemExecutor>::run_systems
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/schedule/executor_parallel.rs:122:9
  26: <bevy_ecs::schedule::stage::SystemStage as bevy_ecs::schedule::stage::Stage>::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/schedule/stage.rs:850:17
  27: bevy_ecs::schedule::Schedule::run_once
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/schedule/mod.rs:344:13
  28: <bevy_ecs::schedule::Schedule as bevy_ecs::schedule::stage::Stage>::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.6.0/src/schedule/mod.rs:362:21
  29: bevy_app::app::App::update
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.6.0/src/app.rs:112:9
  30: bevy_winit::winit_runner_with::{{closure}}
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.6.0/src/lib.rs:504:21
  31: winit::platform_impl::platform::sticky_exit_callback
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.0/src/platform_impl/linux/mod.rs:753:5
  32: winit::platform_impl::platform::x11::EventLoop<T>::run_return
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.0/src/platform_impl/linux/x11/mod.rs:293:17
  33: winit::platform_impl::platform::x11::EventLoop<T>::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.0/src/platform_impl/linux/x11/mod.rs:392:9
  34: winit::platform_impl::platform::EventLoop<T>::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.0/src/platform_impl/linux/mod.rs:669:56
  35: winit::event_loop::EventLoop<T>::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/winit-0.26.0/src/event_loop.rs:154:9
  36: bevy_winit::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.6.0/src/lib.rs:171:5
  37: bevy_winit::winit_runner_with
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.6.0/src/lib.rs:513:9
  38: bevy_winit::winit_runner
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_winit-0.6.0/src/lib.rs:211:5
  39: core::ops::function::Fn::call
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/ops/function.rs:70:5
  40: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/alloc/src/boxed.rs:1825:9
  41: bevy_app::app::App::run
             at /home/pree/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.6.0/src/app.rs:130:9
  42: bevy1_1::main
             at ./src/main.rs:30:5
  43: core::ops::function::FnOnce::call_once
             at /rustc/c09a9529c51cde41c1101e56049d418edb07bf71/library/core/src/ops/function.rs:227:5

thread panicked at 'Graph::add_edge: node indices out of bounds'

I'm implementing a simple shooting mechanism using bullet with actual CCD-enabled rigid body and sensor collider. When I spawn a lots of bullet in a short time frame (ie. 15 bullets per 5 seconds) and each bullet despawn after 1 or 5 seconds after spawning, the app will panick. If I spawn bullets slowly, it won't panick. If I increase bullet lifespan to a very high value, it won't panic. It is possible that spawning and despawning multiple times in a short time causes panic.

Here is the app: https://github.com/Looooong/doce/tree/5b03c8839468b10bac926617a9581b409328839d

How to reproduce:

  • Press "Play"
  • Click as fast as possible anywhere on the screen to spawn the bullet.

Here is the full trace:

thread 'main' panicked at 'Graph::add_edge: node indices out of bounds', C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\rapier3d-0.9.1\src\data\graph.rs:228:27
stack backtrace:
   0: std::panicking::begin_panic<str>
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:519
   1: rapier3d::data::graph::Graph::add_edge<rapier3d::geometry::collider_components::ColliderHandle,bool>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\rapier3d-0.9.1\src\data\graph.rs:228
   2: rapier3d::geometry::interaction_graph::InteractionGraph::add_edge<rapier3d::geometry::collider_components::ColliderHandle,bool>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\rapier3d-0.9.1\src\geometry\interaction_graph.rs:44
   3: rapier3d::geometry::narrow_phase::NarrowPhase::add_pair<bevy_rapier3d::physics::collider_component_set::ColliderComponentsSet>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\rapier3d-0.9.1\src\geometry\narrow_phase.rs:594
   4: rapier3d::geometry::narrow_phase::NarrowPhase::register_pairs<bevy_rapier3d::physics::rigid_body_component_set::RigidBodyComponentsSet,bevy_rapier3d::physics::collider_component_set::ColliderComponentsSet>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\rapier3d-0.9.1\src\geometry\narrow_phase.rs:649
   5: rapier3d::pipeline::physics_pipeline::PhysicsPipeline::detect_collisions<bevy_rapier3d::physics::rigid_body_component_set::RigidBodyComponentsSet,bevy_rapier3d::physics::collider_component_set::ColliderComponentsSet>        
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\rapier3d-0.9.1\src\pipeline\physics_pipeline.rs:137
   6: rapier3d::pipeline::physics_pipeline::PhysicsPipeline::step_generic<bevy_rapier3d::physics::rigid_body_component_set::RigidBodyComponentsSet,bevy_rapier3d::physics::collider_component_set::ColliderComponentsSet>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\rapier3d-0.9.1\src\pipeline\physics_pipeline.rs:705
   7: bevy_rapier3d::physics::systems::step_world_system<tuple<>*>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_rapier3d-0.10.0\src\physics\systems.rs:313
   8: core::ops::function::Fn::call<fn(bevy_ecs::system::commands::Commands, tuple<bevy_ecs::system::system_param::Res<bevy_core::time::time::Time>, bevy_ecs::system::system_param::ResMut<bevy_rapier3d::physics::resources::SimulationToRenderTime>>, tuple<bevy_e
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:70
   9: core::ops::function::impls::{{impl}}::call_mut<tuple<bevy_ecs::system::commands::Commands, tuple<bevy_ecs::system::system_param::Res<bevy_core::time::time::Time>, bevy_ecs::system::system_param::ResMut<bevy_rapier3d::physics::resources::SimulationToRender
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:247
  10: bevy_ecs::system::into_system::{{impl}}::run<tuple<>,fn(bevy_ecs::system::commands::Commands, tuple<bevy_ecs::system::system_param::Res<bevy_core::time::time::Time>, bevy_ecs::system::system_param::ResMut<bevy_rapier3d::physics::resources::SimulationToRen
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\system\into_system.rs:207
  11: bevy_ecs::system::into_system::{{impl}}::run_unsafe<tuple<>,tuple<>,tuple<bevy_ecs::system::commands::Commands, tuple<bevy_ecs::system::system_param::Res<bevy_core::time::time::Time>, bevy_ecs::system::system_param::ResMut<bevy_rapier3d::physics::resource
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\system\into_system.rs:147
  12: bevy_ecs::schedule::executor_parallel::{{impl}}::prepare_systems::{{closure}}
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\schedule\executor_parallel.rs:200
  13: core::future::from_generator::{{impl}}::poll<generator-0>
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\future\mod.rs:80
  14: async_executor::{{impl}}::spawn::{{closure}}
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\async-executor-1.4.1\src\lib.rs:144
  15: core::future::from_generator::{{impl}}::poll<generator-0>
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\future\mod.rs:80
  16: async_task::raw::RawTask::run<core::future::from_generator::GenFuture<generator-0>,tuple<>,closure-0>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\async-task-4.0.3\src\raw.rs:489
  17: async_executor::Executor::try_tick
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\async-executor-1.4.1\src\lib.rs:181
  18: bevy_tasks::task_pool::{{impl}}::scope::{{closure}}
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_tasks-0.5.0\src\task_pool.rs:222
  19: std::thread::local::LocalKey::try_with
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:272
  20: std::thread::local::LocalKey::with
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:248
  21: bevy_tasks::task_pool::TaskPool::scope<closure-1,tuple<>>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_tasks-0.5.0\src\task_pool.rs:169
  22: bevy_ecs::schedule::executor_parallel::{{impl}}::run_systems
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\schedule\executor_parallel.rs:121
  23: bevy_ecs::schedule::stage::{{impl}}::run
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\schedule\stage.rs:822
  24: bevy_ecs::schedule::Schedule::run_once
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\schedule\mod.rs:201
  25: bevy_ecs::schedule::{{impl}}::run
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\schedule\mod.rs:219
  26: bevy_winit::winit_runner_with::{{closure}}
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_winit-0.5.0\src\lib.rs:485
  27: winit::platform_impl::platform::event_loop::{{impl}}::run_return::{{closure}}<tuple<>,closure-1>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:203
  28: alloc::boxed::{{impl}}::call_mut
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\boxed.rs:1553
  29: winit::platform_impl::platform::event_loop::runner::{{impl}}::call_event_handler::{{closure}}
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:245
  30: std::panic::{{impl}}::call_once<tuple<>,closure-0>
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:344
  31: std::panicking::try::do_call
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:379
  32: std::panicking::try
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:343
  33: std::panic::catch_unwind
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:431
  34: winit::platform_impl::platform::event_loop::runner::EventLoopRunner::catch_unwind
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:152
  35: winit::platform_impl::platform::event_loop::runner::EventLoopRunner::call_event_handler<tuple<>>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:239
  36: winit::platform_impl::platform::event_loop::runner::EventLoopRunner::move_state_to<tuple<>>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:303
  37: winit::platform_impl::platform::event_loop::runner::EventLoopRunner::main_events_cleared
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:227
  38: winit::platform_impl::platform::event_loop::flush_paint_messages
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:676
  39: winit::platform_impl::platform::event_loop::thread_event_target_callback::{{closure}}
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:1967
  40: std::panic::{{impl}}::call_once<isize,closure-0>
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:344
  41: std::panicking::try::do_call
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:379
  42: std::panicking::try
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:343
  43: std::panic::catch_unwind
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:431
  44: winit::platform_impl::platform::event_loop::runner::EventLoopRunner::catch_unwind<tuple<>,isize,closure-0>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop\runner.rs:152
  45: winit::platform_impl::platform::event_loop::thread_event_target_callback<tuple<>>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:2151
  46: DefSubclassProc
  47: DefSubclassProc
  48: CallWindowProcW
  49: DispatchMessageW
  50: SendMessageTimeoutW
  51: KiUserCallbackDispatcher
  52: NtUserDispatchMessage
  53: DispatchMessageW
  54: winit::platform_impl::platform::event_loop::EventLoop::run_return<tuple<>,closure-1>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:218
  55: winit::platform_impl::platform::event_loop::EventLoop::run<tuple<>,closure-1>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\platform_impl\windows\event_loop.rs:188
  56: winit::event_loop::EventLoop::run<tuple<>,closure-1>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\winit-0.24.0\src\event_loop.rs:154
  57: bevy_winit::run<closure-1>
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_winit-0.5.0\src\lib.rs:171
  58: bevy_winit::winit_runner_with
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_winit-0.5.0\src\lib.rs:493
  59: bevy_winit::winit_runner
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_winit-0.5.0\src\lib.rs:211
  60: core::ops::function::Fn::call<fn(bevy_app::app::App),tuple<bevy_app::app::App>>
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:70
  61: alloc::boxed::{{impl}}::call
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\boxed.rs:1560
  62: bevy_app::app::App::run
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_app-0.5.0\src\app.rs:68
  63: bevy_app::app_builder::AppBuilder::run
             at C:\Users\duclo\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_app-0.5.0\src\app_builder.rs:49
  64: deterministic_online_coop_experiment::main
             at .\src\main.rs:40
  65: core::ops::function::FnOnce::call_once<fn(),tuple<>>
             at C:\Users\duclo\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227

Make converting positions to points easier

I often find myself doing something like:

let p1: Point<f32> = position.position.translation.vector.into();

if I want to get the distance between entities. This gets verbose quickly, especially with multiple entities.

I wonder if it makes sense to add the conversions higher up in the chain:

let p1: Point<f32> = position.position.translation.into();

Most straight-forward, since I'm working directly on the translation.

let p1: Point<f32> = position.position.into();

Unless there's some other, more meaningful point that can be derived from the isometry, this would be preferable since distance between positions seems common enough.

let p1: Point<f32> = position.into();

In general, if someone isn't interested in the next position, I'd argue that current should be the default assumption without having to be explicit about it every time. This makes calculating distances between two entities a whole lot cleaner:

let distance = na::distance(position1.into(), position2.into());

Thanks.

Problem with deterministic simulation

I'm experimenting with deterministic physics simulation using Rapier with Bevy. The initial state includes a main character and a set of balls inside a room. The main character can be controlled to move around the room and push the balls. After simulating for awhile, a replay button can be pressed to replay the physics simulation along with the recorded character movements.

The final position of the main character at the end of the replay is identical between multiple replays. This confirms that moving the kinematic character using velocity is deterministic.

However, the final positions of the balls are not the same between replays. At first, I thought maybe deleting and recreating all the physics entities causes the order of the physics bodies on the memory changed, thus changes the processing order of physics contacts. I modified the code to retain the physics entities between replays. Nevertheless, the balls' final positions still change between replays.

The enhanced-determinism feature is already enabled, and the timestep mode is set to TimestepMode::FixedTimestep. Is there anything else to make the simulation deterministic?

The app repo: https://github.com/Looooong/doce/tree/67a32acbd8cfbf31c88b253bf5991a17da5d06bc

Make it easier to get static snapshots of collider data

I've been having a very hard time with this and wonder if there's any way bevy_rapier might make this easier. I'm trying to integrate physics into my pathfinding, which can take more than a single frame. Previously, my AStar calls generated paths that routed entities through areas in which they couldn't physically fit. I'm trying to add shapes to this algorithm such that valid successors to a given tile are only those in which the shape of the source entity can fit. Here's an example of what I have right now:

fn find_path_for_shape(
    pool: &AsyncComputeTaskPool,
    initiator: Entity,
    start: &dyn PointLike,
    destination: &dyn PointLike,
    map: &Map,
    query_pipeline: &QueryPipeline,
    collider_query: &QueryPipelineColliderComponentsQuery,
    shape: &dyn Shape,
    channel: &Sender<Option<Path>>,
) {
    let collider_set = QueryPipelineColliderComponentsSet(&collider_query);
    let shapes = Shapes(
        collider_query
            .iter()
            .map(|(a, b, c, d)| (a, b.clone(), c.clone(), d.clone()))
            .collect::<Vec<(Entity, ColliderPosition, ColliderShape, ColliderFlags)>>(),
    );
    let start = start.i32();
    let destination = destination.i32();
    let map_clone = map.clone();
    let shape_clone = shape.clone();
    let channel_clone = channel.clone();
    pool.spawn(async {
        let path = astar(
            &start,
            |p| {
                let mut successors: Vec<((i32, i32), u32)> = vec![];
                for tile in map_clone.get_available_exits(p.0 as usize, p.1 as usize) {
                    let mut should_push = true;
                    let shape_pos = Isometry::new(vector![tile.0 as f32, tile.1 as f32], 0.);
                    query_pipeline.intersections_with_shape(
                        &shapes,
                        &shape_pos,
                        &*shape_clone,
                        InteractionGroups::all(),
                        Some(&|v| v.entity() != initiator),
                        |handle| {
                            should_push = false;
                            false
                        },
                    );
                    if should_push {
                        successors.push(((tile.0 as i32, tile.1 as i32), (tile.2 * 100.) as u32));
                    }
                }
                successors
            },
            |p| (p.distance_squared(&destination) * 100.) as u32,
            |p| *p == destination.into(),
        );
        channel_clone
            .send(if let Some(path) = path {
                Some(Path(path.0))
            } else {
                None
            })
            .expect("Channel should exist");
    })
    .detach();
}

It was suggested that I make a wrapper type that creates a static snapshots of colliders to pass into the pool. I'm fine with this, as I can probably correct for changes in the system that actually negotiates calculated paths for cases where a path gets blocked. Here is a partial attempt at that:

struct Shapes(Vec<(Entity, ColliderPosition, ColliderShape, ColliderFlags)>);

impl ComponentSet<SharedShape> for Shapes {
    fn size_hint(&self) -> usize {
        self.0.len()
    }

    fn for_each(&self, f: impl FnMut(bevy_rapier2d::rapier::data::Index, &SharedShape)) {
        unimplemented!()
    }
}

impl ComponentSetOption<SharedShape> for Shapes {
    fn get(&self, index: Index) -> std::option::Option<&SharedShape> {
        self.0
            .get(index.into())
            .map(|v: &(Entity, ColliderPosition, ColliderShape, ColliderFlags)| &v.2)
    }
}

impl ComponentSet<ColliderFlags> for Shapes {
    fn size_hint(&self) -> usize {
        self.0.len()
    }

    fn for_each(&self, f: impl FnMut(bevy_rapier2d::rapier::data::Index, &ColliderFlags)) {
        unimplemented!()
    }
}

impl ComponentSetOption<ColliderFlags> for Shapes {
    fn get(
        &self,
        index: bevy_rapier2d::rapier2d::data::Index,
    ) -> std::option::Option<&ColliderFlags> {
        self.0.get(index)
    }
}

impl ComponentSet<ColliderPosition> for Shapes {
    fn size_hint(&self) -> usize {
        self.0.len()
    }

    fn for_each(&self, f: impl FnMut(bevy_rapier2d::rapier::data::Index, &ColliderPosition)) {
        unimplemented!()
    }
}

impl ComponentSetOption<ColliderPosition> for Shapes {
    fn get(
        &self,
        index: bevy_rapier2d::rapier2d::data::Index,
    ) -> std::option::Option<&ColliderPosition> {
        self.0.get(index)
    }
}

Obviously that's incomplete, but here are some of the errors I'm getting:

error[E0284]: type annotations needed: cannot satisfy <_ as SliceIndex<[(bevy::prelude::Entity, bevy_rapier2d::prelude::ColliderPosition, bevy_rapier2d::prelude::SharedShape, bevy_rapier2d::prelude::ColliderFlags)]>>::Output == (bevy::prelude::Entity, bevy_rapier2d::prelude::ColliderPosition, bevy_rapier2d::prelude::SharedShape, bevy_rapier2d::prelude::ColliderFlags)
--> src\pathfinding.rs:63:14
|
63 | .get(index.into())
| ^^^ cannot satisfy <_ as SliceIndex<[(bevy::prelude::Entity, bevy_rapier2d::prelude::ColliderPosition, bevy_rapier2d::prelude::SharedShape, bevy_rapier2d::prelude::ColliderFlags)]>>::Output == (bevy::prelude::Entity, bevy_rapier2d::prelude::ColliderPosition, bevy_rapier2d::prelude::SharedShape, bevy_rapier2d::prelude::ColliderFlags)

error[E0621]: explicit lifetime required in the type of shape
--> src\pathfinding.rs:129:10
|
114 | shape: &dyn Shape,
| ---------- help: add explicit lifetime 'static to the type of shape: &'static (dyn bevy_rapier2d::prelude::Shape + 'static)
...
129 | pool.spawn(async {
| ^^^^^ lifetime 'static required

error[E0621]: explicit lifetime required in the type of query_pipeline
--> src\pathfinding.rs:129:10
|
112 | query_pipeline: &QueryPipeline,
| -------------- help: add explicit lifetime 'static to the type of query_pipeline: &'static bevy_rapier2d::prelude::QueryPipeline
...
129 | pool.spawn(async {
| ^^^^^ lifetime 'static required

This is probably a more advanced use case, and I'm not sure what the plugin might do to make this easier. Maybe even an example of snapshotting collision data and accessing it in a pool would be useful? There are some obvious mistakes in my Shapes code--Rust Analyzer's automatic import added a few broken paths, for instance--but I feel like I'm adding mud to an existing mess rather than working toward a solution. Alternately, I'm not sure if there's a better solution to my pathfinding issue than taking physical shapes into account, but I had enough special cases for handling bad data that I thought it might help to prevent that bad data from being generated in the first place.

Thanks.

Moving physics hooks' initialization breaks them

I've hit an issue where collision hooks don't run in my game, no matter where I put them.

I changed the contact_filter2.rs example in a way that duplicates this behavior. I initialize the PhysicsHooksWithQueryObject resource in app initialization, which makes more sense to me since it's where I configure my other Bevy plugins. But this change seems to break the hooks such that they don't run. Even if I initialize my hooks in another startup system, they don't seem to work, so I'm wondering if something is trashing the resource without first checking if it exists and leaving it alone if it does? No matter where I insert this resource in my own game, it never runs even though I configure the hooks on the collider.

Here is the modified broken example:

extern crate rapier2d as rapier; // For the debug UI.

use bevy::prelude::*;
use bevy_rapier2d::prelude::*;

use bevy::render::pass::ClearColor;
use rapier::geometry::SolverFlags;
use rapier2d::pipeline::{PairFilterContext, PhysicsPipeline};
use ui::DebugUiPlugin;

#[path = "../../src_debug_ui/mod.rs"]
mod ui;

#[derive(PartialEq, Eq, Clone, Copy)]
enum CustomFilterTag {
    GroupA,
    GroupB,
}

impl CustomFilterTag {
    fn with_id(id: usize) -> Self {
        if id % 2 == 0 {
            Self::GroupA
        } else {
            Self::GroupB
        }
    }
}

// A custom filter that allows contacts only between rigid-bodies with the
// same user_data value.
// Note that using collision groups would be a more efficient way of doing
// this, but we use custom filters instead for demonstration purpose.
struct SameUserDataFilter;
impl<'a> PhysicsHooksWithQuery<&'a CustomFilterTag> for SameUserDataFilter {
    fn filter_contact_pair(
        &self,
        context: &PairFilterContext<RigidBodyComponentsSet, ColliderComponentsSet>,
        tags: &Query<&'a CustomFilterTag>,
    ) -> Option<SolverFlags> {
        println!("Here");
        if tags.get(context.collider1.entity()).ok().copied()
            == tags.get(context.collider2.entity()).ok().copied()
        {
            Some(SolverFlags::COMPUTE_IMPULSES)
        } else {
            None
        }
    }
}

fn main() {
    App::build()
        .insert_resource(ClearColor(Color::rgb(
            0xF9 as f32 / 255.0,
            0xF9 as f32 / 255.0,
            0xFF as f32 / 255.0,
        )))
        .insert_resource(Msaa::default())
        .add_plugins(DefaultPlugins)
        .add_plugin(bevy_winit::WinitPlugin::default())
        .add_plugin(bevy_wgpu::WgpuPlugin::default())
        .insert_resource(PhysicsHooksWithQueryObject(Box::new(SameUserDataFilter {})))
        .add_plugin(RapierPhysicsPlugin::<&CustomFilterTag>::default())
        .add_plugin(RapierRenderPlugin)
        .add_plugin(DebugUiPlugin)
        .add_startup_system(setup_graphics.system())
        .add_startup_system(setup_physics.system())
        .add_startup_system(enable_physics_profiling.system())
        .run();
}

fn enable_physics_profiling(mut pipeline: ResMut<PhysicsPipeline>) {
    pipeline.counters.enable()
}

fn setup_graphics(mut commands: Commands, mut configuration: ResMut<RapierConfiguration>) {
    configuration.scale = 10.0;

    let mut camera = OrthographicCameraBundle::new_2d();
    camera.transform = Transform::from_translation(Vec3::new(0.0, 200.0, 0.0));
    commands.spawn_bundle(LightBundle {
        transform: Transform::from_translation(Vec3::new(1000.0, 10.0, 2000.0)),
        light: Light {
            intensity: 100_000_000_.0,
            range: 6000.0,
            ..Default::default()
        },
        ..Default::default()
    });
    commands.spawn_bundle(camera);
}

pub fn setup_physics(mut commands: Commands) {
    /*
     * Ground
     */

    let ground_size = 10.0;

    let collider = ColliderBundle {
        shape: ColliderShape::cuboid(ground_size, 1.2),
        position: [0.0, -10.0].into(),
        ..Default::default()
    };
    commands
        .spawn_bundle(collider)
        .insert(ColliderDebugRender::default())
        .insert(ColliderPositionSync::Discrete)
        .insert(CustomFilterTag::GroupA);

    let collider = ColliderBundle {
        shape: ColliderShape::cuboid(ground_size, 1.2),
        ..Default::default()
    };
    commands
        .spawn_bundle(collider)
        .insert(ColliderDebugRender::default())
        .insert(ColliderPositionSync::Discrete)
        .insert(CustomFilterTag::GroupB);
    /*
     * Create the cubes
     */
    let num = 4;
    let rad = 0.5;

    let shift = rad * 2.0;
    let centerx = shift * (num as f32) / 2.0;
    let centery = shift / 2.0;
    let mut color = 0;

    for i in 0..num {
        for j in 0usize..num * 5 {
            let x = (i as f32 + j as f32 * 0.2) * shift - centerx;
            let y = j as f32 * shift + centery + 2.0;
            color += 1;

            // Build the rigid body.
            let body = RigidBodyBundle {
                position: [x, y].into(),
                ..Default::default()
            };

            let collider = ColliderBundle {
                shape: ColliderShape::cuboid(rad, rad),
                flags: ColliderFlags {
                    active_hooks: ActiveHooks::FILTER_CONTACT_PAIRS,
                    ..Default::default()
                },
                ..Default::default()
            };
            commands
                .spawn_bundle(body)
                .insert_bundle(collider)
                .insert(ColliderDebugRender::with_id(color % 2))
                .insert(ColliderPositionSync::Discrete)
                .insert(CustomFilterTag::with_id(color));
        }
    }
}

Collider shapes cause unwanted `Transform` scaling with ColliderDebugRender

An entity spawned like so:

commands
    .spawn_bundle(ColliderBundle {
        shape: ColliderShape::cuboid(0.2, 0.4, 0.2),
        ..Default::default()
    })
    .insert(ColliderDebugRender::with_id(1));

ends up with a Transform::scale value of [0.2, 0.4, 0.2]. This is troublesome for child entities, which inherit the scale of their parent; to avoid inheriting the parent's scale, a child of an entity with a ColliderBundle needs to transform itself by the inverse of its parent's scale.

In particular, this seems to preclude an entity with a ColliderBundle from parenting another entity with a ColliderBundle if any of the colliders' dimensions are not 1.

The issue only seems to appear with entities with a ColliderDebugRender. Removing that component causes the scale to return to [1, 1, 1] as expected.

bevy_rapier2d 0.1.0 fails to build on WASM

I have a bevy game that runs both natively and in the browser using WASM. However, after adding bevy_rapier2d to my Cargo.toml, like this...

bevy_rapier2d = { version="0.10.0", features = ["wasm-bindgen"] } 

...the project fails to build for WASM (cargo build --target wasm32-unknown-unknown --release) with the following error:

   Compiling bevy_rapier2d v0.10.0
error[E0277]: `T` cannot be shared between threads safely
   --> ...\Cargo\registry\src\github.com-1ecc6299db9ec823\bevy_rapier2d-0.10.0\src\physics\resources.rs:309:19
    |
284 | pub trait PhysicsHooksWithQuery<UserData: WorldQuery>: Send + Sync {
    |                                                               ---- required by this bound in `resources::PhysicsHooksWithQuery`
...
309 | impl<T, UserData> PhysicsHooksWithQuery<UserData> for T
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be shared between threads safely
    |
help: consider further restricting this bound
    |
314 |     > + Sync,
    |       ^^^^^^

error[E0277]: `T` cannot be sent between threads safely
   -->..\Cargo\registry\src\github.com-1ecc6299db9ec823\bevy_rapier2d-0.10.0\src\physics\resources.rs:309:19
    |
284 | pub trait PhysicsHooksWithQuery<UserData: WorldQuery>: Send + Sync {
    |                                                        ---- required by this bound in `resources::PhysicsHooksWithQuery`
...
309 | impl<T, UserData> PhysicsHooksWithQuery<UserData> for T
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be sent between threads safely
    |
help: consider further restricting this bound
    |
314 |     > + Send,
    |       ^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
error: could not compile `bevy_rapier2d`

However, when I build it natively (cargo build --release), it works perfectly fine. Any ideas?

I tried both nightly and stable toolchains.

(This is on Windows btw, if that matters)

Expose up to date contact impulses

I want to play audio in response to collisions. There are already ways to respond to collisions but none of them contains up to date impulses because the logic happens between collision detection and collision response.

The details are in step_generic in physics_pipeline.rs. It runs detect_collisions towards the end of each substep after velocities and positions have been updated. This will erase the information about impulses for all contacts that are no longer touching. I think it would make sense to add a new event or a hook to publish the correct impulses before calling detect_collisions.

Improve ergonomics `Position.position` and `position.next_position`

Intellectually I get why we have position.position.foo and position.next_position.foo but it still trips me up every time. I have two suggestions of potentially increasing controversy:

  1. Rename position.position to position.current and position.next_position to position.next. This, to me, feels much cleaner than position.position which makes me wonder why every time. :)
  2. Make the top-level RigidBodyPosition component Deref and DerefMut to the position field. I'd argue that in most instances, someone is accessing the current position directly and has no interest in manually setting the next position. In cases where they are, position.next is a concise indicator of what they intend.

Thanks.

UI Rendering Glitches After Spawning Multiple Entities

bevy_rapier version: https://github.com/indiv0/bevy_rapier/tree/5d19dc991cc3f18d9012524d08ff30ade915a2ae
bevy_webgl2 version: https://github.com/indiv0/bevy_webgl2/tree/a53c9ca296a46019d833da9be6f69f099ac63159
bevy version: https://github.com/bevyengine/bevy/tree/2e2423139e0cd8efda3aa0d474d3eb231dad566b
Example source: https://github.com/indiv0/colonize/tree/75ee66f710a4b9444a4b2119f27422e6fdeb3723
Example compilation args:

cargo build --target wasm32-unknown-unknown --no-default-features --features wasm
wasm-bindgen --out-dir target --target web target/wasm32-unknown-unknown/debug/colonize.wasm
wasm-opt --debuginfo -Oz target/colonize_bg.wasm -o target/colonize_bg_opt.wasm
sed -i 's/_bg\.wasm/_bg_opt\.wasm/g' target/colonize.js

Example demo: https://dev.colonize.rs/
rustc version: rustc 1.50.0-nightly (f0f68778f 2020-12-09)

Hello!

I have a game I'm working on. Currently you can spawn cubes in the game by pressing T.
This will attempt to spawn cubes in the air in some radius above the origin coordinate.

On some platforms (Firefox on Windows on my laptop) I've observed behaviour where if I spawn a lot of cubes at once
the UI begins to glitch out. It's not a framerate issue, but rather meshes start being drawn/not drawn at random.

You can see an example of the behaviour here:
Rendering example

I think this might be caused by me spawning rigid bodies/colliders within one another since my spawning algorithm doesn't prevent that, but what's weird is that it doesn't happen on any other device I've tested.

lock_rotations() does not seem to work when the rigid body has multiple colliders attached to it

Hello ! I am a beginner with bevy_rapier so maybe it's just me not using the function properly.

If you run the 'multiple_colliders2' and 'multiple_colliders3' examples with bevy_rapier v0.7.0 (the same happens with bevy_rapier v0.6.2) after adding the lock_rotations() function to the RigidBodyBuilder, the rigid bodies still rotate but if you attach only one collider they don't.

So I think that when you create a rigid body and you attach more than one collider to it, it can rotate because of forces even if you use lock_rotations().

Fast-forwarding the simulation

Quick question, is it possible to fast-forward the physics simulation? E.g. if I want to run 10 physics steps per frame instead of 1, which makes the simulation run 10x as fast?

Support for bevy::math::Vec3 in addition to nalgebra vectors

I think it would be fitting for a bevy plugin to accept bevy's vector type.

Currently I do the following to use RapierConfiguration:

use bevy::prelude::*;
use bevy_rapier3d::physics::{RapierPhysicsPlugin, RapierConfiguration};
use bevy_rapier3d::rapier::na::Vector;

fn main() {
    App::build()
        .add_plugins(DefaultPlugins)
        .add_plugin(RapierPhysicsPlugin)
        .add_resource(RapierConfiguration {
            gravity: Vector::y(),
            ..Default::default()
        })
        .run();
}

It would be nice if there was a way to use Bevy's Vec3 type rather than having to import nalgebra's vector.
Ultimately, I don't think anything can implement From or Into for this besides nalgebra (which shouldn't depend/care about Bevy of course), but functions in bevy_rapier could be made generic to accept Bevy's Vec3:

        .add_resource(RapierConfiguration {
            gravity: Vec3::unit_y(),
            ..Default::default()
        })

Unable to query PhysicsPipeline with WASM build

Hi,

I tried to port the boxes2d example to WebAssembly using bevy_wegl2.

So far it works quite good, except I get an error that it cannot query PhysicsPipeline:

panicked at 'Resource requested by app::rapier::enable_physics_profiling does not exist: rapier2d::pipeline::physics_pipeline::PhysicsPipeline', /home/marior/.cargo/git/checkouts/bevy-f7ffde730c324c74/43d99bb/crates/bevy_ecs/src/system/system_param.rs:416:17

To reproduce this you can clone this repository.
Then run:

yarn install
yarn start

and wait for it to finish the bundle and serve it at http://localhost:8080. This could take a while.

I use forks of bevy_rapier and bevy_webgl2, which mostly just point to bevy's Github repo instead of the crates.io version.

I'm wondering how this can happen, because the plugin clearly provides the resource.

Raycasting roadmap priority

Hi,
I am wondering where raycasting is on the priority list. Do you have even a wild guess on when it might drop?
Is it a matter of migrating the code over from nphysics with changes to support parallelism or is it an entire rewrite? Will it still use ncollide on the back end to process it?

I am not opposed to contributing at some point but I am so green with regards to rust that it might be a bit.
Thanks for the great project and great work!

CPU usages is just ~13% even after setting everything correctly

OS: Ubuntu 20.04
Bevy: 0.5
Bevy Rapier: 10.02
CPU: Ryzen 4600H

Set the features: https://github.com/Nickan/bevytest/blob/master/Cargo.toml
Set the profile.release https://github.com/Nickan/bevytest/blob/master/.cargo/config
And the run cargo run --release

Added just 30000 ColliderBundles: https://github.com/Nickan/bevytest/blob/6df6ea9c40838c2cb138355813074f547f891903/src/main.rs#L45

RapierConfiguration::query_pipeline_active to false jumps the fps to 60fps

Actual Result: Still I am just getting ~20fps and only using 13% of CPU

Expected Result: 60fps and use more than 13% of CPU

Edit: Updated CPU percent

ColliderBuilder::trimesh() panics

I am getting the error below when I am trying to use ColliderBuilder::trimesh(), I am using it to create an equilateral triangle here: https://github.com/Nickan/bevytest/blob/c84b384692dc59d5a5182f8fb51f9a27ad98cd2f/src/main.rs#L89

I don't have a clue what's wrong, the mesh is rendering correctly in Bevy, need help. Thanks.

thread 'Compute Task Pool (0)' panicked at 'attempt to subtract with overflow', /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier3d-0.2.0/src/geometry/wquadtree.rs:553:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'Compute Task Pool (1)' panicked at 'task has failed', /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.2/src/task.rs:368:45
thread 'main' panicked at 'task has failed', /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.2/src/task.rs:368:45
thread 'main' panicked at 'task thread panicked while executing: Any', /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.2.1/src/task_pool.rs:72:18
stack backtrace:
thread '<unnamed>' panicked at 'loaded asset should have been sent: "SendError(..)"', /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_asset-0.2.1/src/load_request.rs:71:14
   0:     0x55b6afadb1d0 - std::backtrace_rs::backtrace::libunwind::trace::ha1eabb142084ea37
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
   1:     0x55b6afadb1d0 - std::backtrace_rs::backtrace::trace_unsynchronized::hbb8825661d997281
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/../../backtrace/src/backtrace/mod.rs:66
   2:     0x55b6afadb1d0 - std::sys_common::backtrace::_print_fmt::h26d850e2f7183914
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/sys_common/backtrace.rs:79
   3:     0x55b6afadb1d0 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h3834b06f68a2b012
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/sys_common/backtrace.rs:58
   4:     0x55b6afb0358c - core::fmt::write::h3a043650ba7bf668
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/core/src/fmt/mod.rs:1117
   5:     0x55b6afad45c7 - std::io::Write::write_fmt::h9c0c8944a1898139
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/io/mod.rs:1514
   6:     0x55b6afaddad0 - std::sys_common::backtrace::_print::h693c0c2cc41d4d10
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/sys_common/backtrace.rs:61
   7:     0x55b6afaddad0 - std::sys_common::backtrace::print::h213be73e5670b8ea
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/sys_common/backtrace.rs:48
   8:     0x55b6afaddad0 - std::panicking::default_hook::{{closure}}::h2d49a3361cc4e7ea
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panicking.rs:200
   9:     0x55b6afadd81c - std::panicking::default_hook::hd41fbdeba93207ba
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panicking.rs:219
  10:     0x55b6afade133 - std::panicking::rust_panic_with_hook::hcab398664b4bd473
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panicking.rs:569
  11:     0x55b6afaddd09 - std::panicking::begin_panic_handler::{{closure}}::h7512c6f2998ba93d
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panicking.rs:476
  12:     0x55b6afadb63c - std::sys_common::backtrace::__rust_end_short_backtrace::h1a25d7e7e1864d3d
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/sys_common/backtrace.rs:153
  13:     0x55b6afaddcc9 - rust_begin_unwind
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panicking.rs:475
  14:     0x55b6afb01141 - core::panicking::panic_fmt::h019ad16a92ccd092
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/core/src/panicking.rs:85
  15:     0x55b6afb00f63 - core::option::expect_none_failed::h7135ba2fdb185931
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/core/src/option.rs:1221
  16:     0x55b6afa4943a - core::result::Result<T,E>::expect::h8e0bac004cb13223
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:933
  17:     0x55b6afa3ac20 - <bevy_tasks::task_pool::TaskPoolInner as core::ops::drop::Drop>::drop::h8e54d09f800cedb4
                               at /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.2.1/src/task_pool.rs:70
  18:     0x55b6afa40162 - core::ptr::drop_in_place::h5c8e0b8e0efafe11
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  19:     0x55b6af99c8dd - alloc::sync::Arc<T>::drop_slow::h4e84094f8b74ce3d
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:840
  20:     0x55b6af99cba3 - <alloc::sync::Arc<T> as core::ops::drop::Drop>::drop::h62841db8b8d95c03
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:1360
  21:     0x55b6af9b42a7 - core::ptr::drop_in_place::h499643d305fdc820
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  22:     0x55b6af9b3c7f - core::ptr::drop_in_place::h0bb54f55a41cf6e2
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  23:     0x55b6af9b5277 - core::ptr::drop_in_place::hec1b4d371d334b32
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  24:     0x55b6af9855e7 - core::ptr::mut_ptr::<impl *mut T>::drop_in_place::h4eaeead91e73b907
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:1000
  25:     0x55b6af974115 - bevy_hecs::archetype::TypeInfo::of::drop_ptr::h337b20aff82147f2
                               at /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_hecs-0.2.1/src/archetype.rs:487
  26:     0x55b6afaabf38 - bevy_hecs::archetype::Archetype::clear::hdcc08d95bd389f07
                               at /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_hecs-0.2.1/src/archetype.rs:85
  27:     0x55b6afaad31e - <bevy_hecs::archetype::Archetype as core::ops::drop::Drop>::drop::h4713e387de577ff4
                               at /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_hecs-0.2.1/src/archetype.rs:419
  28:     0x55b6afab35f2 - core::ptr::drop_in_place::h0285bedc71b244e6
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  29:     0x55b6af984e72 - core::ptr::drop_in_place::haa06b97eca578020
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  30:     0x55b6af9852ce - core::ptr::drop_in_place::hca6e5c95e287815d
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  31:     0x55b6af96b517 - core::ptr::mut_ptr::<impl *mut T>::drop_in_place::h73f68efb854bb8f1
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:1000
  32:     0x55b6af976745 - hashbrown::raw::Bucket<T>::drop::h206661a37ebb5945
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.8.2/src/raw/mod.rs:334
  33:     0x55b6af975f3c - <hashbrown::raw::RawTable<T> as core::ops::drop::Drop>::drop::hd0fc5e42815de58f
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.8.2/src/raw/mod.rs:1292
  34:     0x55b6af984737 - core::ptr::drop_in_place::h37c4ea20e0b1a17b
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  35:     0x55b6af984bee - core::ptr::drop_in_place::h8ab2f2c3893acdff
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  36:     0x55b6af984a47 - core::ptr::drop_in_place::h5a2cca079b0385be
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  37:     0x55b6af9852e7 - core::ptr::drop_in_place::hd23e12fcd8540e35
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  38:     0x55b6af984970 - core::ptr::drop_in_place::h4df16b15061e9f78
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  39:     0x55b6af9819b1 - bevy_app::app::App::run::he4d61dc1a539e67c
                               at /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.2.1/src/app.rs:83
  40:     0x55b6af9825af - bevy_app::app_builder::AppBuilder::run::h4802f305118353d2
                               at /home/nickan/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.2.1/src/app_builder.rs:45
  41:     0x55b6add9251a - client::main::h365c0e5b8c2cefef
                               at /home/nickan/gamedev/src/ironverse/client/src/main.rs:18
  42:     0x55b6add29283 - core::ops::function::FnOnce::call_once::h2cd5851c4bd5fc0e
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:233
  43:     0x55b6ade5a399 - std::sys_common::backtrace::__rust_begin_short_backtrace::hc7fcf7bbc48ab8ba
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:137
  44:     0x55b6ade5a4e9 - std::rt::lang_start::{{closure}}::hc4deb8e96ce55c44
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:66
  45:     0x55b6afade51e - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hde9814ae740a85dc
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/core/src/ops/function.rs:265
  46:     0x55b6afade51e - std::panicking::try::do_call::h3026bab8cd7540d7
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panicking.rs:373
  47:     0x55b6afade51e - std::panicking::try::h852bb5e5a66f7f84
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panicking.rs:337
  48:     0x55b6afade51e - std::panic::catch_unwind::hfeb0f3dddf7c6a72
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/panic.rs:379
  49:     0x55b6afade51e - std::rt::lang_start_internal::h32f0ac6e87476559
                               at /rustc/de521cbb303c08febd9fa3755caccd4f3e491ea3/library/std/src/rt.rs:51
  50:     0x55b6ade5a4c8 - std::rt::lang_start::h21dab0570b6fe43f
                               at /home/nickan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:65
  51:     0x55b6add9257a - main
  52:     0x7f49e9eb3b97 - __libc_start_main
  53:     0x55b6add2802a - _start
  54:                0x0 - <unknown>
thread panicked while panicking. aborting.
Illegal instruction (core dumped)
Makefile:60: recipe for target 'c' failed
make: *** [c] Error 132

Collider not moving with RigidBody

I have a SpriteComponents that has a RigidBody & Collider attached, but the collider doesn't seem to move along with the RigidBody. I have a debug system that prints out the location of both, which reports that the collider is not moving off the starting location (despite having the correct starting location associated with the rigid body).

2020-10-03T06:00:07Z DEBUG tntw::physics] new rigid body
[2020-10-03T06:00:07Z DEBUG tntw::physics] new rigid body
[2020-10-03T06:00:08Z TRACE tntw::physics] entity 2v0 at (50, 0)
[2020-10-03T06:00:08Z TRACE tntw::physics] entity 4v0 at (-50, 0)
[2020-10-03T06:00:08Z TRACE tntw::physics] collider Index { index: 0, generation: 0 } at (50, 0)
[2020-10-03T06:00:08Z TRACE tntw::physics] collider Index { index: 1, generation: 0 } at (-50, 0)
[2020-10-03T06:00:09Z TRACE tntw::physics] entity 2v0 at (50, 0)
[2020-10-03T06:00:09Z TRACE tntw::physics] entity 4v0 at (-50, 0)
[2020-10-03T06:00:09Z TRACE tntw::physics] collider Index { index: 0, generation: 0 } at (50, 0)
[2020-10-03T06:00:09Z TRACE tntw::physics] collider Index { index: 1, generation: 0 } at (-50, 0)
# move command issued
[2020-10-03T06:00:10Z TRACE tntw::physics] entity 2v0 at (6.74163, -1.6019167)
[2020-10-03T06:00:10Z TRACE tntw::physics] entity 4v0 at (-50, 0)
[2020-10-03T06:00:10Z TRACE tntw::physics] collider Index { index: 0, generation: 0 } at (50, 0)
[2020-10-03T06:00:10Z TRACE tntw::physics] collider Index { index: 1, generation: 0 } at (-50, 0)
[2020-10-03T06:00:11Z TRACE tntw::physics] entity 2v0 at (-44.039185, -3.4823992)
[2020-10-03T06:00:11Z TRACE tntw::physics] entity 4v0 at (-50, 0)
[2020-10-03T06:00:11Z TRACE tntw::physics] collider Index { index: 0, generation: 0 } at (50, 0)
[2020-10-03T06:00:11Z TRACE tntw::physics] collider Index { index: 1, generation: 0 } at (-50, 0)

The setup code is as follows, from https://github.com/jmrgibson/tntw/blob/master/src/main.rs#L89

    for (x, y) in unit_start_positions.into_iter() {
        
        let body = RigidBodyBuilder::new_dynamic().translation(x, y);
        let collider = ColliderBuilder
            ::cuboid(unit_size, unit_size)
            .sensor(true);

        commands
            .spawn(SpriteComponents {
                material: selection_materials.normal.into(),
                transform: Transform::from_translation(Vec3::new(x, y, 1.0)),
                sprite: Sprite::new(Vec2::new(unit_size, unit_size)),
                ..Default::default()
            })
            .with(Unit::default())
            .with(Waypoint::default())
            .with_bundle((body, collider))

Is this because I'm using body.set_position() to update the position of the rigidbody?

None of the examples work on current master branch

Hello, I've been trying to run the examples after doing a simple git clone but all I get is a crash (and not the nice kind ๐Ÿ˜„ ):

thread 'Compute Task Pool (10)' panicked at 'Resource does not exist alloc::boxed::Box<dyn bevy_render::renderer::render_resource_context::RenderResourceContext>', /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.3.0/src/resource/resources.rs:298:32
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'Compute Task Pool (11)' panicked at 'Resource does not exist alloc::boxed::Box<dyn bevy_render::renderer::render_resource_context::RenderResourceContext>', /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.3.0/src/resource/resources.rs:298:32
thread 'Compute Task Pool (13)' panicked at 'task has failed', /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/task.rs:368:45
thread 'main' panicked at 'task has failed', /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/task.rs:368:45
thread 'main' panicked at 'task thread panicked while executing: Any', /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.3.0/src/task_pool.rs:75:18
stack backtrace:
   0:     0x5646f73c4000 - std::backtrace_rs::backtrace::libunwind::trace::h577ea05e9ca4629a
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
   1:     0x5646f73c4000 - std::backtrace_rs::backtrace::trace_unsynchronized::h50b9b72b84c7dd56
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/../../backtrace/src/backtrace/mod.rs:66
   2:     0x5646f73c4000 - std::sys_common::backtrace::_print_fmt::h6541cf9823837fac
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:79
   3:     0x5646f73c4000 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hf64fbff071026df5
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:58
   4:     0x5646f73e565c - core::fmt::write::h9ddafa4860d8adff
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/fmt/mod.rs:1082
   5:     0x5646f73c1617 - std::io::Write::write_fmt::h1d2ee292d2b65481
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/io/mod.rs:1514
   6:     0x5646f73c6320 - std::sys_common::backtrace::_print::ha25f9ff5080d886d
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:61
   7:     0x5646f73c6320 - std::sys_common::backtrace::print::h213e8aa8dc5405c0
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:48
   8:     0x5646f73c6320 - std::panicking::default_hook::{{closure}}::h6482fae49ef9d963
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:200
   9:     0x5646f73c606c - std::panicking::default_hook::he30ad7589e0970f9
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:219
  10:     0x5646f73c6983 - std::panicking::rust_panic_with_hook::haa1ed36ada4ffb03
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:569
  11:     0x5646f73c6559 - std::panicking::begin_panic_handler::{{closure}}::h7001af1bb21aeaeb
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:476
  12:     0x5646f73c448c - std::sys_common::backtrace::__rust_end_short_backtrace::h39910f557f5f2367
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/sys_common/backtrace.rs:153
  13:     0x5646f73c6519 - rust_begin_unwind
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:475
  14:     0x5646f73e34d1 - core::panicking::panic_fmt::h4e2659771ebc78eb
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/panicking.rs:85
  15:     0x5646f73e32f3 - core::option::expect_none_failed::h448b58a024c2c33a
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/option.rs:1221
  16:     0x5646f716db76 - core::result::Result<T,E>::expect::h0471d7f662a3e0b0
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:933
  17:     0x5646f7162a48 - <bevy_tasks::task_pool::TaskPoolInner as core::ops::drop::Drop>::drop::h1ee0865263a8cc95
                               at /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.3.0/src/task_pool.rs:73
  18:     0x5646f7161f06 - core::ptr::drop_in_place::hd696189e8fec61f4
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  19:     0x5646f712fb14 - alloc::sync::Arc<T>::drop_slow::hc1577fa02e8a40fb
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:934
  20:     0x5646f712ff36 - <alloc::sync::Arc<T> as core::ops::drop::Drop>::drop::h6297633483556a56
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/sync.rs:1454
  21:     0x5646f712ccdf - core::ptr::drop_in_place::h20d4a1282243e947
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  22:     0x5646f712e7a1 - core::ptr::drop_in_place::hefa8de62f547a4bd
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  23:     0x5646f712cd9f - core::ptr::drop_in_place::h2af9e6883f61ecc4
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  24:     0x5646f712e9db - core::ptr::mut_ptr::<impl *mut T>::drop_in_place::hc3aef1eacb23f9da
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:963
  25:     0x5646f713176f - bevy_hecs::archetype::TypeInfo::of::drop_ptr::h989d92051da5268a
                               at /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_hecs-0.3.0/src/archetype.rs:493
  26:     0x5646f71dd929 - bevy_hecs::archetype::Archetype::clear::hb1ad12cab40a1163
                               at /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_hecs-0.3.0/src/archetype.rs:88
  27:     0x5646f71df0b3 - <bevy_hecs::archetype::Archetype as core::ops::drop::Drop>::drop::h9069d781b4e0f6a1
                               at /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_hecs-0.3.0/src/archetype.rs:424
  28:     0x5646f71c9206 - core::ptr::drop_in_place::h5a5faa7a9f2bfa33
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  29:     0x5646f712d6f6 - core::ptr::drop_in_place::h79e49295e133eb4e
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  30:     0x5646f712c936 - core::ptr::drop_in_place::h04fbb348e6716c00
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  31:     0x5646f710d7db - core::ptr::mut_ptr::<impl *mut T>::drop_in_place::h8549b5e438db27a4
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:963
  32:     0x5646f70f279f - hashbrown::raw::Bucket<T>::drop::hd78df31ea57baae9
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.8.2/src/raw/mod.rs:334
  33:     0x5646f70f0b06 - <hashbrown::raw::RawTable<T> as core::ops::drop::Drop>::drop::hab388faa5bb20afb
                               at /cargo/registry/src/github.com-1ecc6299db9ec823/hashbrown-0.8.2/src/raw/mod.rs:1292
  34:     0x5646f712d33f - core::ptr::drop_in_place::h5c3e54056a2306b7
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  35:     0x5646f712e016 - core::ptr::drop_in_place::hbb6cd912752ad259
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  36:     0x5646f712e98f - core::ptr::drop_in_place::hfeeaba5cc2e234b0
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  37:     0x5646f70e3926 - core::ptr::drop_in_place::h59ab487fa838f3f3
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  38:     0x5646f70e42d8 - core::ptr::drop_in_place::hb2d86bc45406f676
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:184
  39:     0x5646f70e2a48 - bevy_app::app::run_once::h3e1145fa153c5801
                               at /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.3.0/src/app.rs:53
  40:     0x5646f70e2df0 - core::ops::function::Fn::call::h657d1f2fc745e704
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:70
  41:     0x5646f70e91da - <alloc::boxed::Box<F> as core::ops::function::Fn<A>>::call::he21fa542dda40a01
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:1056
  42:     0x5646f70e2ce9 - bevy_app::app::App::run::hf13156cd7dd3b398
                               at /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.3.0/src/app.rs:81
  43:     0x5646f70ef005 - bevy_app::app_builder::AppBuilder::run::hd6f21adcfd01248b
                               at /home/dimitri/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_app-0.3.0/src/app_builder.rs:43
  44:     0x5646f67f0eb9 - boxes2::main::h5c4a4f423a96f49b
                               at /home/dimitri/gits/bevy_rapier/bevy_rapier2d/examples/boxes2.rs:16
  45:     0x5646f67dae6b - core::ops::function::FnOnce::call_once::hf99d6a902a97212d
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227
  46:     0x5646f67f27ae - std::sys_common::backtrace::__rust_begin_short_backtrace::hd7b87dfc1e7da85c
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/backtrace.rs:137
  47:     0x5646f67eb811 - std::rt::lang_start::{{closure}}::h3f55fcfa98729fac
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:66
  48:     0x5646f73c6d81 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h6a3209f124be2235
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/core/src/ops/function.rs:259
  49:     0x5646f73c6d81 - std::panicking::try::do_call::h88ce358792b64df0
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:373
  50:     0x5646f73c6d81 - std::panicking::try::h6311c259678e50fc
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:337
  51:     0x5646f73c6d81 - std::panic::catch_unwind::h56c5716807d659a1
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panic.rs:379
  52:     0x5646f73c6d81 - std::rt::lang_start_internal::h73711f37ecfcb277
                               at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/rt.rs:51
  53:     0x5646f67eb7e7 - std::rt::lang_start::hc004543f065fb8f5
                               at /home/dimitri/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:65
  54:     0x5646f67f1c7a - main
  55:     0x7f4c1dd46cb2 - __libc_start_main
  56:     0x5646f67cf03e - _start
  57:                0x0 - <unknown>
thread panicked while panicking. aborting.
Illegal instruction (core dumped)

I get similar crashes on other examples as well. So far none have worked for me.

I run the examples from the root of the repository using cargo run --example boxes2 so It's not a duplicate of #2.

Invasive RapierRenderPlugin

the RapierRenderPlugin from bevy_rapier is a nice touch ! But as I was testing my project, it's incompatible with my system, I'll explain:

My setup

  • I have configuration scale set to 1 for now so I'm not mentally switching scales.
  • I have ball shapes at around 20 radius
  • I have child sprites to these ball shapes for different renders (face, selection, orientation, etc..) ; I made them child so they follow the physics "by design"

My issue

  • Now, when I use the RapierRenderPlugin, the sprites are added to each "root" physic Entities ; it's a minor problem because it's expecting the user NOT insert a spriteBundle to the same Entity (one would overwrite the other)
  • the RapierRenderPlugin scales its transform to fit the size of the collider, I think it's clever because it easily enables "squished" balls, but combined with minor issue above, it makes everything scaled very high, thus making the plugin useless (and iterfering with my transforms)

Proposed Solution

  • I think the RapierRenderPlugin should avoid at all costs to interfere with existing components, and spawn a new Entity as child, rather than inserting and modifying the existing ones.

Read-only API for EntityMap

It would be nice to have a read-only API for EntityMaps. Right now every member is marked as pub(crate), so there's no way to access them.

My particular use-case is to get an Entity that I hit with QueryPipeline::cast_ray. I hoped I could avoid linear search among all the spawned entities with ColliderHandle.

System order is undefined

Both Rapier's sync_transform_system and bevy's transform_propagate_system happen in POST_UPDATE in Bevy 0.3. As far as I know, ordering of systems is not guaranteed within a stage. When testing, there is a difference between the two orderings:

        .add_plugin(RapierPhysicsPlugin)
        .add_plugins(DefaultPlugins)

When sniffing translations, this gives sync updates to the GlobalTransform:

postupdate with
body Matrix { data: [0.0, 8.499997] }
transform Vec3(0.0, 8.166663, -5.0)
global Vec3(0.0, 8.166663, -5.0)
after postupdate
pb Matrix { data: [0.0, 8.499997] }
pt Vec3(0.0, 8.499997, -5.0)
pg Vec3(0.0, 8.499997, -5.0)

The opposite order results in globaltransform lagging (this carries over the entire frame):

        .add_plugins(DefaultPlugins)
        .add_plugin(RapierPhysicsPlugin)
postupdate with
pb Matrix { data: [0.0, 18.333336] }
pt Vec3(0.0, 18.000004, -5.0)
pg Vec3(0.0, 17.666672, -5.0)
next with
pb Matrix { data: [0.0, 18.333336] }
pt Vec3(0.0, 18.333336, -5.0)
pg Vec3(0.0, 18.000004, -5.0)

Perhaps it would make sense to create another named stage between UPDATE and POST_UPDATE just to update Transform positions? It would also make it possible to insert another custom updater in between Rapier and transform (trying to do that is how I found out there is a problem).

Rust API of Rapier vs JS API and Bevy_rapier rb Performance

The performance of the Web Assembly examples here are fantastic: https://rapier.rs/demos3d/index.html.

But when I tried the examples using the rust API "cargo run --bin all_examples3" I got terrible performance.
I tried using the Bevy_rapier plugin in a bevy project thinking it might be related to kiss but I ran into the same performance drop when spawning 500+ rigidbodies at start up .
The exe is only utilizing 10-30% of the cpu.

I am very new to rust and wondering if I am missing something dumb like a flag or something.
Thanks

Panic when using Bevy parenting

I tried to bevy_rapier 0.10 into my game project. But i was met with some issues namely this panic that occurs when you add a ColliderBundle to an entity that has a parent (in the Bevy sense).

Example code that exhibits the crash, adapted from one of your examples:

use bevy::prelude::*;
use bevy_rapier3d::prelude::*;

use rapier3d::pipeline::PhysicsPipeline;

fn main() {
    App::build()
        .add_plugins(DefaultPlugins)
        .add_plugin(bevy_winit::WinitPlugin::default())
        .add_plugin(bevy_wgpu::WgpuPlugin::default())
        .add_plugin(RapierPhysicsPlugin::<NoUserData>::default())
        .add_startup_system(setup_physics.system())
        .run();
}

pub fn setup_physics(mut commands: Commands) {
    let parent = commands
        .spawn_bundle((Transform::identity(), GlobalTransform::identity()))
        .id();

    let collider = ColliderBundle {
        shape: ColliderShape::cuboid(4.0, 1.2, 1.2),
        ..ColliderBundle::default()
    };

    commands
        .spawn_bundle(collider)
        // This next line is the offending code, uncomment and it works
        .insert(Parent(parent))
        .insert(ColliderDebugRender::default())
        .insert(ColliderPositionSync::Discrete);
}

Change system order so it's possible to have synchronized transforms for newly spawned entities

Right now, the ordering is:

create_body_and_collider_system --> bevy's transform_systems --> sync_transform_system

And that means no matter when you spawn, the entities will have one out-of-sync frame when the rigid body gets created. But if you change the ordering to:

create_body_and_collider_system --> sync_transform_system --> bevy's transform_systems

Then you can spawn on either side of that chain and you'll always be in sync.

Rendering collider/sprites/rigidbodies only half the time.

I'm creating a simple 2d platformer and for some reason the objects render to the screen correctly only half the time. As you can see below, all I have on the screen is a player, the ground, and invisibile left, right and top boundaries.

Working correctly

image

Below you can see that there is either a missing player, missing ground and boundaries, or nothing at all. I am not changing anything between taking these screen shots.

Missing everything

image

Missing player

image

Main function

fn main() {
    App::build()
        .insert_resource(WindowDescriptor {
            mode: WindowMode::Fullscreen { use_size: false },
            resizable: true,
            vsync: false,
            ..Default::default()
        })
        .insert_resource(ClearColor(Color::rgb(0.47, 0.78, 1.0)))
        .add_plugins(DefaultPlugins)
        .add_plugin(RapierPhysicsPlugin::<NoUserData>::default()) // required for 'RapierConfiguration'
        .add_plugin(RapierRenderPlugin) // required to render items
        .add_plugin(map::MapPlugin)
        .add_plugin(player::PlayerPlugin)
        .add_startup_system(setup.system())
        .run();
}

Player file

pub struct PlayerPlugin;

impl Plugin for PlayerPlugin {
    fn build(&self, app: &mut AppBuilder) {
        app.add_startup_system(spawn_player.system())
            .add_system(player_movement.system());
    }
}

fn spawn_player(
    mut commands: Commands,
    mut materials: ResMut<Assets<ColorMaterial>>,
    windows: Res<Windows>,
    config: Res<RapierConfiguration>,
) {
    let window = windows.get_primary().unwrap();

    let player_color = (0.69, 0.46, 0.05);
    let player_size = 4.0;
    let gravity = 1.0;

    // ensure player will start at left most position regardless of screen size
    let player_x = window.width() / 2.0 / config.scale - player_size - 5.0;

    let collider = ColliderBundle {
        shape: ColliderShape::cuboid(player_size, player_size),
        position: [-player_x, -10.0].into(),
        ..Default::default()
    };

    let rigid_body = RigidBodyBundle {
        body_type: RigidBodyType::Dynamic,
        damping: RigidBodyDamping {
            // linear_damping: 10.0,
            ..Default::default()
        },
        forces: RigidBodyForces {
            gravity_scale: gravity,
            ..Default::default()
        },

        // prevent player from rotating
        mass_properties: (RigidBodyMassPropsFlags::ROTATION_LOCKED).into(),
        ..Default::default()
    };

    // handles cosmetics
    let sprite = SpriteBundle {
        material: materials.add(Color::rgb(player_color.0, player_color.1, player_color.2).into()),
        sprite: Sprite::new(Vec2::new(1.0, 1.0)),
        ..Default::default()
    };

    commands
        .spawn()
        .insert_bundle(sprite)
        .insert_bundle(rigid_body)
        .insert_bundle(collider)
        // syncs the collider position width the sprite position
        .insert(ColliderPositionSync::Discrete)
        .insert(ColliderDebugRender::default())
        .insert(Player)
        .insert(Speed(PLAYER_SPEED));
}

Map File

pub struct MapPlugin;

impl Plugin for MapPlugin {
    fn build(&self, app: &mut AppBuilder) {
        app.add_startup_system(boundaries.system());
    }
}

fn boundaries(
    mut commands: Commands,
    windows: Res<Windows>,
    config: Res<RapierConfiguration>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    let window = windows.get_primary().unwrap();

    // width and height
    let width = 1.0;
    let height = window.height();

    let x = window.width() / 2.0 / config.scale + width;
    let y = 0.0;

    // a closure to use for the left, right, bottom and top colliders of the map
    let collider = |x: f32, y: f32, w: f32, h: f32| -> ColliderBundle {
        ColliderBundle {
            position: [x, y].into(),
            shape: ColliderShape::cuboid(w, h),
            ..Default::default()
        }
    };

    // right
    commands.spawn_bundle(collider(x, y, width, height));

    // left
    commands.spawn_bundle(collider(-x, y, width, height));

    // top
    let width = window.width() / 2.0;
    let height = 1.0;
    let x = 0.0;
    let y = window.height() / 2.0 / config.scale + height;

    commands.spawn_bundle(collider(x, y, width, height));

    // bottom
    let height = 5.0;

    let sprite = SpriteBundle {
        material: materials.add(Color::rgb(0.08, 0.58, 0.0).into()),
        // the sprite vector is directly proportionate to the collider size.
        // eg 1: a new vec of 'x: 1.0, y: 1.0' is the same exact size as the collider
        // eg 2: a vec of 'x: 2.0, y: 2.0' is twice as large as the collider
        sprite: Sprite::new(Vec2::new(1.0, 1.0)),
        ..Default::default()
    };

    commands
        .spawn()
        .insert_bundle(sprite)
        .insert_bundle(collider(x, -y, width, height))
        .insert(ColliderDebugRender::default())
        // syncs the collider position with the sprite position
        .insert(ColliderPositionSync::Discrete);
}

NOTE - These are not the entire files. I did not want to bloat this issue. I can update the code blocks with the entire files if need be.

Publish `bevy_rapier`

Only two flavours are available for bevy_rapier as 2D and 3D which is fine however, if a library is depending on the crate and also has an optional 2D or 3D varient, it becomes awkward to forward the features.

Which ends up looking like the below:

# 2D
dim2 = []
dim2-enhanced-determinism = ["bevy_rapier2d/enhanced-determinism"]
dim2-parallel = ["bevy_rapier2d/parallel"]
dim2-serde-serialize = ["bevy_rapier2d/serde-serialize"]
dim2-simd-nightly = ["bevy_rapier2d/simd-nightly"]
dim2-simd-stable = ["bevy_rapier2d/simd-stable"]
dim2-wasm-bindgen = ["bevy_rapier2d/wasm-bindgen"]

# 3D
dim3 = []
dim3-enhanced-determinism = ["bevy_rapier3d/enhanced-determinism"]
dim3-parallel = ["bevy_rapier3d/parallel"]
dim3-serde-serialize = ["bevy_rapier3d/serde-serialize"]
dim3-simd-nightly = ["bevy_rapier3d/simd-nightly"]
dim3-simd-stable = ["bevy_rapier3d/simd-stable"]
dim3-wasm-bindgen = ["bevy_rapier3d/wasm-bindgen"]

A solution would be simply just to publish bevy_rapier which allows people to conditionally feature gate it as they wish given context. Its just so much cleaner.

Then simply would end up looking like:

dim2 = []
dim3 = []
enhanced-determinism = ["bevy_rapier/enhanced-determinism"]
parallel = ["bevy_rapier/parallel"]
serde-serialize = ["bevy_rapier/serde-serialize"]
simd-nightly = ["bevy_rapier/simd-nightly"]
simd-stable = ["bevy_rapier/simd-stable"]
wasm-bindgen = ["bevy_rapier/wasm-bindgen"]

Joints as children?

Thanks for the lib, the docs and code. All very inspiring stuff :)

This might be a bevy API limitation, but I'm asking here anyway since it feels relevant to rapier usage. So I'm spawning a humanoid entity in a startup system, using commands.spawn() which then also is supposed to hold its body parts, spawned through with_children(|parent| { parent.spawn(); }). Now I want to create joints within that hierarchy, which need to be initialized with an entity.
The problem is that I can only run commands.current_entity() and because parent.current_entity() does not exist. I also can't run the former for borrowing-reasons (commands not being available in the closure).

Am I doing things wrong or might this be an API limitation?

Won't compile for wasm32-unknown-unknown

bevy_rapier is defined in my Cargo.toml as follows:

bevy_rapier3d = { version = "0.5.0", features = ["wasm-bindgen"] }

When I'm trying to compile my project for wasm32-unknown-unknown, it fails with the following errors:

error[E0425]: cannot find function `allocation_granularity` in this scope
 --> /home/mvlabat/.cargo/registry/src/github.com-1ecc6299db9ec823/slice-deque-0.3.0/src/mirrored/buffer.rs:7:14
  |
7 |     let ag = allocation_granularity();
  |              ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `allocation_granularity` in this scope
   --> /home/mvlabat/.cargo/registry/src/github.com-1ecc6299db9ec823/slice-deque-0.3.0/src/mirrored/buffer.rs:112:15
    |
112 |             * allocation_granularity();
    |               ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `allocation_granularity` in this scope
   --> /home/mvlabat/.cargo/registry/src/github.com-1ecc6299db9ec823/slice-deque-0.3.0/src/mirrored/buffer.rs:135:41
    |
135 |         assert!(mem::align_of::<T>() <= allocation_granularity());
    |                                         ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `allocation_granularity` in this scope
   --> /home/mvlabat/.cargo/registry/src/github.com-1ecc6299db9ec823/slice-deque-0.3.0/src/mirrored/buffer.rs:148:36
    |
148 |         debug_assert!(alloc_size % allocation_granularity() == 0);
    |                                    ^^^^^^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `allocate_mirrored` in this scope
   --> /home/mvlabat/.cargo/registry/src/github.com-1ecc6299db9ec823/slice-deque-0.3.0/src/mirrored/buffer.rs:151:19
    |
151 |         let ptr = allocate_mirrored(alloc_size)?;
    |                   ^^^^^^^^^^^^^^^^^ not found in this scope

error[E0425]: cannot find function `deallocate_mirrored` in this scope
   --> /home/mvlabat/.cargo/registry/src/github.com-1ecc6299db9ec823/slice-deque-0.3.0/src/mirrored/buffer.rs:172:18
    |
172 |         unsafe { deallocate_mirrored(first_half_ptr, buffer_size_in_bytes) };
    |                  ^^^^^^^^^^^^^^^^^^^ not found in this scope

error: aborting due to 9 previous errors

This might be caused by the fact that bevy_rapier requires bevy with a default set of features, while some of them don't compile for wasm32-unknown-unknown. I believe this can be fixed with specifying the minimal set of features for bevy, which are needed for bevy_rapier to work.

project structure

Hi, I am using workspaces: I pull Bevy from the repo and then I add my projects inside of the Bevy workspace so no need to recompile the engine for new projects. How to do the same with rapier? cargo does not support nested workspaces.

Add JointHandleComponent to the prelude

If I want to control a joint from a Bevy system, I think JointHandleComponent needs to be added here:

bevy_rapier/src/lib.rs

Lines 25 to 36 in bb1abd2

pub mod prelude {
pub use super::physics::{
ColliderBundle, ColliderComponentsSet, ColliderPositionSync, IntoEntity, IntoHandle,
JointBuilderComponent, NoUserData, PhysicsHooksWithQuery, PhysicsHooksWithQueryObject,
QueryPipelineColliderComponentsQuery, QueryPipelineColliderComponentsSet,
RapierConfiguration, RapierPhysicsPlugin, RigidBodyBundle, RigidBodyComponentsSet,
RigidBodyPositionSync,
};
#[cfg(feature = "render")]
pub use super::render::{ColliderDebugRender, RapierRenderPlugin};
pub use rapier::prelude::*;
}

Can't find resource QueryPipeline

I was running the raycasting example from the Scene queries page on the website:

/* Cast a ray inside of a system. */
fn cast_ray(query_pipeline: Res<QueryPipeline>, collider_query: QueryPipelineColliderComponentsQuery) {
    // Wrap the bevy query so it can be used by the query pipeline.
    let collider_set = QueryPipelineColliderComponentsSet(&collider_query);

    let ray = Ray::new(Vec3::new(1.0, 2.0, 3.0).into(), Vec3::new(0.0, 1.0, 0.0).into());
    let max_toi = 4.0;
    let solid = true;
    let groups = InteractionGroups::all();
    let filter = None;

    if let Some((handle, toi)) = query_pipeline.cast_ray(
        &collider_set, &ray, max_toi, solid, groups, filter
    ) {
        // The first collider hit has the handle `handle` and it hit after
        // the ray travelled a distance equal to `ray.dir * toi`.
        let hit_point = ray.point_at(toi); // Same as: `ray.origin + ray.dir * toi`
        println!("Entity {:?} hit at point {}", handle.entity(), hit_point);
    }


    if let Some((handle, intersection)) = query_pipeline.cast_ray_and_get_normal(
        &collider_set, &ray, max_toi, solid, groups, filter
    ) {
        // This is similar to `QueryPipeline::cast_ray` illustrated above except
        // that it also returns the normal of the collider shape at the hit point.
        let hit_point = ray.point_at(intersection.toi);
        let hit_normal = intersection.normal;
        println!("Entity {:?} hit at point {} with normal {}", handle.entity(), hit_point, hit_normal);
    }

    query_pipeline.intersections_with_ray(
        &collider_set, &ray, max_toi, solid, groups, filter,
        |handle, intersection| {
        // Callback called on each collider hit by the ray.
        let hit_point = ray.point_at(intersection.toi);
        let hit_normal = intersection.normal;
        println!("Entity {:?} hit at point {} with normal {}", handle.entity(), hit_point, hit_normal);
        true // Return `false` instead if we want to stop searching for other hits.
    });
}

and I get this error:
thread 'main' panicked at 'Requested resource does not exist: rapier3d::pipeline::query_pipeline::QueryPipeline', C:\Users\joshu\.cargo\registry\src\github.com-1ecc6299db9ec823\bevy_ecs-0.5.0\src\system\system_param.rs:244:17

The weird thing is that when I go to look at rapier3d I find the QueryPipeline, but the path is rapier3d::pipeline::QueryPipeline and not rapier3d::pipeline::query_pipeline::QueryPipeline like the error said. This makes me think that the bevy_rapier3d QueryPipeline uses the regular rapier3d QueryPipeline but looks in the wrong path.

Cannot run plugin without RenderPlugin setup for headless applications

I have noticed that this plugin only works when using Bevy's DefaultPlugins which includes RenderPlugin.
For cases that involve a GPU-less/headless dedicated server, one cannot rely on the usage of RenderPlugin. DefaultPlugins introduce application graphics and does not keep the Bevy app minimalistic as a simple console application which is very much preferred for headless Bevy applications.

Is there any known solution to this?

IntersectionEvent not firing with multiple sensor colliders

Hi,

I encountered a problem, that an IntersectionEvent with intersecting: false has a chance of failing to be fired, if multiple sensor colliders are attached to a rigid body (as multiple children).
I am fairly certain, that it only happens in this specific use case, where multiple sensor colliders are attached to it and it seems like moving one collider to the parent doesn't solve the problem.
It only happens with a chance of about 10-20%.

I'm not sure, if the problem comes from the Bevy plugin or from Rapier itself.

bevy_rapier master branch won't compile with bevy latest master

โฏ cargo build
Updating git repository https://github.com/bevyengine/bevy
Updating git repository https://github.com/dimforge/bevy_rapier
Updating crates.io index
error: failed to select a version for syn.
... required by package wasm-bindgen-macro-support v0.2.73
... which satisfies dependency wasm-bindgen-macro-support = "=0.2.73" of package wasm-bindgen-macro v0.2.73
... which satisfies dependency wasm-bindgen-macro = "=0.2.73" of package wasm-bindgen v0.2.73
... which satisfies dependency wasm-bindgen = "^0.2.73" of package wgpu v0.9.0
... which satisfies dependency wgpu = "^0.9" of package bevy_wgpu v0.5.0 (https://github.com/bevyengine/bevy?rev=6a8a8c9d21f32e0e46623db9438813b009f9e014#6a8a8c9d)
... which satisfies git dependency bevy_wgpu of package bevy_internal v0.5.0 (https://github.com/bevyengine/bevy?rev=6a8a8c9d21f32e0e46623db9438813b009f9e014#6a8a8c9d)
... which satisfies git dependency bevy_internal of package bevy v0.5.0 (https://github.com/bevyengine/bevy?rev=6a8a8c9d21f32e0e46623db9438813b009f9e014#6a8a8c9d)
... which satisfies git dependency bevy of package guild-mayhem v0.1.0 (/home/niedzwiedz/Programming/guild-mayhem)
versions that meet the requirements ^1.0.67 are: 1.0.81, 1.0.80, 1.0.79, 1.0.78, 1.0.77, 1.0.76, 1.0.75, 1.0.74, 1.0.73, 1.0.72, 1.0.71, 1.0.70, 1.0.69, 1.0.68, 1.0.67

all possible versions conflict with previously selected packages.

previously selected package syn v1.0.65
... which satisfies dependency syn = "=1.0.65" of package bevy v0.5.0
... which satisfies dependency bevy = "^0.5" of package bevy_rapier3d v0.11.0 (https://github.com/dimforge/bevy_rapier?rev=f3e984c#f3e984cc)
... which satisfies git dependency bevy_rapier3d of package guild-mayhem v0.1.0 (/home/niedzwiedz/Programming/guild-mayhem)

failed to select a version for syn which could resolve this conflict

0.10.1: Panic after despawning rigid bodies/colliders

I have some entities that have both RigidBodyBundle + ColliderBundle, some of these are also connected by joints. After despawning all joint entitites (which now works in 0.10.1) and despawning some of the bodies, there's a panic:

   0: rust_begin_unwind
             at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/core/src/panicking.rs:92:14
   2: core::panicking::panic
             at /rustc/2fd73fabe469357a12c2c974c140f67e7cdd76d0/library/core/src/panicking.rs:50:5
   3: core::option::Option<T>::unwrap
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:386:21
   4: rapier2d::data::component_set::ComponentSet::index
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.9.1/src/data/component_set.rs:27:9
   5: rapier2d::dynamics::island_manager::IslandManager::wake_up
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.9.1/src/dynamics/island_manager.rs:98:38
   6: rapier2d::dynamics::joint::joint_set::JointSet::remove
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/rapier2d-0.9.1/src/dynamics/joint/joint_set.rs:272:17
   7: bevy_rapier2d::physics::resources::ModificationTracker::propagate_removals
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_rapier2d-0.10.1/src/physics/resources.rs:278:17
   8: bevy_rapier2d::physics::systems::step_world_system
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_rapier2d-0.10.1/src/physics/systems.rs:242:5
   9: core::ops::function::Fn::call
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:70:5
  10: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ops/function.rs:247:13
  11: <Func as bevy_ecs::system::into_system::SystemParamFunction<(),Out,(F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11),()>>::run
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/system/into_system.rs:207:21
  12: <bevy_ecs::system::into_system::FunctionSystem<In,Out,Param,Marker,F> as bevy_ecs::system::system::System>::run_unsafe
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/system/into_system.rs:147:19
  13: bevy_ecs::schedule::executor_parallel::ParallelExecutor::prepare_systems::{{closure}}
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_ecs-0.5.0/src/schedule/executor_parallel.rs:200:30
  14: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  15: async_executor::Executor::spawn::{{closure}}
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:144:13
  16: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  17: async_task::raw::RawTask<F,T,S>::run
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/raw.rs:489:20
  18: async_task::runnable::Runnable::run
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/async-task-4.0.3/src/runnable.rs:309:18
  19: async_executor::Executor::run::{{closure}}::{{closure}}
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:235:21
  20: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  21: <futures_lite::future::Or<F1,F2> as core::future::future::Future>::poll
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/future.rs:529:33
  22: async_executor::Executor::run::{{closure}}
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/async-executor-1.4.1/src/lib.rs:242:9
  23: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/future/mod.rs:80:19
  24: futures_lite::future::block_on::{{closure}}
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/future.rs:89:27
  25: std::thread::local::LocalKey<T>::try_with
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:272:16
  26: std::thread::local::LocalKey<T>::with
             at /Users/audun/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/thread/local.rs:248:9
  27: futures_lite::future::block_on
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-lite-1.12.0/src/future.rs:79:5
  28: bevy_tasks::task_pool::TaskPool::new_internal::{{closure}}::{{closure}}
             at /Users/audun/.cargo/registry/src/github.com-1ecc6299db9ec823/bevy_tasks-0.5.0/src/task_pool.rs:139:25

I can likely produce code that reproductes the issue if that's needed.

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.