Jump to content
  • Advertisement
Sign in to follow this  
Starfox

Understanding Skeletal Animation

This topic is 2125 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to write my own skeletal animation program and I'm having some trouble finding a source explaining the math involved as opposed to just dumping equations or code, so I have a few questions. In case it makes a difference, I'm using Open Asset Import to load Collada files with animations - the format's data layout is explained at 

 

As far as I understand it (and please correct me if I'm wrong), the inverse bind pose matrices convert from object space to each joint's space (and they don't need to be updated every time an animation is interpolated). The inverse bind pose matrices also don't need to be transformed by their parent's inverse bind pose (i.e. are not hierarchical). 

 

For every frame, once I have each joint's position / rotation interpolated from animation data, I go over ever vertex's weights. For each weight I transform the original vertex by the inverse bind pose matrix (to go to joint space), then by the joint's hierarchical transform (local + parent) then by the scalar weight, and the final vertex position is the sum over all weights. Is that all or am I missing something?

 

Another question I have is whether the inverse bind pose matrices are mesh-specific or skeleton-specific. Let's say I'm using a single skeleton and animation set to animate two different meshes (character A and character B, for example). Would the inverse bind pose matrices be the same or are they different for each mesh? Either case, why?

Share this post


Link to post
Share on other sites
Advertisement

As far as I understand it (and please correct me if I'm wrong), the inverse bind pose matrices convert from object space to each joint's space (and they don't need to be updated every time an animation is interpolated). The inverse bind pose matrices also don't need to be transformed by their parent's inverse bind pose (i.e. are not hierarchical).

 
The first sentence is true, but the second might depend on format. I've worked with md5 meshes and for them bind pose matrices are always stored so that no multiplication by parents is required. I'm not sure if this holds for all formats, but I don't see any reason why they should be stored the other way.
 
 
 

For every frame, once I have each joint's position / rotation interpolated from animation data, I go over ever vertex's weights. For each weight I transform the original vertex by the inverse bind pose matrix (to go to joint space), then by the joint's hierarchical transform (local + parent) then by the scalar weight, and the final vertex position is the sum over all weights. Is that all or am I missing something?

 
Sounds about right, although there is a choice here. What you describe is suitable for GPU skinning, as you can compute poseMatrix*inverseBindPose and put these as uniforms to be used in a shader, where the vertices are then transformed. Another choice would be to transform the vertices into bone space by multiplication by the inverse bind pose matrix as a pre-computation. Then the pre-transformed vertices only need to be multiplied by the animation transform during rendering. This is cannot be implemented on GPU in a sensible way.
 
 
 

Another question I have is whether the inverse bind pose matrices are mesh-specific or skeleton-specific. Let's say I'm using a single skeleton and animation set to animate two different meshes (character A and character B, for example). Would the inverse bind pose matrices be the same or are they different for each mesh? Either case, why?

 
I would think that the bind pose matrices and (their inverses) are only skeleton specific and can be applied to multiple meshes using the same skeleton.

Edited by jmakitalo

Share this post


Link to post
Share on other sites


Another question I have is whether the inverse bind pose matrices are mesh-specific or skeleton-specific. Let's say I'm using a single skeleton and animation set to animate two different meshes (character A and character B, for example). Would the inverse bind pose matrices be the same or are they different for each mesh? Either case, why?

 

I still haven't finished my skeletal system, but I've planned this and for now I'm giving each mesh a specific skeleton.

That means HumanA and HumanB won't share the same skeleton if they're slightly different, because the bones' positions wouldn't match the exact vertex positions and that would mess the rotations (translations are fine, but rotations need to rotate in the bone center, so it needs to match).

 

But I'm separating skeletons as types, such as "Humanoid". This skeleton has (in my exemple) 42 bones without face bones, and follow the same hierarchy.

I'm storing animation data separately with just boneIDs and translation/rotation. So if I have two skeletons, even though they're different in positions and such, but have the same hierarchy, the transformations remains the same.

 

So my animationA data says "add XYZ to Bone 1, rotate Y to Bone 2", and it applies equally to different models as long as their skeleton hierarchy is equal.

 

I don't know if there's an easier way to deal with this (I'd like to have a single skeleton called "Humanoid" that worked for all humanoid types, but then I'd need to save somehow where each joint should be in the mesh data so the rotations are constant), but for now this is what I'm going for...

Share this post


Link to post
Share on other sites

Thanks, that cleared up some issues. I implemented the basic code and it's working just fine. The thing I'm still not sure about is whether two meshes using the same skeleton layout would need two different sets of inverse bind pose matrices, and why. Does anybody know the answer to that part?

Share this post


Link to post
Share on other sites


Another question I have is whether the inverse bind pose matrices are mesh-specific or skeleton-specific.

Both.

 

The difference between the skeleton’s bind-pose matrices and the model’s bind-pose matrices is used to calculate an offset matrix which is applied to the run-time joints prior to any other matrix-combining.

 

This is necessary for applying the skeleton to other models.  Just because 2 models have the same joint structure does not mean they can use the same skeleton/animation.

Imagine a car and a truck.  Both have 4 wheels, and the skeleton may have the same names for each wheel, but the truck’s wheels will be spaced further apart.

If the animation is designed for the car but then applied to the truck, the wheels will spin, but they will be located inside of the truck.

 

You need to store the original bind pose for the model inside the model data and the bind pose for the skeleton for the animation data.

At run-time you calculate what type of offset is needed to convert from the car’s wheel locations to the truck’s wheel locations.

 

 

L. Spiro

Share this post


Link to post
Share on other sites

 


Another question I have is whether the inverse bind pose matrices are mesh-specific or skeleton-specific.

Both.

 

The difference between the skeleton’s bind-pose matrices and the model’s bind-pose matrices is used to calculate an offset matrix which is applied to the run-time joints prior to any other matrix-combining.

 

This is necessary for applying the skeleton to other models.  Just because 2 models have the same joint structure does not mean they can use the same skeleton/animation.

Imagine a car and a truck.  Both have 4 wheels, and the skeleton may have the same names for each wheel, but the truck’s wheels will be spaced further apart.

If the animation is designed for the car but then applied to the truck, the wheels will spin, but they will be located inside of the truck.

 

You need to store the original bind pose for the model inside the model data and the bind pose for the skeleton for the animation data.

At run-time you calculate what type of offset is needed to convert from the car’s wheel locations to the truck’s wheel locations.

 

 

L. Spiro

 

 

That doesn't tackle my question, though I can see where the confusion stems from. 

 

My question is this: Given a skeleton, let's call it Humanoid, as a bunch of joint matrices and parent / child relationships, and two meshes that use that skeleton for animations, GoodGuy and BadGuy - are the inverse bind pose matrices for GoodGuy and BadGuy the same? Why or why not? Note that I'm not talking about different skeletons using the same bone names or shape - I'm talking about one exact skeleton and a set of associated animations.

Share this post


Link to post
Share on other sites

As long as no adjustments need to be made for any joints to accommodate the shapes of the 2 characters, they should still have bind-pose information embedded in the model file, but it will end up being the same data for each.

Due to the limitations this imposes compared to the low overhead in implementation and memory consumption, it is worth it just embed bind-pose data into both.

 

 

L. Spiro

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!