Sign in to follow this  
RobMaddison

Animation

Recommended Posts

RobMaddison    1151
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

Share this post


Link to post
Share on other sites
BornToCode    1185
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.

Share this post


Link to post
Share on other sites
RobMaddison    1151
[quote name='BornToCode' timestamp='1330134818' post='4916410']
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.
[/quote]

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

Share this post


Link to post
Share on other sites
BornToCode    1185
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.

Share this post


Link to post
Share on other sites
Ashaman73    13715
[quote name='RobMaddison' timestamp='1330164048' post='4916460']
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.
[/quote]
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.

Share this post


Link to post
Share on other sites
Ashaman73    13715
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.

Share this post


Link to post
Share on other sites
Ashaman73    13715
Here's the code:
[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);
}
[/CODE]
I use the invQuatTransform to transform the vertices from model space into the final animated object space position:
[CODE]
// 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;
[/CODE]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this