Sign in to follow this  
SteveDeFacto

Still trying to get animations working...

Recommended Posts

I've been trying to get my animation system working for the last two months but without any luck. Everything should be right but I just can't get the rotations to move the way they are suppose to. It appears no matter how hard I try I make no progress. What should I do? Are their any tutorials that may help? Book? Anything?

Here is the code though I doubt it will help:


[code]
void Ovgl::Actor::UpdateAnimation( int bone, Ovgl::Matrix44* matrix, DWORD time )
{
// Initialize animation rotation matrix.
Ovgl::Matrix44 animRot;
Ovgl::Matrix44 animRot2;
animRot = Ovgl::MatrixIdentity();
animRot2 = Ovgl::MatrixIdentity();

// Get animation rotation.
float currentRot[3] = {0};
for( unsigned int a = 0; a < 3; a++)
{
Ovgl::Curve uCurve;
Ovgl::Curve lCurve;
uCurve.time = ULONG_MAX;
uCurve.value = 0;
lCurve.time = 0;
lCurve.value = 0;

// Find two frames that are directly before and after the current time.
for( unsigned int i = 0; i < mesh->bones[bone]->Rot_Keys[a].size(); i++)
{
Ovgl::Curve nCurve = mesh->bones[bone]->Rot_Keys[a][i];
if(nCurve.time > lCurve.time && nCurve.time < time )
{
lCurve = nCurve;
}
if(nCurve.time < uCurve.time && nCurve.time > time )
{
uCurve = nCurve;
}
}

// If we can't find an upper curve then just set it to the lower curve.
if(uCurve.time == ULONG_MAX)
{
uCurve = lCurve;
}

// Check if we found any frames then interpolate between the two curves.
if(uCurve.time > 0)
{
currentRot[a] = Ovgl::DegToRad(Ovgl::Lerp(lCurve.value, uCurve.value, (float)time / (float)uCurve.time));
}
}
animRot = Ovgl::MatrixRotationEuler(currentRot[0], currentRot[2], currentRot[3]);

// Offset the center of rotation.
animRot2 = Ovgl::MatrixInverse( &Ovgl::Vector4(), &mesh->bones[bone]->matrix.Translation()) * animRot * mesh->bones[bone]->matrix.Translation();

// Get difference from original pose to the animated pose.
matrices[bone] = animRot2 * (*matrix) * Ovgl::MatrixInverse( &Ovgl::Vector4(), &mesh->bones[bone]->matrix);

// Loop through all child bones and update their animations.
for( unsigned int i = 0; i < mesh->bones[bone]->childen.size(); i++)
{
Ovgl::Matrix44 accumulate;
Ovgl::Matrix44 Bone2Parent;
Ovgl::Matrix44 animRot3 = Ovgl::MatrixInverse( &Ovgl::Vector4(), &mesh->bones[mesh->bones[bone]->childen[i]]->matrix.Translation()) * Ovgl::MatrixInverse( &Ovgl::Vector4(),&animRot) * mesh->bones[mesh->bones[bone]->childen[i]]->matrix.Translation();
Bone2Parent = Ovgl::MatrixInverse( &Ovgl::Vector4(), &mesh->bones[bone]->matrix ) * mesh->bones[mesh->bones[bone]->childen[i]]->matrix;
accumulate = animRot3 * animRot2 * (*matrix) * Bone2Parent;
Ovgl::Actor::UpdateAnimation( mesh->bones[bone]->childen[i], &accumulate, time );
}
}[/code]

Share this post


Link to post
Share on other sites
Can I see the code that loads the animations? Specifically the Rot_Keys array(s)

Other things I would suggest:
Make a debug function that draws a skeleton. Just draw coloured lines between the transformed positions of joints. I used this when implementing my own skeletal animation, and it saved a lot of time when I realised the joints were being transformed correctly but the vertices were not.

Share this post


Link to post
Share on other sites
[quote name='hupsilardee' timestamp='1317734411' post='4868972']
Can I see the code that loads the animations? Specifically the Rot_Keys array(s)

Other things I would suggest:
Make a debug function that draws a skeleton. Just draw coloured lines between the transformed positions of joints. I used this when implementing my own skeletal animation, and it saved a lot of time when I realised the joints were being transformed correctly but the vertices were not.
[/quote]

By all means but I don't think I should post the full mesh loading function since it is quite huge. I am using the FBX SDK btw.


[code]
// Get animation curves for this mesh.
if(AnimationStack)
{
for(DWORD bn = 0; bn < BoneNodes.size(); bn++ )
{
mesh->bones[bn]->Rot_Keys.resize(3);
KFbxAnimCurve* lAnimCurve[3];
lAnimCurve[0] = BoneNodes[bn]->LclRotation.GetCurve<KFbxAnimCurve>(lCurrentAnimationLayer, KFCURVENODE_R_X);
lAnimCurve[1] = BoneNodes[bn]->LclRotation.GetCurve<KFbxAnimCurve>(lCurrentAnimationLayer, KFCURVENODE_R_Y);
lAnimCurve[2] = BoneNodes[bn]->LclRotation.GetCurve<KFbxAnimCurve>(lCurrentAnimationLayer, KFCURVENODE_R_Z);
for( DWORD c = 0; c < 3; c++ )
{
if(lAnimCurve[c])
{
for( int k = 0; k < lAnimCurve[c]->KeyGetCount(); k++ )
{
KFbxAnimCurveKey lKey = lAnimCurve[c]->KeyGet(k);
Ovgl::Curve lCurve;
lCurve.time = (DWORD)lKey.GetTime().GetMilliSeconds();
lCurve.value = lKey.GetValue();
mesh->bones[bn]->Rot_Keys[c].push_back(lCurve);
}
}
}
}
}[/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