Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bevy_gltf: Add support for using name-based labels #11279

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

dmlary
Copy link
Contributor

@dmlary dmlary commented Jan 9, 2024

Objective

Allow the use of names while loading assets from a gltf file.

Solution

This is a first pass at supporting name-based labels for GLTF, and intended to spark discussion.

This is implemented by adding a the settings field GltfLoaderSettings.label_by_name. When set to true, the majority of asset labels will be created using the name of the asset in the gltf file if present. If there is no name, it will fall back to the index-based naming scheme.

When label_by_name == true, Animation, Mesh, Node, and Primitive assets will use any available name when adding labeled assets. For example, the naming for models/animated/Fox.glb becomes:

'Animation/Run', 'Animation/Survey', 'Animation/Walk', 'Material0', 'Mesh/fox1', 'Mesh/fox1.0', 'Node/_rootJoint', 'Node/b_Head_05', 'Node/b_Hip
_01', 'Node/b_LeftFoot01_017', 'Node/b_LeftFoot02_018', 'Node/b_LeftForeArm_010', 'Node/b_LeftHand_011', 'Node/b_LeftLeg01_015', 'Node/b_LeftLeg02_016', 'Node/b_
LeftUpperArm_09', 'Node/b_Neck_04', 'Node/b_RightFoot01_021', 'Node/b_RightFoot02_022', 'Node/b_RightForeArm_07', 'Node/b_RightHand_08', 'Node/b_RightLeg01_019',
 'Node/b_RightLeg02_020', 'Node/b_RightUpperArm_06', 'Node/b_Root_00', 'Node/b_Spine01_02', 'Node/b_Spine02_03', 'Node/b_Tail01_012', 'Node/b_Tail02_013', 'Node/
b_Tail03_014', 'Node/fox', 'Node/root', 'Scene0', 'Skin0', 'Texture0'

There is a usability problem here as the load settings must be set every time an asset is loaded from the file.

        asset_server.load_with_settings(
            "models/animated/Fox.glb#Animation/Survey",
            |s: &mut GltfLoaderSettings| {
                s.label_by_name = true;
            },
        ),

On top of that there's a race-condition in the label naming as the first asset AssetServer loads for the file determines how the labels were created. This is demonstrated in the modified animaled_fox example in this PR. When it runs, it's unable to find the name-based assets because the index-based assets have been loaded first. As a result we get the asset not found error:

2024-01-09T23:20:27.232388Z ERROR bevy_asset::server: The file at 'models/animated/Fox.glb' does not contain the labeled asset 'Animation/Survey'; it contains th
e following 35 assets: 'Animation0', 'Animation1', 'Animation2', 'Material0', 'Mesh0', 'Mesh0/Primitive0', 'Node0', 'Node1', 'Node10', 'Node11', 'Node12', 'Node1
3', 'Node14', 'Node15', 'Node16', 'Node17', 'Node18', 'Node19', 'Node2', 'Node20', 'Node21', 'Node22', 'Node23', 'Node24', 'Node25', 'Node3', 'Node4', 'Node5', '
Node6', 'Node7', 'Node8', 'Node9', 'Scene0', 'Skin0', 'Texture0'

Questions for Contributors

  • Is there a concept of registering a global configuration for an asset loader?
  • Bike shed: Any suggestions regarding naming schemes?
    • Support loading GLTF assets by name #2948 suggests my_scenes.gltf#Scene:'Winter Scene'
    • My suggestion is state up-front that the asset label does not need to be parsable after the first #, so we never have to escape anything that happens to be in the name

Changelog

  • Added GltfLoaderSettings.label_by_name; when set to true, will use gltf names in most asset labels (Animation, Mesh, Node, Primitive)

This is a first pass at supporting name-based labels for GLTF.  This is
implemented by adding a the settings field `GltfLoaderSettings.label_by_name`.
When set to true, the majority of asset labels will be created using the
name of the asset in the gltf file if present.  If there is no name, it
will fall back to the old naming scheme.

There is a bit of a usability problem here as the load settings must be
set every time an asset is loaded from the file.   On top of that there's a
race-condition in the label naming as the first asset AssetServer loads
for the file determines how the labels were created.  This is
demonstrated in the animaled_fox example.
@alice-i-cecile alice-i-cecile added C-Feature A new feature, making something new possible A-Assets Load files from disk to use for things like images, models, and sounds A-Animation Make things move and change over time labels Jan 9, 2024
@mockersf
Copy link
Member

On top of that there's a race-condition in the label naming as the first asset AssetServer loads for the file determines how the labels were created.

This is #11111

@@ -4,6 +4,7 @@ use std::f32::consts::PI;
use std::time::Duration;

use bevy::{animation::RepeatAnimation, pbr::CascadeShadowConfigBuilder, prelude::*};
use bevy_internal::gltf::GltfLoaderSettings;
Copy link
Member

@mockersf mockersf Jan 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no bevy_internal in examples even if your IDE really really want to import it 😄

@SpecificProtagonist
Copy link
Contributor

An alternate approach is to follow #2948 and allow both name- and index-based paths (as in #5808) instead of allowing only one and switching based on a setting.

@dmlary
Copy link
Contributor Author

dmlary commented Jan 10, 2024

An alternate approach is to follow #2948 and allow both name- and index-based paths (as in #5808) instead of allowing only one and switching based on a setting.

Honestly, I agree with supporting both name and index-based labels. It looks like this will become possible with #10153, but we end up duplicating the assets for each label (#10715 (comment)).

The most obvious step from there seems to be to exploring asset label aliasing, allowing multiple labels to point at the same asset. The challenge there is that the PR will likely fall into Controversial territory, causing delays.

If there's sufficient interest in asset label aliases I'm happy to put together a PR building on the changes in #10153, but I think a more immediate solution is needed. Something that has a shorter path to adoption.

@dmlary dmlary marked this pull request as ready for review January 27, 2024 19:32
@dmlary
Copy link
Contributor Author

dmlary commented Jan 27, 2024

This isn't my preferred approach here, but I felt like it was useful to at least complete the implementation so it's available. Also moving this out of draft.

|s: &mut GltfLoaderSettings| {
s.label_by_name = true;
},
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bah, forgot to remove this. Due to #11111 this does not work right now.

@@ -1194,35 +1229,37 @@ fn primitive_name(mesh: &gltf::Mesh, primitive: &Primitive) -> String {
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't change primitive_name to match the changes to the asset labels because I wanted to limit scope to only the asset labels. This appears to be used when naming the entities within a Scene. This can be changed to match if anyone has a preference here.

crates/bevy_gltf/src/loader.rs Outdated Show resolved Hide resolved
@alice-i-cecile alice-i-cecile added A-glTF Related to the glTF 3D scene/model format and removed A-Assets Load files from disk to use for things like images, models, and sounds labels Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Animation Make things move and change over time A-glTF Related to the glTF 3D scene/model format C-Feature A new feature, making something new possible
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support loading GLTF assets by name
4 participants