From bab3431674cd5d5cbacdfcb7582b44cba7158028 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 9 Sep 2024 15:28:56 +0200 Subject: [PATCH] Rapier context as a Component (#545) Co-authored-by: Anthony Tornetta <25857049+AnthonyTornetta@users.noreply.github.com> --- CHANGELOG.md | 13 + bevy_rapier2d/Cargo.toml | 1 + bevy_rapier2d/examples/player_movement2.rs | 3 +- bevy_rapier2d/examples/testbed2.rs | 4 +- bevy_rapier3d/Cargo.toml | 1 + bevy_rapier3d/examples/joints3.rs | 2 +- bevy_rapier3d/examples/multi_world3.rs | 120 +++++ bevy_rapier3d/examples/ray_casting3.rs | 2 +- bevy_rapier_benches3d/src/lib.rs | 5 +- src/pipeline/events.rs | 32 +- src/plugin/configuration.rs | 43 +- src/plugin/{context.rs => context/mod.rs} | 82 +++- src/plugin/context/systemparams/mod.rs | 12 + .../rapier_context_systemparam.rs | 140 ++++++ src/plugin/mod.rs | 10 +- src/plugin/plugin.rs | 296 ++++++++++-- src/plugin/systems/character_controller.rs | 24 +- src/plugin/systems/collider.rs | 180 +++++-- src/plugin/systems/joint.rs | 81 +++- src/plugin/systems/mod.rs | 63 +-- .../systems/multiple_rapier_contexts.rs | 223 +++++++++ src/plugin/systems/remove.rs | 122 +++-- src/plugin/systems/rigid_body.rs | 438 +++++++++++------- src/plugin/systems/writeback.rs | 20 +- src/render/mod.rs | 59 +-- 25 files changed, 1558 insertions(+), 418 deletions(-) create mode 100644 bevy_rapier3d/examples/multi_world3.rs rename src/plugin/{context.rs => context/mod.rs} (92%) create mode 100644 src/plugin/context/systemparams/mod.rs create mode 100644 src/plugin/context/systemparams/rapier_context_systemparam.rs create mode 100644 src/plugin/systems/multiple_rapier_contexts.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c34d5e2..f5b8ddc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,19 @@ which was its hardcoded behaviour. `RapierDebugColliderPlugin` and `DebugRenderContext`, as well as individual collider setup via a `ColliderDebug` component. +### Modified + +- `RapierContext`, `RapierConfiguration` and `RenderToSimulationTime` are now a `Component` instead of resources. + - Rapier now supports multiple independent physics worlds, see example `multi_world3` for usage details. + - Migration guide: + - `ResMut` -> `WriteDefaultRapierContext` + - `Res` -> `ReadDefaultRapierContext` + - Access to `RapierConfiguration` and `RenderToSimulationTime` should query for it +on the responsible entity owning the `RenderContext`. + - If you are building a library on top of `bevy_rapier` and would want to support multiple independent physics worlds too, +you can check out the details of [#545](https://github.com/dimforge/bevy_rapier/pull/545) +to get more context and information. + ## v0.27.0 (07 July 2024) **This is an update from rapier 0.19 to Rapier 0.21 which includes several stability improvements diff --git a/bevy_rapier2d/Cargo.toml b/bevy_rapier2d/Cargo.toml index b15d611b..4f0a145c 100644 --- a/bevy_rapier2d/Cargo.toml +++ b/bevy_rapier2d/Cargo.toml @@ -58,6 +58,7 @@ serde = { version = "1", features = ["derive"], optional = true } bevy = { version = "0.14", default-features = false, features = [ "x11", "bevy_state", + "bevy_debug_stepping", ] } oorandom = "11" approx = "0.5.1" diff --git a/bevy_rapier2d/examples/player_movement2.rs b/bevy_rapier2d/examples/player_movement2.rs index 1a4c0910..7cc1cab5 100644 --- a/bevy_rapier2d/examples/player_movement2.rs +++ b/bevy_rapier2d/examples/player_movement2.rs @@ -24,7 +24,8 @@ fn main() { #[derive(Component)] pub struct Player(f32); -pub fn spawn_player(mut commands: Commands, mut rapier_config: ResMut) { +pub fn spawn_player(mut commands: Commands, mut rapier_config: Query<&mut RapierConfiguration>) { + let mut rapier_config = rapier_config.single_mut(); // Set gravity to 0.0 and spawn camera. rapier_config.gravity = Vec2::ZERO; commands.spawn(Camera2dBundle::default()); diff --git a/bevy_rapier2d/examples/testbed2.rs b/bevy_rapier2d/examples/testbed2.rs index 3e8dfd27..8a433e22 100644 --- a/bevy_rapier2d/examples/testbed2.rs +++ b/bevy_rapier2d/examples/testbed2.rs @@ -204,7 +204,9 @@ fn main() { OnExit(Examples::PlayerMovement2), ( cleanup, - |mut rapier_config: ResMut, ctxt: Res| { + |mut rapier_config: Query<&mut RapierConfiguration>, + ctxt: ReadDefaultRapierContext| { + let mut rapier_config = rapier_config.single_mut(); rapier_config.gravity = RapierConfiguration::new(ctxt.integration_parameters.length_unit).gravity; }, diff --git a/bevy_rapier3d/Cargo.toml b/bevy_rapier3d/Cargo.toml index ac470cec..5e2a77bc 100644 --- a/bevy_rapier3d/Cargo.toml +++ b/bevy_rapier3d/Cargo.toml @@ -60,6 +60,7 @@ bevy = { version = "0.14", default-features = false, features = [ "x11", "tonemapping_luts", "bevy_state", + "bevy_debug_stepping", ] } approx = "0.5.1" glam = { version = "0.27", features = ["approx"] } diff --git a/bevy_rapier3d/examples/joints3.rs b/bevy_rapier3d/examples/joints3.rs index 6eb2721c..2864d33b 100644 --- a/bevy_rapier3d/examples/joints3.rs +++ b/bevy_rapier3d/examples/joints3.rs @@ -284,7 +284,7 @@ pub fn setup_physics(mut commands: Commands) { } pub fn print_impulse_revolute_joints( - context: Res, + context: ReadDefaultRapierContext, joints: Query<(Entity, &ImpulseJoint)>, ) { for (entity, impulse_joint) in joints.iter() { diff --git a/bevy_rapier3d/examples/multi_world3.rs b/bevy_rapier3d/examples/multi_world3.rs new file mode 100644 index 00000000..dc5fa807 --- /dev/null +++ b/bevy_rapier3d/examples/multi_world3.rs @@ -0,0 +1,120 @@ +use bevy::{input::common_conditions::input_just_pressed, prelude::*}; +use bevy_rapier3d::prelude::*; + +const N_WORLDS: usize = 2; + +fn main() { + App::new() + .insert_resource(ClearColor(Color::srgb( + 0xF9 as f32 / 255.0, + 0xF9 as f32 / 255.0, + 0xFF as f32 / 255.0, + ))) + .add_plugins(( + DefaultPlugins, + RapierPhysicsPlugin::::default() + .with_custom_initialization(RapierContextInitialization::NoAutomaticRapierContext), + RapierDebugRenderPlugin::default(), + )) + .add_systems( + Startup, + ((create_worlds, setup_physics).chain(), setup_graphics), + ) + .add_systems(Update, move_platforms) + .add_systems( + Update, + change_world.run_if(input_just_pressed(KeyCode::KeyC)), + ) + .run(); +} + +fn create_worlds(mut commands: Commands) { + for i in 0..N_WORLDS { + let mut world = commands.spawn((RapierContext::default(), WorldId(i))); + if i == 0 { + world.insert(DefaultRapierContext); + } + } +} + +fn setup_graphics(mut commands: Commands) { + commands.spawn(Camera3dBundle { + transform: Transform::from_xyz(0.0, 3.0, -10.0) + .looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), + ..Default::default() + }); +} + +#[derive(Component)] +pub struct WorldId(pub usize); + +#[derive(Component)] +struct Platform { + starting_y: f32, +} + +fn move_platforms(time: Res