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.
This commit is contained in:
parent
135c7240f1
commit
184f233a67
@ -525,20 +525,7 @@ async fn load_gltf<'a, 'b, 'c>(
|
||||
.mesh()
|
||||
.map(|mesh| mesh.index())
|
||||
.and_then(|i| meshes.get(i).cloned()),
|
||||
transform: match node.transform() {
|
||||
gltf::scene::Transform::Matrix { matrix } => {
|
||||
Transform::from_matrix(Mat4::from_cols_array_2d(&matrix))
|
||||
}
|
||||
gltf::scene::Transform::Decomposed {
|
||||
translation,
|
||||
rotation,
|
||||
scale,
|
||||
} => Transform {
|
||||
translation: bevy_math::Vec3::from(translation),
|
||||
rotation: bevy_math::Quat::from_array(rotation),
|
||||
scale: bevy_math::Vec3::from(scale),
|
||||
},
|
||||
},
|
||||
transform: node_transform(&node),
|
||||
extras: get_gltf_extras(node.extras()),
|
||||
},
|
||||
node.children()
|
||||
@ -690,6 +677,29 @@ fn get_gltf_extras(extras: &gltf::json::Extras) -> Option<GltfExtras> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Calculate the transform of gLTF node.
|
||||
///
|
||||
/// This should be used instead of calling [`gltf::scene::Transform::matrix()`]
|
||||
/// on [`Node::transform()`] directly because it uses optimized glam types and
|
||||
/// if `libm` feature of `bevy_math` crate is enabled also handles cross
|
||||
/// platform determinism properly.
|
||||
fn node_transform(node: &Node) -> Transform {
|
||||
match node.transform() {
|
||||
gltf::scene::Transform::Matrix { matrix } => {
|
||||
Transform::from_matrix(Mat4::from_cols_array_2d(&matrix))
|
||||
}
|
||||
gltf::scene::Transform::Decomposed {
|
||||
translation,
|
||||
rotation,
|
||||
scale,
|
||||
} => Transform {
|
||||
translation: bevy_math::Vec3::from(translation),
|
||||
rotation: bevy_math::Quat::from_array(rotation),
|
||||
scale: bevy_math::Vec3::from(scale),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn node_name(node: &Node) -> Name {
|
||||
let name = node
|
||||
.name()
|
||||
@ -916,9 +926,8 @@ fn load_node(
|
||||
active_camera_found: &mut bool,
|
||||
parent_transform: &Transform,
|
||||
) -> Result<(), GltfError> {
|
||||
let transform = gltf_node.transform();
|
||||
let mut gltf_error = None;
|
||||
let transform = Transform::from_matrix(Mat4::from_cols_array_2d(&transform.matrix()));
|
||||
let transform = node_transform(gltf_node);
|
||||
let world_transform = *parent_transform * transform;
|
||||
// according to https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#instantiation,
|
||||
// if the determinant of the transform is negative we must invert the winding order of
|
||||
|
||||
Loading…
Reference in New Issue
Block a user