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](94c1a4b86f/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 <JustTheCoolDude@gmail.com>
This commit is contained in:
parent
be0ca7f168
commit
cc8f023b3a
@ -110,7 +110,7 @@ impl Mesh {
|
||||
attribute: MeshVertexAttribute,
|
||||
values: impl Into<VertexAttributeValues>,
|
||||
) {
|
||||
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 });
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user