wde_gltf/lib.rs
1//! GLTF Loader for WaterDropEngine
2//!
3//! This crate provides functionality to load and parse glTF files, converting them into assets that can be used within the WaterDropEngine. It supports loading meshes, materials, and textures defined in glTF files and integrates them with the engine's rendering system.
4//!
5//! # Example
6//! To load a glTF model, you can use the [`GltfLoader`](crate::GltfLoader) in your `setup` system as follows:
7//! ```rust
8//! if let Ok(gltf_model) = GltfLoader::load("models/model.gltf", &asset_server) {
9//! commands.spawn((
10//! Transform::from_translation(Vec3::ZERO).with_scale(Vec3::splat(1.0)),
11//! PbrModel(gltf_model.models)
12//! ));
13//! }
14//! ```
15//! The rendering of the loaded model is then managed by the [`wde_pbr`](wde_pbr) crate, which handles the materials and shaders for the meshes.
16#![allow(clippy::too_many_arguments)]
17use wde_logger::prelude::*;
18
19use bevy::prelude::*;
20use wde_pbr::prelude::*;
21use wde_renderer::prelude::*;
22
23#[doc(hidden)]
24pub mod prelude {
25 pub use crate::GltfAsset;
26 pub use crate::GltfError;
27 pub use crate::GltfLoader;
28}
29
30mod accessor;
31mod error;
32mod loader;
33mod material;
34mod model;
35mod parser;
36
37pub use error::GltfError;
38
39/// Representation of a 3D GLTF model asset.
40/// This will spawn the model and return the parent entity ID.
41/// See the [crate] documentation for usage examples.
42#[derive(Asset, TypePath, Clone)]
43pub struct GltfAsset {
44 pub path: String,
45 /// The list of parsed glTF models.
46 /// Each model is represented by a mesh and its associated material.
47 pub models: Vec<(Handle<Mesh>, Handle<PbrMaterial>)>
48}
49
50/// Manager to load glTF models into the Bevy world.
51/// See the [crate] documentation for usage examples.
52pub struct GltfLoader;
53impl GltfLoader {
54 /// Load a glTF file and register its models and materials into the Bevy world.
55 /// Returns a loaded `GltfAsset` which contains handles to the meshes and materials.
56 pub fn load(path: &str, asset_server: &AssetServer) -> Result<GltfAsset, GltfError> {
57 debug!("Loading glTF model {}.", path);
58
59 // Parse the glTF file
60 let model = parser::parse_gltf(path)?;
61
62 // Form and load the model into the Bevy world
63 let (materials, meshes, bounding_boxes) = loader::form_models(&model)?;
64 let gltf_asset = loader::load_models(
65 &model.path,
66 &materials,
67 &meshes,
68 &bounding_boxes,
69 asset_server
70 );
71 Ok(gltf_asset)
72 }
73
74 /// Spawn the loaded glTF model into the Bevy world, returning the parent entity ID.
75 pub fn spawn(commands: &mut Commands, gltf_asset: &GltfAsset) -> Entity {
76 let parent_entity = commands.spawn((
77 Name::new(format!("GLTF Model {}", gltf_asset.path)),
78 Transform::default()
79 )).id();
80 for (i, (mesh_handle, material_handle)) in gltf_asset.models.iter().enumerate() {
81 commands.spawn((
82 Name::new(format!("Mesh Entity {} for GLTF Model {}", i, gltf_asset.path)),
83 Transform::default(),
84 Mesh3d(mesh_handle.clone()),
85 PbrMaterial3d(material_handle.clone()),
86 ChildOf(parent_entity)
87 ));
88 }
89 parent_entity
90 }
91}