From a0743b8a55c06803427f150b09600f6ca26d09dc Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 06:02:03 +0200 Subject: [PATCH 01/12] Remove default schedule --- avian3d/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/avian3d/src/lib.rs b/avian3d/src/lib.rs index d636a1f71..6aa4e7f62 100644 --- a/avian3d/src/lib.rs +++ b/avian3d/src/lib.rs @@ -50,8 +50,7 @@ impl Plugin for TnuaAvian3dPlugin { app.configure_sets( self.schedule, TnuaSystemSet - .before(PhysicsSet::Prepare) - .before(PhysicsStepSet::First) + .in_set(PhysicsStepSet::First) .run_if(|physics_time: Res>| !physics_time.is_paused()), ); app.add_systems( From d890cd9f00154974e22d2b75e42d8dbc524a5194 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 06:16:39 +0200 Subject: [PATCH 02/12] Use physical transform instead of rendered --- avian3d/src/lib.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/avian3d/src/lib.rs b/avian3d/src/lib.rs index 6aa4e7f62..a721fadbf 100644 --- a/avian3d/src/lib.rs +++ b/avian3d/src/lib.rs @@ -75,21 +75,24 @@ pub struct TnuaAvian3dSensorShape(pub Collider); fn update_rigid_body_trackers_system( gravity: Res, mut query: Query<( - &GlobalTransform, + &Position, + &Rotation, &LinearVelocity, &AngularVelocity, &mut TnuaRigidBodyTracker, Option<&TnuaToggle>, )>, ) { - for (transform, linaer_velocity, angular_velocity, mut tracker, tnua_toggle) in query.iter_mut() + for (position, rotation, linaer_velocity, angular_velocity, mut tracker, tnua_toggle) in + query.iter_mut() { match tnua_toggle.copied().unwrap_or_default() { TnuaToggle::Disabled => continue, TnuaToggle::SenseOnly => {} TnuaToggle::Enabled => {} } - let (_, rotation, translation) = transform.to_scale_rotation_translation(); + let translation = position.0; + let rotation = rotation.0; *tracker = TnuaRigidBodyTracker { translation: translation.adjust_precision(), rotation: rotation.adjust_precision(), @@ -106,7 +109,9 @@ fn update_proximity_sensors_system( collisions: Res, mut query: Query<( Entity, - &GlobalTransform, + &Position, + &Rotation, + &Collider, &mut TnuaProximitySensor, Option<&TnuaAvian3dSensorShape>, Option<&mut TnuaGhostSensor>, @@ -115,7 +120,7 @@ fn update_proximity_sensors_system( )>, collision_layers_entity: Query<&CollisionLayers>, other_object_query: Query<( - Option<(&GlobalTransform, &LinearVelocity, &AngularVelocity)>, + Option<(&Position, &LinearVelocity, &AngularVelocity)>, Option<&CollisionLayers>, Has, Has, @@ -124,7 +129,9 @@ fn update_proximity_sensors_system( query.par_iter_mut().for_each( |( owner_entity, - transform, + position, + rotation, + collider, mut sensor, shape, mut ghost_sensor, @@ -136,6 +143,11 @@ fn update_proximity_sensors_system( TnuaToggle::SenseOnly => {} TnuaToggle::Enabled => {} } + let transform = Transform { + translation: position.0, + rotation: rotation.0, + scale: collider.scale(), + }; // TODO: is there any point in doing these transformations as f64 when that feature // flag is active? @@ -205,14 +217,14 @@ fn update_proximity_sensors_system( let entity_linvel; let entity_angvel; - if let Some((entity_transform, entity_linear_velocity, entity_angular_velocity)) = + if let Some((entity_position, entity_linear_velocity, entity_angular_velocity)) = entity_kinematic_data { entity_angvel = entity_angular_velocity.0.adjust_precision(); entity_linvel = entity_linear_velocity.0.adjust_precision() + if 0.0 < entity_angvel.length_squared() { - let relative_point = intersection_point - - entity_transform.translation().adjust_precision(); + let relative_point = + intersection_point - entity_position.adjust_precision(); // NOTE: no need to project relative_point on the // rotation plane, it will not affect the cross // product. @@ -254,7 +266,7 @@ fn update_proximity_sensors_system( let query_filter = SpatialQueryFilter::from_excluded_entities([owner_entity]); if let Some(TnuaAvian3dSensorShape(shape)) = shape { - let (_, owner_rotation, _) = transform.to_scale_rotation_translation(); + let owner_rotation = transform.rotation; let owner_rotation = Quat::from_axis_angle( *cast_direction, owner_rotation.to_scaled_axis().dot(*cast_direction), From 31dafba0a26ecec46fe88a388b2c61e7a729590a Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 06:25:30 +0200 Subject: [PATCH 03/12] Patch to newest avian --- Cargo.toml | 2 +- avian3d/Cargo.toml | 2 +- avian3d/src/lib.rs | 4 ++-- demos/Cargo.toml | 2 +- examples/example.rs | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3adfa5ee5..7502676cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,7 @@ bevy = { version = "^0.14", default-features = false, features = [ "x11", # "filesystem_watcher", ] } -avian3d = { version = "^0.1", features = ["3d", "debug-plugin", "parallel", "parry-f32"] } +avian3d = { version = "^0.1", git = "https://github.com/Jondolf/avian", features = ["3d", "debug-plugin", "parallel", "parry-f32"] } bevy-tnua-avian3d = { path = "avian3d" } [package.metadata.docs.rs] diff --git a/avian3d/Cargo.toml b/avian3d/Cargo.toml index 825913529..3f49c0a5f 100644 --- a/avian3d/Cargo.toml +++ b/avian3d/Cargo.toml @@ -13,7 +13,7 @@ readme = "../README.md" [dependencies] bevy = { version = "^0.14", default-features = false } -avian3d = {version = "^0.1", default-features = false, features = ["3d", "debug-plugin", "parallel"] } +avian3d = {version = "^0.1", git = "https://github.com/Jondolf/avian", default-features = false, features = ["3d", "debug-plugin", "parallel"] } bevy-tnua-physics-integration-layer = { version = "^0.4", path = "../physics-integration-layer" } [package.metadata.docs.rs] diff --git a/avian3d/src/lib.rs b/avian3d/src/lib.rs index a721fadbf..1f9a8874f 100644 --- a/avian3d/src/lib.rs +++ b/avian3d/src/lib.rs @@ -278,7 +278,7 @@ fn update_proximity_sensors_system( cast_direction, sensor.cast_range, true, - query_filter, + &query_filter, |shape_hit_data| { apply_cast(CastResult { entity: shape_hit_data.entity, @@ -295,7 +295,7 @@ fn update_proximity_sensors_system( cast_direction, sensor.cast_range, true, - query_filter, + &query_filter, |ray_hit_data| { apply_cast(CastResult { entity: ray_hit_data.entity, diff --git a/demos/Cargo.toml b/demos/Cargo.toml index 1f5aa5811..68cf51a26 100644 --- a/demos/Cargo.toml +++ b/demos/Cargo.toml @@ -62,7 +62,7 @@ bevy-tnua-rapier3d = { path = "../rapier3d", optional = true } avian2d = {version = "^0.1", default-features = false, features = ["2d","debug-plugin", "parallel"], optional = true} bevy-tnua-avian2d = { path = "../avian2d", default-features = false, optional = true } -avian3d = {version = "^0.1", default-features = false, features = ["3d","debug-plugin", "parallel"], optional = true } +avian3d = {version = "^0.1", git = "https://github.com/Jondolf/avian", default-features = false, features = ["3d","debug-plugin", "parallel"], optional = true } bevy-tnua-avian3d = { path = "../avian3d", default-features = false, optional = true } bevy_egui = { version = "0.28", optional = true, default-features = false, features = ["default_fonts", "render"] } diff --git a/examples/example.rs b/examples/example.rs index 94171c917..ce050ba64 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -11,9 +11,9 @@ fn main() { DefaultPlugins, PhysicsPlugins::default(), // We need both Tnua's main controller plugin, and the plugin to connect to the physics - // backend (in this case XBPD-3D) - TnuaControllerPlugin::default(), - TnuaAvian3dPlugin::default(), + // backend (in this case Avian 3D) + TnuaControllerPlugin::new(PhysicsSchedule), + TnuaAvian3dPlugin::new(PhysicsSchedule), )) .add_systems( Startup, From 6afb0a658b4bd276a5376f2cd25c11aa25bd8f0f Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 06:39:05 +0200 Subject: [PATCH 04/12] Add docs --- avian3d/src/lib.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/avian3d/src/lib.rs b/avian3d/src/lib.rs index 1f9a8874f..54436c1e1 100644 --- a/avian3d/src/lib.rs +++ b/avian3d/src/lib.rs @@ -27,6 +27,20 @@ use bevy_tnua_physics_integration_layer::TnuaSystemSet; /// Add this plugin to use avian3d as a physics backend. /// /// This plugin should be used in addition to `TnuaControllerPlugin`. +/// Note that you should make sure both of these plugins use the same schedule. +/// This should usually be `PhysicsSchedule`, which by default is `FixedUpdate`. +/// +/// # Example +/// +/// ```ignore +/// App::new() +/// .add_plugins(( +/// DefaultPlugins, +/// PhysicsPlugins::default(), +/// TnuaControllerPlugin::new(PhysicsSchedule), +/// TnuaAvian3dPlugin::new(PhysicsSchedule), +/// )); +/// ``` pub struct TnuaAvian3dPlugin { schedule: InternedScheduleLabel, } From 2c955b5d4d2ff0cfb896f9548c61d4812b17e754 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 06:56:35 +0200 Subject: [PATCH 05/12] Update 2D and examples --- avian2d/Cargo.toml | 2 +- avian2d/src/lib.rs | 57 ++++++++++++++++++++++------------ avian3d/src/lib.rs | 4 +-- demos/Cargo.toml | 2 +- demos/src/app_setup_options.rs | 2 -- demos/src/bin/platformer_2d.rs | 17 +--------- demos/src/bin/platformer_3d.rs | 21 ++----------- demos/src/bin/shooter_like.rs | 19 +----------- examples/example.rs | 5 ++- examples/example_animating.rs | 9 ++++-- 10 files changed, 55 insertions(+), 83 deletions(-) diff --git a/avian2d/Cargo.toml b/avian2d/Cargo.toml index c890e4aec..7284bac96 100644 --- a/avian2d/Cargo.toml +++ b/avian2d/Cargo.toml @@ -13,7 +13,7 @@ readme = "../README.md" [dependencies] bevy = { version = "^0.14", default-features = false } -avian2d = {version = "^0.1", default-features = false, features = ["2d", "debug-plugin", "parallel"]} +avian2d = {version = "^0.1", git = "https://github.com/Jondolf/avian", default-features = false, features = ["2d", "debug-plugin", "parallel"]} bevy-tnua-physics-integration-layer = { version = "^0.4", path = "../physics-integration-layer" } [package.metadata.docs.rs] diff --git a/avian2d/src/lib.rs b/avian2d/src/lib.rs index ec8aeb9d1..708c21fa3 100644 --- a/avian2d/src/lib.rs +++ b/avian2d/src/lib.rs @@ -22,6 +22,20 @@ use bevy_tnua_physics_integration_layer::*; /// Add this plugin to use avian2d as a physics backend. /// /// This plugin should be used in addition to `TnuaControllerPlugin`. +/// Note that you should make sure both of these plugins use the same schedule. +/// This should usually be `PhysicsSchedule`, which by default is `FixedUpdate`. +/// +/// # Example +/// +/// ```ignore +/// App::new() +/// .add_plugins(( +/// DefaultPlugins, +/// PhysicsPlugins::default(), +/// TnuaControllerPlugin::new(PhysicsSchedule), +/// TnuaAvian2dPlugin::new(PhysicsSchedule), +/// )); +/// ``` pub struct TnuaAvian2dPlugin { schedule: InternedScheduleLabel, } @@ -34,19 +48,12 @@ impl TnuaAvian2dPlugin { } } -impl Default for TnuaAvian2dPlugin { - fn default() -> Self { - Self::new(Update) - } -} - impl Plugin for TnuaAvian2dPlugin { fn build(&self, app: &mut App) { app.configure_sets( self.schedule, TnuaSystemSet - .before(PhysicsSet::Prepare) - .before(PhysicsStepSet::First) + .in_set(PhysicsStepSet::First) .run_if(|physics_time: Res>| !physics_time.is_paused()), ); app.add_systems( @@ -71,23 +78,24 @@ pub struct TnuaAvian2dSensorShape(pub Collider); fn update_rigid_body_trackers_system( gravity: Res, mut query: Query<( - &GlobalTransform, + &Position, + &Rotation, &LinearVelocity, &AngularVelocity, &mut TnuaRigidBodyTracker, Option<&TnuaToggle>, )>, ) { - for (transform, linaer_velocity, angular_velocity, mut tracker, tnua_toggle) in query.iter_mut() + for (position, rotation, linaer_velocity, angular_velocity, mut tracker, tnua_toggle) in + query.iter_mut() { match tnua_toggle.copied().unwrap_or_default() { TnuaToggle::Disabled => continue, TnuaToggle::SenseOnly => {} TnuaToggle::Enabled => {} } - let (_, rotation, translation) = transform.to_scale_rotation_translation(); *tracker = TnuaRigidBodyTracker { - translation: translation.adjust_precision(), + translation: position.adjust_precision(), rotation: rotation.adjust_precision(), velocity: linaer_velocity.0.extend(0.0), angvel: Vector3::new(0.0, 0.0, angular_velocity.0), @@ -102,7 +110,9 @@ fn update_proximity_sensors_system( collisions: Res, mut query: Query<( Entity, - &GlobalTransform, + &Position, + &Rotation, + &Collider, &mut TnuaProximitySensor, Option<&TnuaAvian2dSensorShape>, Option<&mut TnuaGhostSensor>, @@ -111,7 +121,7 @@ fn update_proximity_sensors_system( )>, collision_layers_entity: Query<&CollisionLayers>, other_object_query: Query<( - Option<(&GlobalTransform, &LinearVelocity, &AngularVelocity)>, + Option<(&Position, &LinearVelocity, &AngularVelocity)>, Option<&CollisionLayers>, Has, Has, @@ -120,7 +130,9 @@ fn update_proximity_sensors_system( query.par_iter_mut().for_each( |( owner_entity, - transform, + position, + rotation, + collider, mut sensor, shape, mut ghost_sensor, @@ -132,6 +144,11 @@ fn update_proximity_sensors_system( TnuaToggle::SenseOnly => {} TnuaToggle::Enabled => {} } + let transform = Transform { + translation: position.0, + rotation: rotation.0, + scale: collider.scale(), + }; let cast_origin = transform.transform_point(sensor.cast_origin.f32()); let cast_direction = sensor.cast_direction; let cast_direction_2d = Dir2::new(cast_direction.truncate()) @@ -201,14 +218,14 @@ fn update_proximity_sensors_system( let entity_linvel; let entity_angvel; - if let Some((entity_transform, entity_linear_velocity, entity_angular_velocity)) = + if let Some((entity_position, entity_linear_velocity, entity_angular_velocity)) = entity_kinematic_data { entity_angvel = Vector3::new(0.0, 0.0, entity_angular_velocity.0); entity_linvel = entity_linear_velocity.0.extend(0.0) + if 0.0 < entity_angvel.length_squared() { - let relative_point = intersection_point - - entity_transform.translation().truncate().adjust_precision(); + let relative_point = + intersection_point - entity_position.adjust_precision(); // NOTE: no need to project relative_point on the // rotation plane, it will not affect the cross // product. @@ -257,7 +274,7 @@ fn update_proximity_sensors_system( cast_direction_2d, sensor.cast_range, true, - query_filter, + &query_filter, #[allow(clippy::useless_conversion)] |shape_hit_data| { apply_cast(CastResult { @@ -275,7 +292,7 @@ fn update_proximity_sensors_system( cast_direction_2d, sensor.cast_range, true, - query_filter, + &query_filter, |ray_hit_data| { apply_cast(CastResult { entity: ray_hit_data.entity, diff --git a/avian3d/src/lib.rs b/avian3d/src/lib.rs index 54436c1e1..32916f28b 100644 --- a/avian3d/src/lib.rs +++ b/avian3d/src/lib.rs @@ -105,10 +105,8 @@ fn update_rigid_body_trackers_system( TnuaToggle::SenseOnly => {} TnuaToggle::Enabled => {} } - let translation = position.0; - let rotation = rotation.0; *tracker = TnuaRigidBodyTracker { - translation: translation.adjust_precision(), + translation: position.adjust_precision(), rotation: rotation.adjust_precision(), velocity: linaer_velocity.0.adjust_precision(), angvel: angular_velocity.0.adjust_precision(), diff --git a/demos/Cargo.toml b/demos/Cargo.toml index 68cf51a26..c6c8d4f70 100644 --- a/demos/Cargo.toml +++ b/demos/Cargo.toml @@ -59,7 +59,7 @@ bevy-tnua-rapier2d = { path = "../rapier2d", optional = true } bevy_rapier3d = { version = "^0.27", features = ["debug-render-3d"], optional = true } bevy-tnua-rapier3d = { path = "../rapier3d", optional = true } -avian2d = {version = "^0.1", default-features = false, features = ["2d","debug-plugin", "parallel"], optional = true} +avian2d = {version = "^0.1", git = "https://github.com/Jondolf/avian", default-features = false, features = ["2d","debug-plugin", "parallel"], optional = true} bevy-tnua-avian2d = { path = "../avian2d", default-features = false, optional = true } avian3d = {version = "^0.1", git = "https://github.com/Jondolf/avian", default-features = false, features = ["3d","debug-plugin", "parallel"], optional = true } diff --git a/demos/src/app_setup_options.rs b/demos/src/app_setup_options.rs index ae04d1ee8..7a71d0232 100644 --- a/demos/src/app_setup_options.rs +++ b/demos/src/app_setup_options.rs @@ -59,8 +59,6 @@ impl AppSetupConfiguration { pub enum ScheduleToUse { Update, FixedUpdate, - #[cfg(feature = "avian")] - PhysicsSchedule, } impl ScheduleToUse { diff --git a/demos/src/bin/platformer_2d.rs b/demos/src/bin/platformer_2d.rs index aca2e225c..eda31dd54 100644 --- a/demos/src/bin/platformer_2d.rs +++ b/demos/src/bin/platformer_2d.rs @@ -60,10 +60,6 @@ fn main() { // bevy-tnua-rapier2d. app.add_plugins(TnuaRapier2dPlugin::new(FixedUpdate)); } - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => { - panic!("Cannot happen - Avian and Rapier used together"); - } } } #[cfg(feature = "avian2d")] @@ -78,12 +74,8 @@ fn main() { } ScheduleToUse::FixedUpdate => { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); - app.add_plugins(TnuaAvian2dPlugin::new(FixedUpdate)); - } - ScheduleToUse::PhysicsSchedule => { - app.add_plugins(PhysicsPlugins::default()); app.insert_resource(Time::new_with(Physics::fixed_hz(144.0))); - app.add_plugins(TnuaAvian2dPlugin::new(PhysicsSchedule)); + app.add_plugins(TnuaAvian2dPlugin::new(FixedUpdate)); } } } @@ -101,11 +93,6 @@ fn main() { app.add_plugins(TnuaControllerPlugin::new(FixedUpdate)); app.add_plugins(TnuaCrouchEnforcerPlugin::new(FixedUpdate)); } - #[cfg(any(feature = "avian", feature = "avian"))] - ScheduleToUse::PhysicsSchedule => { - app.add_plugins(TnuaControllerPlugin::new(PhysicsSchedule)); - app.add_plugins(TnuaCrouchEnforcerPlugin::new(PhysicsSchedule)); - } } #[cfg(feature = "egui")] @@ -128,8 +115,6 @@ fn main() { match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => Update.intern(), ScheduleToUse::FixedUpdate => FixedUpdate.intern(), - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => PhysicsSchedule.intern(), }, apply_platformer_controls.in_set(TnuaUserControlsSystemSet), ); diff --git a/demos/src/bin/platformer_3d.rs b/demos/src/bin/platformer_3d.rs index e436f509f..aeb2a0799 100644 --- a/demos/src/bin/platformer_3d.rs +++ b/demos/src/bin/platformer_3d.rs @@ -64,29 +64,21 @@ fn main() { app.add_plugins(RapierPhysicsPlugin::::default().in_fixed_schedule()); app.add_plugins(TnuaRapier3dPlugin::new(FixedUpdate)); } - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => { - panic!("Cannot happen - Avian and Rapier used together"); - } } } #[cfg(feature = "avian3d")] { match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => { - app.add_plugins(PhysicsPlugins::default()); + app.add_plugins(PhysicsPlugins::new(Update)); // To use Tnua with avian3d, you need the `TnuaAvian3dPlugin` plugin from // bevy-tnua-avian3d. - app.add_plugins(TnuaAvian3dPlugin::default()); + app.add_plugins(TnuaAvian3dPlugin::new(Update)); } ScheduleToUse::FixedUpdate => { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); - app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); - } - ScheduleToUse::PhysicsSchedule => { - app.add_plugins(PhysicsPlugins::default()); app.insert_resource(Time::new_with(Physics::fixed_hz(144.0))); - app.add_plugins(TnuaAvian3dPlugin::new(PhysicsSchedule)); + app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); } } } @@ -104,11 +96,6 @@ fn main() { app.add_plugins(TnuaControllerPlugin::new(FixedUpdate)); app.add_plugins(TnuaCrouchEnforcerPlugin::new(FixedUpdate)); } - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => { - app.add_plugins(TnuaControllerPlugin::new(PhysicsSchedule)); - app.add_plugins(TnuaCrouchEnforcerPlugin::new(PhysicsSchedule)); - } } #[cfg(feature = "egui")] @@ -136,8 +123,6 @@ fn main() { match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => Update.intern(), ScheduleToUse::FixedUpdate => FixedUpdate.intern(), - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => PhysicsSchedule.intern(), }, apply_platformer_controls.in_set(TnuaUserControlsSystemSet), ); diff --git a/demos/src/bin/shooter_like.rs b/demos/src/bin/shooter_like.rs index 8522ed74b..8dc365077 100644 --- a/demos/src/bin/shooter_like.rs +++ b/demos/src/bin/shooter_like.rs @@ -63,10 +63,6 @@ fn main() { app.add_plugins(RapierPhysicsPlugin::::default().in_fixed_schedule()); app.add_plugins(TnuaRapier3dPlugin::new(FixedUpdate)); } - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => { - panic!("Cannot happen - Avian and Rapier used together"); - } } } #[cfg(feature = "avian3d")] @@ -80,12 +76,8 @@ fn main() { } ScheduleToUse::FixedUpdate => { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); - app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); - } - ScheduleToUse::PhysicsSchedule => { - app.add_plugins(PhysicsPlugins::default()); app.insert_resource(Time::new_with(Physics::fixed_hz(144.0))); - app.add_plugins(TnuaAvian3dPlugin::new(PhysicsSchedule)); + app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); } } } @@ -103,11 +95,6 @@ fn main() { app.add_plugins(TnuaControllerPlugin::new(FixedUpdate)); app.add_plugins(TnuaCrouchEnforcerPlugin::new(FixedUpdate)); } - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => { - app.add_plugins(TnuaControllerPlugin::new(PhysicsSchedule)); - app.add_plugins(TnuaCrouchEnforcerPlugin::new(PhysicsSchedule)); - } } #[cfg(feature = "egui")] @@ -131,16 +118,12 @@ fn main() { let system = apply_camera_controls; #[cfg(feature = "rapier")] let system = system.after(bevy_rapier3d::prelude::PhysicsSet::SyncBackend); - #[cfg(feature = "avian")] - let system = system.after(avian3d::prelude::PhysicsSet::Sync); system.before(bevy::transform::TransformSystem::TransformPropagate) }); app.add_systems( match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => Update.intern(), ScheduleToUse::FixedUpdate => FixedUpdate.intern(), - #[cfg(feature = "avian")] - ScheduleToUse::PhysicsSchedule => PhysicsSchedule.intern(), }, apply_platformer_controls.in_set(TnuaUserControlsSystemSet), ); diff --git a/examples/example.rs b/examples/example.rs index ce050ba64..9c6e44a06 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -19,7 +19,10 @@ fn main() { Startup, (setup_camera_and_lights, setup_level, setup_player), ) - .add_systems(Update, apply_controls.in_set(TnuaUserControlsSystemSet)) + .add_systems( + PhysicsSchedule, + apply_controls.in_set(TnuaUserControlsSystemSet), + ) .run(); } diff --git a/examples/example_animating.rs b/examples/example_animating.rs index 87544851d..258f1df6d 100644 --- a/examples/example_animating.rs +++ b/examples/example_animating.rs @@ -16,17 +16,20 @@ fn main() { .add_plugins(( DefaultPlugins, PhysicsPlugins::default(), - TnuaControllerPlugin::default(), - TnuaAvian3dPlugin::default(), + TnuaControllerPlugin::new(PhysicsSchedule), + TnuaAvian3dPlugin::new(PhysicsSchedule), )) .add_systems( Startup, (setup_camera_and_lights, setup_level, setup_player), ) + .add_systems( + PhysicsSchedule, + apply_controls.in_set(TnuaUserControlsSystemSet), + ) .add_systems( Update, ( - apply_controls.in_set(TnuaUserControlsSystemSet), prepare_animations, handle_animating, ), From 3bc32f860169ce70b53ff19fad60682a23c48cd5 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 08:00:28 +0200 Subject: [PATCH 06/12] Fix various fixed timestep issues --- avian2d/src/lib.rs | 10 +-- demos/src/app_setup_options.rs | 12 ++- demos/src/bin/platformer_2d.rs | 19 +++-- demos/src/bin/platformer_3d.rs | 23 +++-- demos/src/bin/shooter_like.rs | 19 +++-- .../platformer_control_systems.rs | 84 ++++++++++++++----- demos/src/levels_setup/for_2d_platformer.rs | 4 +- demos/src/levels_setup/for_3d_platformer.rs | 4 +- 8 files changed, 125 insertions(+), 50 deletions(-) diff --git a/avian2d/src/lib.rs b/avian2d/src/lib.rs index 708c21fa3..273dcb36a 100644 --- a/avian2d/src/lib.rs +++ b/avian2d/src/lib.rs @@ -95,8 +95,8 @@ fn update_rigid_body_trackers_system( TnuaToggle::Enabled => {} } *tracker = TnuaRigidBodyTracker { - translation: position.adjust_precision(), - rotation: rotation.adjust_precision(), + translation: position.adjust_precision().extend(0.0), + rotation: Quat::from_rotation_z(rotation.as_radians()).adjust_precision(), velocity: linaer_velocity.0.extend(0.0), angvel: Vector3::new(0.0, 0.0, angular_velocity.0), gravity: gravity.0.extend(0.0), @@ -145,9 +145,9 @@ fn update_proximity_sensors_system( TnuaToggle::Enabled => {} } let transform = Transform { - translation: position.0, - rotation: rotation.0, - scale: collider.scale(), + translation: position.extend(0.0), + rotation: Quat::from_rotation_z(rotation.as_radians()), + scale: collider.scale().extend(1.0), }; let cast_origin = transform.transform_point(sensor.cast_origin.f32()); let cast_direction = sensor.cast_direction; diff --git a/demos/src/app_setup_options.rs b/demos/src/app_setup_options.rs index 7a71d0232..433ea1ade 100644 --- a/demos/src/app_setup_options.rs +++ b/demos/src/app_setup_options.rs @@ -5,7 +5,11 @@ use clap::{Parser, ValueEnum}; #[derive(Resource, Debug, Parser, Clone)] pub struct AppSetupConfiguration { - #[arg(long = "schedule", default_value = "update")] + #[cfg_attr(feature = "rapier", arg(long = "schedule", default_value = "update"))] + #[cfg_attr( + feature = "avian", + arg(long = "schedule", default_value = "fixed-update") + )] pub schedule_to_use: ScheduleToUse, #[arg(long = "level")] pub level_to_load: Option, @@ -25,8 +29,12 @@ impl AppSetupConfiguration { Self { schedule_to_use: if let Some(value) = url_params.get("schedule") { ScheduleToUse::from_str(&value, true).unwrap() - } else { + } else if cfg!(feature = "avian") { + ScheduleToUse::FixedUpdate + } else if cfg!(feature = "rapier") { ScheduleToUse::Update + } else { + panic!("No schedule was specified, but also no physics engine is avaible. Therefore, there is no fallback.") }, level_to_load: url_params.get("level"), } diff --git a/demos/src/bin/platformer_2d.rs b/demos/src/bin/platformer_2d.rs index eda31dd54..69280af5f 100644 --- a/demos/src/bin/platformer_2d.rs +++ b/demos/src/bin/platformer_2d.rs @@ -1,5 +1,5 @@ #[cfg(feature = "avian2d")] -use avian2d::{prelude as avian, prelude::*, schedule::PhysicsSchedule}; +use avian2d::{prelude as avian, prelude::*}; use bevy::ecs::schedule::ScheduleLabel; use bevy::prelude::*; #[cfg(feature = "rapier2d")] @@ -22,6 +22,7 @@ use tnua_demos_crate::app_setup_options::{AppSetupConfiguration, ScheduleToUse}; use tnua_demos_crate::character_control_systems::info_dumpeing_systems::character_control_info_dumping_system; use tnua_demos_crate::character_control_systems::platformer_control_systems::{ apply_platformer_controls, CharacterMotionConfigForPlatformerDemo, FallingThroughControlScheme, + JustPressedCachePlugin, }; use tnua_demos_crate::character_control_systems::Dimensionality; use tnua_demos_crate::level_mechanics::LevelMechanicsPlugin; @@ -67,14 +68,13 @@ fn main() { app.add_plugins(PhysicsDebugPlugin::default()); match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => { - app.add_plugins(PhysicsPlugins::default()); + app.add_plugins(PhysicsPlugins::new(Update)); // To use Tnua with avian2d, you need the `TnuaAvian2dPlugin` plugin from // bevy-tnua-avian2d. - app.add_plugins(TnuaAvian2dPlugin::default()); + app.add_plugins(TnuaAvian2dPlugin::new(Update)); } ScheduleToUse::FixedUpdate => { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); - app.insert_resource(Time::new_with(Physics::fixed_hz(144.0))); app.add_plugins(TnuaAvian2dPlugin::new(FixedUpdate)); } } @@ -118,7 +118,7 @@ fn main() { }, apply_platformer_controls.in_set(TnuaUserControlsSystemSet), ); - app.add_plugins(LevelMechanicsPlugin); + app.add_plugins((LevelMechanicsPlugin, JustPressedCachePlugin)); #[cfg(feature = "rapier2d")] { app.add_systems(Startup, |mut cfg: ResMut| { @@ -286,9 +286,14 @@ fn setup_player(mut commands: Commands) { #[cfg(feature = "avian2d")] { let player_layers: LayerMask = if use_collision_groups { - [LayerNames::Player].into() + [LayerNames::Player, LayerNames::Default].into() } else { - [LayerNames::Player, LayerNames::PhaseThrough].into() + [ + LayerNames::Player, + LayerNames::PhaseThrough, + LayerNames::Default, + ] + .into() }; cmd.insert(CollisionLayers::new(player_layers, player_layers)); } diff --git a/demos/src/bin/platformer_3d.rs b/demos/src/bin/platformer_3d.rs index aeb2a0799..c03f69ab4 100644 --- a/demos/src/bin/platformer_3d.rs +++ b/demos/src/bin/platformer_3d.rs @@ -1,5 +1,5 @@ #[cfg(feature = "avian3d")] -use avian3d::{prelude as avian, prelude::*, schedule::PhysicsSchedule}; +use avian3d::{prelude as avian, prelude::*}; use bevy::ecs::schedule::ScheduleLabel; use bevy::prelude::*; #[cfg(feature = "rapier3d")] @@ -19,9 +19,6 @@ use bevy_tnua_avian3d::*; use bevy_tnua_rapier3d::*; use tnua_demos_crate::app_setup_options::{AppSetupConfiguration, ScheduleToUse}; -use tnua_demos_crate::character_animating_systems::platformer_animating_systems::{ - animate_platformer_character, AnimationState, -}; #[cfg(feature = "egui")] use tnua_demos_crate::character_control_systems::info_dumpeing_systems::character_control_info_dumping_system; use tnua_demos_crate::character_control_systems::platformer_control_systems::{ @@ -41,6 +38,12 @@ use tnua_demos_crate::ui::plotting::PlotSource; #[cfg(feature = "egui")] use tnua_demos_crate::ui::DemoInfoUpdateSystemSet; use tnua_demos_crate::util::animating::{animation_patcher_system, GltfSceneHandler}; +use tnua_demos_crate::{ + character_animating_systems::platformer_animating_systems::{ + animate_platformer_character, AnimationState, + }, + character_control_systems::platformer_control_systems::JustPressedCachePlugin, +}; fn main() { tnua_demos_crate::verify_physics_backends_features!("rapier3d", "avian3d"); @@ -77,7 +80,6 @@ fn main() { } ScheduleToUse::FixedUpdate => { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); - app.insert_resource(Time::new_with(Physics::fixed_hz(144.0))); app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); } } @@ -128,7 +130,7 @@ fn main() { ); app.add_systems(Update, animation_patcher_system); app.add_systems(Update, animate_platformer_character); - app.add_plugins(LevelMechanicsPlugin); + app.add_plugins((LevelMechanicsPlugin, JustPressedCachePlugin)); app.run(); } @@ -317,9 +319,14 @@ fn setup_player(mut commands: Commands, asset_server: Res) { #[cfg(feature = "avian3d")] { let player_layers: LayerMask = if use_collision_groups { - [LayerNames::Player].into() + [LayerNames::Player, LayerNames::Default].into() } else { - [LayerNames::Player, LayerNames::PhaseThrough].into() + [ + LayerNames::Player, + LayerNames::PhaseThrough, + LayerNames::Default, + ] + .into() }; cmd.insert(CollisionLayers::new(player_layers, player_layers)); } diff --git a/demos/src/bin/shooter_like.rs b/demos/src/bin/shooter_like.rs index 8dc365077..96ca9b078 100644 --- a/demos/src/bin/shooter_like.rs +++ b/demos/src/bin/shooter_like.rs @@ -1,5 +1,5 @@ #[cfg(feature = "avian3d")] -use avian3d::{prelude as avian, prelude::*, schedule::PhysicsSchedule}; +use avian3d::{prelude as avian, prelude::*}; use bevy::ecs::schedule::ScheduleLabel; use bevy::input::mouse::MouseMotion; use bevy::prelude::*; @@ -23,12 +23,15 @@ use tnua_demos_crate::app_setup_options::{AppSetupConfiguration, ScheduleToUse}; use tnua_demos_crate::character_animating_systems::platformer_animating_systems::{ animate_platformer_character, AnimationState, }; -use tnua_demos_crate::character_control_systems::info_dumpeing_systems::character_control_info_dumping_system; use tnua_demos_crate::character_control_systems::platformer_control_systems::{ apply_platformer_controls, CharacterMotionConfigForPlatformerDemo, FallingThroughControlScheme, ForwardFromCamera, }; use tnua_demos_crate::character_control_systems::Dimensionality; +use tnua_demos_crate::character_control_systems::{ + info_dumpeing_systems::character_control_info_dumping_system, + platformer_control_systems::JustPressedCachePlugin, +}; use tnua_demos_crate::level_mechanics::LevelMechanicsPlugin; #[cfg(feature = "avian3d")] use tnua_demos_crate::levels_setup::for_3d_platformer::LayerNames; @@ -76,7 +79,6 @@ fn main() { } ScheduleToUse::FixedUpdate => { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); - app.insert_resource(Time::new_with(Physics::fixed_hz(144.0))); app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); } } @@ -129,7 +131,7 @@ fn main() { ); app.add_systems(Update, animation_patcher_system); app.add_systems(Update, animate_platformer_character); - app.add_plugins(LevelMechanicsPlugin); + app.add_plugins((LevelMechanicsPlugin, JustPressedCachePlugin)); app.run(); } @@ -321,9 +323,14 @@ fn setup_player(mut commands: Commands, asset_server: Res) { #[cfg(feature = "avian3d")] { let player_layers: LayerMask = if use_collision_groups { - [LayerNames::Player].into() + [LayerNames::Player, LayerNames::Default].into() } else { - [LayerNames::Player, LayerNames::PhaseThrough].into() + [ + LayerNames::Player, + LayerNames::PhaseThrough, + LayerNames::Default, + ] + .into() }; cmd.insert(CollisionLayers::new(player_layers, player_layers)); } diff --git a/demos/src/character_control_systems/platformer_control_systems.rs b/demos/src/character_control_systems/platformer_control_systems.rs index 8cdca7bdc..d5f8f0196 100644 --- a/demos/src/character_control_systems/platformer_control_systems.rs +++ b/demos/src/character_control_systems/platformer_control_systems.rs @@ -1,4 +1,4 @@ -use bevy::prelude::*; +use bevy::{app::RunFixedMainLoop, prelude::*, time::run_fixed_main_schedule}; #[cfg(feature = "egui")] use bevy_egui::{egui, EguiContexts}; use bevy_tnua::builtins::{TnuaBuiltinCrouch, TnuaBuiltinCrouchState, TnuaBuiltinDash}; @@ -18,6 +18,7 @@ use super::Dimensionality; pub fn apply_platformer_controls( #[cfg(feature = "egui")] mut egui_context: EguiContexts, keyboard: Res>, + mut just_pressed: ResMut, mut query: Query<( &CharacterMotionConfigForPlatformerDemo, // This is the main component used for interacting with Tnua. It is used for both issuing @@ -111,25 +112,13 @@ pub fn apply_platformer_controls( let turn_in_place = forward_from_camera.is_none() && keyboard.any_pressed([KeyCode::AltLeft, KeyCode::AltRight]); - let crouch_pressed: bool; - let crouch_just_pressed: bool; - match config.dimensionality { - Dimensionality::Dim2 => { - let crouch_buttons = [ - KeyCode::ControlLeft, - KeyCode::ControlRight, - KeyCode::ArrowDown, - KeyCode::KeyS, - ]; - crouch_pressed = keyboard.any_pressed(crouch_buttons); - crouch_just_pressed = keyboard.any_just_pressed(crouch_buttons); - } - Dimensionality::Dim3 => { - let crouch_buttons = [KeyCode::ControlLeft, KeyCode::ControlRight]; - crouch_pressed = keyboard.any_pressed(crouch_buttons); - crouch_just_pressed = keyboard.any_just_pressed(crouch_buttons); - } - } + let crouch_buttons = match config.dimensionality { + Dimensionality::Dim2 => CROUCH_BUTTONS_2D.iter().copied(), + Dimensionality::Dim3 => CROUCH_BUTTONS_3D.iter().copied(), + }; + let crouch_pressed = keyboard.any_pressed(crouch_buttons); + let crouch_just_pressed = just_pressed.crouch; + just_pressed.was_read = true; // This needs to be called once per frame. It lets the air actions counter know about the // air status of the character. Specifically: @@ -457,3 +446,58 @@ impl Default for ForwardFromCamera { } } } + +/// Since the fixed timestep schedule does not cache just pressed states that happened +/// in a frame with no fixed updates, we need to cache them ourselves in order to not miss them. +/// Note that if you use a smarter input manager like LWIM, this is handled for you. +/// If the demo is running with a variable timestep, this will just report the current frame's +/// state as expected. +pub struct JustPressedCachePlugin; + +impl Plugin for JustPressedCachePlugin { + fn build(&self, app: &mut App) { + app.init_resource::(); + app.add_systems( + RunFixedMainLoop, + ( + collect_just_pressed_cache.before(run_fixed_main_schedule), + clear_just_pressed_cache.after(run_fixed_main_schedule), + ), + ); + } +} + +fn collect_just_pressed_cache( + query: Query<&CharacterMotionConfigForPlatformerDemo>, + keyboard: Res>, + mut just_pressed: ResMut, +) { + for config in &query { + let crouch_buttons = match config.dimensionality { + Dimensionality::Dim2 => CROUCH_BUTTONS_2D.iter().copied(), + Dimensionality::Dim3 => CROUCH_BUTTONS_3D.iter().copied(), + }; + just_pressed.crouch = keyboard.any_just_pressed(crouch_buttons); + } +} + +fn clear_just_pressed_cache(mut just_pressed: ResMut) { + if just_pressed.was_read { + *just_pressed = default() + } +} + +#[derive(Resource, Default)] +pub struct JustPressedCache { + crouch: bool, + was_read: bool, +} + +const CROUCH_BUTTONS_2D: &[KeyCode] = &[ + KeyCode::ControlLeft, + KeyCode::ControlRight, + KeyCode::ArrowDown, + KeyCode::KeyS, +]; + +const CROUCH_BUTTONS_3D: &[KeyCode] = &[KeyCode::ControlLeft, KeyCode::ControlRight]; diff --git a/demos/src/levels_setup/for_2d_platformer.rs b/demos/src/levels_setup/for_2d_platformer.rs index 3d5f1224d..f7c9658de 100644 --- a/demos/src/levels_setup/for_2d_platformer.rs +++ b/demos/src/levels_setup/for_2d_platformer.rs @@ -16,8 +16,10 @@ use super::{ }; #[cfg(feature = "avian2d")] -#[derive(PhysicsLayer)] +#[derive(PhysicsLayer, Default)] pub enum LayerNames { + #[default] + Default, Player, FallThrough, PhaseThrough, diff --git a/demos/src/levels_setup/for_3d_platformer.rs b/demos/src/levels_setup/for_3d_platformer.rs index 1dc68380e..0e39c7952 100644 --- a/demos/src/levels_setup/for_3d_platformer.rs +++ b/demos/src/levels_setup/for_3d_platformer.rs @@ -16,8 +16,10 @@ use super::{ }; #[cfg(feature = "avian3d")] -#[derive(PhysicsLayer)] +#[derive(PhysicsLayer, Default)] pub enum LayerNames { + #[default] + Default, Player, FallThrough, PhaseThrough, From a10433cd9d1905198ec4ea7e69c0790f651b3850 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 08:31:34 +0200 Subject: [PATCH 07/12] Revert removal of running demos in physics schedule --- demos/src/app_setup_options.rs | 6 ++++-- demos/src/bin/platformer_2d.rs | 18 ++++++++++++++++++ demos/src/bin/platformer_3d.rs | 18 ++++++++++++++++++ demos/src/bin/shooter_like.rs | 18 ++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/demos/src/app_setup_options.rs b/demos/src/app_setup_options.rs index 433ea1ade..1222db218 100644 --- a/demos/src/app_setup_options.rs +++ b/demos/src/app_setup_options.rs @@ -8,7 +8,7 @@ pub struct AppSetupConfiguration { #[cfg_attr(feature = "rapier", arg(long = "schedule", default_value = "update"))] #[cfg_attr( feature = "avian", - arg(long = "schedule", default_value = "fixed-update") + arg(long = "schedule", default_value = "physics-schedule") )] pub schedule_to_use: ScheduleToUse, #[arg(long = "level")] @@ -30,7 +30,7 @@ impl AppSetupConfiguration { schedule_to_use: if let Some(value) = url_params.get("schedule") { ScheduleToUse::from_str(&value, true).unwrap() } else if cfg!(feature = "avian") { - ScheduleToUse::FixedUpdate + ScheduleToUse::PhysicsSchedule } else if cfg!(feature = "rapier") { ScheduleToUse::Update } else { @@ -67,6 +67,8 @@ impl AppSetupConfiguration { pub enum ScheduleToUse { Update, FixedUpdate, + #[cfg(feature = "avian")] + PhysicsSchedule, } impl ScheduleToUse { diff --git a/demos/src/bin/platformer_2d.rs b/demos/src/bin/platformer_2d.rs index 69280af5f..90c18d9dc 100644 --- a/demos/src/bin/platformer_2d.rs +++ b/demos/src/bin/platformer_2d.rs @@ -61,6 +61,10 @@ fn main() { // bevy-tnua-rapier2d. app.add_plugins(TnuaRapier2dPlugin::new(FixedUpdate)); } + #[cfg(feature = "avian")] + ScheduleToUse::PhysicsSchedule => { + panic!("Cannot happen - Avian and Rapier used together"); + } } } #[cfg(feature = "avian2d")] @@ -77,6 +81,10 @@ fn main() { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); app.add_plugins(TnuaAvian2dPlugin::new(FixedUpdate)); } + ScheduleToUse::PhysicsSchedule => { + app.add_plugins(PhysicsPlugins::default()); + app.add_plugins(TnuaAvian2dPlugin::new(PhysicsSchedule)); + } } } @@ -93,6 +101,11 @@ fn main() { app.add_plugins(TnuaControllerPlugin::new(FixedUpdate)); app.add_plugins(TnuaCrouchEnforcerPlugin::new(FixedUpdate)); } + #[cfg(feature = "avian")] + ScheduleToUse::PhysicsSchedule => { + app.add_plugins(TnuaControllerPlugin::new(PhysicsSchedule)); + app.add_plugins(TnuaCrouchEnforcerPlugin::new(PhysicsSchedule)); + } } #[cfg(feature = "egui")] @@ -115,6 +128,11 @@ fn main() { match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => Update.intern(), ScheduleToUse::FixedUpdate => FixedUpdate.intern(), + #[cfg(feature = "avian")] + // `PhysicsSchedule` is `FixedPostUpdate` by default, which allows us + // to run user code like the platformer controls in `FixedUpdate`, + // which is a bit more idiomatic. + ScheduleToUse::PhysicsSchedule => FixedUpdate.intern(), }, apply_platformer_controls.in_set(TnuaUserControlsSystemSet), ); diff --git a/demos/src/bin/platformer_3d.rs b/demos/src/bin/platformer_3d.rs index c03f69ab4..e4641de2b 100644 --- a/demos/src/bin/platformer_3d.rs +++ b/demos/src/bin/platformer_3d.rs @@ -67,6 +67,10 @@ fn main() { app.add_plugins(RapierPhysicsPlugin::::default().in_fixed_schedule()); app.add_plugins(TnuaRapier3dPlugin::new(FixedUpdate)); } + #[cfg(feature = "avian")] + ScheduleToUse::PhysicsSchedule => { + panic!("Cannot happen - Avian and Rapier used together"); + } } } #[cfg(feature = "avian3d")] @@ -82,6 +86,10 @@ fn main() { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); } + ScheduleToUse::PhysicsSchedule => { + app.add_plugins(PhysicsPlugins::default()); + app.add_plugins(TnuaAvian3dPlugin::new(PhysicsSchedule)); + } } } @@ -98,6 +106,11 @@ fn main() { app.add_plugins(TnuaControllerPlugin::new(FixedUpdate)); app.add_plugins(TnuaCrouchEnforcerPlugin::new(FixedUpdate)); } + #[cfg(feature = "avian")] + ScheduleToUse::PhysicsSchedule => { + app.add_plugins(TnuaControllerPlugin::new(PhysicsSchedule)); + app.add_plugins(TnuaCrouchEnforcerPlugin::new(PhysicsSchedule)); + } } #[cfg(feature = "egui")] @@ -125,6 +138,11 @@ fn main() { match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => Update.intern(), ScheduleToUse::FixedUpdate => FixedUpdate.intern(), + #[cfg(feature = "avian")] + // `PhysicsSchedule` is `FixedPostUpdate` by default, which allows us + // to run user code like the platformer controls in `FixedUpdate`, + // which is a bit more idiomatic. + ScheduleToUse::PhysicsSchedule => FixedUpdate.intern(), }, apply_platformer_controls.in_set(TnuaUserControlsSystemSet), ); diff --git a/demos/src/bin/shooter_like.rs b/demos/src/bin/shooter_like.rs index 96ca9b078..146dd2da6 100644 --- a/demos/src/bin/shooter_like.rs +++ b/demos/src/bin/shooter_like.rs @@ -66,6 +66,10 @@ fn main() { app.add_plugins(RapierPhysicsPlugin::::default().in_fixed_schedule()); app.add_plugins(TnuaRapier3dPlugin::new(FixedUpdate)); } + #[cfg(feature = "avian")] + ScheduleToUse::PhysicsSchedule => { + panic!("Cannot happen - Avian and Rapier used together"); + } } } #[cfg(feature = "avian3d")] @@ -81,6 +85,10 @@ fn main() { app.add_plugins(PhysicsPlugins::new(FixedUpdate)); app.add_plugins(TnuaAvian3dPlugin::new(FixedUpdate)); } + ScheduleToUse::PhysicsSchedule => { + app.add_plugins(PhysicsPlugins::default()); + app.add_plugins(TnuaAvian3dPlugin::new(PhysicsSchedule)); + } } } @@ -97,6 +105,11 @@ fn main() { app.add_plugins(TnuaControllerPlugin::new(FixedUpdate)); app.add_plugins(TnuaCrouchEnforcerPlugin::new(FixedUpdate)); } + #[cfg(feature = "avian")] + ScheduleToUse::PhysicsSchedule => { + app.add_plugins(TnuaControllerPlugin::new(PhysicsSchedule)); + app.add_plugins(TnuaCrouchEnforcerPlugin::new(PhysicsSchedule)); + } } #[cfg(feature = "egui")] @@ -126,6 +139,11 @@ fn main() { match app_setup_configuration.schedule_to_use { ScheduleToUse::Update => Update.intern(), ScheduleToUse::FixedUpdate => FixedUpdate.intern(), + #[cfg(feature = "avian")] + // `PhysicsSchedule` is `FixedPostUpdate` by default, which allows us + // to run user code like the platformer controls in `FixedUpdate`, + // which is a bit more idiomatic. + ScheduleToUse::PhysicsSchedule => FixedUpdate.intern(), }, apply_platformer_controls.in_set(TnuaUserControlsSystemSet), ); From 54924842fc9b4886e0f3d116cd288b5b9ebe78c7 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 09:11:55 +0200 Subject: [PATCH 08/12] Make examples a bit more idiomatic --- examples/example.rs | 4 ++-- examples/example_animating.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/example.rs b/examples/example.rs index 9c6e44a06..d2b7fed84 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -20,8 +20,8 @@ fn main() { (setup_camera_and_lights, setup_level, setup_player), ) .add_systems( - PhysicsSchedule, - apply_controls.in_set(TnuaUserControlsSystemSet), + FixedUpdate, + apply_controls, ) .run(); } diff --git a/examples/example_animating.rs b/examples/example_animating.rs index 258f1df6d..68aa3339d 100644 --- a/examples/example_animating.rs +++ b/examples/example_animating.rs @@ -24,8 +24,8 @@ fn main() { (setup_camera_and_lights, setup_level, setup_player), ) .add_systems( - PhysicsSchedule, - apply_controls.in_set(TnuaUserControlsSystemSet), + FixedUpdate, + apply_controls, ) .add_systems( Update, From 0f28eb636a2a6cb42f0e95aebf8dc97c4953f3b2 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 21:15:56 +0200 Subject: [PATCH 09/12] Use direct into impl --- avian2d/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/avian2d/src/lib.rs b/avian2d/src/lib.rs index 273dcb36a..eb04aa207 100644 --- a/avian2d/src/lib.rs +++ b/avian2d/src/lib.rs @@ -96,7 +96,7 @@ fn update_rigid_body_trackers_system( } *tracker = TnuaRigidBodyTracker { translation: position.adjust_precision().extend(0.0), - rotation: Quat::from_rotation_z(rotation.as_radians()).adjust_precision(), + rotation: Quaternion::from(*rotation).adjust_precision(), velocity: linaer_velocity.0.extend(0.0), angvel: Vector3::new(0.0, 0.0, angular_velocity.0), gravity: gravity.0.extend(0.0), @@ -145,9 +145,9 @@ fn update_proximity_sensors_system( TnuaToggle::Enabled => {} } let transform = Transform { - translation: position.extend(0.0), - rotation: Quat::from_rotation_z(rotation.as_radians()), - scale: collider.scale().extend(1.0), + translation: position.adjust_precision().extend(0.0), + rotation: Quaternion::from(*rotation).adjust_precision(), + scale: collider.scale().adjust_precision().extend(1.0), }; let cast_origin = transform.transform_point(sensor.cast_origin.f32()); let cast_direction = sensor.cast_direction; From e8425b07984a7fd1080f135cd5b71becf98e5e2a Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 21:19:13 +0200 Subject: [PATCH 10/12] Remove useless line --- avian3d/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/avian3d/src/lib.rs b/avian3d/src/lib.rs index 32916f28b..c0d31a853 100644 --- a/avian3d/src/lib.rs +++ b/avian3d/src/lib.rs @@ -278,10 +278,9 @@ fn update_proximity_sensors_system( let query_filter = SpatialQueryFilter::from_excluded_entities([owner_entity]); if let Some(TnuaAvian3dSensorShape(shape)) = shape { - let owner_rotation = transform.rotation; let owner_rotation = Quat::from_axis_angle( *cast_direction, - owner_rotation.to_scaled_axis().dot(*cast_direction), + rotation.to_scaled_axis().dot(*cast_direction), ); spatial_query_pipeline.shape_hits_callback( shape, From e4d1d3bf7e5565395ac54a639145205f938e2026 Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 21:20:50 +0200 Subject: [PATCH 11/12] Fix compile error --- demos/src/app_setup_options.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/demos/src/app_setup_options.rs b/demos/src/app_setup_options.rs index 1222db218..316403376 100644 --- a/demos/src/app_setup_options.rs +++ b/demos/src/app_setup_options.rs @@ -29,12 +29,19 @@ impl AppSetupConfiguration { Self { schedule_to_use: if let Some(value) = url_params.get("schedule") { ScheduleToUse::from_str(&value, true).unwrap() - } else if cfg!(feature = "avian") { - ScheduleToUse::PhysicsSchedule - } else if cfg!(feature = "rapier") { - ScheduleToUse::Update } else { - panic!("No schedule was specified, but also no physics engine is avaible. Therefore, there is no fallback.") + #[cfg(feature = "avian")] + { + ScheduleToUse::PhysicsSchedule + } + #[cfg(feature = "rapier")] + { + ScheduleToUse::Update + } + #[cfg(all(not(feature = "avian"), not(feature = "rapier")))] + { + panic!("No schedule was specified, but also no physics engine is avaible. Therefore, there is no fallback.") + } }, level_to_load: url_params.get("level"), } From 6099a73bfb1b550345dec7ac3802c91aaa3d579a Mon Sep 17 00:00:00 2001 From: Jan Hohenheim Date: Sun, 8 Sep 2024 21:21:03 +0200 Subject: [PATCH 12/12] Run cargo fmt --- examples/example.rs | 5 +---- examples/example_animating.rs | 13 ++----------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/examples/example.rs b/examples/example.rs index d2b7fed84..7b188671d 100644 --- a/examples/example.rs +++ b/examples/example.rs @@ -19,10 +19,7 @@ fn main() { Startup, (setup_camera_and_lights, setup_level, setup_player), ) - .add_systems( - FixedUpdate, - apply_controls, - ) + .add_systems(FixedUpdate, apply_controls) .run(); } diff --git a/examples/example_animating.rs b/examples/example_animating.rs index 68aa3339d..9250e4994 100644 --- a/examples/example_animating.rs +++ b/examples/example_animating.rs @@ -23,17 +23,8 @@ fn main() { Startup, (setup_camera_and_lights, setup_level, setup_player), ) - .add_systems( - FixedUpdate, - apply_controls, - ) - .add_systems( - Update, - ( - prepare_animations, - handle_animating, - ), - ) + .add_systems(FixedUpdate, apply_controls) + .add_systems(Update, (prepare_animations, handle_animating)) .run(); }