From a7b99f0500d6301bc4e59cce07a7ecc0ee46016c Mon Sep 17 00:00:00 2001 From: Cornelius <8294697+CorneliusCornbread@users.noreply.github.com> Date: Mon, 15 Jan 2024 09:38:01 -0600 Subject: [PATCH] GLTF extension support (#11138) # Objective Adds support for accessing raw extension data of loaded GLTF assets ## Solution Via the GLTF loader settings, you can specify whether or not to include the GLTF source. While not the ideal way of solving this problem, modeling all of GLTF within Bevy just for extensions adds a lot of complexity to the way Bevy handles GLTF currently. See the example GLTF meta file and code ``` ( meta_format_version: "1.0", asset: Load( loader: "bevy_gltf::loader::GltfLoader", settings: ( load_meshes: true, load_cameras: true, load_lights: true, include_source: true, ), ), ) ``` ```rs pub fn load_gltf(mut commands: Commands, assets: Res) { let my_gltf = assets.load("test_platform.gltf"); commands.insert_resource(MyAssetPack { spawned: false, handle: my_gltf, }); } #[derive(Resource)] pub struct MyAssetPack { pub spawned: bool, pub handle: Handle, } pub fn spawn_gltf_objects( mut commands: Commands, mut my: ResMut, assets_gltf: Res>, ) { // This flag is used to because this system has to be run until the asset is loaded. // If there's a better way of going about this I am unaware of it. if my.spawned { return; } if let Some(gltf) = assets_gltf.get(&my.handle) { info!("spawn"); my.spawned = true; // spawn the first scene in the file commands.spawn(SceneBundle { scene: gltf.scenes[0].clone(), ..Default::default() }); let source = gltf.source.as_ref().unwrap(); info!("materials count {}", &source.materials().size_hint().0); info!( "materials ext is some {}", &source.materials().next().unwrap().extensions().is_some() ); } } ``` --- ## Changelog Added support for GLTF extensions through including raw GLTF source via loader flag `GltfLoaderSettings::include_source == true`, stored in `Gltf::source: Option` ## Migration Guide This will have issues with "asset migrations", as there is currently no way for .meta files to be migrated. Attempting to migrate .meta files without the new flag will yield the following error: ``` bevy_asset::server: Failed to deserialize meta for asset test_platform.gltf: Failed to deserialize asset meta: SpannedError { code: MissingStructField { field: "include_source", outer: Some("GltfLoaderSettings") }, position: Position { line: 9, col: 9 } } ``` This means users who want to migrate their .meta files will have to add the `include_source: true,` setting to their meta files by hand. --- crates/bevy_gltf/Cargo.toml | 3 ++- crates/bevy_gltf/src/lib.rs | 2 ++ crates/bevy_gltf/src/loader.rs | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/bevy_gltf/Cargo.toml b/crates/bevy_gltf/Cargo.toml index d3cf482c4b..05cbd9a940 100644 --- a/crates/bevy_gltf/Cargo.toml +++ b/crates/bevy_gltf/Cargo.toml @@ -35,7 +35,7 @@ bevy_tasks = { path = "../bevy_tasks", version = "0.12.0" } bevy_utils = { path = "../bevy_utils", version = "0.12.0" } # other -gltf = { version = "1.3.0", default-features = false, features = [ +gltf = { version = "1.4.0", default-features = false, features = [ "KHR_lights_punctual", "KHR_materials_transmission", "KHR_materials_ior", @@ -43,6 +43,7 @@ gltf = { version = "1.3.0", default-features = false, features = [ "KHR_materials_unlit", "KHR_materials_emissive_strength", "extras", + "extensions", "names", "utils", ] } diff --git a/crates/bevy_gltf/src/lib.rs b/crates/bevy_gltf/src/lib.rs index fe47fd4dfd..0e7e882d23 100644 --- a/crates/bevy_gltf/src/lib.rs +++ b/crates/bevy_gltf/src/lib.rs @@ -98,6 +98,8 @@ pub struct Gltf { /// Named animations loaded from the glTF file. #[cfg(feature = "bevy_animation")] pub named_animations: HashMap>, + /// The gltf root of the gltf asset, see . Only has a value when `GltfLoaderSettings::include_source` is true. + pub source: Option, } /// A glTF node with all of its child nodes, its [`GltfMesh`], diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index dae9cb647b..19e0f07b6b 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -131,6 +131,8 @@ pub struct GltfLoaderSettings { pub load_cameras: bool, /// If true, the loader will spawn lights for gltf light nodes. pub load_lights: bool, + /// If true, the loader will include the root of the gltf root node. + pub include_source: bool, } impl Default for GltfLoaderSettings { @@ -139,6 +141,7 @@ impl Default for GltfLoaderSettings { load_meshes: true, load_cameras: true, load_lights: true, + include_source: false, } } } @@ -673,6 +676,11 @@ async fn load_gltf<'a, 'b, 'c>( animations, #[cfg(feature = "bevy_animation")] named_animations, + source: if settings.include_source { + Some(gltf) + } else { + None + }, }) }