Transforming Vertices with Smooth Skinning

Started by
0 comments, last by Buckshag 11 years, 8 months ago
Hi,

I'm having an issue when trying to animate a mesh within my game using smooth skinning. I'm exporting a mesh, it's joints, and all animation data from Maya and it's importing properly within the game. I've also got my joints displayed in-game as spheres, just to make sure they are animating properly, and they are. I'm having trouble when transforming the vertices to bone space, and I'm clueless as to why. Here's a basic run-down of what I'm currently doing.

  • Precalculating the inverse of each bone in it's bind-pose. The bone hierarchy is also set up here, I'm only setting their local matrices as their world matrices are calculated upon request.
  • Interpolating matrices between keyframes, this appears to be working as the spheres are animating correctly.
  • Copying the meshes vertices from the bind-pose into a seperate buffer to be modified
  • Transforming each vertex:

For each vertex

For each influencing bone in vertex

Vertex tempvert;
tempvert = vertex.position * local bone inverse matrix;
tempvert = tempvert * interpolation of the bones world matrix between the current and next frame;
tempvert *= influence weight;
vertex += tempvert;

  • Update the GPU with the transformed vertices

I've also tried switching around local and world transforms for the bones, but to no avail. I'm pretty sure I'm doing something stupid, I just want to make sure that's the case before I go tearing apart my math library.

Thanks for the help.
Advertisement
Using spheres to check the bone transforms is not a good idea. The translations might be correct, but maybe your rotations are wrong.
Although let's just assume that is all fine.

You shouldn't be interpolating matrices really though. You should interpolate the local transformation components themselves, so the position, rotation quaternion, etc.
Then build the local space matrix from that.

Also your vertex data, in what space is it exported for skinned geometry? Do the bones appear correctly inside the mesh when you render it, without animating.
Your skin loop has to change a little as well.

You should, before you enter the per vertex loop, precalculate the skinning matrices by multiplying the world space matrix with the inverse bind pose matrix.
Then multiply this matrix with your vertex position in bind pose, and add it to the result.
[source lang="cpp"]
skinnedPos = (0,0,0)
for each vertex
for each influence i
skinnedPos += (inputVertexPos * skinMatrix[ vertex.boneIndex ]) * vertex.weights
[/source]

Kind of comes down to the same though, although a bit more efficient.
Also what do you see? What happens exactly to the skin, and does it work fine when it is not animating?
Also have you tried it on a simple cylinder with 2 bones in it, and then rotate the child bone over some axis, instead of directly trying it on a full character.

This topic is closed to new replies.

Advertisement