Matrix33 invmat;
m_Joints[x].m_Relative = Matrix33::BuildRotationMatrix(m_Joints[x].m_Rotation.x,
m_Joints[x].m_Rotation.y, m_Joints[x].m_Rotation.z);
invmat = Matrix33::BuildRotationMatrix(-m_Joints[x].m_Rotation.x,
-m_Joints[x].m_Rotation.y, -m_Joints[x].m_Rotation.z);
if(m_Joints[x].m_ParentJoint != -1)
{
m_Joints[x].m_Absolute = m_Joints[m_Joints[x].m_ParentJoint].m_Absolute * m_Joints[x].m_Relative;
m_Joints[x].m_AbsoluteInverse = m_Joints[m_Joints[x].m_ParentJoint].m_AbsoluteInverse * invmat;
m_Joints[x].m_AbsoluteTranslation = m_Joints[m_Joints[x].m_ParentJoint].m_AbsoluteTranslation + m_Joints[x].m_Translation;
}
else //i have no daddy
{
m_Joints[x].m_Absolute = m_Joints[x].m_Relative;
m_Joints[x].m_AbsoluteInverse = invmat;
m_Joints[x].m_AbsoluteTranslation = m_Joints[x].m_Translation;
}
//transfor joint's vertices back to origin so we don't have to do it each frame
for(uint i=0; i<m_Joints[x].m_NumVertices; ++i)
{
Vertex& vert = m_Vertices[m_Joints[x].m_Vertices];
vert.SetCoordinates(vert.GetCoordinates() - m_Joints[x].m_AbsoluteTranslation);
vert.SetCoordinates(vert.GetCoordinates()*(m_Joints[x].m_AbsoluteInverse));
//also need to transform normals
vert.SetNormal(vert.GetNormal()*(m_Joints[x].m_AbsoluteInverse));
}
for(uint x=0; x<m_NumJoints; ++x)
{
Vector3 trans; Quaternion rot;
while(m_Joints[x].m_RotationKeyframes[m_Joints[x].m_CurRotKeyframe].m_Time < m_CurTime &&
m_Joints[x].m_CurRotKeyframe <= m_Joints[x].m_NumRotationKeyframes)
++m_Joints[x].m_CurRotKeyframe;
if(m_Joints[x].m_CurRotKeyframe == 0)
rot = Quaternion::BuildFromEulerAngles(m_Joints[x].m_RotationKeyframes[0].m_Data);
else if(m_Joints[x].m_CurRotKeyframe >= m_Joints[x].m_NumRotationKeyframes)
rot = Quaternion::BuildFromEulerAngles(m_Joints[x].m_RotationKeyframes[m_Joints[x].m_NumRotationKeyframes-1].m_Data);
else
{
ModelKeyframe& prevFrame = m_Joints[x].m_RotationKeyframes[m_Joints[x].m_CurRotKeyframe-1];
ModelKeyframe& curFrame = m_Joints[x].m_RotationKeyframes[m_Joints[x].m_CurRotKeyframe];
//need to interpolate values
float interpolation = (float)(m_CurTime - prevFrame.m_Time) /
(curFrame.m_Time - prevFrame.m_Time);
Quaternion prev = Quaternion::BuildFromEulerAngles(prevFrame.m_Data);
Quaternion cur = Quaternion::BuildFromEulerAngles(curFrame.m_Data);
rot = Quaternion::Slerp(prev, cur, interpolation);
}
//find translation
while(m_Joints[x].m_TranslationKeyframes[m_Joints[x].m_CurTransKeyframe].m_Time < m_CurTime &&
m_Joints[x].m_CurTransKeyframe <= m_Joints[x].m_NumTranslationKeyframes)
++m_Joints[x].m_CurTransKeyframe;
if(m_Joints[x].m_CurTransKeyframe == 0)
trans = m_Joints[x].m_TranslationKeyframes[0].m_Data;
else if(m_Joints[x].m_CurTransKeyframe >= m_Joints[x].m_NumRotationKeyframes)
trans = m_Joints[x].m_TranslationKeyframes[m_Joints[x].m_NumTranslationKeyframes-1].m_Data;
else
{
ModelKeyframe& prevFrame = m_Joints[x].m_TranslationKeyframes[m_Joints[x].m_CurTransKeyframe-1];
ModelKeyframe& curFrame = m_Joints[x].m_TranslationKeyframes[m_Joints[x].m_CurTransKeyframe];
//need to interpolate values
float interpolation = (float)(m_CurTime - prevFrame.m_Time) /
(curFrame.m_Time - prevFrame.m_Time);
trans = prevFrame.m_Data;
trans += (curFrame.m_Data - prevFrame.m_Data) * interpolation;
}
//create final mat and transform to use when moving verts
m_Joints[x].m_FinalMat = m_Joints[x].m_Relative * rot.BuildRotationMatrix();
m_Joints[x].m_FinalTransformation = m_Joints[x].m_Translation + trans;
//now we need to use our parent ro make the final absolute instead of relative
if(m_Joints[x].m_ParentJoint != -1)
{
m_Joints[x].m_FinalMat = m_Joints[m_Joints[x].m_ParentJoint].m_FinalMat * m_Joints[x].m_FinalMat;
m_Joints[x].m_FinalTransformation = m_Joints[m_Joints[x].m_ParentJoint].m_FinalTransformation + m_Joints[x].m_FinalTransformation;
}
//transformify the vertices
for(uint i=0; i<m_Joints[x].m_NumVertices; ++i)
{
uint vert = m_Joints[x].m_Vertices;
m_TransformedVerts[vert].SetCoordinates((m_Vertices[vert].GetCoordinates()
* m_Joints[x].m_FinalMat) + m_Joints[x].m_FinalTransformation);
m_TransformedVerts[vert].SetNormal(m_Vertices[vert].GetNormal() * m_Joints[x].m_FinalMat);
//all other parts of transformed verts must have been set during initialization
}
}