Good tutorials on Skeletal Animations?

Started by
6 comments, last by JD 19 years, 7 months ago
Hi, I need to look into animations, and from what I read, Skeletal Animation is the thing to do. I have been looking on Google for good tutorials, but I seem to have trouble finding them. Plez help me in the right direction :) Thanx.
Quote:CalvinI am only polite because I don't know enough foul languageQuote:Original post by superpigI think the reason your rating has dropped so much, Mercenarey, is that you come across as an arrogant asshole.
Advertisement
Come on now, has noone here been through Skeletal Animations?
Quote:CalvinI am only polite because I don't know enough foul languageQuote:Original post by superpigI think the reason your rating has dropped so much, Mercenarey, is that you come across as an arrogant asshole.
What part of bones do you want to know about? How to implement it in code? how to create the art? The theory behind how it works?

Anyway, at one point I was recruited on the spot to give an IRC talk on bones... Clicky. From here you can browse to the logs, and read the advanced animation: bones page. It might give you a starting place.

Last week there was a tutorial posted in the Theory forum for doing bones in software. Because of how the data was laid out, it couldn't directly transfer to hardware implementations. Between learning the theory from that page, and my IRC chat you should be able to figure it out.
I was merely looking for a pointer in the right direction. Maybe some text that could introduce me to the concepts AND the implementations. I have already read some, and the guy used CharacterFX to make the skeleton.
Right now Im using DirectX' Mesh structures, but I am *not* going into their animation structures/functions, it is far too complex, and I want to learn the stuff myself. I don't want to tie myself down and have to start over one day, if I need to make my software platform independent.

So thats why I want to learn the stuff from the ground-up (while using only the most basic storage capabilities of the DX Mesh structure, since it is easy to load from .x files with it - but if necessary Im willing to write my own Mesh class as well, a thing I plan to do at some point in any case).

Im a bit blank on what the best approach is, that is why I asked for a pointer to some good introductions.

I will take a look at your texts, thanx for the help.
Quote:CalvinI am only polite because I don't know enough foul languageQuote:Original post by superpigI think the reason your rating has dropped so much, Mercenarey, is that you come across as an arrogant asshole.
Bones Tutorial

What are bones?

Bones in 3D mimic joints, rather than actual bones. You have a bone in your forearm. When you rotate your elbow joint, the forearm bone moves, along with all your skin and muscle attached to the forearm bone. A bone in 3D is just a position and an orientation... a joint that matter rotates around.

In some modelling packages, the bone appears to have volume. This can be either just a visual aid, showing bones attaching to other bones, or used to automatically attach vertices to the bone.

Bones are laid out in a tree hierarchy. There is one root bone, and all bones are children of that bone, or children of it's children. Assuming the hip is the root bone, you might then have three children, left thigh, right thigh, midsection. The thighs will then each have lower legs, which then have feet, which may in turn have several toes. The toes might be jointed. The midsection will go up to an upper chest, split into shoulders and neck. The neck will likely have a child bone for the head. The shoulders will branch out to upperarms, forearms, hands, and fingers.

While the bones actually describe the physical joints, we often name them for the bone that joint will affect when a bone has only a single child, or even the general area of the body it may affect.


Why use bones?

Once a character has been rigged up to a skelton, ie, it's vertices associated with a bone, or several bones, bones become quite useful. By moving the bones, all the child bones are moved along with it. When you move your forearm, your wrist, hand, and fingers come along for the ride. A bone rotation is often stored as a quaternion, which is just 4 numbers. Keeping track of each vertex for each keyframe would take much more room, so, bones are efficient in terms of storage space. Bones also improve the visual quality of the animation. Imagine two keyframes, indicating a start point, and a rotation of 90 degrees. Typical vertex tweening would distort the mesh as it moves each vertex linearly between the two keyframes. With bones, we interpolate the angle, not the positions, resulting in an object which keeps it's shape, and just rotates about the joint.

So, bones give us smaller, better looking animations, that are easier for the animator to animate, and much easier to control in code for advanced users.


What's this about multiple bones affecting a vertex?

Near joints, you often affect these vertices by both the bone you're coming from, and the bone you're heading to. For example, vertices near your knee are affected by both the thigh and lower leg. The mimics the elasticity of skin. When you rotate a joint 90 degrees, you don't see a square jagged rotation in your arm, you see a gentle curve easing around the joint.


So, what's the mathematical theory behind these things?

For each bone you have a translation, and rotation... maybe a scale, but often not. Each bone is just a transformation like your world transform. For each vertex you have a number of bones that influence this vertex. Each bone influence has a weight, and the weights must add to 1.0f. For example, a vertex in the middle of your forearm is likely affected only by that one bone, so we associate the vertex with bone n, and weight 1.0f. As we approach the elbow, a vertex is likely affected by bone n, and bone n+1. As you pass the joint, the weights will change from being weighted towards bone n, to bone n+1... ie: As we pass the elbow, we'll lower the influence of the forearm, and increase the influence of the lowerarm. Typically for hardware based skinning, we have four bones, and three weights. The 4th weight can be inferred as 1.0f minus the other three weights. When first learning, it's easiest to ignore the weighting, and just associate a single bone to each vertex. The weighting is easily added later once everything else is working.

There are two main parts to the math. The vertex level math, and the bone level math. What we want to do eventually, is to take a vertex and move from it's position and orientation relative to where the bone was when you exported your mesh, rotate it around that point to the angle we'd like it at, then move it back relative to where the bone is now. We'd also like each bone to be affected by all it's parent bones.

At the bone level, you have two poses. The first describes the pose the vertex data is in. If your model is exported in a sitting position with it's hands in it's lap, you need to know the translation and rotatation of each bone that describes that pose. This is called the reference pose. The other pose describes the pose you'd like the mesh to use... for instance, a keyframe of your walk cycle.

Both of these poses can be described mathematically using the following technique:

As mentioned, a bone is just a transform matrix. Each bone is multiplied by it's parent bone's transform. If you start with your root bone and then go to it's children, then their children, you're fine, as you'll always process the parent first, then the child. So, start with the hip, then create your left thigh matrix, multiply it by the hip, then create your left lowerleg matrix, and multiply that by the left thigh, then create the left foot, and multiply that by the left lowerleg, etc.

hip = createtransform(hip_pos, hip_rot);
hip_total = hip;
leftthigh = createtransform(leftthigh_pos, leftthigh_rot);
leftthigh_total = hip_total * leftthigh;
...

Ok, so now we've got two poses convertex to matrices, but what now? Usually, after you've created your pose for your reference pose, you'll take each matrix and find it's inverse. Store this set of inverse matrices, it's really the only part of the reference pose we care about. You do this once, when you've loaded your mesh and just refer to it as needed. An inverse matrix does the opposite of the matrix. The inverse of the reference pose can be thought of as "undo the reference pose". Multiplying a vertex by the inverse reference pose of a bone will move the vertex to be relative to that bone, and undo any rotation the bone may have applied.

Now we need to blend the two poses. Again, it's just matrix multiplication.

hip_xform = invrefpos_hip_total * currentpose_hip_total
leftthigh_xform = invrefpos_leftthigh_total * currentpose_leftthigh_total
...

If we look back at what we were trying to do, you'll see we've done it. That's it.


At the vertex level, we want to perform the following math.
vertex = (originalpos * bonexform1) * weight1
vertex += (originalpos * bonexform2) * weight2
vertex += (originalpos * bonexform3) * weight3
vertex += (originalpos * bonexform4) * (1 - (weight1 + weight2 + weight3))

In software skinning you can just use as many matrices as you'd like. In hardware skinning, typically all 4 bones are used on each vertex. Unused bones just set their weight to 0 to have no influence.

edit:
leftthigh_total = hip_total * leftthigh;
used to say
leftthigh_total = hip_total * leftthigh_total;
by mistake. :(

edit:

Where to bones fit into the pipeline?

Right before world transformation, while you're still in object space.

If doing skinning in software, you can apply the bones and write the vertices to a new chunk of memory, put the data into a dynamic vertex buffer, and render.

If doing skinning in hardware, simply put the skinning code before your world,view,proj code, and change the worldviewproj code to use whatever temporary register you used as their source.


Can bones be mixed with morphing?

Yes. In our engine we apply morphs first, then move the vertices with bones. We typically reserve morphing for things like facial animation, and things that are too finicky or detailed to use bones easily.

[Edited by - Namethatnobodyelsetook on August 31, 2004 8:44:32 AM]
Yeah the above description is very nice. I wrote a skeletal animation tutorial awhile back. It presents techniques used by industry professionals. At the bottom of the tut, I list other helpful resources as well.
Thanx alot for the help guys :)

Now I will head down to the pixel mines, you will probley see me again in a few months :)
Quote:CalvinI am only polite because I don't know enough foul languageQuote:Original post by superpigI think the reason your rating has dropped so much, Mercenarey, is that you come across as an arrogant asshole.
What I know is this: you make your model in object space including your bones, etc. then to xform the whole thing into world space. This way the character has its own vector base and can be oriented any which way by way of going from object to world space ie. by world matrix.

The character is constructed out of continuous triangle mesh. The vertices are shared among triangles for texturing reasons and to save memory/file space. Each vertex in the mesh can be influenced by more than one xform matrix thus each vertex need to be given a weight value that tells you how much each matrix influences the vertex. One vertex can be static thus not influenced by any bone or matrix if you want that. So, after you have created the tri mesh ie. your character or object, then you use a capsule or volume to enclose some vertices. Thus your mesh is enclosed by several capsules. Say a character's leg is enclosed by upper and lower capsules. The capsules at the knee can overlap and thus one vertex can be influenced by two capsules ie. your matrices.

In anotherwords, instead of moving the vertices of a mesh yourself to create some pose you let the bones and such to move/orient those vertices. Instead of having 10 meshes each representing some pose that are then run one after another thus creating an animation you have one mesh in its base pose with arms stretched out to the side and legs spread out. Then you push those vertices thru the matrices and you also interpolate the vertex's position since you only have a small room for couple of those matrices or bones. So you could have only two matrices and then interpolate the vertices between the two animations using time.

So your first animation pose will have say 10 matrices with some values that will move the mesh to some pose. Then the next pose will also have 10 matrices but with different values that will move the mesh into some other pose. You thus have one mesh and several matrices. I think you will have angles from which the matrices are built instead of saving 16 floats that make up the matrix. I think they use quaternions because you only need rotations for characters. The reason why there is an origin bone and all other bones stem from that bone is because you want to move only that bone when moving the character in a game for example and all the other connected bones are relative from the origin bone so they move if origin bone also moves.

You can also create these matrices on the gpu instead of cpu. I think on vs1.1 you have 96 4D vectors, three of them can be used to rotate a vertex. You got then 32 matrices but alas some of them will be used for modelview and projection matrices. New gpus allow for many more matrices in your vertex shader.

Ok, I have not coded this up, just things that I picked up by reading stuff and I might got things wrong here and there. But the reason for skinning is to prevent vertices folding on each other by allowing them to be moved not only by one bone but by neighboring one as well. Make a cylinder with couple of slices and experiment with bones and skinning. I'll go check out those articles now :)

This topic is closed to new replies.

Advertisement