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

Add labels to Gltf Node and Mesh assets #13558

Merged

Conversation

freiksenet
Copy link
Contributor

@freiksenet freiksenet commented May 28, 2024

Objective

Add labels to GltfNode and GltfMesh - they are missing from the assets even though they are need if one wants to write a custom Gltf spawning logic.

Eg AnimationPlayer relies on Name component of the node entities to control the animation. There is no way to actually get names of the gltf nodes, thus you can't manually spawn subtree from the scene and animate it.

Solution

  • Add label field and make use of existing label creation logic to store it there.

Testing

  • Ran all tests
  • Fixed tests for node_hierarchy to use lable now

Copy link
Contributor

Welcome, new contributor!

Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨

@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 labels May 28, 2024
@alice-i-cecile alice-i-cecile requested a review from IceSentry May 28, 2024 16:04
Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

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

This is a nice simple change, and the code quality benefits are a great side effect.

@alice-i-cecile alice-i-cecile added X-Uncontroversial This work is generally agreed upon D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels May 28, 2024
@mockersf
Copy link
Member

doesn't do what it says, it always uses the auto generated label

@mockersf mockersf removed X-Uncontroversial This work is generally agreed upon D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels May 28, 2024
@freiksenet
Copy link
Contributor Author

freiksenet commented May 28, 2024

Yeah, let's not merge it yet - we discussed it with @mockersf and I'll fix it tomorrow, then it should be gtg. It seems I was looking at different bevy version's code when using those helper functions.

@freiksenet
Copy link
Contributor Author

freiksenet commented May 29, 2024

Ok, fixed the logic now. I guess the following can be a possible follow-up:

  1. Add label to other "GLTF" named types.
  2. Consider wrapping stuff like StandardMaterial or Scene in a Gltf wrapper that has same label/name logic.
  3. Add backlinks to parents to all nodes and possibly backlink to scene - this can be problematic because the code operates partially on gltf::Node and partially on GltfNode types (confusing).
  4. It is maybe ergonomic, but currently GltfNodes in children of GltfNodes are not the same GltfNodes as the ones in Assets, because they are cloned. I think children should be changed to be Handle. That is a breaking change.
  5. Potentially a way of loading GLTF that doesn't create a bevy scene for scenes would be good - I think loader shouldn't be the place scene is created, but rather a separate command should be added to spawn gltf that handles all the stuff there.

Could you take a look @mockersf?

@freiksenet freiksenet requested a review from alice-i-cecile May 29, 2024 11:18
@freiksenet
Copy link
Contributor Author

I think I'll try to prototype a different kind of bevy gltf plugin for my usages, that doesn't do this work in loaders and let's see how it goes. I think this PR is still good tho.

@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label May 29, 2024
}

/// Computed name for a node - either a user defined name or a generated name from index
pub fn name(&self) -> String {
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer those to not return owned string, but not sur that's easy

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 can make name/asset_label be precomputed on construction - but that mean it won't update if the object is mutated. That's probably okay tho.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a commit with that option, can revert it.

Co-authored-by: François Mockers <[email protected]>
Copy link
Contributor

@Olle-Lukowski Olle-Lukowski left a comment

Choose a reason for hiding this comment

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

Other than the concerns that were already mentioned, this looks good to me!

@alice-i-cecile alice-i-cecile added S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 31, 2024
@alice-i-cecile alice-i-cecile removed the S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged label Jun 4, 2024
@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Jun 4, 2024
@alice-i-cecile
Copy link
Member

Can you resolve merge conflicts?

@freiksenet
Copy link
Contributor Author

@mockersf Addressed the issues, ported to new GltfAssetLabel system, added name/index/label for primitive. Ready for review.

@freiksenet freiksenet requested a review from mockersf June 4, 2024 15:35
crates/bevy_gltf/src/lib.rs Outdated Show resolved Hide resolved
crates/bevy_gltf/src/lib.rs Outdated Show resolved Hide resolved
crates/bevy_gltf/src/lib.rs Outdated Show resolved Hide resolved
crates/bevy_gltf/src/lib.rs Outdated Show resolved Hide resolved
crates/bevy_gltf/src/loader.rs Outdated Show resolved Hide resolved
@freiksenet
Copy link
Contributor Author

freiksenet commented Jun 5, 2024

@mockersf Apologies, one change didn't get added, I had those fixes in already. Welp.

@freiksenet
Copy link
Contributor Author

@mockersf Added an issue with follow-up work, would appreciate your input. #13681

Copy link
Member

@mockersf mockersf left a comment

Choose a reason for hiding this comment

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

I would prefer if the asset_label fields were functions instead, as is they could have incoherent data with the index fields

@alice-i-cecile alice-i-cecile added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jun 5, 2024
@alice-i-cecile
Copy link
Member

I'm going to merge this for now, but I think that Francois's comment above has merit.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Jun 5, 2024
Merged via the queue into bevyengine:main with commit 52215ce Jun 5, 2024
28 checks passed
@freiksenet freiksenet deleted the freiksenet/add-labels-to-gltf-assets branch June 6, 2024 09:26
github-merge-queue bot pushed a commit that referenced this pull request Jul 1, 2024
Part of #13681 

# Objective

gLTF Assets shouldn't be duplicated between Assets resource and node
children.

Also changed `asset_label` to be a method as [per previous PR
comment](#13558).

## Solution

- Made GltfNode children be Handles instead of asset copies.

## Testing

- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.

---

## Changelog

### Changed

- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.

## Migration Guide

If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.

#### Before

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child = first_node.children.get(0).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```

#### After

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child_handle = first_node.children.get(0).unwrap();
        let first_child = gltf_nodes.get(first_child_handle).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```
zmbush pushed a commit to zmbush/bevy that referenced this pull request Jul 3, 2024
Part of bevyengine#13681 

# Objective

gLTF Assets shouldn't be duplicated between Assets resource and node
children.

Also changed `asset_label` to be a method as [per previous PR
comment](bevyengine#13558).

## Solution

- Made GltfNode children be Handles instead of asset copies.

## Testing

- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.

---

## Changelog

### Changed

- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.

## Migration Guide

If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.

#### Before

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child = first_node.children.get(0).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```

#### After

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child_handle = first_node.children.get(0).unwrap();
        let first_child = gltf_nodes.get(first_child_handle).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```
MrGVSV pushed a commit to MrGVSV/bevy that referenced this pull request Jul 5, 2024
Part of bevyengine#13681 

# Objective

gLTF Assets shouldn't be duplicated between Assets resource and node
children.

Also changed `asset_label` to be a method as [per previous PR
comment](bevyengine#13558).

## Solution

- Made GltfNode children be Handles instead of asset copies.

## Testing

- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.

---

## Changelog

### Changed

- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.

## Migration Guide

If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.

#### Before

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child = first_node.children.get(0).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```

#### After

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child_handle = first_node.children.get(0).unwrap();
        let first_child = gltf_nodes.get(first_child_handle).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```
dekirisu pushed a commit to dekirisu/bevy_gltf_trait that referenced this pull request Jul 7, 2024
Part of #13681 

# Objective

gLTF Assets shouldn't be duplicated between Assets resource and node
children.

Also changed `asset_label` to be a method as [per previous PR
comment](bevyengine/bevy#13558).

## Solution

- Made GltfNode children be Handles instead of asset copies.

## Testing

- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.

---

## Changelog

### Changed

- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.

## Migration Guide

If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.

#### Before

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child = first_node.children.get(0).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```

#### After

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child_handle = first_node.children.get(0).unwrap();
        let first_child = gltf_nodes.get(first_child_handle).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```
barsoosayque pushed a commit to barsoosayque/bevy that referenced this pull request Jul 15, 2024
Part of bevyengine#13681

# Objective

gLTF Assets shouldn't be duplicated between Assets resource and node
children.

Also changed `asset_label` to be a method as [per previous PR
comment](bevyengine#13558).

## Solution

- Made GltfNode children be Handles instead of asset copies.

## Testing

- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.

---

## Changelog

### Changed

- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.

## Migration Guide

If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.

#### Before

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child = first_node.children.get(0).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```

#### After

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child_handle = first_node.children.get(0).unwrap();
        let first_child = gltf_nodes.get(first_child_handle).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```
barsoosayque pushed a commit to barsoosayque/bevy that referenced this pull request Aug 12, 2024
Part of bevyengine#13681

# Objective

gLTF Assets shouldn't be duplicated between Assets resource and node
children.

Also changed `asset_label` to be a method as [per previous PR
comment](bevyengine#13558).

## Solution

- Made GltfNode children be Handles instead of asset copies.

## Testing

- Added tests that actually test loading and hierarchy as previous ones
unit tested only one function and that makes little sense.
- Made circular nodes an actual loading failure instead of a warning
no-op. You [_MUST NOT_ have cycles in
gLTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#nodes-and-hierarchy)
according to the spec.
- IMO this is a bugfix, not a breaking change. But in an extremely
unlikely event in which you relied on invalid behavior for loading gLTF
with cyclic children, you will not be able to do that anymore. You
should fix your gLTF file as it's not valid according to gLTF spec. For
it to for work someone, it had to be bevy with bevy_animation flag off.

---

## Changelog

### Changed

- `GltfNode.children` are now `Vec<Handle<GltfNode>>` instead of
`Vec<GltfNode>`
- Having children cycles between gLTF nodes in a gLTF document is now an
explicit asset loading failure.

## Migration Guide

If accessing children, use `Assets<GltfNode>` resource to get the actual
child object.

#### Before

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child = first_node.children.get(0).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```

#### After

```rs
fn gltf_print_first_node_children_system(gltf_component_query: Query<Handle<Gltf>>, gltf_assets: Res<Assets<Gltf>>, gltf_nodes: Res<Assets<GltfNode>>) {
    for gltf_handle in gltf_component_query.iter() {
        let gltf_root = gltf_assets.get(gltf_handle).unwrap();
        let first_node_handle = gltf_root.nodes.get(0).unwrap();
        let first_node = gltf_nodes.get(first_node_handle).unwrap();
        let first_child_handle = first_node.children.get(0).unwrap();
        let first_child = gltf_nodes.get(first_child_handle).unwrap();
        println!("First nodes child node name is {:?)", first_child.name);
    }
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Assets Load files from disk to use for things like images, models, and sounds C-Feature A new feature, making something new possible S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants