Skip to content

Commit 590da83

Browse files
Fix glTF coordinate conversion not converting mesh bounds (#20608)
glTF coordinate conversion is applied to mesh assets, but not their bounds: <img width="1602" height="939" alt="image" src="https://github.com/user-attachments/assets/b2bd0c4b-c9aa-4d53-b33d-c3463af7480e" /> After the fix: <img width="1602" height="939" alt="image" src="https://github.com/user-attachments/assets/ffb40e11-14e4-427f-adfb-5007e6b2cb0a" /> The PR also adds the above scene to `testbed_3d`. ## Testing ```sh cargo run --example testbed_3d ``` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
1 parent 7cd2270 commit 590da83

File tree

2 files changed

+101
-6
lines changed

2 files changed

+101
-6
lines changed

crates/bevy_gltf/src/loader/mod.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,10 +1539,19 @@ fn load_node(
15391539
// > the accessors of the original primitive.
15401540
mesh_entity.insert(MeshMorphWeights::new(weights).unwrap());
15411541
}
1542-
mesh_entity.insert(Aabb::from_min_max(
1543-
Vec3::from_slice(&bounds.min),
1544-
Vec3::from_slice(&bounds.max),
1545-
));
1542+
1543+
let mut bounds_min = Vec3::from_slice(&bounds.min);
1544+
let mut bounds_max = Vec3::from_slice(&bounds.max);
1545+
1546+
if convert_coordinates {
1547+
let converted_min = bounds_min.convert_coordinates();
1548+
let converted_max = bounds_max.convert_coordinates();
1549+
1550+
bounds_min = converted_min.min(converted_max);
1551+
bounds_max = converted_min.max(converted_max);
1552+
}
1553+
1554+
mesh_entity.insert(Aabb::from_min_max(bounds_min, bounds_max));
15461555

15471556
if let Some(extras) = primitive.extras() {
15481557
mesh_entity.insert(GltfExtras {

examples/testbed/3d.rs

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,17 @@ fn main() {
1616
.add_systems(OnEnter(Scene::Gltf), gltf::setup)
1717
.add_systems(OnEnter(Scene::Animation), animation::setup)
1818
.add_systems(OnEnter(Scene::Gizmos), gizmos::setup)
19+
.add_systems(
20+
OnEnter(Scene::GltfCoordinateConversion),
21+
gltf_coordinate_conversion::setup,
22+
)
1923
.add_systems(Update, switch_scene)
20-
.add_systems(Update, gizmos::draw_gizmos.run_if(in_state(Scene::Gizmos)));
24+
.add_systems(Update, gizmos::draw_gizmos.run_if(in_state(Scene::Gizmos)))
25+
.add_systems(
26+
Update,
27+
gltf_coordinate_conversion::draw_gizmos
28+
.run_if(in_state(Scene::GltfCoordinateConversion)),
29+
);
2130

2231
#[cfg(feature = "bevy_ci_testing")]
2332
app.add_systems(Update, helpers::switch_scene_in_ci::<Scene>);
@@ -33,6 +42,7 @@ enum Scene {
3342
Gltf,
3443
Animation,
3544
Gizmos,
45+
GltfCoordinateConversion,
3646
}
3747

3848
impl Next for Scene {
@@ -42,7 +52,8 @@ impl Next for Scene {
4252
Scene::Bloom => Scene::Gltf,
4353
Scene::Gltf => Scene::Animation,
4454
Scene::Animation => Scene::Gizmos,
45-
Scene::Gizmos => Scene::Light,
55+
Scene::Gizmos => Scene::GltfCoordinateConversion,
56+
Scene::GltfCoordinateConversion => Scene::Light,
4657
}
4758
}
4859
}
@@ -340,3 +351,78 @@ mod gizmos {
340351
}
341352
}
342353
}
354+
355+
mod gltf_coordinate_conversion {
356+
use bevy::{
357+
color::palettes::basic::*, gltf::GltfLoaderSettings, prelude::*, scene::SceneInstanceReady,
358+
};
359+
360+
const CURRENT_SCENE: super::Scene = super::Scene::GltfCoordinateConversion;
361+
362+
pub fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
363+
commands.spawn((
364+
Camera3d::default(),
365+
Transform::from_xyz(-4.0, 4.0, -5.0).looking_at(Vec3::ZERO, Vec3::Y),
366+
DespawnOnExitState(CURRENT_SCENE),
367+
));
368+
369+
commands.spawn((
370+
DirectionalLight {
371+
color: BLUE.into(),
372+
..default()
373+
},
374+
Transform::IDENTITY.looking_to(Dir3::Z, Dir3::Y),
375+
DespawnOnExitState(CURRENT_SCENE),
376+
));
377+
378+
commands.spawn((
379+
DirectionalLight {
380+
color: RED.into(),
381+
..default()
382+
},
383+
Transform::IDENTITY.looking_to(Dir3::X, Dir3::Y),
384+
DespawnOnExitState(CURRENT_SCENE),
385+
));
386+
387+
commands.spawn((
388+
DirectionalLight {
389+
color: GREEN.into(),
390+
..default()
391+
},
392+
Transform::IDENTITY.looking_to(Dir3::NEG_Y, Dir3::X),
393+
DespawnOnExitState(CURRENT_SCENE),
394+
));
395+
396+
commands
397+
.spawn((
398+
SceneRoot(asset_server.load_with_settings(
399+
GltfAssetLabel::Scene(0).from_asset("models/Faces/faces.glb"),
400+
|s: &mut GltfLoaderSettings| {
401+
s.use_model_forward_direction = Some(true);
402+
},
403+
)),
404+
DespawnOnExitState(CURRENT_SCENE),
405+
))
406+
.observe(show_aabbs);
407+
}
408+
409+
pub fn show_aabbs(
410+
trigger: On<SceneInstanceReady>,
411+
mut commands: Commands,
412+
children: Query<&Children>,
413+
meshes: Query<(), With<Mesh3d>>,
414+
) {
415+
for child in children
416+
.iter_descendants(trigger.target())
417+
.filter(|&e| meshes.contains(e))
418+
{
419+
commands.entity(child).insert(ShowAabbGizmo {
420+
color: Some(BLACK.into()),
421+
});
422+
}
423+
}
424+
425+
pub fn draw_gizmos(mut gizmos: Gizmos) {
426+
gizmos.axes(Transform::IDENTITY, 1.0);
427+
}
428+
}

0 commit comments

Comments
 (0)