Archived

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

Problem with .ms3d skeletal animation and matrices

This topic is 5658 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

I have been trying to make an implementation of Brett Porters skeletal animation in Direct3D. The problem is that somehow I get the wrong transformation matrices from the keyframes. Here is some code to demonstrate how I have done:
    

// First I create all the relative and absolute matrices of the joints/bones just like Brett do

// Please note that the rotations are in the same order as Brett's

for (i = 0; i < jointCount; i++)
{
	D3DXMATRIX temp;
	D3DXMatrixRotationZ(&joints[i].relative, joints[i].rotation[2]);
	D3DXMatrixRotationY(&temp, joints[i].rotation[1]);
	D3DXMatrixMultiply(&joints[i].relative, &joints[i].relative, &temp);
	D3DXMatrixRotationX(&temp, joints[i].rotation[0]);
	D3DXMatrixMultiply(&joints[i].relative, &joints[i].relative, &temp);

	D3DXMatrixTranslation(&temp, joints[i].position[0], joints[i].position[1], joints[i].position[2]);
	D3DXMatrixMultiply(&joints[i].relative, &joints[i].relative, &temp);

	D3DXMatrixInverse(&joints[i].relative, Null, &joints[i].relative);

	if (joints[i].parentJoint != (Word)-1)
	{
		D3DXMatrixMultiply(&joints[i].absolute, &joints[joints[i].parentJoint].absolute, &joints[i].relative);
	}
	else
		joints[i].absolute = joints[i].relative;

	joints[i].final = joints[i].absolute;
}

// Then I transform all the vertices with the inverse of the absolute matrix

// The normals of the vertices are also transformed and normalized

for (i = 0; i < vertexCount; i++)
{
	if (vertices[i].boneIndex != (Word)-1)
	{
		D3DXMatrixInverse(&invTrans, Null, &joints[vertices[i].boneIndex].absolute);
		D3DXVec3Transform(&trans, &vertices[i].position, &invTrans);			
		vertices[i].position.x = trans.x;
		vertices[i].position.y = trans.y;
		vertices[i].position.z = trans.z;

		D3DXVec3Transform(&trans, &vertices[i].normal, &invTrans);
		vertices[i].normal.x = trans.x;
		vertices[i].normal.y = trans.y;
		vertices[i].normal.z = trans.z;
		D3DXVec3Normalize(&vertices[i].normal, &vertices[i].normal);
	}
}


for (i = 0; i < jointCount; i++)
{
        // I have left out some code here that fills rotVec and transVec (of the type D3DXVECTOR3).

//I am pretty confident that the fault lies somewhere else as it is 

//pretty straight-forward


	D3DXMatrixRotationZ(&transform, rotVec.z);
	D3DXMatrixRotationY(&temp, rotVec.y);
	D3DXMatrixMultiply(&transform, &transform, &temp);
	D3DXMatrixRotationX(&temp, rotVec.x);
	D3DXMatrixMultiply(&transform, &transform, &temp);

	D3DXMatrixTranslation(&temp, transVec.x, transVec.y, transVec.z);
	D3DXMatrixMultiply(&transform, &transform, &temp);

	D3DXMatrixMultiply(&final, &joint.relative, &transform);

	if (joint.parentJoint == (Word) -1)
	{
		joint.final = final;
	}
	else
	{
		D3DXMatrixMultiply(&joint.final, &joints[ joint.parentJoint ].final, &final);
	}	
}


// Lastly I have a vertexbuffer that I fill with the retransformed vertices

// Note that DRUVertexD3D is just a custom FVF-vertex

for (j = 0; j < groups[i].vertexCount; j++)
{
	const Dword & idx = groups[i].indexBuffer[j];
			
	if (vertices[ idx ].boneIndex != (Word) -1)
	{
		const D3DXMATRIX & mat = joints[ vertices[idx].boneIndex ].final;

		DRUVertexD3D & vert = vertex[j];
					
		D3DXVec3Transform(&vec, &vertices[ idx ].position, &mat);
		vert.x = vec.x;
		vert.y = vec.y;
		vert.z = vec.z;

		D3DXVec3Transform(&vec, &vertices[idx].normal, &mat);
					
		vert.nX = vec.x;
		vert.nY = vec.y;
		vert.nZ = vec.z;
				
	}
}
  
These are snippets from the code that perform the various tasks. I am not that good at matrix math, so I think that the problem probably lies in that area... I would be immensely grateful for help as I've been tearing my hair for about a week now. And I'm running out.... :-) [edited by - nyStagmus on June 5, 2002 5:45:29 PM] [edited by - nyStagmus on June 5, 2002 5:47:03 PM]

Share this post


Link to post
Share on other sites
Just to clarify what my actual question is... Why does the model take on very strange shapes as it is supposed to move? (It is not so much movement as morphing..)

Share this post


Link to post
Share on other sites
I sympathize with you Actually, if you''re noticing the mesh deforming strangely while animating, than it''s more than likely you are using different coordinate systems than Milkshape 3D uses. You can''t just swap the coordinates while loading, you have to mirror the bone transformations as well.


Jim Adams
home.att.net/~rpgbook
Author, Programming Role-Playing Games with DirectX

Share this post


Link to post
Share on other sites
I have done some further research on this and I am beginning to believe that I am either somehow doing something wrong with the conversion from right-handed to left-handed or that I am not understanding how the D3DX matrices are supposed to be multiplied. I.e in which order. I have tried oh so many ways to convert the coordinates, but all I get are equally strange, although not the same, shapes. So I still believe that I am doing something wrong with the matrices.

Has someone done ms3d skeletal animation in D3D? Could I take a look at your code to figure out what I am doing wrong?

Share this post


Link to post
Share on other sites