Animation

Started by
7 comments, last by Ashaman73 12 years ago
Can anyone suggest a really good book/tutorial website/page on animation?

In my engine (dx9/c++), I have implemented skinning and animation using skeletons. I have also written a Collada converter which converts from Collada into my native engine format. This all works great. What I'd now like to do is extend it by adding animation blending, timelines, inverse kinematics, etc.

Thanks in advance
Advertisement
It all depends on how you have your skeletal animation system set up. The way i have mine set up is that each animation is on a TimeLineLayer which is part of a timeline. Each TimeLineLayer contains an blendweight factor. So to blend all i have to do is have more than one timelineLayer on a TimeLine. Then from there i can just blend two timelinelayer to get a different timelinelayer which contains the new blendkeys. Perfoming the blend is very easy from that point, all i do is take the global time and feed it for each layer of my timeline, which in terms returns the position/rotation for the current time for each timelinelayer. From there i just apply the blend factor of each layer then add them both to get the new blendkey.

It all depends on how you have your skeletal animation system set up. The way i have mine set up is that each animation is on a TimeLineLayer which is part of a timeline. Each TimeLineLayer contains an blendweight factor. So to blend all i have to do is have more than one timelineLayer on a TimeLine. Then from there i can just blend two timelinelayer to get a different timelinelayer which contains the new blendkeys. Perfoming the blend is very easy from that point, all i do is take the global time and feed it for each layer of my timeline, which in terms returns the position/rotation for the current time for each timelinelayer. From there i just apply the blend factor of each layer then add them both to get the new blendkey.


Thanks for the response, that's pretty much how I envisaged it might happen.

As a further question, I just looked over my code (haven't touched on it for a few months) and I think I'm doing something pretty inefficient. My skeleton is loaded as per Collada and my local joint matrices are stored as matrices, not quaternions. My animation clips are stored as matrices and time intervals - essentially exactly how it looks in Collada. When I animate my skeleton, for each bone and key frame, I convert the current and next frame animation matrix to quaternions, interpolate based on the time interval (between frames) and then convert back to a matrix in order to pass to the shader. Is this how it's currently done? Or should I be converting to quaternions when I load my animation - seems like I should to make it more efficient.

Thanks
Mine is very similar. The only different is that i am storing each Joint as a Vector3 and Quaternion. After the transformation is done i convert my quaternion/vector3 into an single matrix which is the final matrix for the joint. That matrix is the one that get send down to the shader. The only difference between yours and mine is that it seems that you are doing the conversion twice.

When I animate my skeleton, for each bone and key frame, I convert the current and next frame animation matrix to quaternions, interpolate based on the time interval (between frames) and then convert back to a matrix in order to pass to the shader. Is this how it's currently done? Or should I be converting to quaternions when I load my animation - seems like I should to make it more efficient.

Because of quaternions having better rotation properties, you could do everything with quaternions. That is, save your animation as quaternions, interpolate with quaternion, send the quaternions to the shader (you save half of the registers this way, 1 position vector + 1 quaternion vs one 4x4 matrix) and transform the vertices with the quaternion instead of converting the quaternion into a matrix first.
Thanks, I wasn't aware you could manipulate vertices in the shader using quarternions, is there something built-in for that?
As far as I know there's no build in function, thought you need only vector operations to rotate a vertex/vector by an quaternion. When there's interest in it, I could post some GLSL code.
I'll be doing this kind of optimisation so I'd be really interested in seeing how it's done.

Thanks
Here's the code:

/**
* transform a vector by a quaternion
*/
vec3 quatTransform( vec4 quaternion, vec3 vector )
{
return vector + 2.0 * cross( quaternion.xyz, cross( quaternion.xyz, vector ) - vector * quaternion.w);
}
/**
* transform a vector by the inverse quaternion
*/
vec3 invQuatTransform( vec4 quaternion, vec3 vector )
{
return vector + 2.0 * cross( -quaternion.xyz, cross( -quaternion.xyz, vector ) - vector * quaternion.w);
}

I use the invQuatTransform to transform the vertices from model space into the final animated object space position:

// transform vertex/normal to animated position
vec3 position_animated = (invQuatTransform( bone_rotations[index.x], position_os) + bone_positions[index.x]) * bone_weight.x;
position_animated += (invQuatTransform( bone_rotations[index.y], position_os) + bone_positions[index.y]) * bone_weight.y;
position_animated += (invQuatTransform( bone_rotations[index.z], position_os) + bone_positions[index.z]) * bone_weight.z;
position_animated += (invQuatTransform( bone_rotations[index.w], position_os) + bone_positions[index.w]) * bone_weight.w;
vec3 normal_animated = (invQuatTransform( bone_rotations[index.x], normal_os.xyz)) * bone_weight.x;
normal_animated += (invQuatTransform( bone_rotations[index.y], normal_os.xyz)) * bone_weight.y;
normal_animated += (invQuatTransform( bone_rotations[index.z], normal_os.xyz)) * bone_weight.z;
normal_animated += (invQuatTransform( bone_rotations[index.w], normal_os.xyz)) * bone_weight.w;

This topic is closed to new replies.

Advertisement