I'm trying to import *.x files to my engine and animate them using OpenGL (without shaders for now, but that isn't really relevant right now). I've found the format reference at MSDN, but it doesn't help much in the problem.
So - basically - I've created a file containing a simple animation of a demon-like being with 7 bones (main, 2 for the tail, and 4 for the legs), from which only 2 (the ones in the right leg) are animated at the moment. I've tested the mesh in the DXViewer, and it seems to work perfectly there, so the problem must be the side of my code.
When I export the mesh, I get a file containing lots of information, from which there are 3 important places for the skeletal animation (all the below matrices are for the RLeg2 bone):
SkinWeights - matrixOffset
-0.361238, -0.932141, -0.024957, 0.000000, 0.081428, -0.004872, -0.996669, 0.000000, 0.928913, -0.362066, 0.077663, 0.000000, 0.139213, -0.057892, -0.009323, 1.000000
FrameTransformMatrix
0.913144, 0.000000, -0.407637, 0.000000, 0.069999, 0.985146, 0.156804, 0.000000, 0.401582, -0.171719, 0.899580, 0.000000, 0.000000, -0.000000, 0.398344, 1.000000
AnimationKey matrix in bind pose
0.913144, 0.000000, -0.407637, 0.000000, 0.069999, 0.985146, 0.156804, 0.000000, 0.401582, -0.171719, 0.899580, 0.000000, 0.000000, -0.000000, 0.398344, 1.000000
My question is - what do I exactly do with these matrices? I've found an equation on the Newcastle University site (http://research.ncl.ac.uk/game/mastersdegree/graphicsforgames/skeletalanimation/), but there's only 1 matrix there. The question is - how do I combine these matrices to get the vertex transform matrix?
This post is not pretend to be a full answer, but a set of helpful links.
How to get all information needed for animation
The question is how do you import your mesh, and why do you do this. You can fight with
.x
meshes for a months, but this doesn't make any sense, because.x
is a very basic, old and really not good enough format. You don't find many fans of.x
format on StackOverflow. =).x
file stores animation data in a tricky way. It was intended to load via set ofD3DX*()
functions. But, to get bones and weights from it manually, you must preprocess loaded data. Much things to code. Here is a big post, explaining how to:Loading and displaying .X files without DirectX
Good way to do things is just switch to some mesh loading library. The most popular and universal one is Assimp. At least, look at their docs and/or source code, on how they handle loading and preprocessing, and what whey have as output. Also, here is a good explanation:
Tutorial 38 - Skeletal Animation With Assimp
So, with assimp you can stop fighting and begin animating right now. And maybe later, when you'll find idea on how it's works, you can write your own loader.
When you've got all information needed for animation
Skeletal animation is a basic topic that explained in details all around the web.
Hope it helps!
Since Drop provided links that talk about the problem, and give clues on how to solve it, but don't quite provide a simple answer, i feel obliged to leave the solution here, in case someone else stumbles on the same problem.
To get the new vertex position in "bind pose"
where:
v'(i)
- new vertex position,v(i)
- old vertex position, andW(bone,i)
- weight of the transformation. (and of course Σ is the sum from 0 to the amount of bones in the skeleton)The
transform(bone)
is equal tosw(bone) * cM(bone)
, wheresw
is the matrix found inside the SkinWeights tag, andcM(bone)
is calculated using a recursive function:The
localTransform
is the matrix located inside the FrameTransformMatrix tag.To get the new vertex position in a certain animation frame
Do the exact same operation as mentioned above, but instead of the matrix in FrameTransformMatrix, use one of the matrices inside the appropriate AnimationKey tag. Note that when an animation is playing, the matrix inside the FrameTransformMatrix tag becomes unused. Which means, you'll probably end up ignoring it most of the time.