8 Months and I Still Can't Get Skeletal Animation Working! Urg!

Started by
10 comments, last by pressgreen 11 years, 10 months ago

The very first thing that pops into my head is: Have you tried using an existing slerp and quaternion-to-matrix from a library you know works? It could be a good sanity check before trying anything else.


I tried using CML and many different variations of those functions I found online. Also Assimp has a built in slerp function called Interpolate and a quaternion to matrix called simply GetMatrix both of which have the exact same results as my functions.

For example here is my implementation using these built in Assimp functions:


void Actor::UpdateAnimation( int32_t bone, Matrix44* matrix, double time )
{
// Initialize animation rotation matrix.
Matrix44 animRot;
Matrix44 animRot2;
animRot = MatrixIdentity();
animRot2 = MatrixIdentity();

// Get animation rotation.
Curve uCurve;
Curve lCurve;
uCurve.time = 0xffffffffUL;
uCurve.value = Vector4( 0.0f, 0.0f, 0.0f, 0.0f );
lCurve.time = 0;
lCurve.value = Vector4( 0.0f, 0.0f, 0.0f, 0.0f );

// Find one frame that are directly before and one that is directly after the current time.
for( uint32_t i = 0; i < mesh->bones[bone]->Rot_Keys.size(); i++)
{
Curve nCurve = mesh->bones[bone]->Rot_Keys;
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 == 0xffffffffUL)
{
uCurve = lCurve;
}

// Check if we found any frames then interpolate between the two rotations and create a matrix from the quaternion.
if(uCurve.time > 0)
{
//Vector4 currentRot;
//currentRot = Slerp(lCurve.value, uCurve.value, (float)(time - lCurve.time) / (float)(uCurve.time - lCurve.time) );
//animRot = MatrixRotationQuaternion( currentRot );

Vector4 currentRot;
currentRot = Slerp(lCurve.value, uCurve.value, (float)(time - lCurve.time) / (float)(uCurve.time - lCurve.time) );
aiQuaternion aiCur, aiLow, aiHi;
aiLow.w = lCurve.value.w;
aiLow.x = lCurve.value.x;
aiLow.y = lCurve.value.y;
aiLow.z = lCurve.value.z;
aiHi.w = uCurve.value.w;
aiHi.x = uCurve.value.x;
aiHi.y = uCurve.value.y;
aiHi.z = uCurve.value.z;
aiCur.Interpolate( aiCur, aiLow, aiHi, (float)(time - lCurve.time) / (float)(uCurve.time - lCurve.time) );
aiMatrix3x3 aiMat;
aiMat = aiCur.GetMatrix();
animRot._11 = aiMat.a1;
animRot._12 = aiMat.a2;
animRot._13 = aiMat.a3;
animRot._14 = 0.0f;
animRot._21 = aiMat.b1;
animRot._22 = aiMat.b2;
animRot._23 = aiMat.b3;
animRot._24 = 0.0f;
animRot._31 = aiMat.c1;
animRot._32 = aiMat.c2;
animRot._33 = aiMat.c3;
animRot._34 = 0.0f;
animRot._41 = 0.0f;
animRot._42 = 0.0f;
animRot._43 = 0.0f;
animRot._44 = 1.0f;
}

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

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

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



The exact same result. I can be almost completely sure that is not the problem.
Advertisement
where you ever able to fix this issue and if so what was causing the problem? going over your code i cant seem to think where the issue would be.
J-GREEN

Greenpanoply
oh did not realize this person was banned never mind blink.png
J-GREEN

Greenpanoply

This topic is closed to new replies.

Advertisement