Sign in to follow this  
Xerios

Animation, bones, matrices,.. skeleton, how does it work ?

Recommended Posts

Well I got this weird annoying problem, which is probably because of my lack of full understanding of skeletal animation.

I wrote this Ogre3D's xml mesh importer which works as it should, all the data is imported correctly and linked ( bone children / vertex indices )

So far the files are parsed correctly, the model is rendered and everything is where it should be.

Now the problem is how to use that animation data, the skinning is not a problem but the matrices that need to be sent to the shader are.

No matter what I tried, I always ended up with a weird animation that made my models look like some bunch of mutated cripples. I have tried different ways to do this but I kept failing, I even failed making it draw a proper bone structure using bunch of lines.


I am using SlimDX ( if that changes anything ) and I would really appreciate if some one could help me on this one. Maybe it's something that I'm doing wrong, or maybe Ogre3D's skeleton format has some values that need to be converted. I just don't really know =(

Here's my incorrect code for drawing the basic skeleton :

public void RenderBones(Bone root) {
root.fullMatrix= root.initialMatrix;
if (root.parent!=null) {
root.fullMatrix *= root.parent.fullMatrix;
RenderLine(root.parent.fullMatrix,root.fullMatrix);
}

foreach (Bone bone in root.children) RenderBones(bone);
}


I spent days trying to figure out how to do this properly, so asking for help is now my final solution =)

[Edited by - jpetrie on December 1, 2010 6:58:38 PM]

Share this post


Link to post
Share on other sites
Quote:

No matter what I tried, I always ended up with a weird animation that made my models look like some bunch of mutated cripples...

I am not familiar with SlimDX but problem sounds like i have some time ago.
See if number of bone matrices that you are passing and number in your shader
are same?

Share this post


Link to post
Share on other sites
Yep, they are the same.

Like I said, how is it supposed to work if my code can't even draw the basic skeleton shape/lines ? =/

Share this post


Link to post
Share on other sites
Can you explain what you mean "the skinning is not a problem"? I would think that would imply that you had it working, but it seems like you're not close.

What are you considering as the "bone matrix"? A hierarchical transform? The inverse bind matrix? I don't think you can do with just one matrix per bone, I believe you need two matrices per bone if you plan to animate anything (transform and inverse bind).

Are you just trying to render the default pose with only the hierarchical matrices, and that doesn't work?

Share this post


Link to post
Share on other sites
I guess my post wasn't clear enough, anyways

When I said "skinning is not a problem" I meant that my models properly adjusted vertexes to the according matrix.

The real problem is that I have no idea on how the whole 'hierarchical transform' thing works and the matrix array that I'm sending to my shader is obviously wrong. The only info that the ogre3d's skeleton file provides are some initial bone properties ( position , rotation, size ) and animation data ( also pos, rot, size )

From Ogre3D's wiki I found out they use 'Hierarchical forward-kinematics' on bones, I suppose it's just a simple form of skeletal animation.

You said that I needed two kind of matrices, like that inverse bind and transform. It'll be helpful if you could explain to me how it works.

Also, does drawing bones require a different approach than preparing that matrix array that I send to my shader

Share this post


Link to post
Share on other sites
First, I'm not familiar with SlimDx in particular. But your post is a bit confusing. In addition, it's not clear what a bone's "initialMatix" is, and what you intend "fullMatrix" to be.

Since you're doing your own import, you'll have to interpret this information.

In general terms, for animation, you need two matrices for each bone:

- an inverse bind-pose matrix
- an animation matrix

Each bone should have a local bind-pose transform (matrix, base transform, frame transform), specifying it's orientation in the bind-pose (or "rest pose" or "initial pose"). Then inverse bind-pose matrix is:

boneInverseBindMatrix = Inverse( bone-bind-pose-matrix * parent-bind-pose-matrix * parent's-parent-bind-pose-matrix * ... * root-bone-bind-pose-matrix);

The inverse bind-pose matrix can be calculated before any animation is done.

The animation matrix is calculated each frame, normally a slerp of the bone's keyframe matrices for the current render time.

boneAnimationMatrix = boneSlerpedMat * parent-slerpedMat * parent's-parent-slerpedMat * ... * root-SlerpedMat;

The matrix that you send to the shader each frame for each bone is:

boneMatInShader = boneInverseBindMatrix * boneAnimationMatrix;

Maybe that will help you understand what you're trying to do.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this