From 3aad5c6b994f61b86fff08c28a868d80aad7d6fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Wed, 16 Aug 2023 09:27:58 +0200 Subject: [PATCH] animations: convert skinning weights from unorm8x4 to float32x4 (#9338) # Objective - Fixes part of #9021 ## Solution - Joint mesh are in format `Unorm8x4` in some gltf file, but Bevy expects a `Float32x4`. Converts them. Also converts `Unorm16x4` - According to gltf spec: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#skinned-mesh-attributes > WEIGHTS_n: float, or normalized unsigned byte, or normalized unsigned short --- crates/bevy_gltf/src/vertex_attributes.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/bevy_gltf/src/vertex_attributes.rs b/crates/bevy_gltf/src/vertex_attributes.rs index 558000cc1bfee..7c3e9b3651599 100644 --- a/crates/bevy_gltf/src/vertex_attributes.rs +++ b/crates/bevy_gltf/src/vertex_attributes.rs @@ -6,7 +6,7 @@ use bevy_render::{ use bevy_utils::HashMap; use gltf::{ accessor::{DataType, Dimensions}, - mesh::util::{ReadColors, ReadJoints, ReadTexCoords}, + mesh::util::{ReadColors, ReadJoints, ReadTexCoords, ReadWeights}, }; use thiserror::Error; @@ -206,6 +206,19 @@ impl<'a> VertexAttributeIter<'a> { } } + /// Materializes joint weight values, converting compatible formats to Float32x4 + fn into_joint_weight_values(self) -> Result { + match self { + VertexAttributeIter::U8x4(it, Normalization(true)) => { + Ok(Values::Float32x4(ReadWeights::U8(it).into_f32().collect())) + } + VertexAttributeIter::U16x4(it, Normalization(true)) => { + Ok(Values::Float32x4(ReadWeights::U16(it).into_f32().collect())) + } + s => s.into_any_values(), + } + } + /// Materializes texture coordinate values, converting compatible formats to Float32x2 fn into_tex_coord_values(self) -> Result { match self { @@ -224,6 +237,7 @@ enum ConversionMode { Any, Rgba, JointIndex, + JointWeight, TexCoord, } @@ -252,7 +266,9 @@ pub(crate) fn convert_attribute( gltf::Semantic::Joints(0) => { Some((Mesh::ATTRIBUTE_JOINT_INDEX, ConversionMode::JointIndex)) } - gltf::Semantic::Weights(0) => Some((Mesh::ATTRIBUTE_JOINT_WEIGHT, ConversionMode::Any)), + gltf::Semantic::Weights(0) => { + Some((Mesh::ATTRIBUTE_JOINT_WEIGHT, ConversionMode::JointWeight)) + } gltf::Semantic::Extras(name) => custom_vertex_attributes .get(name) .map(|attr| (attr.clone(), ConversionMode::Any)), @@ -264,6 +280,7 @@ pub(crate) fn convert_attribute( ConversionMode::Rgba => iter.into_rgba_values(), ConversionMode::TexCoord => iter.into_tex_coord_values(), ConversionMode::JointIndex => iter.into_joint_index_values(), + ConversionMode::JointWeight => iter.into_joint_weight_values(), }); match converted_values { Ok(values) => {