From cc8f023b3afecfc73be60fbdb5859b90c69aa075 Mon Sep 17 00:00:00 2001 From: robtfm <50659922+robtfm@users.noreply.github.com> Date: Mon, 10 Apr 2023 08:49:53 +0100 Subject: [PATCH] fix invalid bone weights (#8316) # Objective when a mesh uses zero for all bone weights, vertices end up in the middle of the screen. ## Solution we can address this by explicitly setting the first bone weight to 1 when the weights are given as zero. this is the approach taken by [unity](https://forum.unity.com/threads/whats-the-problem-with-this-import-fbx-warning.133736/) (although that also sets the bone index to zero) and [three.js](https://github.com/mrdoob/three.js/blob/94c1a4b86f53c91b61ec4ca3299b4ad02422ddb8/src/objects/SkinnedMesh.js#L98), and likely other engines. ## Alternatives it does add a bit of overhead, and users can always fix this themselves, though it's a bit awkward particularly with gltfs. (note - this is for work so my sme status shouldn't apply) --------- Co-authored-by: ira --- crates/bevy_render/src/mesh/mesh/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/mesh/mesh/mod.rs b/crates/bevy_render/src/mesh/mesh/mod.rs index d58c5e2cf7..6e407510f2 100644 --- a/crates/bevy_render/src/mesh/mesh/mod.rs +++ b/crates/bevy_render/src/mesh/mesh/mod.rs @@ -110,7 +110,7 @@ impl Mesh { attribute: MeshVertexAttribute, values: impl Into, ) { - let values = values.into(); + let mut values = values.into(); let values_format = VertexFormat::from(&values); if values_format != attribute.format { panic!( @@ -119,6 +119,17 @@ impl Mesh { ); } + // validate attributes + if attribute.id == Self::ATTRIBUTE_JOINT_WEIGHT.id { + let VertexAttributeValues::Float32x4(ref mut values) = values else { + unreachable!() // we confirmed the format above + }; + for value in values.iter_mut().filter(|v| *v == &[0.0, 0.0, 0.0, 0.0]) { + // zero weights are invalid + value[0] = 1.0; + } + } + self.attributes .insert(attribute.id, MeshAttributeData { attribute, values }); }