Help needed with combining skinned mesh bindposes

(Originally posted as a forum thread here)

I’m trying to merge together several skinned meshes into a single SkinnedMeshRenderer, for performance reasons. I can do the basic concatenation of the mesh OK, but some of the parts reference the same bones, and so concatenation means those bones are getting referenced more than once - it makes for 80 bones total, rather than 60. So I want to try and patch up the mesh when I combine it so that it shares bones correctly.

Question 1: Is this actually possible?

What I’m finding is that I need to patch up the vertex positions, because the new mesh has different bindposes to the old one.

Question 2: Does it actually make sense that this would be the case?

I’m still fuzzy on exactly what the bindposes are so I’m not entirely sure what determines whether they’re the same or different. I have this vague understanding that they map from mesh-local space to bone-local space. The runtime then maps from bone-local space to world space. So, if I want to use different bindpose matrices, I should only need to alter the mesh-local vertex positions so that they end up in the same bone-local space positions.

So I thought I had to do this:

var boneLocalPosition = oldBindPoses[bone].MultiplyPoint3x4(vertex);
var newVertex = newBindPoses[bone].inverse.MultiplyPoint3x4(boneLocalPosition);

but this produces something that, while roughly correct (no horrendous distortion) doesn’t have the parts in quite the right places, and it begins to distort horribly when the character starts animating.

Question 3: Why didn’t this work?

If you’re with me this far, then hopefully you can answer the most important question:

Question 4: How do I patch the vertices in my skinned meshes to account for new bindpose matrices, in a way that is visually identical to running the meshes through separate SkinnedMeshRenderers on the same skeleton?

This is almost correct, however why does the bones have a new bind pose? That doesn’t make much sense if the skeleton is the same. As you already guessed, the bindposes virtually parent a vertex to a bone by transfering the vertex position into the bones local space.

That’s why it’s called bind pose. The skeleton hierarchy and the vertices are completely seperate in the beginning. Now you place the skeleton into the mesh so the bones are relatively to your mesh at the correct position. At this point you take a snapshot of the bones position / rotation / scale as a reference. Together with the boneWeights you’ve bound the vertices to the skeleton in the current position.

Usually if you used the same skeleton, the bind poses should be the same. If you use two completely different but similar skeletons it’s almost impossible to merge them. If both models were rigged correctly to different but similar skeletons, the way you’ve done the convertion is correct. Are you sure you match up the same bones? if they are different skeletons the bone-order doesn’t have to be the same. You might want to use the bone names to reference them. If the order is different you have to fix the boneWeights of the vertices as well (the bone indices).

Can you post a screenshot of the model(s)? I can’t imagine two models that can be merged into one except a character and a seperate cloth mesh maybe :wink: