Matrix concatenation
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
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]
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...
Everything works fine for translation but the rotation part acts really weird...
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:
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 - |
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
Popular Topics
Advertisement