Skip to content

feat(gltf): add name component to gltf mesh primitive#13912

Merged
alice-i-cecile merged 6 commits intobevyengine:mainfrom
Soulghost:main
Sep 30, 2024
Merged

feat(gltf): add name component to gltf mesh primitive#13912
alice-i-cecile merged 6 commits intobevyengine:mainfrom
Soulghost:main

Conversation

@Soulghost
Copy link
Copy Markdown
Contributor

@Soulghost Soulghost commented Jun 18, 2024

Objective

Solution

  • When a single mesh is assigned multiple materials, it is divided into several primitive nodes, with each primitive assigned a unique material. Presently, these primitives are named using the format Mesh.index, which complicates querying. To improve this, we can assign a specific name to each primitive based on the material’s name, since each primitive corresponds to one material exclusively.

Testing

  • I have included a simple example which shows how to query a material and mesh part based on the new name component.

Changelog

  • adds GltfMaterialName component to the mesh entity of the gltf primitive node.

@github-actions
Copy link
Copy Markdown
Contributor

Welcome, new contributor!

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

@Soulghost Soulghost force-pushed the main branch 2 times, most recently from b4270d9 to d3cbf42 Compare June 18, 2024 15:11
@janhohenheim janhohenheim added C-Examples An addition or correction to our examples A-Assets Load files from disk to use for things like images, models, and sounds C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Jun 18, 2024
Copy link
Copy Markdown
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.

Useful, but I this should just use the standard Bevy Name component. That reduces the code that we have to maintain, and will play nicer with various tooling like bevy_inspector_egui.

I'm also having a hard time figuring out how the example demonstrates the added functionality. Can you explain what you were after? I may be able to suggest how to make things clearer.

@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 Jul 14, 2024
@Soulghost
Copy link
Copy Markdown
Contributor Author

Useful, but I this should just use the standard Bevy Name component. That reduces the code that we have to maintain, and will play nicer with various tooling like bevy_inspector_egui.

I'm also having a hard time figuring out how the example demonstrates the added functionality. Can you explain what you were after? I may be able to suggest how to make things clearer.

Hi Alice, I apologize for the confusion caused by the buggy example query_gltf_primitives. As detailed in the issue #13473, the newly introduced GltfMaterialName component is used to query for a mesh part with the specific material. When multiple materials are assigned to different parts of a mesh, the corresponding primitives are generated in equal number. However, these primitives currently lack individual names.

{
  "meshes": [
    {
      "name": "Cube",
      "primitives": [
        {
          "attributes": { "POSITION": 0, "NORMAL": 1, "TEXCOORD_0": 2 },
          "indices": 3,
          "material": 0
        },
        {
          "attributes": { "POSITION": 4, "NORMAL": 5, "TEXCOORD_0": 6 },
          "indices": 7,
          "material": 1
        },
        {
          "attributes": { "POSITION": 8, "NORMAL": 9, "TEXCOORD_0": 10 },
          "indices": 11,
          "material": 2
        },
        {
          "attributes": { "POSITION": 12, "NORMAL": 13, "TEXCOORD_0": 14 },
          "indices": 15,
          "material": 3
        }
      ]
    }
  ]
}

In bevy, each primitive is named according to its index.

// crates/bevy_gltf/src/loader.rs
fn primitive_name(mesh: &gltf::Mesh, primitive: &Primitive) -> String {
    let mesh_name = mesh.name().unwrap_or("Mesh");
    if mesh.primitives().len() > 1 {
        format!("{}.{}", mesh_name, primitive.index())
    } else {
        mesh_name.to_string()
    }
}

This causes a problem, which is addressed by @MatrixDev in the above issue:

I don't know which primitive contains which material. In case I want to motify some named material, I have to play with scene directly, used entities mapping, it's a boilerplate mess and not ECS friendly.

So it appears useful to name each primitive according to its associated material, given that primitives are distinguished based on the number of materials assigned to a single mesh. However, since some may rely on the indexed names stored in the Name component, I decided to introduce a new naming component for this purpose. This may not be the optimal solution, and I would appreciate your suggestions. Thank you.

@MatrixDev
Copy link
Copy Markdown
Contributor

I think using 'Name' for everything is not enough. Entity can have a GLTF node/primitive name/index and material name/index all at the same time.

We should be able to query using any of those at any time. Sometimes I want to query for all entities with a specific material, other times I'd like to query for all entities with a specific primitive. Names of materials and primitives might be different.

I'm not even talking about bevy generating names for entites when nodes contain multiple primitives.

@alice-i-cecile alice-i-cecile self-requested a review July 15, 2024 13:11
@alice-i-cecile
Copy link
Copy Markdown
Member

Right 🤔 Okay, I see your point. Thank you for explaining!

@alice-i-cecile alice-i-cecile added S-Needs-Review Needs reviewer attention (from anyone!) to move forward and removed S-Waiting-on-Author The author needs to make changes or address concerns before this can be merged labels Jul 15, 2024
Copy link
Copy Markdown
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.

I think I'm on board now, but there's some work to be done to make this clearer and more beginner friendly.

@Soulghost
Copy link
Copy Markdown
Contributor Author

I have improved the documentation, corrected capitalization errors, and optimized the code of the find_top_material_and_mesh system to achieve smooth color transitions and vertex transformations.

@alice-i-cecile
Copy link
Copy Markdown
Member

Fantastic, thank you!

@alice-i-cecile alice-i-cecile added the M-Release-Note Work that should be called out in the blog due to impact label Sep 22, 2024
@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 A-glTF Related to the glTF 3D scene/model format and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward A-Assets Load files from disk to use for things like images, models, and sounds labels Sep 25, 2024
@alice-i-cecile alice-i-cecile added this pull request to the merge queue Sep 30, 2024
Merged via the queue into bevyengine:main with commit 78a3aae Sep 30, 2024
robtfm pushed a commit to robtfm/bevy that referenced this pull request Oct 4, 2024
# Objective

- fixes bevyengine#13473

## Solution

- When a single mesh is assigned multiple materials, it is divided into
several primitive nodes, with each primitive assigned a unique material.
Presently, these primitives are named using the format Mesh.index, which
complicates querying. To improve this, we can assign a specific name to
each primitive based on the material’s name, since each primitive
corresponds to one material exclusively.

## Testing

- I have included a simple example which shows how to query a material
and mesh part based on the new name component.

## Changelog
- adds `GltfMaterialName` component to the mesh entity of the gltf
primitive node.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
github-merge-queue bot pushed a commit that referenced this pull request Oct 7, 2024
This example was missed during the port to required components for
meshes and materials.
Easy fix, I checked that it works as it did in the PR that added the
example (#13912).
@alice-i-cecile
Copy link
Copy Markdown
Member

Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1703 if you'd like to help out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-glTF Related to the glTF 3D scene/model format C-Examples An addition or correction to our examples C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples M-Release-Note Work that should be called out in the blog due to impact 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.

Add additional names to GLTF entities for easier querying

5 participants