bevy/examples/3d/query_gltf_primitives.rs
Rob Parrett 3fc2bd71ea
Cosmetic tweaks to query_gltf_primitives (#16102)
# Objective

This example is really confusing to look at and tell at a glance whether
it's broken or not.

It's displaying a strange shape -- a cube with two vertices stretched in
a couple dimensions at an odd angle, and doing its vertex position
modification in a way where the intent isn't obvious.

## Solution

- Change the gltf geometry so that the object is a recognizable regular
shape
- Change the vertex modification so that the entire cube top is being
"lifted" from the cube
- Adjust colors, lighting, and camera location so we can see what's
going on
- Also remove some irrelevant shadow and environment map setup

## Before


![Image](https://github.com/user-attachments/assets/e5dd5075-0480-49d4-b1ed-cf1fe6106f3c)

## After

<img width="1280" alt="image"
src="https://github.com/user-attachments/assets/59cab60d-efbc-47c3-8688-e4544b462421">
2024-10-27 19:06:19 +00:00

69 lines
2.3 KiB
Rust

//! This example demonstrates how to query a [`StandardMaterial`] within a glTF scene.
//! It is particularly useful for glTF scenes with a mesh that consists of multiple primitives.
use std::f32::consts::PI;
use bevy::{gltf::GltfMaterialName, prelude::*, render::mesh::VertexAttributeValues};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, find_top_material_and_mesh)
.run();
}
fn find_top_material_and_mesh(
mut materials: ResMut<Assets<StandardMaterial>>,
mut meshes: ResMut<Assets<Mesh>>,
time: Res<Time>,
mat_query: Query<(
&MeshMaterial3d<StandardMaterial>,
&Mesh3d,
&GltfMaterialName,
)>,
) {
for (mat_handle, mesh_handle, name) in mat_query.iter() {
// locate a material by material name
if name.0 == "Top" {
if let Some(material) = materials.get_mut(mat_handle) {
if let Color::Hsla(ref mut hsla) = material.base_color {
*hsla = hsla.rotate_hue(time.delta_secs() * 100.0);
} else {
material.base_color = Color::from(Hsla::hsl(0.0, 0.9, 0.7));
}
}
if let Some(mesh) = meshes.get_mut(mesh_handle) {
if let Some(VertexAttributeValues::Float32x3(positions)) =
mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION)
{
for position in positions {
*position = (
position[0],
1.5 + 0.5 * ops::sin(time.elapsed_secs() / 2.0),
position[2],
)
.into();
}
}
}
}
}
}
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
commands.spawn((
Camera3d::default(),
Transform::from_xyz(4.0, 4.0, 12.0).looking_at(Vec3::new(0.0, 0.0, 0.5), Vec3::Y),
));
commands.spawn((
Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)),
DirectionalLight::default(),
));
commands.spawn(SceneRoot(asset_server.load(
GltfAssetLabel::Scene(0).from_asset("models/GltfPrimitives/gltf_primitives.glb"),
)));
}