From 05b089200772fd880b6b27196e6ff8622edb4fdb Mon Sep 17 00:00:00 2001 From: Robert Swain Date: Tue, 29 Mar 2022 03:05:01 +0000 Subject: [PATCH] bevy_transform: Use Changed in the query for much faster transform_propagate_system (#4180) # Objective - Improve transform propagation performance ## Solution - Use `Changed` as part of the `root_query` and `transform_query` to avoid the indirection of having to look up the `Entity` in the `changed_transform_query` - Get rid of the `changed_transform_query` entirely - `transform_propagate_system` execution time for `many_cubes -- sphere` dropped from 1.07ms to 0.159ms, an 85% reduction for this system. Frame rate increased from ~42fps to ~44fps --- crates/bevy_transform/src/systems.rs | 35 +++++++++++++++++----------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs index 9fb2e9a2d0ef9a..bc40d58bb61df5 100644 --- a/crates/bevy_transform/src/systems.rs +++ b/crates/bevy_transform/src/systems.rs @@ -1,7 +1,8 @@ use crate::components::{GlobalTransform, Transform}; use bevy_ecs::{ entity::Entity, - query::{Changed, With, Without}, + prelude::Changed, + query::{With, Without}, system::Query, }; use bevy_hierarchy::{Children, Parent}; @@ -10,16 +11,23 @@ use bevy_hierarchy::{Children, Parent}; /// [`Transform`] component. pub fn transform_propagate_system( mut root_query: Query< - (Entity, Option<&Children>, &Transform, &mut GlobalTransform), + ( + Option<&Children>, + &Transform, + Changed, + &mut GlobalTransform, + ), Without, >, - mut transform_query: Query<(&Transform, &mut GlobalTransform), With>, - changed_transform_query: Query>, + mut transform_query: Query< + (&Transform, Changed, &mut GlobalTransform), + With, + >, children_query: Query, (With, With)>, ) { - for (entity, children, transform, mut global_transform) in root_query.iter_mut() { + for (children, transform, transform_changed, mut global_transform) in root_query.iter_mut() { let mut changed = false; - if changed_transform_query.get(entity).is_ok() { + if transform_changed { *global_transform = GlobalTransform::from(*transform); changed = true; } @@ -28,7 +36,6 @@ pub fn transform_propagate_system( for child in children.iter() { propagate_recursive( &global_transform, - &changed_transform_query, &mut transform_query, &children_query, *child, @@ -41,16 +48,19 @@ pub fn transform_propagate_system( fn propagate_recursive( parent: &GlobalTransform, - changed_transform_query: &Query>, - transform_query: &mut Query<(&Transform, &mut GlobalTransform), With>, + transform_query: &mut Query< + (&Transform, Changed, &mut GlobalTransform), + With, + >, children_query: &Query, (With, With)>, entity: Entity, mut changed: bool, ) { - changed |= changed_transform_query.get(entity).is_ok(); - let global_matrix = { - if let Ok((transform, mut global_transform)) = transform_query.get_mut(entity) { + if let Ok((transform, transform_changed, mut global_transform)) = + transform_query.get_mut(entity) + { + changed |= transform_changed; if changed { *global_transform = parent.mul_transform(*transform); } @@ -64,7 +74,6 @@ fn propagate_recursive( for child in children.iter() { propagate_recursive( &global_matrix, - changed_transform_query, transform_query, children_query, *child,