Created
February 6, 2024 03:01
-
-
Save pcwalton/c10a157285015b9f2ea2a66730aa7425 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit acdae9ee7d92c7bfbbe2d560a3e00039ce5a3380 | |
Author: Patrick Walton <[email protected]> | |
Date: Mon Feb 5 18:10:52 2024 -0800 | |
wip | |
diff --git a/crates/bevy_transform/Cargo.toml b/crates/bevy_transform/Cargo.toml | |
index 8e5e93718..cde746d06 100644 | |
--- a/crates/bevy_transform/Cargo.toml | |
+++ b/crates/bevy_transform/Cargo.toml | |
@@ -19,6 +19,7 @@ bevy_math = { path = "../bevy_math", version = "0.12.0" } | |
bevy_reflect = { path = "../bevy_reflect", version = "0.12.0", features = [ | |
"bevy", | |
] } | |
+bevy_utils = { path = "../bevy_utils", version = "0.12.0" } | |
serde = { version = "1", features = ["derive"], optional = true } | |
thiserror = "1.0" | |
diff --git a/crates/bevy_transform/src/systems.rs b/crates/bevy_transform/src/systems.rs | |
index 8f6bac916..d5365b944 100644 | |
--- a/crates/bevy_transform/src/systems.rs | |
+++ b/crates/bevy_transform/src/systems.rs | |
@@ -7,6 +7,7 @@ use bevy_ecs::{ | |
system::{Local, ParamSet}, | |
}; | |
use bevy_hierarchy::{Children, Parent}; | |
+use bevy_utils::EntityHashSet; | |
/// Update [`GlobalTransform`] component of entities that aren't in the hierarchy | |
/// | |
@@ -54,19 +55,41 @@ pub fn propagate_transforms( | |
mut orphaned: RemovedComponents<Parent>, | |
transform_query: Query<(Ref<Transform>, &mut GlobalTransform, Option<&Children>), With<Parent>>, | |
parent_query: Query<(Entity, Ref<Parent>)>, | |
+ dirty_roots: Query<Entity, Or<(Changed<Parent>, Changed<Transform>)>>, | |
mut orphaned_entities: Local<Vec<Entity>>, | |
) { | |
orphaned_entities.clear(); | |
orphaned_entities.extend(orphaned.read()); | |
orphaned_entities.sort_unstable(); | |
+ | |
+ let mut dirty_entities = EntityHashSet::default(); | |
+ for mut current in dirty_roots.iter() { | |
+ while dirty_entities.insert(current) { | |
+ let Ok((parent, _)) = parent_query.get(current) else { | |
+ break; | |
+ }; | |
+ current = parent; | |
+ } | |
+ } | |
+ | |
root_query.par_iter_mut().for_each( | |
|(entity, children, transform, mut global_transform)| { | |
+ // If this entire tree is clean, do nothing. | |
+ if !dirty_entities.contains(&entity) { | |
+ return; | |
+ } | |
+ | |
let changed = transform.is_changed() || global_transform.is_added() || orphaned_entities.binary_search(&entity).is_ok(); | |
if changed { | |
*global_transform = GlobalTransform::from(*transform); | |
} | |
for (child, actual_parent) in parent_query.iter_many(children) { | |
+ // Don't bother checking children if we know their transform didn't change. | |
+ if !changed && !dirty_entities.contains(&child) { | |
+ continue; | |
+ } | |
+ | |
assert_eq!( | |
actual_parent.get(), entity, | |
"Malformed hierarchy. This probably means that your hierarchy has been improperly maintained, or contains a cycle" | |
@@ -84,6 +107,7 @@ pub fn propagate_transforms( | |
&global_transform, | |
&transform_query, | |
&parent_query, | |
+ &dirty_entities, | |
child, | |
changed || actual_parent.is_changed(), | |
); | |
@@ -113,6 +137,7 @@ unsafe fn propagate_recursive( | |
With<Parent>, | |
>, | |
parent_query: &Query<(Entity, Ref<Parent>)>, | |
+ dirty_entities: &EntityHashSet<Entity>, | |
entity: Entity, | |
mut changed: bool, | |
) { | |
@@ -157,6 +182,11 @@ unsafe fn propagate_recursive( | |
let Some(children) = children else { return }; | |
for (child, actual_parent) in parent_query.iter_many(children) { | |
+ // Don't bother checking children if we know their transform didn't change. | |
+ if !changed && !dirty_entities.contains(&child) { | |
+ continue; | |
+ } | |
+ | |
assert_eq!( | |
actual_parent.get(), entity, | |
"Malformed hierarchy. This probably means that your hierarchy has been improperly maintained, or contains a cycle" | |
@@ -171,6 +201,7 @@ unsafe fn propagate_recursive( | |
&global_matrix, | |
transform_query, | |
parent_query, | |
+ dirty_entities, | |
child, | |
changed || actual_parent.is_changed(), | |
); | |
diff --git a/examples/tools/scene_viewer/main.rs b/examples/tools/scene_viewer/main.rs | |
index e80b3965b..3ef3f739b 100644 | |
--- a/examples/tools/scene_viewer/main.rs | |
+++ b/examples/tools/scene_viewer/main.rs | |
@@ -8,6 +8,7 @@ | |
//! If you want to hot reload asset changes, enable the `file_watcher` cargo feature. | |
use bevy::{ | |
+ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, | |
math::Vec3A, | |
prelude::*, | |
render::primitives::{Aabb, Sphere}, | |
@@ -44,6 +45,8 @@ fn main() { | |
CameraControllerPlugin, | |
SceneViewerPlugin, | |
MorphViewerPlugin, | |
+ FrameTimeDiagnosticsPlugin, | |
+ LogDiagnosticsPlugin::default(), | |
)) | |
.add_systems(Startup, setup) | |
.add_systems(PreUpdate, setup_scene_after_load); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment