From 909f43959f714fefa081dbb1703136ee2e8893e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Tue, 5 Apr 2022 21:52:00 +0000 Subject: [PATCH] add AnimationPlayer component only on scene roots that are also animation roots (#4417) # Objective - Fix #4416 - The scene has two root nodes, with the second one being the animation root ## Solution - Check all scene root nodes, and add the `AnimationPlayer` component to nodes that are also animation roots --- crates/bevy_gltf/src/loader.rs | 38 +++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index e68f326d0a101d..43068b6e3f60b0 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -133,19 +133,21 @@ async fn load_gltf<'a, 'b>( #[cfg(feature = "bevy_animation")] let paths = { - let mut paths = HashMap::>::new(); + let mut paths = HashMap::)>::new(); for scene in gltf.scenes() { for node in scene.nodes() { - paths_recur(node, &[], &mut paths); + let root_index = node.index(); + paths_recur(node, &[], &mut paths, root_index); } } paths }; #[cfg(feature = "bevy_animation")] - let (animations, named_animations) = { + let (animations, named_animations, animation_roots) = { let mut animations = vec![]; let mut named_animations = HashMap::default(); + let mut animation_roots = HashSet::default(); for animation in gltf.animations() { let mut animation_clip = AnimationClip::default(); for channel in animation.channels() { @@ -192,7 +194,8 @@ async fn load_gltf<'a, 'b>( return Err(GltfError::MissingAnimationSampler(animation.index())); }; - if let Some(path) = paths.get(&node.index()) { + if let Some((root_index, path)) = paths.get(&node.index()) { + animation_roots.insert(root_index); animation_clip.add_curve_to_path( EntityPath { parts: path.clone(), @@ -218,7 +221,7 @@ async fn load_gltf<'a, 'b>( } animations.push(handle); } - (animations, named_animations) + (animations, named_animations, animation_roots) }; let mut meshes = vec![]; @@ -470,10 +473,16 @@ async fn load_gltf<'a, 'b>( } #[cfg(feature = "bevy_animation")] - if !animations.is_empty() { - world - .entity_mut(*node_index_to_entity_map.get(&0).unwrap()) - .insert(AnimationPlayer::default()); + { + // for each node root in a scene, check if it's the root of an animation + // if it is, add the AnimationPlayer component + for node in scene.nodes() { + if animation_roots.contains(&node.index()) { + world + .entity_mut(*node_index_to_entity_map.get(&node.index()).unwrap()) + .insert(AnimationPlayer::default()); + } + } } for (&entity, &skin_index) in &entity_to_skin_index_map { @@ -529,13 +538,18 @@ fn node_name(node: &Node) -> Name { Name::new(name) } -fn paths_recur(node: Node, current_path: &[Name], paths: &mut HashMap>) { +fn paths_recur( + node: Node, + current_path: &[Name], + paths: &mut HashMap)>, + root_index: usize, +) { let mut path = current_path.to_owned(); path.push(node_name(&node)); for child in node.children() { - paths_recur(child, &path, paths); + paths_recur(child, &path, paths, root_index); } - paths.insert(node.index(), path); + paths.insert(node.index(), (root_index, path)); } /// Loads a glTF texture as a bevy [`Image`] and returns it together with its label.