Here is the function I made to apply animations to my model (most likely reason I'm having this problem):

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 = ULONG_MAX; 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[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 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 = Ovgl::MatrixRotationQuaternion(¤tRot); } // 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[i]]->matrix; accumulate = animRot2 * (*matrix) * Bone2Parent; Actor::UpdateAnimation( mesh->bones[bone]->childen[i], &accumulate, time ); } }Here is my Slerp function:

Vector4 Slerp( Vector4 q1, Vector4 q2, float t ) { // Quaternion to return. Vector4 qm; // Calculate angle between them. float cosHalfTheta = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z; if (cosHalfTheta < 0) { q2.w = -q2.w; q2.x = -q2.x; q2.y = -q2.y; q2.z = q2.z; cosHalfTheta = -cosHalfTheta; } // if qa=qb or qa=-qb then theta = 0 and we can return qa if (abs(cosHalfTheta) >= 1.0f){ qm.w = q1.w;qm.x = q1.x;qm.y = q1.y;qm.z = q1.z; return qm; } // Calculate temporary values. float halfTheta = acos(cosHalfTheta); float sinHalfTheta = sqrt(1.0f - cosHalfTheta*cosHalfTheta); // if theta = 180 degrees then result is not fully defined // we could rotate around any axis normal to qa or qb if (fabs(sinHalfTheta) < 0.001){ // fabs is floating point absolute qm.w = (q1.w * 0.5f + q2.w * 0.5f); qm.x = (q1.x * 0.5f + q2.x * 0.5f); qm.y = (q1.y * 0.5f + q2.y * 0.5f); qm.z = (q1.z * 0.5f + q2.z * 0.5f); return qm; } float ratioA = sinf((1.0f - t) * halfTheta) / sinHalfTheta; float ratioB = sinf(t * halfTheta) / sinHalfTheta; //calculate Quaternion. qm.w = (q1.w * ratioA + q2.w * ratioB); qm.x = (q1.x * ratioA + q2.x * ratioB); qm.y = (q1.y * ratioA + q2.y * ratioB); qm.z = (q1.z * ratioA + q2.z * ratioB); return qm; }

Here is my quaternion to matrix function:

Matrix44 MatrixRotationQuaternion( Vector4* q ) { Matrix44 out; float xx = q->x * q->x; float xy = q->x * q->y; float xz = q->x * q->z; float xw = q->x * q->w; float yy = q->y * q->y; float yz = q->y * q->z; float yw = q->y * q->w; float zz = q->z * q->z; float zw = q->z * q->w; out._11 = 1 - 2 * ( yy + zz ); out._12 = 2 * ( xy - zw ); out._13 = 2 * ( xz + yw ); out._21 = 2 * ( xy + zw ); out._22 = 1 - 2 * ( xx + zz ); out._23 = 2 * ( yz - xw ); out._31 = 2 * ( xz - yw ); out._32 = 2 * ( yz + xw ); out._33 = 1 - 2 * ( xx + yy ); out._14 = out._24 = out._34 = out._41 = out._42 = out._43 = 0; out._44 = 1; return out; }

Here is the function I use to load the model:

Mesh* MediaLibrary::ImportModel( const std::string& file ) { if(!file.empty()) { Mesh* mesh = new Ovgl::Mesh; // Set media library to this library. mesh->ml = this; // Import scene from file. const aiScene* scene = aiImportFile(file.c_str(), 0); // Iterate through scene nodes. for( uint32_t n = 0; n < scene->mRootNode->mNumChildren; n++) { // Iterate through meshes of this node. for( uint32_t sm = 0; sm < scene->mRootNode->mChildren[n]->mNumMeshes; sm++) { uint32_t voffset = mesh->vertices.size(); uint32_t foffset = mesh->faces.size(); uint32_t aoffset = 0; for( uint32_t i = 0; i < mesh->faces.size(); i++ ) { if( mesh->attributes[i] > aoffset ) { aoffset = mesh->attributes[i]; } } uint32_t m = scene->mRootNode->mChildren[n]->mMeshes[sm]; Matrix44 matrix; if(scene->mMeshes[m]->HasBones()) matrix = Ovgl::MatrixTranspose((Matrix44*)&scene->mRootNode->FindNode(scene->mMeshes[m]->mBones[0]->mName)->mTransformation).Translation(); else matrix = *(Matrix44*)&scene->mRootNode->mChildren[n]->mTransformation.Transpose(); matrix = matrix * MatrixRotationX(1.57f); if(scene->mMeshes[m]->HasBones()) matrix = matrix * Ovgl::MatrixTranspose((Matrix44*)&scene->mMeshes[m]->mBones[0]->mOffsetMatrix).Translation(); std::vector< std::vector< float > > weights(scene->mMeshes[m]->mNumVertices); std::vector< std::vector< float > > indices(scene->mMeshes[m]->mNumVertices); std::vector< Face > faces; std::vector< uint32_t > attributes; mesh->vertices.resize( voffset + scene->mMeshes[m]->mNumVertices); // Get skeleton. if(scene->mMeshes[m]->HasBones()) { for( uint32_t b = 0; b < scene->mMeshes[m]->mNumBones; b++ ) { Bone* bone = new Bone; mesh->bones.push_back(bone); bone->length = 1.0f; bone->mesh = new Mesh; bone->convex = NULL; aiNode* bnode = scene->mRootNode->FindNode(scene->mMeshes[m]->mBones[b]->mName); aiMatrix4x4 GlobalTransform = bnode->mTransformation; aiNode* parent = bnode->mParent; while( parent->mParent != scene->mRootNode ) { GlobalTransform = parent->mTransformation * GlobalTransform; parent = parent->mParent; } bone->matrix = Ovgl::MatrixTranspose((Matrix44*)&GlobalTransform)* MatrixRotationX(1.57f); // Get bone hierarchy. for( uint32_t cb = 0; cb < bnode->mNumChildren; cb++ ) { for( uint32_t mb = 0; mb < scene->mMeshes[m]->mNumBones; mb++ ) { if( bnode->mParent->mName == scene->mMeshes[m]->mBones[mb]->mName ) { bone->parent = mb; } if( bnode->mChildren[cb]->mName == scene->mMeshes[m]->mBones[mb]->mName ) { bone->childen.push_back(mb); } } } for (uint32_t w = 0 ; w < scene->mMeshes[m]->mBones[b]->mNumWeights; w++) { weights[scene->mMeshes[m]->mBones[b]->mWeights[w].mVertexId].push_back((float)scene->mMeshes[m]->mBones[b]->mWeights[w].mWeight); indices[scene->mMeshes[m]->mBones[b]->mWeights[w].mVertexId].push_back((float)b); } // Get animation for this bone. for( uint32_t a = 0; a < scene->mNumAnimations; a++ ) { for( uint32_t ac = 0; ac < scene->mAnimations[a]->mNumChannels; ac++ ) { if(scene->mAnimations[a]->mChannels[ac]->mNodeName == scene->mMeshes[m]->mBones[b]->mName) { for( uint32_t rk = 0; rk < scene->mAnimations[a]->mChannels[ac]->mNumRotationKeys; rk++ ) { scene->mAnimations[a]->mChannels[ac]->mPreState = aiAnimBehaviour_LINEAR; Ovgl::Curve curve; curve.time = scene->mAnimations[a]->mChannels[ac]->mRotationKeys[rk].mTime; curve.value.w = scene->mAnimations[a]->mChannels[ac]->mRotationKeys[rk].mValue.w; curve.value.x = scene->mAnimations[a]->mChannels[ac]->mRotationKeys[rk].mValue.x; curve.value.y = scene->mAnimations[a]->mChannels[ac]->mRotationKeys[rk].mValue.y; curve.value.z = scene->mAnimations[a]->mChannels[ac]->mRotationKeys[rk].mValue.z; mesh->bones[b]->Rot_Keys.push_back( curve ); } } } } } } // Cap off bone influences to no more than 4. for ( uint32_t w = 0; w < scene->mMeshes[m]->mNumVertices; w++) { weights[w].resize(4); indices[w].resize(4); if(!scene->mMeshes[m]->HasBones()) weights[w][0] = 1.0f; } // Get geometry. for( uint32_t f = 0; f < scene->mMeshes[m]->mNumFaces; f++ ) { uint32_t findices[4]; for( uint32_t i = 0; i < scene->mMeshes[m]->mFaces[f].mNumIndices; i++ ) { int vi = scene->mMeshes[m]->mFaces[f].mIndices[i]; Vertex vertex; vertex.position.x = scene->mMeshes[m]->mVertices[vi].x; vertex.position.y = scene->mMeshes[m]->mVertices[vi].y; vertex.position.z = scene->mMeshes[m]->mVertices[vi].z; vertex.position = Vector3Transform(&vertex.position, &matrix); vertex.normal.x = scene->mMeshes[m]->mNormals[vi].x; vertex.normal.y = scene->mMeshes[m]->mNormals[vi].y; vertex.normal.z = scene->mMeshes[m]->mNormals[vi].z; vertex.normal = Vector3Transform(&vertex.normal, &matrix.Rotation()); if(scene->mMeshes[m]->GetNumUVChannels() > 0) { vertex.texture.x = scene->mMeshes[m]->mTextureCoords[0][vi].x; vertex.texture.y = scene->mMeshes[m]->mTextureCoords[0][vi].y; } else { vertex.texture.x = 0.0f; vertex.texture.y = 0.0f; } vertex.weight[0] = weights[vi][0]; vertex.weight[1] = weights[vi][1]; vertex.weight[2] = weights[vi][2]; vertex.weight[3] = weights[vi][3]; vertex.indices[0] = indices[vi][0]; vertex.indices[1] = indices[vi][1]; vertex.indices[2] = indices[vi][2]; vertex.indices[3] = indices[vi][3]; findices[i] = (uint32_t)vi + voffset; mesh->vertices[vi+voffset] = vertex; } if(scene->mMeshes[m]->mFaces[f].mNumIndices == 4) { Face face; face.indices[0] = findices[0]; face.indices[1] = findices[2]; face.indices[2] = findices[3]; mesh->faces.push_back( face ); mesh->attributes.push_back(scene->mMeshes[m]->mMaterialIndex); } Face face; face.indices[0] = findices[0]; face.indices[1] = findices[1]; face.indices[2] = findices[2]; mesh->faces.push_back( face ); mesh->attributes.push_back(scene->mMeshes[m]->mMaterialIndex); } } } // If no bones exist create one. if(mesh->bones.size() == 0 ) { Bone* bone = new Bone; bone->matrix = MatrixIdentity(); bone->length = 1.0f; bone->mesh = new Mesh; bone->convex = NULL; mesh->bones.push_back(bone); } // Save vertices which influence each bone for bone shape automatic generation. for( uint32_t i = 0; i < mesh->bones.size(); i++ ) { for( uint32_t v = 0; v < mesh->vertices.size(); v++ ) { for( uint32_t j = 0; j < 4; j++) { if(mesh->vertices[v].indices[j] == i && mesh->vertices[v].weight[j] > 0.1f) { Vertex Vertex; Vertex.position = Vector3Transform( &mesh->vertices[v].position, &MatrixInverse( &Vector4( 0.0f, 0.0f, 0.0f, 0.0f ), &mesh->bones[i]->matrix)); Vertex.weight[0] = 1.0f; mesh->bones[i]->mesh->vertices.push_back( Vertex ); } } } } // Null index and vertex buffers. mesh->VertexBuffer = 0; mesh->IndexBuffers = 0; // Update video memory copies of index and vertex buffers. mesh->Update(); Meshes.push_back( mesh ); return mesh; } // Function failed so return NULL. return NULL; }

If anyone can help me figure this out they will be my hero!!!