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
This commit is contained in:
		
							parent
							
								
									7e3637c36f
								
							
						
					
					
						commit
						30878e3a7d
					
				| @ -133,19 +133,21 @@ async fn load_gltf<'a, 'b>( | |||||||
| 
 | 
 | ||||||
|     #[cfg(feature = "bevy_animation")] |     #[cfg(feature = "bevy_animation")] | ||||||
|     let paths = { |     let paths = { | ||||||
|         let mut paths = HashMap::<usize, Vec<Name>>::new(); |         let mut paths = HashMap::<usize, (usize, Vec<Name>)>::new(); | ||||||
|         for scene in gltf.scenes() { |         for scene in gltf.scenes() { | ||||||
|             for node in scene.nodes() { |             for node in scene.nodes() { | ||||||
|                 paths_recur(node, &[], &mut paths); |                 let root_index = node.index(); | ||||||
|  |                 paths_recur(node, &[], &mut paths, root_index); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         paths |         paths | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     #[cfg(feature = "bevy_animation")] |     #[cfg(feature = "bevy_animation")] | ||||||
|     let (animations, named_animations) = { |     let (animations, named_animations, animation_roots) = { | ||||||
|         let mut animations = vec![]; |         let mut animations = vec![]; | ||||||
|         let mut named_animations = HashMap::default(); |         let mut named_animations = HashMap::default(); | ||||||
|  |         let mut animation_roots = HashSet::default(); | ||||||
|         for animation in gltf.animations() { |         for animation in gltf.animations() { | ||||||
|             let mut animation_clip = AnimationClip::default(); |             let mut animation_clip = AnimationClip::default(); | ||||||
|             for channel in animation.channels() { |             for channel in animation.channels() { | ||||||
| @ -192,7 +194,8 @@ async fn load_gltf<'a, 'b>( | |||||||
|                     return Err(GltfError::MissingAnimationSampler(animation.index())); |                     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( |                     animation_clip.add_curve_to_path( | ||||||
|                         EntityPath { |                         EntityPath { | ||||||
|                             parts: path.clone(), |                             parts: path.clone(), | ||||||
| @ -218,7 +221,7 @@ async fn load_gltf<'a, 'b>( | |||||||
|             } |             } | ||||||
|             animations.push(handle); |             animations.push(handle); | ||||||
|         } |         } | ||||||
|         (animations, named_animations) |         (animations, named_animations, animation_roots) | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     let mut meshes = vec![]; |     let mut meshes = vec![]; | ||||||
| @ -470,10 +473,16 @@ async fn load_gltf<'a, 'b>( | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         #[cfg(feature = "bevy_animation")] |         #[cfg(feature = "bevy_animation")] | ||||||
|         if !animations.is_empty() { |         { | ||||||
|             world |             // for each node root in a scene, check if it's the root of an animation
 | ||||||
|                 .entity_mut(*node_index_to_entity_map.get(&0).unwrap()) |             // if it is, add the AnimationPlayer component
 | ||||||
|                 .insert(AnimationPlayer::default()); |             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 { |         for (&entity, &skin_index) in &entity_to_skin_index_map { | ||||||
| @ -529,13 +538,18 @@ fn node_name(node: &Node) -> Name { | |||||||
|     Name::new(name) |     Name::new(name) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn paths_recur(node: Node, current_path: &[Name], paths: &mut HashMap<usize, Vec<Name>>) { | fn paths_recur( | ||||||
|  |     node: Node, | ||||||
|  |     current_path: &[Name], | ||||||
|  |     paths: &mut HashMap<usize, (usize, Vec<Name>)>, | ||||||
|  |     root_index: usize, | ||||||
|  | ) { | ||||||
|     let mut path = current_path.to_owned(); |     let mut path = current_path.to_owned(); | ||||||
|     path.push(node_name(&node)); |     path.push(node_name(&node)); | ||||||
|     for child in node.children() { |     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.
 | /// Loads a glTF texture as a bevy [`Image`] and returns it together with its label.
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 François
						François