docs/bevy/examples/gltf/gltf_skinned_mesh.rs 2.5 K · 71 lines · raw · history

1 //! Skinned mesh example with mesh and joints data loaded from a glTF file.
2 //! Example taken from <https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_019_SimpleSkin.md>
3
4 use std::f32::consts::*;
5
6 use bevy::{math::ops, mesh::skinning::SkinnedMesh, prelude::*};
7
8 fn main() {
9 App::new()
10 .add_plugins(DefaultPlugins)
11 .insert_resource(GlobalAmbientLight {
12 brightness: 750.0,
13 ..default()
14 })
15 .add_systems(Startup, setup)
16 .add_systems(Update, joint_animation)
17 .run();
18 }
19
20 fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
21 // Create a camera
22 commands.spawn((
23 Camera3d::default(),
24 Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::new(0.0, 1.0, 0.0), Vec3::Y),
25 ));
26
27 // Spawn the first scene in `models/SimpleSkin/SimpleSkin.gltf`
28 commands.spawn(WorldAssetRoot(asset_server.load(
29 GltfAssetLabel::Scene(0).from_asset("models/SimpleSkin/SimpleSkin.gltf"),
30 )));
31 }
32
33 /// The scene hierarchy currently looks somewhat like this:
34 ///
35 /// ```text
36 /// <Parent entity>
37 /// + Mesh node (without `Mesh3d` or `SkinnedMesh` component)
38 /// + Skinned mesh entity (with `Mesh3d` and `SkinnedMesh` component, created by glTF loader)
39 /// + First joint
40 /// + Second joint
41 /// ```
42 ///
43 /// In this example, we want to get and animate the second joint.
44 /// It is similar to the animation defined in `models/SimpleSkin/SimpleSkin.gltf`.
45 fn joint_animation(
46 time: Res<Time>,
47 children: Query<&ChildOf, With<SkinnedMesh>>,
48 parents: Query<&Children>,
49 mut transform_query: Query<&mut Transform>,
50 ) {
51 // Iter skinned mesh entity
52 for child_of in &children {
53 // Mesh node is the parent of the skinned mesh entity.
54 let mesh_node_entity = child_of.parent();
55 // Get `Children` in the mesh node.
56 let mesh_node_parent = parents.get(mesh_node_entity).unwrap();
57
58 // First joint is the second child of the mesh node.
59 let first_joint_entity = mesh_node_parent[1];
60 // Get `Children` in the first joint.
61 let first_joint_children = parents.get(first_joint_entity).unwrap();
62
63 // Second joint is the first child of the first joint.
64 let second_joint_entity = first_joint_children[0];
65 // Get `Transform` in the second joint.
66 let mut second_joint_transform = transform_query.get_mut(second_joint_entity).unwrap();
67
68 second_joint_transform.rotation =
69 Quat::from_rotation_z(FRAC_PI_2 * ops::sin(time.elapsed_secs()));
70 }
71 }