From c62ca1a0d36c064e82f25c10b820b9dcdc319a87 Mon Sep 17 00:00:00 2001 From: DaoLendaye Date: Tue, 20 May 2025 22:45:04 +0800 Subject: [PATCH] Use material name for mesh entity's Name when available (#19287) # Objective Fixes #19286 ## Solution Use material name for mesh entity's Name when available ## Testing Test code, modified from examples/load_gltf.rs ```rust //! Loads and renders a glTF file as a scene. use bevy::{gltf::GltfMaterialName, prelude::*, scene::SceneInstanceReady}; fn main() { App::new() .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_observer(on_scene_load) .run(); } fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(( Camera3d::default(), Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y), )); commands.spawn((DirectionalLight { shadows_enabled: true, ..default() },)); commands.spawn(SceneRoot(asset_server.load( GltfAssetLabel::Scene(0).from_asset("models/FlightHelmet/FlightHelmet.gltf"), ))); } fn on_scene_load( trigger: Trigger, children: Query<&Children>, names: Query<&Name>, material_names: Query<&GltfMaterialName>, ) { let target = trigger.target(); for child in children.iter_descendants(target) { let name = if let Ok(name) = names.get(child) { Some(name.to_string()) } else { None }; let material_name = if let Ok(name) = material_names.get(child) { Some(name.0.clone()) } else { None }; info!("Entity name:{:?} | material name:{:?}", name, material_name); } } ``` --- ## Showcase Run log: Image --------- Co-authored-by: Alice Cecile Co-authored-by: Greeble <166992735+greeble-dev@users.noreply.github.com> --- crates/bevy_gltf/src/loader/gltf_ext/mesh.rs | 12 ++++++++---- crates/bevy_gltf/src/loader/mod.rs | 5 +++-- .../rename_spawn_gltf_material_name.md | 9 +++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 release-content/migration-guides/rename_spawn_gltf_material_name.md diff --git a/crates/bevy_gltf/src/loader/gltf_ext/mesh.rs b/crates/bevy_gltf/src/loader/gltf_ext/mesh.rs index ef719891a4..60a153fed3 100644 --- a/crates/bevy_gltf/src/loader/gltf_ext/mesh.rs +++ b/crates/bevy_gltf/src/loader/gltf_ext/mesh.rs @@ -1,13 +1,17 @@ use bevy_mesh::PrimitiveTopology; -use gltf::mesh::{Mesh, Mode, Primitive}; +use gltf::{ + mesh::{Mesh, Mode}, + Material, +}; use crate::GltfError; -pub(crate) fn primitive_name(mesh: &Mesh<'_>, primitive: &Primitive) -> String { +pub(crate) fn primitive_name(mesh: &Mesh<'_>, material: &Material) -> String { let mesh_name = mesh.name().unwrap_or("Mesh"); - if mesh.primitives().len() > 1 { - format!("{}.{}", mesh_name, primitive.index()) + + if let Some(material_name) = material.name() { + format!("{}.{}", mesh_name, material_name) } else { mesh_name.to_string() } diff --git a/crates/bevy_gltf/src/loader/mod.rs b/crates/bevy_gltf/src/loader/mod.rs index f85a739b2e..b65e4bf81a 100644 --- a/crates/bevy_gltf/src/loader/mod.rs +++ b/crates/bevy_gltf/src/loader/mod.rs @@ -1464,10 +1464,11 @@ fn load_node( } if let Some(name) = material.name() { - mesh_entity.insert(GltfMaterialName(String::from(name))); + mesh_entity.insert(GltfMaterialName(name.to_string())); } - mesh_entity.insert(Name::new(primitive_name(&mesh, &primitive))); + mesh_entity.insert(Name::new(primitive_name(&mesh, &material))); + // Mark for adding skinned mesh if let Some(skin) = gltf_node.skin() { entity_to_skin_index_map.insert(mesh_entity.id(), skin.index()); diff --git a/release-content/migration-guides/rename_spawn_gltf_material_name.md b/release-content/migration-guides/rename_spawn_gltf_material_name.md new file mode 100644 index 0000000000..630697b5fd --- /dev/null +++ b/release-content/migration-guides/rename_spawn_gltf_material_name.md @@ -0,0 +1,9 @@ +--- +title: Use Gltf material names for spawned primitive entities +authors: ["@rendaoer"] +pull_requests: [19287] +--- + +When loading a Gltf scene in Bevy, each mesh primitive will generate an entity and store a `GltfMaterialName` component and `Name` component. + +The `Name` components were previously stored as mesh name plus primitive index - for example, `MeshName.0` and `MeshName.1`. To make it easier to view these entities in Inspector-style tools, they are now stored as mesh name plus material name - for example, `MeshName.Material1Name` and `MeshName.Material2Name`.