Matrix concatenation

Started by
2 comments, last by ichiban_addict 19 years, 11 months ago
Hi, I''m trying to make a simple program that lets you create a place joints in 3D to create a skeleton and animate it. Allthough I have run into a major road block, When the user moves a parent joint i want all the children joints to move in the same way. For a while I got the translation part working...like if i translated a parent joint by a couple units the children would translate the same way. But I can''t seam to get the rotation portion working, I want it so that if you rotate a joint then the children rotate around that joint the same way. But when I rotate the parent joint all the children just rotate crazily around all over the place, then if i try to translate them, they just rotate all over the place still. The way I''m doing things is...each joint has 3 values for a translation 3 values for rotation a relative matrix absolute matrix(which i don''t really use) and a final matrix. what i do is when the use presses a arrow key, a transform matrix is created with the rotation or translation needed. Then I have to calculate the relative matrices so i simple set the base joint to the 3 rotation and translation values, set a temporary matrix to its absolute matrix, which is the same as the relative. then to get the childs relative matrix I inverse translate and rotate the copies of the childs 3 rotation and translation values by the temporary absolute matrix, then set the temporary matrix to the childs 3 rotation and translation values. then i just concatenate all the matrices i just multiply the selected joints matrix by the transform and then set its child matrix to its final matrix and post multiply by the relative-final matrix...etc etc Does it sound like I am doing this right at all? Heh, sorry if i haven''t explained enough I''ll post my code if i havent. If you guys have any other ways that would work better than mine or have had this same kind of trouble please help me out Thanx
Advertisement
I think you do it that same way as i do, rotate and translate to the joint in a matrix, then rotate again (child joint rotation) and translate again, and so on. I think you'll have to post code as the idea is correct.

EDIT: by the way, funny you are doing exactly the same thing as me at the moment .

[edited by - Tree Penguin on May 20, 2004 1:15:27 PM]
Here''s the main part of the source that does the joint concatenation...

float trans[3];		float rot[3];    	if(g_Trans) {		   			trans[0] = 0.0f;			trans[1] = 0.0f;			trans[2] = 0.0f;						if(wParam == VK_RIGHT) trans[0] = 0.1f;		    if(wParam == VK_LEFT) trans[0] = -0.1f;		    if(wParam == VK_UP) trans[1] = 0.1f;		    if(wParam == VK_DOWN) trans[1] = -0.1f;		    if(wParam == ''S'') trans[2] = 0.1f;		    if(wParam == ''W'') trans[2] = -0.1f;		}		else {			            rot[0] = 0.0f;			rot[1] = 0.0f;			rot[2] = 0.0f;			if(wParam == VK_RIGHT) rot[0] = -0.06f;		    if(wParam == VK_LEFT) rot[0] = 0.06f;		    if(wParam == VK_UP) rot[1] = 0.06f;		    if(wParam == VK_DOWN) rot[1] = -0.06f;		    if(wParam == ''S'') rot[2] = -0.06f;		    if(wParam == ''W'') rot[2] = 0.06f;		}		if(wParam == VK_RIGHT || wParam == VK_LEFT ||		   wParam == VK_UP || wParam == VK_DOWN ||		   wParam == ''S'' || wParam == ''W'' || wParam == VK_RETURN) {              			   			  			   Matrix transform;			   if(g_Trans) transform.SetTranslation(trans);			   if(!g_Trans) transform.SetRotationRads(rot);               			   Matrix abs;                   float r[3];                   float t[3];			   			   for(int i = 0; i < g_numJoints; i++) {			       				   				   r[0] = g_Joints[g_Frame][i].rot[0];				   r[1] = g_Joints[g_Frame][i].rot[1];				   r[2] = g_Joints[g_Frame][i].rot[2];				   t[0] = g_Joints[g_Frame][i].trans[0];				   t[1] = g_Joints[g_Frame][i].trans[1];				   t[2] = g_Joints[g_Frame][i].trans[2];				   if(i == 0) {					   g_Joints[g_Frame][i].rel.SetRotationRads(g_Joints[g_Frame][i].rot);					   g_Joints[g_Frame][i].rel.SetTranslation(g_Joints[g_Frame][i].trans);					   					   abs = g_Joints[g_Frame][i].rel;				   }				   else {					   					  abs.InvRotateVect(r);					  abs.InvTranslateVect(t);					  					  g_Joints[g_Frame][i].rel.SetRotationRads(r);					  g_Joints[g_Frame][i].rel.SetTranslation(t);					  abs.SetRotationRads(g_Joints[g_Frame][i].rot);					  abs.SetTranslation(g_Joints[g_Frame][i].trans);				   }			   			   }               Matrix relfin;			   for(int i = 0; i < g_numJoints; i++) {				   				   relfin = g_Joints[g_Frame][i].rel;				   if(i == g_JointSel) relfin = transform * relfin;				   				   if(g_Joints[g_Frame][i].parent == -1) {                       g_Joints[g_Frame][i].fin = relfin;				   }				   else {				       g_Joints[g_Frame][i].fin = g_Joints[g_Frame][g_Joints[g_Frame][i].parent].fin;				       g_Joints[g_Frame][i].fin = relfin * g_Joints[g_Frame][i].fin;				   }				   GetTrans(g_Joints[g_Frame][i].trans, g_Joints[g_Frame][i].fin);				   GetRot(g_Joints[g_Frame][i].rot, g_Joints[g_Frame][i].fin);				   			   }			   	    }



Everything works fine for translation but the rotation part acts really weird...
not sure if I read you right, but here is a good way to do it:


class Joint{public:	Matrix localMatrix, matrix;	Joint * children;	int numChildren;	Joint * parent;	//how you do this next bit is up to you, this just an example	void setJointRotation(Vector3 position, Vector3 rotation)	{		localMatrix.identity();		localMatrix.translate(position);		localMatrix.rotate(rotation);	}	//this is the major bit of it...	void generateMatrices()	{		if (parent)			return;	//must call this on the root node		Matrix m; // assumed to be identity		generateMatrices(m);	}protected:	void generateMatrices(Matrix prevMatrix)	{		matrix = prevMatrix * localMatrix;		for (int n=0; n<numChildren; n++)			children[n].generateMatrices(matrix);	}}


this isn''t guarenteed to work of course, I just wrote it now, and it''s assuming your matrix class can do a few simple things.

| - My project website - | - email me - |

This topic is closed to new replies.

Advertisement