//! Plugin providing an [`AssetLoader`](bevy_asset::AssetLoader) and type definitions //! for loading glTF 2.0 (a standard 3D scene definition format) files in Bevy. //! //! The [glTF 2.0 specification](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html) defines the format of the glTF files. #![warn(missing_docs)] #[cfg(feature = "bevy_animation")] use bevy_animation::AnimationClip; use bevy_utils::HashMap; mod loader; mod vertex_attributes; pub use loader::*; use bevy_app::prelude::*; use bevy_asset::{Asset, AssetApp, Handle}; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_pbr::StandardMaterial; use bevy_reflect::{Reflect, TypePath}; use bevy_render::{ mesh::{Mesh, MeshVertexAttribute}, renderer::RenderDevice, texture::CompressedImageFormats, }; use bevy_scene::Scene; /// Adds support for glTF file loading to the app. #[derive(Default)] pub struct GltfPlugin { custom_vertex_attributes: HashMap, } impl GltfPlugin { /// Register a custom vertex attribute so that it is recognized when loading a glTF file with the [`GltfLoader`]. /// /// `name` must be the attribute name as found in the glTF data, which must start with an underscore. /// See [this section of the glTF specification](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview) /// for additional details on custom attributes. pub fn add_custom_vertex_attribute( mut self, name: &str, attribute: MeshVertexAttribute, ) -> Self { self.custom_vertex_attributes .insert(name.to_string(), attribute); self } } impl Plugin for GltfPlugin { fn build(&self, app: &mut App) { app.register_type::() .init_asset::() .init_asset::() .init_asset::() .init_asset::() .preregister_asset_loader::(&["gltf", "glb"]); } fn finish(&self, app: &mut App) { let supported_compressed_formats = match app.world.get_resource::() { Some(render_device) => CompressedImageFormats::from_features(render_device.features()), None => CompressedImageFormats::NONE, }; app.register_asset_loader(GltfLoader { supported_compressed_formats, custom_vertex_attributes: self.custom_vertex_attributes.clone(), }); } } /// Representation of a loaded glTF file. #[derive(Asset, Debug, TypePath)] pub struct Gltf { /// All scenes loaded from the glTF file. pub scenes: Vec>, /// Named scenes loaded from the glTF file. pub named_scenes: HashMap>, /// All meshes loaded from the glTF file. pub meshes: Vec>, /// Named meshes loaded from the glTF file. pub named_meshes: HashMap>, /// All materials loaded from the glTF file. pub materials: Vec>, /// Named materials loaded from the glTF file. pub named_materials: HashMap>, /// All nodes loaded from the glTF file. pub nodes: Vec>, /// Named nodes loaded from the glTF file. pub named_nodes: HashMap>, /// Default scene to be displayed. pub default_scene: Option>, /// All animations loaded from the glTF file. #[cfg(feature = "bevy_animation")] pub animations: Vec>, /// Named animations loaded from the glTF file. #[cfg(feature = "bevy_animation")] pub named_animations: HashMap>, } /// A glTF node with all of its child nodes, its [`GltfMesh`], /// [`Transform`](bevy_transform::prelude::Transform) and an optional [`GltfExtras`]. /// /// See [the relevant glTF specification section](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-node). #[derive(Asset, Debug, Clone, TypePath)] pub struct GltfNode { /// Direct children of the node. pub children: Vec, /// Mesh of the node. pub mesh: Option>, /// Local transform. pub transform: bevy_transform::prelude::Transform, /// Additional data. pub extras: Option, } /// A glTF mesh, which may consist of multiple [`GltfPrimitives`](GltfPrimitive) /// and an optional [`GltfExtras`]. /// /// See [the relevant glTF specification section](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-mesh). #[derive(Asset, Debug, Clone, TypePath)] pub struct GltfMesh { /// Primitives of the glTF mesh. pub primitives: Vec, /// Additional data. pub extras: Option, } /// Part of a [`GltfMesh`] that consists of a [`Mesh`], an optional [`StandardMaterial`] and [`GltfExtras`]. /// /// See [the relevant glTF specification section](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-mesh-primitive). #[derive(Asset, Debug, Clone, TypePath)] pub struct GltfPrimitive { /// Topology to be rendered. pub mesh: Handle, /// Material to apply to the `mesh`. pub material: Option>, /// Additional data. pub extras: Option, /// Additional data of the `material`. pub material_extras: Option, } /// Additional untyped data that can be present on most glTF types. /// /// See [the relevant glTF specification section](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-extras). #[derive(Clone, Debug, Reflect, Default, Component)] #[reflect(Component)] pub struct GltfExtras { /// Content of the extra data. pub value: String, }