Optimize transform systems to only run on change (#417)
Optimize transform systems to only run on change
This commit is contained in:
parent
9eba19c8f0
commit
43463a7a06
@ -16,6 +16,7 @@ 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,
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ pub fn local_transform_translation_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
Rotation,
|
||||
Without<Scale, Without<NonUniformScale, (&mut LocalTransform, &Translation)>>,
|
||||
Without<Scale, Without<NonUniformScale, (&mut LocalTransform, Changed<Translation>)>>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
@ -20,7 +20,7 @@ pub fn local_transform_rotation_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
Translation,
|
||||
Without<Scale, Without<NonUniformScale, (&mut LocalTransform, &Rotation)>>,
|
||||
Without<Scale, Without<NonUniformScale, (&mut LocalTransform, Changed<Rotation>)>>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
@ -33,7 +33,7 @@ pub fn local_transform_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
Translation,
|
||||
Without<Rotation, Without<NonUniformScale, (&mut LocalTransform, &Scale)>>,
|
||||
Without<Rotation, Without<NonUniformScale, (&mut LocalTransform, Changed<Scale>)>>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
@ -46,7 +46,7 @@ pub fn local_transform_non_uniform_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
Translation,
|
||||
Without<Rotation, Without<Scale, (&mut LocalTransform, &NonUniformScale)>>,
|
||||
Without<Rotation, Without<Scale, (&mut LocalTransform, Changed<NonUniformScale>)>>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
@ -57,20 +57,38 @@ pub fn local_transform_non_uniform_scale_system(
|
||||
|
||||
pub fn local_transform_translation_rotation_system(
|
||||
mut query: Query<
|
||||
Without<Scale, Without<NonUniformScale, (&mut LocalTransform, &Translation, &Rotation)>>,
|
||||
Without<
|
||||
Scale,
|
||||
Without<
|
||||
NonUniformScale,
|
||||
(
|
||||
&mut LocalTransform,
|
||||
Or<(Changed<Translation>, Changed<Rotation>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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<Rotation, Without<NonUniformScale, (&mut LocalTransform, &Translation, &Scale)>>,
|
||||
Without<
|
||||
Rotation,
|
||||
Without<
|
||||
NonUniformScale,
|
||||
(
|
||||
&mut LocalTransform,
|
||||
Or<(Changed<Translation>, Changed<Scale>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +99,19 @@ pub fn local_transform_translation_scale_system(
|
||||
|
||||
pub fn local_transform_translation_non_uniform_scale_system(
|
||||
mut query: Query<
|
||||
Without<Rotation, Without<Scale, (&mut LocalTransform, &Translation, &NonUniformScale)>>,
|
||||
Without<
|
||||
Rotation,
|
||||
Without<
|
||||
Scale,
|
||||
(
|
||||
&mut LocalTransform,
|
||||
Or<(Changed<Translation>, Changed<NonUniformScale>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +122,16 @@ pub fn local_transform_translation_non_uniform_scale_system(
|
||||
|
||||
pub fn local_transform_rotation_scale_system(
|
||||
mut query: Query<
|
||||
Without<Translation, Without<NonUniformScale, (&mut LocalTransform, &Rotation, &Scale)>>,
|
||||
Without<
|
||||
Translation,
|
||||
Without<
|
||||
NonUniformScale,
|
||||
(&mut LocalTransform, Or<(Changed<Rotation>, Changed<Scale>)>),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +142,19 @@ pub fn local_transform_rotation_scale_system(
|
||||
|
||||
pub fn local_transform_rotation_non_uniform_scale_system(
|
||||
mut query: Query<
|
||||
Without<Translation, Without<Scale, (&mut LocalTransform, &Rotation, &NonUniformScale)>>,
|
||||
Without<
|
||||
Translation,
|
||||
Without<
|
||||
Scale,
|
||||
(
|
||||
&mut LocalTransform,
|
||||
Or<(Changed<Rotation>, Changed<NonUniformScale>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +165,16 @@ pub fn local_transform_rotation_non_uniform_scale_system(
|
||||
|
||||
pub fn local_transform_translation_rotation_scale_system(
|
||||
mut query: Query<
|
||||
Without<NonUniformScale, (&mut LocalTransform, &Translation, &Rotation, &Scale)>,
|
||||
Without<
|
||||
NonUniformScale,
|
||||
(
|
||||
&mut LocalTransform,
|
||||
Or<(Changed<Translation>, Changed<Rotation>, Changed<Scale>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +189,16 @@ pub fn local_transform_translation_rotation_non_uniform_scale_system(
|
||||
Scale,
|
||||
(
|
||||
&mut LocalTransform,
|
||||
&Translation,
|
||||
&Rotation,
|
||||
&NonUniformScale,
|
||||
Or<(
|
||||
Changed<Translation>,
|
||||
Changed<Rotation>,
|
||||
Changed<NonUniformScale>,
|
||||
)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +320,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<LocalTransform>) {
|
||||
assert!(false)
|
||||
}
|
||||
|
||||
schedule.add_system_to_stage("update", assert_no_local_transforms_changed_system.system());
|
||||
schedule.run(&mut world, &mut resources);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ pub fn transform_translation_system(
|
||||
LocalTransform,
|
||||
Without<
|
||||
Rotation,
|
||||
Without<Scale, Without<NonUniformScale, (&mut Transform, &Translation)>>,
|
||||
Without<Scale, Without<NonUniformScale, (&mut Transform, Changed<Translation>)>>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
@ -29,7 +29,7 @@ pub fn transform_rotation_system(
|
||||
LocalTransform,
|
||||
Without<
|
||||
Translation,
|
||||
Without<Scale, Without<NonUniformScale, (&mut Transform, &Rotation)>>,
|
||||
Without<Scale, Without<NonUniformScale, (&mut Transform, Changed<Rotation>)>>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
@ -49,7 +49,7 @@ pub fn transform_scale_system(
|
||||
LocalTransform,
|
||||
Without<
|
||||
Translation,
|
||||
Without<Rotation, Without<NonUniformScale, (&mut Transform, &Scale)>>,
|
||||
Without<Rotation, Without<NonUniformScale, (&mut Transform, Changed<Scale>)>>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
@ -69,7 +69,7 @@ pub fn transform_non_uniform_scale_system(
|
||||
LocalTransform,
|
||||
Without<
|
||||
Translation,
|
||||
Without<Rotation, Without<Scale, (&mut Transform, &NonUniformScale)>>,
|
||||
Without<Rotation, Without<Scale, (&mut Transform, Changed<NonUniformScale>)>>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
@ -87,11 +87,20 @@ pub fn transform_translation_rotation_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
LocalTransform,
|
||||
Without<Scale, Without<NonUniformScale, (&mut Transform, &Translation, &Rotation)>>,
|
||||
Without<
|
||||
Scale,
|
||||
Without<
|
||||
NonUniformScale,
|
||||
(
|
||||
&mut Transform,
|
||||
Or<(Changed<Translation>, Changed<Rotation>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
for (mut transform, translation, rotation) in &mut query.iter() {
|
||||
for (mut transform, (translation, rotation)) in &mut query.iter() {
|
||||
if !transform.sync {
|
||||
continue;
|
||||
}
|
||||
@ -104,11 +113,17 @@ pub fn transform_translation_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
LocalTransform,
|
||||
Without<Rotation, Without<NonUniformScale, (&mut Transform, &Translation, &Scale)>>,
|
||||
Without<
|
||||
Rotation,
|
||||
Without<
|
||||
NonUniformScale,
|
||||
(&mut Transform, Or<(Changed<Translation>, Changed<Scale>)>),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
for (mut transform, translation, scale) in &mut query.iter() {
|
||||
for (mut transform, (translation, scale)) in &mut query.iter() {
|
||||
if !transform.sync {
|
||||
continue;
|
||||
}
|
||||
@ -125,11 +140,20 @@ pub fn transform_translation_non_uniform_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
LocalTransform,
|
||||
Without<Rotation, Without<Scale, (&mut Transform, &Translation, &NonUniformScale)>>,
|
||||
Without<
|
||||
Rotation,
|
||||
Without<
|
||||
Scale,
|
||||
(
|
||||
&mut Transform,
|
||||
Or<(Changed<Translation>, Changed<NonUniformScale>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +170,14 @@ pub fn transform_rotation_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
LocalTransform,
|
||||
Without<Translation, Without<NonUniformScale, (&mut Transform, &Rotation, &Scale)>>,
|
||||
Without<
|
||||
Translation,
|
||||
Without<NonUniformScale, (&mut Transform, Or<(Changed<Rotation>, Changed<Scale>)>)>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
for (mut transform, rotation, scale) in &mut query.iter() {
|
||||
for (mut transform, (rotation, scale)) in &mut query.iter() {
|
||||
if !transform.sync {
|
||||
continue;
|
||||
}
|
||||
@ -167,11 +194,20 @@ pub fn transform_rotation_non_uniform_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
LocalTransform,
|
||||
Without<Translation, Without<Scale, (&mut Transform, &Rotation, &NonUniformScale)>>,
|
||||
Without<
|
||||
Translation,
|
||||
Without<
|
||||
Scale,
|
||||
(
|
||||
&mut Transform,
|
||||
Or<(Changed<Rotation>, Changed<NonUniformScale>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +224,17 @@ pub fn transform_translation_rotation_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
LocalTransform,
|
||||
Without<NonUniformScale, (&mut Transform, &Translation, &Rotation, &Scale)>,
|
||||
Without<
|
||||
NonUniformScale,
|
||||
(
|
||||
&mut Transform,
|
||||
Or<(Changed<Translation>, Changed<Rotation>, Changed<Scale>)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +251,21 @@ pub fn transform_translation_rotation_non_uniform_scale_system(
|
||||
mut query: Query<
|
||||
Without<
|
||||
LocalTransform,
|
||||
Without<Scale, (&mut Transform, &Translation, &Rotation, &NonUniformScale)>,
|
||||
Without<
|
||||
Scale,
|
||||
(
|
||||
&mut Transform,
|
||||
Or<(
|
||||
Changed<Translation>,
|
||||
Changed<Rotation>,
|
||||
Changed<NonUniformScale>,
|
||||
)>,
|
||||
),
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
) {
|
||||
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 +388,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<Transform>) {
|
||||
assert!(false)
|
||||
}
|
||||
|
||||
schedule.add_system_to_stage("update", assert_no_transforms_changed_system.system());
|
||||
schedule.run(&mut world, &mut resources);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user