Skip to content

Commit

Permalink
GLTF extension support (#11138)
Browse files Browse the repository at this point in the history
# 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<AssetServer>) {
    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<Gltf>,
}

pub fn spawn_gltf_objects(
    mut commands: Commands,
    mut my: ResMut<MyAssetPack>,
    assets_gltf: Res<Assets<Gltf>>,
) {
    // 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<gltf::Gltf>`

## 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.
  • Loading branch information
CorneliusCornbread authored Jan 15, 2024
1 parent c29a972 commit a7b99f0
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 1 deletion.
3 changes: 2 additions & 1 deletion crates/bevy_gltf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ 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",
"KHR_materials_volume",
"KHR_materials_unlit",
"KHR_materials_emissive_strength",
"extras",
"extensions",
"names",
"utils",
] }
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_gltf/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ pub struct Gltf {
/// Named animations loaded from the glTF file.
#[cfg(feature = "bevy_animation")]
pub named_animations: HashMap<String, Handle<AnimationClip>>,
/// The gltf root of the gltf asset, see <https://docs.rs/gltf/latest/gltf/struct.Gltf.html>. Only has a value when `GltfLoaderSettings::include_source` is true.
pub source: Option<gltf::Gltf>,
}

/// A glTF node with all of its child nodes, its [`GltfMesh`],
Expand Down
8 changes: 8 additions & 0 deletions crates/bevy_gltf/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -139,6 +141,7 @@ impl Default for GltfLoaderSettings {
load_meshes: true,
load_cameras: true,
load_lights: true,
include_source: false,
}
}
}
Expand Down Expand Up @@ -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
},
})
}

Expand Down

0 comments on commit a7b99f0

Please sign in to comment.