Understanding skeletal animations

Started by
2 comments, last by ill 11 years, 1 month ago

So I'm using Assimp to convert models into my own format, and things work fine if I use Assimp's animation data format. This would store absolute transforms per keyframe relative the the parent bone.

For reasons relating to blending animations and flexibility, I was making my format use transforms relative to the bind pose instead, and this was working very nicely for some models.

I was experimenting with converting md5 models and the Doom 3 player character and hell knight work fine. I got their run straight animations working. The pinky demon though kindof explodes.

I've noticed that the bind pose for the player and the hell knight are 90 degrees perpendicular to their walk straight animation. While the model faces down z, its animation goes down the x axis. The pinky demon, however, faces down the x axis in its bind pose and moves in the same direction.

This ends up making the pinky demon kindof awkwardly moonwalk sideways while also twisting a few bones a bit more than they should be.

One of the artists on our team gave me an animation that explodes similarly once the root bone starts to move in some direction.

The only connection I've made so far is my format only works if the model faces down z and has the root bone translate along x.

I've spent hours trying to debug the math myself. Maybe there's something I'm not understanding about transforms and am making the wrong assumptions about something?

Advertisement

Obviously things are in one matrix space and not the one you want. Have your artist edit the messed up skeleton down to 1 single bone. Have him edit the geometry down to a cube. Have him do 3 snapshot frames. Rotated 90 on the x only, 90 on y only , 90 on z only. Look at what comes out and try to make logic of it. Does a rotation on the x designate a y rotation? Make sure he edits and doesnt create new ones so that you can verify the data is identical and not some new object that may be working in the frame you want.

The skeleton may have an object level rotation. Meaning after creating the skeleton, the user selected it as a whole and rotated. This caused problems for me in blender so I got lazy and didnt fix it. I make sure the skeletons matrix is the identity and then if I need to fix the skeleton to point down the z I edit the skeletons bind pose itself, not the actual skeleton object, or any keyframes.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

So I'm using Assimp to convert models into my own format, and things work fine if I use Assimp's animation data format. This would store absolute transforms per keyframe relative the the parent bone.

For reasons relating to blending animations and flexibility, I was making my format use transforms relative to the bind pose instead, and this was working very nicely for some models.

Hey Ill. First off: thanks for using Assimp :-) I once tried the same route you're treading now, making all my animations to only add "offsets" to the bind pose. I was hoping to be able to combine animations better, and maybe being able to scale them in terms of effect strength. I ultimately failed in reliably finding a complete bind pose for all models. I came up with two ways:

a) Expect the model to be in bind pose when importing. If you get ALL of your assets from artists working for you, you could do this. But it's simply not the case for models you get from other sources, and there's no way to detect if the skeleton isn't in bind pose.

b) Calculate the bone's bind transformation by inverting the bone's offset matrix and "subtract" the parent's bone's offset matrix. This should give you the bind transformation in relation to its parent node. But it fails as soon as you get a skeleton where a bone doesn't affect any vertices. My code assumed a unity matrix in that case, and I saw a similar explosion of the character when trying to animate it.

Case b) can happen quite often. Most character artists today use some sort of predefined skeleton, for example 3DSMax biped. To my knowledge this is necessary to use the builtin animation tools that really seem to make artist's life easier. But when skinning the model they don't need some of the bones, and therefore don't assign any vertices to some of the bones, and BOOM. No bone is exported, no offset matrix can be found, character explodes when being animated.

So my suggestion is: only go that route if you can really rely on every asset being specifically made for you, by people you can give commands to, if necessary. In all other case, absolute animation data is the way to go. I converted all of my animation code to this option after wasting several days on the problem.

----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.

Nice, did you work on Assimp?

I'm still working on the converter but I made it so you can import multiple files at once, which is great for things like Md5 models that I'm using for fun.

I keep my mesh, animation, skeleton, and bind pose files separate. I was hoping that using relative bone transforms I could do something similar to what they did in Gears of War, have female and male characters use the same animations but with slightly different bind poses, and just use relative transforms. I'm not 100% sure this will work, but using relative transforms definitely made my animation code simpler as well.

The skeleton file would keep all bone names to indices and parent hierarchy. The bind pose file would just have bone index to bind pose and offset matrix per bone. I computed the offset matrix manually rather than using the built in assimp bone offset since some nodes didn't have bones referenced from the mesh data. The animations file would just have a bone index followed by its keys, allowing for an animation to not have data on all bones, but only the ones affected by that animation.

Every time you use the exporter, you would either import a previously created skeleton file, or generate a new one based on all scene files imported. This would find all bones in all files and assign indices to them. This ensured that tag bones like SOUL_CUBE_ATTACHER in the Doom space marine would export if I import both the md5mesh file and the md5anim file. The problem before was the md5mesh file held the bind pose needed for the skeleton but assimp wouldn't have reference to some of these extra bones for attaching weapons that were present in the animation file until I made it so I can import both an md5mesh file and an md5anim file at the same time.

When I'm computing the animation keyframes, for each bone, I decompose the bone transform into the translation, scale, and rotation components using the matrix decompose method that comes with Assimp. Then for each key, I compute the translation, scale, and rotation that's relative to those components and export that.

I'm still not sure what would actually cause the animation itself to get a bit weird with the problem that I'm having. It doesn't really explode, it's just some translations seem to be in the wrong coordinate space or something like dpadm450 said. I'm pretty sure that the way I wrote the converter should get around the problems you described would happen because I allow multiple files to be imported at once.

I did find that you can't always consistently decompose a matrix. Like I'd have some translation, rotation, scale, multiply those all together to get a matrix, decompose, and get slightly inverted rotations and scales that would lead to the equivalent matrix if multiplied together again.

This topic is closed to new replies.

Advertisement