Archived

This topic is now archived and is closed to further replies.

Jo

I need a fresh pair of eyes on this...

Recommended Posts

I've been looking at this code so long I can't even see it anymore. Something's wrong, and I'll be jiggered if I know where it is. Any thoughts? It's some pretty basic code for creating the matrices for skeletal animation (exported from Milkshape). The inverse base matrices are created...
void Bone::BuildInvBaseMat()
{
	if ( m_bDone == *m_bDoneVal )
		return;

	D3DXMatrixRotationQuaternion( &m_RelativeMat, &m_BaseRot );
	m_RelativeMat._41 = m_BasePos.x; m_RelativeMat._42 = m_BasePos.y; m_RelativeMat._43 = m_BasePos.z;

	if ( m_pParent )
	{
		m_pParent->BuildInvBaseMat();
		D3DXMatrixMultiply( &m_FinalMat, &m_pParent->m_FinalMat, &m_RelativeMat );
	}
	else
		memcpy( &m_FinalMat, &m_RelativeMat, sizeof( D3DXMATRIX ) );

	memcpy( &m_InvBaseMat, &m_FinalMat, sizeof( D3DXMATRIX ) );
	D3DXMatrixInverse( &m_InvBaseMat, NULL, &m_InvBaseMat );
	m_bDone = *m_bDoneVal;
}
 
The other bone matrices are created (without keyframe info (yet)...
void Bone::AnimateBone( int iFrame, int iAnimID )
{
	// Has this bone already been calculated?

	if ( m_bDone == *m_bDoneVal )
		return;

/*	D3DXVECTOR3			Pos;
	D3DXQUATERNION		Rot;
	D3DXMATRIX			KeyMat, Mat;

	m_Anims.GetAt( iAnimID )->LerpPos( iFrame, &Pos );
	m_Anims.GetAt( iAnimID )->SlerpRot( iFrame, &Rot );
	D3DXMatrixRotationQuaternion( &KeyMat, &Rot );
	KeyMat._41 = Pos.x; KeyMat._42 = Pos.y; KeyMat._43 = Pos.z;*/

	if ( m_pParent )
	{
		m_pParent->AnimateBone( iFrame, iAnimID );
		D3DXMatrixMultiply( &m_WorldMat, &m_pParent->m_WorldMat, &m_RelativeMat );
	}
	else
		memcpy( &m_WorldMat, &m_RelativeMat, sizeof( D3DXMATRIX ) );

	D3DXMatrixMultiply( &m_FinalMat, &m_InvBaseMat, &m_WorldMat );
	m_bDone = *m_bDoneVal;
}
 
And the skeleton is drawn using this method to grab the bone positions...
void Bone::GetPos_World( D3DXVECTOR3 *pVec )
{
	pVec->x = 0.0f;
	pVec->y = 0.0f;
	pVec->z = 0.0f;
	D3DXVec3TransformCoord( pVec, pVec, &m_WorldMat );
}
 
HELP! The first person to save my weary butt gets to go straight to heaven. [edited by - Jo on April 21, 2004 6:10:12 PM]

Share this post


Link to post
Share on other sites
Logic, the very best kind of error in the whole wide world.

The skeleton is being drawn, but as far as I can tell the rotations are just way off. Oddly enough when I pre-multiply the parent''s world matrix with the relative matrix instead of post-multiplying it things straighten out, although it''s still wrong. Plus I know the matrix should be post-multiplied.

I''m totally stumped.

Share this post


Link to post
Share on other sites
I believe that the problem is with the order in which you multiply your local matrix from the bone to your world matrix from the bone''s parent. In forward kinematics, W = L x parentW but not the other way around. Remember that matrix multiplication is order-dependent.

Try changing D3DXMatrixMultiply(&m_FinalMat, &m_pParent->m_FinalMat, &m_RelativeMat ); to D3DXMatrixMultiply(&m_FinalMat, &m_RelativeMat, &m_pParent->m_FinalMat);
and see if it works.

I think it should help.

Share this post


Link to post
Share on other sites
Hey thanks for the reply! Thankfully I managed to figure it out on my own about three seconds before I tore my hair out by the roots. As it turns out I "solved" the problem hours ago, but due to my near clipping plane being closer than I thought it was, I misinterpreted the clipped skeleton as just another wrong turn.

Que sera sera.

Share this post


Link to post
Share on other sites