bevy_gltf/
label.rs

1//! Labels that can be used to load part of a glTF
2
3use bevy_asset::AssetPath;
4
5/// Labels that can be used to load part of a glTF
6///
7/// You can use [`GltfAssetLabel::from_asset`] to add it to an asset path
8///
9/// ```
10/// # use bevy_ecs::prelude::*;
11/// # use bevy_asset::prelude::*;
12/// # use bevy_scene::prelude::*;
13/// # use bevy_gltf::prelude::*;
14///
15/// fn load_gltf_scene(asset_server: Res<AssetServer>) {
16///     let gltf_scene: Handle<Scene> = asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
17/// }
18/// ```
19///
20/// Or when formatting a string for the path
21///
22/// ```
23/// # use bevy_ecs::prelude::*;
24/// # use bevy_asset::prelude::*;
25/// # use bevy_scene::prelude::*;
26/// # use bevy_gltf::prelude::*;
27///
28/// fn load_gltf_scene(asset_server: Res<AssetServer>) {
29///     let gltf_scene: Handle<Scene> = asset_server.load(format!("models/FlightHelmet/FlightHelmet.gltf#{}", GltfAssetLabel::Scene(0)));
30/// }
31/// ```
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum GltfAssetLabel {
34    /// `Scene{}`: glTF Scene as a Bevy [`Scene`](bevy_scene::Scene)
35    Scene(usize),
36    /// `Node{}`: glTF Node as a [`GltfNode`](crate::GltfNode)
37    Node(usize),
38    /// `Mesh{}`: glTF Mesh as a [`GltfMesh`](crate::GltfMesh)
39    Mesh(usize),
40    /// `Mesh{}/Primitive{}`: glTF Primitive as a Bevy [`Mesh`](bevy_mesh::Mesh)
41    Primitive {
42        /// Index of the mesh for this primitive
43        mesh: usize,
44        /// Index of this primitive in its parent mesh
45        primitive: usize,
46    },
47    /// `Mesh{}/Primitive{}/MorphTargets`: Morph target animation data for a glTF Primitive
48    /// as a Bevy [`Image`](bevy_image::prelude::Image)
49    MorphTarget {
50        /// Index of the mesh for this primitive
51        mesh: usize,
52        /// Index of this primitive in its parent mesh
53        primitive: usize,
54    },
55    /// `Texture{}`: glTF Texture as a Bevy [`Image`](bevy_image::prelude::Image)
56    Texture(usize),
57    /// `Material{}`: glTF Material as a Bevy [`StandardMaterial`](bevy_pbr::StandardMaterial)
58    Material {
59        /// Index of this material
60        index: usize,
61        /// Used to set the [`Face`](bevy_render::render_resource::Face) of the material,
62        /// useful if it is used with negative scale
63        is_scale_inverted: bool,
64    },
65    /// `DefaultMaterial`: glTF's default Material as a
66    /// Bevy [`StandardMaterial`](bevy_pbr::StandardMaterial)
67    DefaultMaterial,
68    /// `Animation{}`: glTF Animation as Bevy [`AnimationClip`](bevy_animation::AnimationClip)
69    Animation(usize),
70    /// `Skin{}`: glTF mesh skin as [`GltfSkin`](crate::GltfSkin)
71    Skin(usize),
72    /// `Skin{}/InverseBindMatrices`: glTF mesh skin matrices as Bevy
73    /// [`SkinnedMeshInverseBindposes`](bevy_mesh::skinning::SkinnedMeshInverseBindposes)
74    InverseBindMatrices(usize),
75}
76
77impl core::fmt::Display for GltfAssetLabel {
78    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
79        match self {
80            GltfAssetLabel::Scene(index) => f.write_str(&format!("Scene{index}")),
81            GltfAssetLabel::Node(index) => f.write_str(&format!("Node{index}")),
82            GltfAssetLabel::Mesh(index) => f.write_str(&format!("Mesh{index}")),
83            GltfAssetLabel::Primitive { mesh, primitive } => {
84                f.write_str(&format!("Mesh{mesh}/Primitive{primitive}"))
85            }
86            GltfAssetLabel::MorphTarget { mesh, primitive } => {
87                f.write_str(&format!("Mesh{mesh}/Primitive{primitive}/MorphTargets"))
88            }
89            GltfAssetLabel::Texture(index) => f.write_str(&format!("Texture{index}")),
90            GltfAssetLabel::Material {
91                index,
92                is_scale_inverted,
93            } => f.write_str(&format!(
94                "Material{index}{}",
95                if *is_scale_inverted {
96                    " (inverted)"
97                } else {
98                    ""
99                }
100            )),
101            GltfAssetLabel::DefaultMaterial => f.write_str("DefaultMaterial"),
102            GltfAssetLabel::Animation(index) => f.write_str(&format!("Animation{index}")),
103            GltfAssetLabel::Skin(index) => f.write_str(&format!("Skin{index}")),
104            GltfAssetLabel::InverseBindMatrices(index) => {
105                f.write_str(&format!("Skin{index}/InverseBindMatrices"))
106            }
107        }
108    }
109}
110
111impl GltfAssetLabel {
112    /// Add this label to an asset path
113    ///
114    /// ```
115    /// # use bevy_ecs::prelude::*;
116    /// # use bevy_asset::prelude::*;
117    /// # use bevy_scene::prelude::*;
118    /// # use bevy_gltf::prelude::*;
119    ///
120    /// fn load_gltf_scene(asset_server: Res<AssetServer>) {
121    ///     let gltf_scene: Handle<Scene> = asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"));
122    /// }
123    /// ```
124    pub fn from_asset(&self, path: impl Into<AssetPath<'static>>) -> AssetPath<'static> {
125        path.into().with_label(self.to_string())
126    }
127}