#Loaded gltf scene lacks AABB

10 messages · Page 1 of 1 (latest)

flat smelt
#

I need the AABB of a loaded scene, however, when query for it, the scene does not seem to have an AABB component. I'm not sure where to start debugging. Maybe a load order issue? Or do some scenes fail to have an AABB component?

fn selection_system(
    ...
    transforms: Query<(&Transform, &Aabb)>,
) {
    if cursor.selection.just_selected {
        create_selection_confirmation_outline(
            &mut commands,
            &cursor,
            &cursor.settings.aesthetics,
            &mut meshes,
            &mut materials,
        );

        for entity in query.iter_mut() {
            match transforms.get(entity) {
                Ok((transform, aabb)) => {
                     ...
                }
                Err(_) => println!("Failed to get extents."),
     ...
}

Here's loading the scene:

    commands
        .spawn((SceneBundle {
            scene: asset_server.load("scp-096/scene.gltf#Scene0"),
            transform: Transform {
                translation: Vec3::new(4.4, 0.0, 3.0),
                ..Default::default()
            },
            ..default()
        },))
        .insert(Pickable)
        .insert(Name::new("scp-096"));

Full project's on Github:
https://github.com/Ladvien/bevy_rts_cursor/blob/main/examples/scene_base.rs

GitHub

A game world cursor for real-time strategy games. Contribute to Ladvien/bevy_rts_cursor development by creating an account on GitHub.

sick sun
#

If I'm not mistaken, this happens because the scene itself won't have an AABB, only the entities with the Handle<Mesh> component within the scene.

#

Take a look at the scene_viewer.rs example in the bevy repo. It contains a system that computes the AABBb of the whole scene iirc

flat smelt
#

Doh! Saving me again, Gibonus. I found this ugly bug when working through your review notes.

#

On it.

sick sun
#

It was all in a single big file before. I'm glad it was moved to a standalone binary with multiple files :D

flat smelt
#

Hello @sick sun, getting my head around the setup_scene_after_load system. But it seems like this system recalculates the AABB of a scene in case the pre-calculated AABB no longer applies? That is, it seems like this system depends on meshes which already have an AABB?:

        if meshes.iter().any(|(_, maybe_aabb)| maybe_aabb.is_none()) {
            return;
        }

Forgive me if I'm being dense.

sick sun
#

Ok, this system is very hacky, for one, it assumes there is nothing else than the loaded scene.

The code you posted here is just to avoid panicking when later in the for (transform, maybe_aabb) in &meshes {, maybe_aabb.unwrap() is used. (I really don't know why it has a Option<&Aabb> and aborts if any is None, I think it should instead just have a &Aabb query parameter)


A gltf file is a "scene" composed of several entities that themselves have a mesh and a material (loaded into bevy as Handle<Mesh> and Handle<StandardMaterial> components).

When loading a gltf file, bevy loads the scene as a hierarchy tree. Where the root is the entity with the SceneBundle, and the leaves are all the gltf scene's entities (some of them with meshes).

Bevy computes and adds an Aabb component to all entities that have a Handle<Mesh>. The scene itself hasn't such component, it only has a Children component that "points to" the hierarchy of the scene.

What this system does is iterate over all the Aabbs in the world and computes the Aabb that encompasses all of them (lines 88 to 105 https://github.com/bevyengine/bevy/blob/c9a53bf5dd7e6ff628b97d4011039f1780878137/examples/tools/scene_viewer/main.rs#L88-L105)


For your case, you need to limit the entities you look at when computing the scene's Aabb to the entities in a specific scene. You can take inspiration from this https://github.com/nicopap/bevy-scene-hook/blob/c8faf2c33d5042b253c041a2dfa8b8d1be30e4cc/src/hook.rs#L104-L120 to only iterate entities in the scene.