bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
34.34k stars 3.35k forks source link

Add additional names to GLTF entities for easier querying #13473

Open MatrixDev opened 2 months ago

MatrixDev commented 2 months ago

What problem does this solve or what need does it fill?

I have a very simple blender file with a single mesh and multiple materials:

image

When exporting to GLTF it creates a mesh with multiple primitives:

image

Bevy creates an entity for the node object and separate entity per each primitive of the mesh (no mesh-specific entity):

image

There are few problems:

  1. there is no mesh entity at all when multiple primitives are available (there is nothing with 'PlaneMesh' name)
  2. 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.
  3. I can't just query for primitives because their names are generated with indexes.

What solution would you like?

I'd like to add more Name-like components to make querying much easier:

// added to all Gltf node entities
#[derive(Component)]
struct GltfNodeName(Arc<str>);

// added to all Gltf mesh entities (or each primitive when mesh is split into multiple entities)
#[derive(Component)]
struct GltfMeshName(Arc<str>);

// added to all entities that contain Gltf materials
#[derive(Component)]
struct GltfMaterialName(Arc<str>);

// added to all entities associated to a Gltf scene
#[derive(Component)]
struct SceneInstanceNode(InstanceId);

Names are not enough in this case because:

  1. some nodes might have mulitple names (Mesh+Material for example)
  2. name doesn't specify which type of entity we're actually talking about

In such case it will be trivial to find/replace components for any Gltf scene.

What alternative(s) have you considered?

I don't see currently any ECS friendly alternative.

We could also have GltfInstance component attached to the root node that will map entities by type/name but IMHO it is not really ECS way of doing things:

#[derive(Component)]
struct GltfInstance {
    nodes: HashMap<String, Entity>,
    meshes: HashMap<String, Vec<Entity>>,
    materials: HashMap<String, Vec<Entity>>,
}

Additional context

This is just a suggestion.

There are 100% better ways to solve this problem but we should improve Gltf usability for sure. Currently it just way to cumbersome and requires huge amount of boilerplate code.

janhohenheim commented 1 month ago

@kaosat-dev you might have expert opinions on this :)