Jump to content
  • Advertisement
Sign in to follow this  
ankhd

Skinned Mesh animation problem Part A

This topic is 3501 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all... Sorry about the two part post but I can't up load the data needed to solve this problem. I am having a problem trying to animate some skinned meshes that where exported by kw-export frome 3ds Max 9. The History... These meshes, Pony Mesh and ninja mesh worked in my old skinning code that was based on the ToyMakers site (www.toymaker.info/) this was using the ID3DXAnimationController to do the animation. they also work with the code from the book intro to 3d game programming with directx 9c(Frank D. Luna) also used the ID3DXAnimationController. but these meshes don't work in the old mesh veiw, but work in the new mesh viewer. so far I can load them and display them with out using animation, But as soon as I try to animate them they get all messed up. Tiny and some other meshes animate with out any problems but they all seem to work in the old mesh veiwer too.??????? I've checked the .X files and the only thing that is different is the following data this may be why they dont work Print out of Pony .X file you will see that there is extra data in the frame member the comment. and also after the TransformationMatrix there is this relative ??? this to may be the problem, whats it mean?????? Q1.What is this ObjectMatrixComment object it looks like some sort of transform



Frame Bip01_L_Finger0 {
 

 FrameTransformMatrix relative {
  0.060009,-0.775715,-0.628224,0.000000,-0.174213,0.611560,-0.771780,0.000000,0.982878,0.155758,-0.098441,0.000000,0.354809,-2.853097,1.463500,1.000000;;
 }

 ObjectMatrixComment object {
  13.020129,-0.000000,-0.000000,0.000000,0.000000,13.020130,0.000000,0.000000,0.000000,0.000000,13.020129,0.000000,0.000015,0.000000,0.000000,1.000000;;
 }
}

Frame Bip01 {
 

 FrameTransformMatrix relative {
  0.071852,-0.991059,0.112423,0.000000,0.997335,0.072817,0.004496,0.000000,-0.012642,0.111800,0.993650,0.000000,-0.254022,0.113471,4.717715,1.000000;;
 }

 ObjectMatrixComment object {
  3.521300,0.000000,0.000000,0.000000,-0.000000,3.521300,-0.000000,0.000000,-0.000000,-0.000000,3.521300,0.000000,-0.000004,0.000000,0.000000,1.000000;;
 }
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////
Tiny has this

Frame Scene_Root {
 

 FrameTransformMatrix {
  1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;
 }

 Frame body {
  

  FrameTransformMatrix {
   1.278853,0.000000,-0.000000,0.000000,0.000000,0.000000,1.123165,0.000000,0.000000,-1.470235,0.000000,0.000000,0.135977,2.027985,133.967667,1.000000;;
  }



[Edited by - ankhd on April 17, 2009 6:40:07 AM]

Share this post


Link to post
Share on other sites
Advertisement
Part B dont know why I cant post the whole thing.




code Im using to setup and animate the meshes(the code comes from the book Advanced Animation with
DirectX(Jim Adams)needed to use this as Directx 10 does not have a Animation class any more....
the code links all bones on all meshes. I don't think the error is in here, because Tiny and some other
mesh's work fine.



void cAnimationCollection::Map(DX10Frame *RootFrame)
{
// Go through each animation set
cAnimationSet *AnimSet = m_AnimationSets;
while(AnimSet != NULL)
{

// Go through each animation object
cAnimation *Anim = AnimSet->m_Animations;
while(Anim != NULL)
{

// Go through all frames and look for match
Anim->m_Bone = RootFrame->Find(Anim->m_Name.c_str());

TCHAR msg[MAX_PATH] = " MAPPING ANIMATION FRAME NAME ->";
strcat_s(msg, MAX_PATH, Anim->m_Bone->Name.c_str());
strcat_s(msg, MAX_PATH, "->");

OutPutDebugText(msg,//the message to display
(TCHAR *)AnimSet->m_Name.c_str(),//the location the message was called Eg. what function
false);//bool Usewindowmsgbox = false);//true if you also want to display it in a messagebox
// Go to next animation object
Anim = Anim->m_Next;
}


/*while(Anim)
{
// Match matrix pointers to frames
UINT NumBones = weights.size();
for(DWORD i=0;i < NumBones; i++)
{

// Get bone name
const char *BoneName = weights.TransformNodeName.c_str();//Weights..TransformNodeName.c_str();//pMesh->pSkinInfo->GetBoneName(i);

// Find matching name in frames
cDX10Frame *pFrame = RootFrame->Find(BoneName);

// Match frame to bone
Anim->m_Bone = pFrame;
}//end all bones

Anim = Anim->m_Next;

}
*/


// Go to next animation set object
AnimSet = AnimSet->m_Next;
}
}




void cAnimationCollection::Update(char *AnimationSetName,
DWORD Time, BOOL Loop)
{
cAnimationSet *AnimSet = m_AnimationSets;

// Look for matching animation set name if used
if(AnimationSetName)
{

// Find matching animation set name
while(AnimSet != NULL)
{

// Break when match found
if(!_stricmp(AnimSet->m_Name.c_str(), AnimationSetName))
break;

// Go to next animation set object
AnimSet = AnimSet->m_Next;
}
}

// Return no set found
if(AnimSet == NULL)
return;

// Bounds time to animation length
if(Time > AnimSet->m_Length)
Time = (Loop==TRUE)?Time%(AnimSet->m_Length+1):AnimSet->m_Length;

// Go through each animation
cAnimation *Anim = AnimSet->m_Animations;
while(Anim)
{

// Only process if it's attached to a bone
if(Anim->m_Bone)
{

// Reset transformation
D3DXMatrixIdentity(&Anim->m_Bone->TransformationMatrix);//THIS ONE LOOK AT THIS IF USED IN buildToRootXForms it screws up my pony and ninja man


//D3DXMATRIX mInvBindPose;

// D3DXMatrixInverse( &mInvBindPose, NULL, &Anim->m_Bone->matOriginal);

//Anim->m_Bone->TransformationMatrix = Anim->m_Bone->matOriginal;//mInvBindPose;

// Apply various matrices to transformation

// Scaling
if(Anim->m_NumScaleKeys && Anim->m_ScaleKeys)
{

// Loop for matching scale key
DWORD Key1 = 0, Key2 = 0;
for(DWORD i=0;i<Anim->m_NumScaleKeys;i++)
{
if(Time >= Anim->m_ScaleKeys.m_Time)
Key1 = i;
}

// Get 2nd key number
Key2 = (Key1>=(Anim->m_NumScaleKeys-1))?Key1:Key1+1;

// Get difference in keys' times
DWORD TimeDiff = Anim->m_ScaleKeys[Key2].m_Time-
Anim->m_ScaleKeys[Key1].m_Time;
if(!TimeDiff)
TimeDiff = 1;

// Calculate a scalar value to use
float Scalar = (float)(Time - Anim->m_ScaleKeys[Key1].m_Time) / (float)TimeDiff;

// Calculate interpolated scale values
D3DXVECTOR3 vecScale = Anim->m_ScaleKeys[Key2].m_vecKey -
Anim->m_ScaleKeys[Key1].m_vecKey;
vecScale *= Scalar;
vecScale += Anim->m_ScaleKeys[Key1].m_vecKey;

// Create scale matrix and combine with transformation
D3DXMATRIX matScale;
D3DXMatrixScaling(&matScale, vecScale.x, vecScale.y, vecScale.z);
Anim->m_Bone->TransformationMatrix *= matScale;
}

// Rotation
if(Anim->m_NumRotationKeys && Anim->m_RotationKeys)
{

// Loop for matching rotation key
DWORD Key1 = 0, Key2 = 0;
for(DWORD i=0;i<Anim->m_NumRotationKeys;i++)
{
if(Time >= Anim->m_RotationKeys.m_Time)
Key1 = i;
}

// Get 2nd key number
Key2 = (Key1>=(Anim->m_NumRotationKeys-1))?Key1:Key1+1;

// Get difference in keys' times
DWORD TimeDiff = Anim->m_RotationKeys[Key2].m_Time-
Anim->m_RotationKeys[Key1].m_Time;
if(!TimeDiff)
TimeDiff = 1;

// Calculate a scalar value to use
float Scalar = (float)(Time - Anim->m_RotationKeys[Key1].m_Time) / (float)TimeDiff;

// slerp rotation values
D3DXQUATERNION quatRotation;
D3DXQuaternionSlerp(&quatRotation,
&Anim->m_RotationKeys[Key1].m_quatKey,
&Anim->m_RotationKeys[Key2].m_quatKey,
Scalar);

// Create rotation matrix and combine with transformation
D3DXMATRIX matRotation;
D3DXMatrixRotationQuaternion(&matRotation, &quatRotation);
Anim->m_Bone->TransformationMatrix *= matRotation;
}

// Translation
if(Anim->m_NumTranslationKeys && Anim->m_TranslationKeys)
{

// Loop for matching translation key
DWORD Key1 = 0, Key2 = 0;
for(DWORD i=0;i<Anim->m_NumTranslationKeys;i++) {
if(Time >= Anim->m_TranslationKeys.m_Time)
Key1 = i;
}

// Get 2nd key number
Key2 = (Key1>=(Anim->m_NumTranslationKeys-1))?Key1:Key1+1;

// Get difference in keys' times
DWORD TimeDiff = Anim->m_TranslationKeys[Key2].m_Time-
Anim->m_TranslationKeys[Key1].m_Time;
if(!TimeDiff)
TimeDiff = 1;

// Calculate a scalar value to use
float Scalar = (float)(Time - Anim->m_TranslationKeys[Key1].m_Time) / (float)TimeDiff;

// Calculate interpolated vector values
D3DXVECTOR3 vecPos = Anim->m_TranslationKeys[Key2].m_vecKey -
Anim->m_TranslationKeys[Key1].m_vecKey;
vecPos *= Scalar;
vecPos += Anim->m_TranslationKeys[Key1].m_vecKey;

// Create translation matrix and combine with transformation
D3DXMATRIX matTranslation;
D3DXMatrixTranslation(&matTranslation, vecPos.x, vecPos.y, vecPos.z);
Anim->m_Bone->TransformationMatrix *= matTranslation;
}

// Matrix
if(Anim->m_NumMatrixKeys && Anim->m_MatrixKeys)
{
// Loop for matching matrix key
DWORD Key1 = 0, Key2 = 0;
for(DWORD i=0;i<Anim->m_NumMatrixKeys;i++)
{
if(Time >= Anim->m_MatrixKeys.m_Time)
Key1 = i;
}

// Get 2nd key number
Key2 = (Key1>=(Anim->m_NumMatrixKeys-1))?Key1:Key1+1;

// Get difference in keys' times
DWORD TimeDiff = Anim->m_MatrixKeys[Key2].m_Time-
Anim->m_MatrixKeys[Key1].m_Time;
if(!TimeDiff)
TimeDiff = 1;

// Calculate a scalar value to use
float Scalar = (float)(Time - Anim->m_MatrixKeys[Key1].m_Time) / (float)TimeDiff;

// Calculate interpolated matrix
D3DXMATRIX matDiff = Anim->m_MatrixKeys[Key2].m_matKey -
Anim->m_MatrixKeys[Key1].m_matKey;
matDiff *= Scalar;
matDiff += Anim->m_MatrixKeys[Key1].m_matKey;

// Combine with transformation
Anim->m_Bone->TransformationMatrix *= matDiff;
}
}

// Go to next animation
Anim = Anim->m_Next;
}
}
























Share this post


Link to post
Share on other sites
And the rest is here



void buildToRootXForms(DX10Frame* frame,
D3DXMATRIX& parentsToRoot)
{
// Save some references to economize line space.
//frame->TransformationMatrix += frame->matOriginal+ frame->TransformationMatrix ;//
D3DXMATRIX& toParent = frame->TransformationMatrix;// parentsToRoot;// + frame->matOriginal ;
D3DXMATRIX& toRoot = frame->matCombined;

toRoot = toParent * parentsToRoot;

DX10Frame* sibling = (DX10Frame*)frame->pFrameSibling;
DX10Frame* firstChild = (DX10Frame*)frame->pFrameFirstChild;

// Recurse down siblings.
if( sibling )
buildToRootXForms(sibling, parentsToRoot);

// Recurse to first child.
if( firstChild )
buildToRootXForms(firstChild, toRoot);
}//end







//updates the mesh to reflect the current bones
HRESULT cDX10Mesh::UpdateMesh(void)
{
//Error checking
if(!m_RootMesh)//m_MeshContainer)
return E_FAIL;
if(!m_RootMesh->pMesh || !m_RootMesh->pSkinMesh || !m_RootMesh->pSkinInfo)
return E_FAIL;

if(!m_RootMesh->pBoneMatrices || !m_RootMesh->ppFrameMatrices)
return E_FAIL;

// Recurse down the tree and generate a frame's toRoot transform from the updated pose.
D3DXMATRIX identity;
D3DXMatrixIdentity(&identity);
buildToRootXForms((DX10Frame*)m_FrameRoot, identity);


UINT mNumBones = m_RootMesh->pSkinInfo->GetNumBones();
// Premultiply the offset-transform to transform the vertices to the bone's local
// coordinate system first, before applying the other transforms.
D3DXMATRIX offsetTemp, toRootTemp;
for(UINT i = 0; i < mNumBones; ++i)
{

//D3DXMATRIX mInvBindPose;

//D3DXMatrixInverse( &mInvBindPose, NULL, m_RootMesh->ppFrameMatrices);
offsetTemp = m_RootMesh->pMatrixOffset;//*mSkinInfo->GetBoneOffsetMatrix(i);
toRootTemp = *m_RootMesh->ppFrameMatrices;//*mToRootXFormPtrs;
m_RootMesh->pBoneMatrices = offsetTemp * toRootTemp;//mFinalXForms = offsetTemp * toRootTemp;
}

return S_OK;

}//end UpdateMesh









Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!