XZibit's picture

Skelettal Animation with OTK

Hey,

im working on some Project and would now like to have an animated 3d Model walking arround my scene.
I created a class that lets me import .obj model files and put them into VertexBuffers. Now i want to get Animation
working.
I know how this works in generel but i cant imagine on how to do the transformation stuff on my static VBO in OpenGL.
Can someone explain it, best on a short peace of code so i could comprehend it to myselfe?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
mOfl's picture

Skeletal animation requires a skeleton, as the name says. Obj does not support skeletals, you'd have to switch to *.x, md5 or collada for example to import them. In the file, for each animation it is saved for each vertex, by which nodes it is transformed at a time in form of an offset matrix. Before rendering, you'd accumulate all bone matrices bottom-up to the root of the skeleton (to get all local transformations heirarchically), store them all in a buffer and at rendering, you'd multiply each vertex in the vertex shader with the matrix bones which influence the vertex according to the list in your file.

Quote:

Can someone explain it, best on a short peace of code

There's no such thing as a short piece of code for skeletal animation - it is quite some work and will take up a few hundred or even thousand lines of code. I for myself use a modified version of Assimp to import and handle animations and just do the transformation stuff myself, but it's still pretty nasty work. Using a library which provides you with the most common tools is the way to go in my opinion.

XZibit's picture
mOfl wrote:

Skeletal animation requires a skeleton, as the name says. Obj does not support skeletals

I know but i could load skelettal files seperately or generate them during game

mOfl wrote:

Before rendering, you'd accumulate all bone matrices bottom-up to the root of the skeleton (to get all local transformations heirarchically), store them all in a buffer and at rendering, you'd multiply each vertex in the vertex shader with the matrix bones which influence the vertex according to the list in your file.

Could you show me that at a short example?

mOfl wrote:

you'd multiply each vertex in the vertex shader

Has it to be a shader or could i do this in my Program for testing how and that it works?

mOfl wrote:

Using a library which provides you with the most common tools is the way to go in my opinion.

To do that i dotn learn how it works!

mOfl's picture
XZibit wrote:

I know but i could load skelettal files seperately or generate them during game

Why would you do that? That's an incredible and easily avoidable overhead.

Quote:

Could you show me that at a short example?

As I wrote, skeletal animation is nothing you could explain with a few lines of sample code. Have a look at some skeletal animation tutorials, you can find a few good ones via Google. The general idea is that you (or the modelling program/animation exporter, to be precise) calculate for each bone of the skeleton the transformation matrix from the bone's local coordinate system to world space. The accumulation of all parent bones' inverse transformation matrix of each bone gives you a list of all bone's inverse bind matrices. As they don't change at runtime, they are usually stored in the file - if it supports skeletal animation. At runtime, you calculate the accumulated transformation matrix for each bone, multiply it with its inverse bind matrix and transform your vertex accordingly, i.e.:

TransformedVertex = Vertex * InverseBind * GlobalTransform * Model * View * Projection

Usually, you'd limit the number of bones which influence a single vertex to e.g. 4. Then, you need to specify weights for the 4 bones for each vertex and in the transformation step, weight the matrices accordingly.

Quote:

Has it to be a shader or could i do this in my Program for testing how and that it works?

Of course you can also do everything on the CPU side of the application. Usually, you'd do the calculation of the inverse bind matrices offline, the calculation of the current global transformation matrices per vertex once per frame on the CPU, multiply them with the inverse bind matrices on the CPU, then upload the multiplied matrices in a buffer to your shader and do the per-vertex weighting in the vertex shader. You can of course do the last step on the CPU, too. You'd have to iterate over all vertices, do weighted transformations with all influencing bone matrices (product of global transform and inverse bind matrices) and update your vertex buffer (object).

Quote:

To do that i dotn learn how it works!

To be honest, there are better things you could do with your time. Getting that matrix stuff straight is a real pain in the ass and you will be happy if you get it working eventually. If you really, really want to do everything yourself and understand what you're doing, books from the 90s are the way to go. But it's like implementing a physics engine on your own - it's annoying, it's boring, there are better implementations freely available and noone will complain if you use them.

flopoloco's picture

This is a good library to use, I don't know though if it updated to the latest OpenTK version but it's cool to learn from.
http://www.opentk.com/node/477?page=1

blackbee's picture

If you are using VBO than the best way to implement skeletal animation is to use vertex shader to do 'weight, bone, vertex' multiplication. You can of course update VBO every frame but it's highly unefficient approach. What I can give you is couple of sources which help me understand how it is made, so here:

http://mathinfo.univ-reims.fr/IMG/pdf/Mesh_Skinning_Domine_.pdf - there are two main methods to implement skeletal animation, depending on data, this will help you understand basics.
http://www.opengl.org/wiki/Skeletal_Animation - this clearly show how does it work from vertex shader point of view.
http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter06.html - here you will find a lot of important stuff about animations. But I think you should look here after two previous lectures.

After reading those I had no problem (well maybe a little bit :)) implementing skeletal animation using Kincect, and OpenTK of course.

migueltk's picture
flopoloco's picture

Here's also a project that uses skeletal animation
http://code.google.com/p/lolmodelviewer/

XZibit's picture

I'll take a look at the projects and how they have done it before implementing my own solution.
Thank you all!

migueltk's picture

I recently completed a model viewer doom 3 "*. Md5mesh and *.md5anim", they use animation skeleton, is an improvement of a previous code. Now support "Bump mapping" and "Specular mapping". For now only supports CPU animation.

The conclusions I have reached are:

1. VBO should only be used if the animation is done on the GPU.
2. If the animation is done using the CPU is faster to use "Vertex Arrays".
3. There is a noticeable difference in "Frames per second" when running the code in DEBUG mode and RELEASE mode. For example, in DEBUG mode I get about 36 FPS and the same code running in RELEASE mode I get about 126 FPS, awesome!.

If anyone is interested, I can publish the source code of a demo of the viewer. I notice that the code is still a little dirty!

flopoloco's picture

Amazing work as always Miguel, I would be very interested to look at your project, though I regularly check your website for updates. :)