Skip to content

Commit 184f233

Browse files
authored
Use glam for computing gLTF node transform (#11361)
# Objective gltf-rs does its own computations when accessing `transform.matrix()` which does not use glam types, rendering #11238 useless if people were to load gltf models and expecting the results to be deterministic across platforms. ## Solution Move the computation to bevy side which uses glam types, it was already used in one place, so I created one common function to handle the two cases. The added benefit this has, is that some gltf files can have translation, rotation and scale directly instead of matrix which skips the transform computation completely, win-win.
1 parent 135c724 commit 184f233

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

crates/bevy_gltf/src/loader.rs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -525,20 +525,7 @@ async fn load_gltf<'a, 'b, 'c>(
525525
.mesh()
526526
.map(|mesh| mesh.index())
527527
.and_then(|i| meshes.get(i).cloned()),
528-
transform: match node.transform() {
529-
gltf::scene::Transform::Matrix { matrix } => {
530-
Transform::from_matrix(Mat4::from_cols_array_2d(&matrix))
531-
}
532-
gltf::scene::Transform::Decomposed {
533-
translation,
534-
rotation,
535-
scale,
536-
} => Transform {
537-
translation: bevy_math::Vec3::from(translation),
538-
rotation: bevy_math::Quat::from_array(rotation),
539-
scale: bevy_math::Vec3::from(scale),
540-
},
541-
},
528+
transform: node_transform(&node),
542529
extras: get_gltf_extras(node.extras()),
543530
},
544531
node.children()
@@ -690,6 +677,29 @@ fn get_gltf_extras(extras: &gltf::json::Extras) -> Option<GltfExtras> {
690677
})
691678
}
692679

680+
/// Calculate the transform of gLTF node.
681+
///
682+
/// This should be used instead of calling [`gltf::scene::Transform::matrix()`]
683+
/// on [`Node::transform()`] directly because it uses optimized glam types and
684+
/// if `libm` feature of `bevy_math` crate is enabled also handles cross
685+
/// platform determinism properly.
686+
fn node_transform(node: &Node) -> Transform {
687+
match node.transform() {
688+
gltf::scene::Transform::Matrix { matrix } => {
689+
Transform::from_matrix(Mat4::from_cols_array_2d(&matrix))
690+
}
691+
gltf::scene::Transform::Decomposed {
692+
translation,
693+
rotation,
694+
scale,
695+
} => Transform {
696+
translation: bevy_math::Vec3::from(translation),
697+
rotation: bevy_math::Quat::from_array(rotation),
698+
scale: bevy_math::Vec3::from(scale),
699+
},
700+
}
701+
}
702+
693703
fn node_name(node: &Node) -> Name {
694704
let name = node
695705
.name()
@@ -916,9 +926,8 @@ fn load_node(
916926
active_camera_found: &mut bool,
917927
parent_transform: &Transform,
918928
) -> Result<(), GltfError> {
919-
let transform = gltf_node.transform();
920929
let mut gltf_error = None;
921-
let transform = Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix()));
930+
let transform = node_transform(gltf_node);
922931
let world_transform = *parent_transform * transform;
923932
// according to https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#instantiation,
924933
// if the determinant of the transform is negative we must invert the winding order of

0 commit comments

Comments
 (0)