From 891fdfd6eb89e67cd957de8ab4a19806192d9f61 Mon Sep 17 00:00:00 2001 From: Tristan Pemble Date: Tue, 1 Sep 2020 19:23:36 -0700 Subject: [PATCH 1/2] Optimize transform systems to only run on change --- crates/bevy_ecs/src/lib.rs | 2 +- .../src/local_transform_systems.rs | 95 +++++++++++++++---- .../bevy_transform/src/transform_systems.rs | 92 ++++++++++++++---- 3 files changed, 150 insertions(+), 39 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index e9fcba8a31808..c8df9e876a618 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -16,6 +16,6 @@ pub mod prelude { Commands, IntoForEachSystem, IntoQuerySystem, IntoThreadLocalSystem, Query, System, }, world::WorldBuilderSource, - Added, Bundle, Changed, Component, Entity, Mut, Mutated, Ref, RefMut, With, Without, World, + Added, Bundle, Changed, Component, Entity, Mut, Mutated, Or, Ref, RefMut, With, Without, World, }; } diff --git a/crates/bevy_transform/src/local_transform_systems.rs b/crates/bevy_transform/src/local_transform_systems.rs index 938aa87b3ccc8..5b13d6744b796 100644 --- a/crates/bevy_transform/src/local_transform_systems.rs +++ b/crates/bevy_transform/src/local_transform_systems.rs @@ -7,7 +7,7 @@ pub fn local_transform_translation_system( mut query: Query< Without< Rotation, - Without>, + Without)>>, >, >, ) { @@ -20,7 +20,7 @@ pub fn local_transform_rotation_system( mut query: Query< Without< Translation, - Without>, + Without)>>, >, >, ) { @@ -33,7 +33,7 @@ pub fn local_transform_scale_system( mut query: Query< Without< Translation, - Without>, + Without)>>, >, >, ) { @@ -46,7 +46,7 @@ pub fn local_transform_non_uniform_scale_system( mut query: Query< Without< Translation, - Without>, + Without)>>, >, >, ) { @@ -57,20 +57,24 @@ pub fn local_transform_non_uniform_scale_system( pub fn local_transform_translation_rotation_system( mut query: Query< - Without>, + Without, Changed)>) + >>, >, ) { - for (mut local, translation, rotation) in &mut query.iter() { + for (mut local, (translation, rotation)) in &mut query.iter() { *local = LocalTransform(Mat4::from_rotation_translation(rotation.0, translation.0)); } } pub fn local_transform_translation_scale_system( mut query: Query< - Without>, + Without, Changed)>) + >>, >, ) { - for (mut local, translation, scale) in &mut query.iter() { + for (mut local, (translation, scale)) in &mut query.iter() { *local = LocalTransform(Mat4::from_scale_rotation_translation( Vec3::new(scale.0, scale.0, scale.0), Quat::default(), @@ -81,10 +85,12 @@ pub fn local_transform_translation_scale_system( pub fn local_transform_translation_non_uniform_scale_system( mut query: Query< - Without>, + Without, Changed)>) + >>, >, ) { - for (mut local, translation, non_uniform_scale) in &mut query.iter() { + for (mut local, (translation, non_uniform_scale)) in &mut query.iter() { *local = LocalTransform(Mat4::from_scale_rotation_translation( non_uniform_scale.0, Quat::default(), @@ -95,10 +101,12 @@ pub fn local_transform_translation_non_uniform_scale_system( pub fn local_transform_rotation_scale_system( mut query: Query< - Without>, + Without, Changed)>) + >>, >, ) { - for (mut local, rotation, scale) in &mut query.iter() { + for (mut local, (rotation, scale)) in &mut query.iter() { *local = LocalTransform(Mat4::from_scale_rotation_translation( Vec3::new(scale.0, scale.0, scale.0), rotation.0, @@ -109,10 +117,12 @@ pub fn local_transform_rotation_scale_system( pub fn local_transform_rotation_non_uniform_scale_system( mut query: Query< - Without>, + Without, Changed)>) + >>, >, ) { - for (mut local, rotation, non_uniform_scale) in &mut query.iter() { + for (mut local, (rotation, non_uniform_scale)) in &mut query.iter() { *local = LocalTransform(Mat4::from_scale_rotation_translation( non_uniform_scale.0, rotation.0, @@ -123,10 +133,11 @@ pub fn local_transform_rotation_non_uniform_scale_system( pub fn local_transform_translation_rotation_scale_system( mut query: Query< - Without, + Without, Changed, Changed)>)>, >, ) { - for (mut local, translation, rotation, scale) in &mut query.iter() { + for (mut local, (translation, rotation, scale)) in &mut query.iter() { *local = LocalTransform(Mat4::from_scale_rotation_translation( Vec3::new(scale.0, scale.0, scale.0), rotation.0, @@ -141,14 +152,16 @@ pub fn local_transform_translation_rotation_non_uniform_scale_system( Scale, ( &mut LocalTransform, - &Translation, - &Rotation, - &NonUniformScale, + Or<( + Changed, + Changed, + Changed, + )>, ), >, >, ) { - for (mut local, translation, rotation, non_uniform_scale) in &mut query.iter() { + for (mut local, (translation, rotation, non_uniform_scale)) in &mut query.iter() { *local = LocalTransform(Mat4::from_scale_rotation_translation( non_uniform_scale.0, rotation.0, @@ -270,4 +283,46 @@ mod test { Mat4::from_scale_rotation_translation(nus.0, r.0, t.0) ); } + + #[test] + fn only_propagates_local_transform_on_change() { + let mut world = World::default(); + let mut resources = Resources::default(); + + let mut schedule = Schedule::default(); + schedule.add_stage("update"); + for system in local_transform_systems() { + schedule.add_system_to_stage("update", system); + } + + let local_transform = LocalTransform::identity(); + let t = Translation::new(1.0, 2.0, 3.0); + let r = Rotation(Quat::from_rotation_ypr(1.0, 2.0, 3.0)); + let s = Scale(2.0); + let nus = NonUniformScale::new(1.0, 2.0, 3.0); + + // Add every combination of transform types. + world.spawn((local_transform, t)); + world.spawn((local_transform, r)); + world.spawn((local_transform, s)); + world.spawn((local_transform, nus)); + world.spawn((local_transform, t, r)); + world.spawn((local_transform, t, s)); + world.spawn((local_transform, t, nus)); + world.spawn((local_transform, r, s)); + world.spawn((local_transform, r, nus)); + world.spawn((local_transform, t, r, s)); + world.spawn((local_transform, t, r, nus)); + + // Run the system, local transforms should mutate since they are new + schedule.run(&mut world, &mut resources); + + // Verify that the local transform is not mutated on the second frame + fn assert_no_local_transforms_changed_system(_: Changed) { + assert!(false) + } + + schedule.add_system_to_stage("update", assert_no_local_transforms_changed_system.system()); + schedule.run(&mut world, &mut resources); + } } diff --git a/crates/bevy_transform/src/transform_systems.rs b/crates/bevy_transform/src/transform_systems.rs index ec2d57c63ece1..3f8b7b9037de8 100644 --- a/crates/bevy_transform/src/transform_systems.rs +++ b/crates/bevy_transform/src/transform_systems.rs @@ -9,7 +9,7 @@ pub fn transform_translation_system( LocalTransform, Without< Rotation, - Without>, + Without)>>, >, >, >, @@ -29,7 +29,7 @@ pub fn transform_rotation_system( LocalTransform, Without< Translation, - Without>, + Without)>>, >, >, >, @@ -49,7 +49,7 @@ pub fn transform_scale_system( LocalTransform, Without< Translation, - Without>, + Without)>>, >, >, >, @@ -69,7 +69,7 @@ pub fn transform_non_uniform_scale_system( LocalTransform, Without< Translation, - Without>, + Without)>>, >, >, >, @@ -87,11 +87,13 @@ pub fn transform_translation_rotation_system( mut query: Query< Without< LocalTransform, - Without>, + Without, Changed)>) + >>, >, >, ) { - for (mut transform, translation, rotation) in &mut query.iter() { + for (mut transform, (translation, rotation)) in &mut query.iter() { if !transform.sync { continue; } @@ -104,11 +106,13 @@ pub fn transform_translation_scale_system( mut query: Query< Without< LocalTransform, - Without>, + Without, Changed)>) + >>, >, >, ) { - for (mut transform, translation, scale) in &mut query.iter() { + for (mut transform, (translation, scale)) in &mut query.iter() { if !transform.sync { continue; } @@ -125,11 +129,13 @@ pub fn transform_translation_non_uniform_scale_system( mut query: Query< Without< LocalTransform, - Without>, + Without, Changed)>) + >>, >, >, ) { - for (mut transform, translation, non_uniform_scale) in &mut query.iter() { + for (mut transform, (translation, non_uniform_scale)) in &mut query.iter() { if !transform.sync { continue; } @@ -146,11 +152,13 @@ pub fn transform_rotation_scale_system( mut query: Query< Without< LocalTransform, - Without>, + Without, Changed)>) + >>, >, >, ) { - for (mut transform, rotation, scale) in &mut query.iter() { + for (mut transform, (rotation, scale)) in &mut query.iter() { if !transform.sync { continue; } @@ -167,11 +175,13 @@ pub fn transform_rotation_non_uniform_scale_system( mut query: Query< Without< LocalTransform, - Without>, + Without, Changed)>) + >>, >, >, ) { - for (mut transform, rotation, non_uniform_scale) in &mut query.iter() { + for (mut transform, (rotation, non_uniform_scale)) in &mut query.iter() { if !transform.sync { continue; } @@ -188,11 +198,13 @@ pub fn transform_translation_rotation_scale_system( mut query: Query< Without< LocalTransform, - Without, + Without, Changed, Changed)>) + >, >, >, ) { - for (mut transform, translation, rotation, scale) in &mut query.iter() { + for (mut transform, (translation, rotation, scale)) in &mut query.iter() { if !transform.sync { continue; } @@ -209,11 +221,13 @@ pub fn transform_translation_rotation_non_uniform_scale_system( mut query: Query< Without< LocalTransform, - Without, + Without, Changed, Changed)>) + >, >, >, ) { - for (mut transform, translation, rotation, non_uniform_scale) in &mut query.iter() { + for (mut transform, (translation, rotation, non_uniform_scale)) in &mut query.iter() { if !transform.sync { continue; } @@ -336,4 +350,46 @@ mod test { Mat4::from_scale_rotation_translation(nus.0, r.0, t.0) ); } + + #[test] + fn only_propagates_transform_on_change() { + let mut world = World::default(); + let mut resources = Resources::default(); + + let mut schedule = Schedule::default(); + schedule.add_stage("update"); + for system in transform_systems() { + schedule.add_system_to_stage("update", system); + } + + let transform = Transform::identity(); + let t = Translation::new(1.0, 2.0, 3.0); + let r = Rotation(Quat::from_rotation_ypr(1.0, 2.0, 3.0)); + let s = Scale(2.0); + let nus = NonUniformScale::new(1.0, 2.0, 3.0); + + // Add every combination of transform types. + world.spawn((transform, t)); + world.spawn((transform, r)); + world.spawn((transform, s)); + world.spawn((transform, nus)); + world.spawn((transform, t, r)); + world.spawn((transform, t, s)); + world.spawn((transform, t, nus)); + world.spawn((transform, r, s)); + world.spawn((transform, r, nus)); + world.spawn((transform, t, r, s)); + world.spawn((transform, t, r, nus)); + + // Run the system, transforms should mutate since they are new + schedule.run(&mut world, &mut resources); + + // Verify that the transform is not mutated on the second frame + fn assert_no_transforms_changed_system(_: Changed) { + assert!(false) + } + + schedule.add_system_to_stage("update", assert_no_transforms_changed_system.system()); + schedule.run(&mut world, &mut resources); + } } From 8b78e38e820e40611f6a0fe50b0df2200957ac43 Mon Sep 17 00:00:00 2001 From: Tristan Pemble Date: Thu, 3 Sep 2020 15:41:50 -0700 Subject: [PATCH 2/2] cargo fmt --- crates/bevy_ecs/src/lib.rs | 3 +- .../src/local_transform_systems.rs | 71 ++++++++++++----- .../bevy_transform/src/transform_systems.rs | 76 ++++++++++++++----- 3 files changed, 113 insertions(+), 37 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index c8df9e876a618..c1266763559bc 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -16,6 +16,7 @@ pub mod prelude { Commands, IntoForEachSystem, IntoQuerySystem, IntoThreadLocalSystem, Query, System, }, world::WorldBuilderSource, - Added, Bundle, Changed, Component, Entity, Mut, Mutated, Or, Ref, RefMut, With, Without, World, + Added, Bundle, Changed, Component, Entity, Mut, Mutated, Or, Ref, RefMut, With, Without, + World, }; } diff --git a/crates/bevy_transform/src/local_transform_systems.rs b/crates/bevy_transform/src/local_transform_systems.rs index 5b13d6744b796..3e9cf0b063f37 100644 --- a/crates/bevy_transform/src/local_transform_systems.rs +++ b/crates/bevy_transform/src/local_transform_systems.rs @@ -57,9 +57,16 @@ pub fn local_transform_non_uniform_scale_system( pub fn local_transform_translation_rotation_system( mut query: Query< - Without, Changed)>) - >>, + Without< + Scale, + Without< + NonUniformScale, + ( + &mut LocalTransform, + Or<(Changed, Changed)>, + ), + >, + >, >, ) { for (mut local, (translation, rotation)) in &mut query.iter() { @@ -69,9 +76,16 @@ pub fn local_transform_translation_rotation_system( pub fn local_transform_translation_scale_system( mut query: Query< - Without, Changed)>) - >>, + Without< + Rotation, + Without< + NonUniformScale, + ( + &mut LocalTransform, + Or<(Changed, Changed)>, + ), + >, + >, >, ) { for (mut local, (translation, scale)) in &mut query.iter() { @@ -85,9 +99,16 @@ pub fn local_transform_translation_scale_system( pub fn local_transform_translation_non_uniform_scale_system( mut query: Query< - Without, Changed)>) - >>, + Without< + Rotation, + Without< + Scale, + ( + &mut LocalTransform, + Or<(Changed, Changed)>, + ), + >, + >, >, ) { for (mut local, (translation, non_uniform_scale)) in &mut query.iter() { @@ -101,9 +122,13 @@ pub fn local_transform_translation_non_uniform_scale_system( pub fn local_transform_rotation_scale_system( mut query: Query< - Without, Changed)>) - >>, + Without< + Translation, + Without< + NonUniformScale, + (&mut LocalTransform, Or<(Changed, Changed)>), + >, + >, >, ) { for (mut local, (rotation, scale)) in &mut query.iter() { @@ -117,9 +142,16 @@ pub fn local_transform_rotation_scale_system( pub fn local_transform_rotation_non_uniform_scale_system( mut query: Query< - Without, Changed)>) - >>, + Without< + Translation, + Without< + Scale, + ( + &mut LocalTransform, + Or<(Changed, Changed)>, + ), + >, + >, >, ) { for (mut local, (rotation, non_uniform_scale)) in &mut query.iter() { @@ -133,8 +165,13 @@ pub fn local_transform_rotation_non_uniform_scale_system( pub fn local_transform_translation_rotation_scale_system( mut query: Query< - Without, Changed, Changed)>)>, + Without< + NonUniformScale, + ( + &mut LocalTransform, + Or<(Changed, Changed, Changed)>, + ), + >, >, ) { for (mut local, (translation, rotation, scale)) in &mut query.iter() { diff --git a/crates/bevy_transform/src/transform_systems.rs b/crates/bevy_transform/src/transform_systems.rs index 3f8b7b9037de8..df5e68d1bc42f 100644 --- a/crates/bevy_transform/src/transform_systems.rs +++ b/crates/bevy_transform/src/transform_systems.rs @@ -87,9 +87,16 @@ pub fn transform_translation_rotation_system( mut query: Query< Without< LocalTransform, - Without, Changed)>) - >>, + Without< + Scale, + Without< + NonUniformScale, + ( + &mut Transform, + Or<(Changed, Changed)>, + ), + >, + >, >, >, ) { @@ -106,9 +113,13 @@ pub fn transform_translation_scale_system( mut query: Query< Without< LocalTransform, - Without, Changed)>) - >>, + Without< + Rotation, + Without< + NonUniformScale, + (&mut Transform, Or<(Changed, Changed)>), + >, + >, >, >, ) { @@ -129,9 +140,16 @@ pub fn transform_translation_non_uniform_scale_system( mut query: Query< Without< LocalTransform, - Without, Changed)>) - >>, + Without< + Rotation, + Without< + Scale, + ( + &mut Transform, + Or<(Changed, Changed)>, + ), + >, + >, >, >, ) { @@ -152,9 +170,10 @@ pub fn transform_rotation_scale_system( mut query: Query< Without< LocalTransform, - Without, Changed)>) - >>, + Without< + Translation, + Without, Changed)>)>, + >, >, >, ) { @@ -175,9 +194,16 @@ pub fn transform_rotation_non_uniform_scale_system( mut query: Query< Without< LocalTransform, - Without, Changed)>) - >>, + Without< + Translation, + Without< + Scale, + ( + &mut Transform, + Or<(Changed, Changed)>, + ), + >, + >, >, >, ) { @@ -198,8 +224,12 @@ pub fn transform_translation_rotation_scale_system( mut query: Query< Without< LocalTransform, - Without, Changed, Changed)>) + Without< + NonUniformScale, + ( + &mut Transform, + Or<(Changed, Changed, Changed)>, + ), >, >, >, @@ -221,8 +251,16 @@ pub fn transform_translation_rotation_non_uniform_scale_system( mut query: Query< Without< LocalTransform, - Without, Changed, Changed)>) + Without< + Scale, + ( + &mut Transform, + Or<( + Changed, + Changed, + Changed, + )>, + ), >, >, >,