• Create Account

We're offering banner ads on our site from just \$5!

Don't forget to read Tuesday's email newsletter for your chance to win a free copy of Construct 2!

# Skeletal animation equation

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

### #1Deliverance  Members   -  Reputation: 309

Like
0Likes
Like

Posted 24 February 2010 - 12:59 AM

Many people think that skeletal animation is just:

$v' = \sum_{1}^{numWeights} jointTransform[i] * weights[i] * v$ Equation 1

but it seems there more going on there than this equation actually shows. Refering to collada's reference the equation for skeletal animation is:

$v' = \sum_{1}^{numWeights} jointMatrix[i] * invBindMatrix[i] * bindShapeMatrix * weights[i] * v$ Equation 2

bindShapeMatrix is fixed, and should multiply all vertices once at initialization.
invBindMatrix takes v from object space to jointspace.
jointMatrix takes v from jointspace back to object space. Also jointMatrix is calculated hierarchically(by starting at the root of the skeleton, and so on) every time the animation is updated.
Now it is obvious what i can do here: precalculate for all frames the following product:

$jointTransform[i] = jointMatrix[i] * invBindMatrix[i] * bindShapeMatrix$ Equation 3

and by Equation 2 becomes exactly as Equation 1. But precalculating all this data for all the frames eats up a lot of memory! The animation data for a model who's static data takes about 0.5 mb is over 18MB in size!!!

So how should i do it then? Having just on matrix to send to the vertex shader is obviously better then sending two!(invBindMatrix and jointMatrix). Also precalculating all the keyframes for the skeletal animation(i'm not talking about vertex tweening animation here) take a lot of memory so it's not feasible.

### #2CaffeinePwrdAl  Members   -  Reputation: 178

Like
0Likes
Like

Posted 24 February 2010 - 01:26 AM

You could save some space using quaternions for rotation, and possibly only a couple of translation terms - scale and complicated translation are often not required in skeletal animation - This might save you both data size and computation time.

Alex

### #3Deliverance  Members   -  Reputation: 309

Like
0Likes
Like

Posted 24 February 2010 - 01:32 AM

Quote:
 Original post by aleks_1661You could save some space using quaternions for rotation, and possibly only a couple of translation terms - scale and complicated translation are often not required in skeletal animation - This might save you both data size and computation time.Alex

Thanks Alex, i already use quaternions! As for the translation and scale i use full 3D vectors. Due to the fact that i precompute the translation and scale i need to store full 3d vectors, so no memory win here..

### #4CaffeinePwrdAl  Members   -  Reputation: 178

Like
0Likes
Like

Posted 24 February 2010 - 01:39 AM

You could have a look at the archives of the SWEng-Gamedev mailing list, there have been a good few threads on there about animation, usually with some comments about hot it is done in Granny, which seems to be a pretty comprehensive package.

Alex

### #5Buckeye  Crossbones+   -  Reputation: 5678

Like
0Likes
Like

Posted 24 February 2010 - 02:38 AM

Normally the jointMatrix is calculated dynamically during execution when the animation time is advanced. Only bindShape*v is precalculated. invBind is stored in an array (size=number of joints).

Calculate jointMatrix (the animation matrix) for each joint.
Calculate jointMatrix*invBindMatrix (jointTransform above) and store in an array (size=number of joints) (and set in a shader array if you're using a shader)
Calculate v' (commonly in a shader)
Render.

### #6Deliverance  Members   -  Reputation: 309

Like
0Likes
Like

Posted 24 February 2010 - 03:30 AM

Quote:
 Original post by BuckeyeNormally the jointMatrix is calculated dynamically during execution when the animation time is advanced. Only bindShape*v is precalculated. invBind is stored in an array (size=number of joints).At each time advance:Calculate jointMatrix (the animation matrix) for each joint.Calculate jointMatrix*invBindMatrix (jointTransform above) and store in an array (size=number of joints) (and set in a shader array if you're using a shader)Calculate v' (commonly in a shader)Render.

Okay, i understand now. By calculating the joint matrix at small intervals you get smooth blended vertex positions!

### #7Buckeye  Crossbones+   -  Reputation: 5678

Like
0Likes
Like

Posted 24 February 2010 - 07:57 AM

Exactly. The jointMatrix will be a lerp/slerp value and may be between jointMatrix[ time x ] and jointMatrix[ time x + 1 ].

Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS