Archived

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

Matrix concatenation

This topic is 4956 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, 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

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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 - |

Share this post


Link to post
Share on other sites