OpenGL world to local rotations

This topic is 2928 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

In opengl I rotate objects in world space:

glRotatef(myObject.zRot, 0, 0, 1);
glRotatef(myObject.xRot, 1, 0, 0);
glRotatef(myObject.yRot, 0, 1, 0);

There is a way to find the object local angles of rotation?

Share on other sites

In opengl I rotate objects in world space:

glRotatef(myObject.zRot, 0, 0, 1);
glRotatef(myObject.xRot, 1, 0, 0);
glRotatef(myObject.yRot, 0, 1, 0);

There is a way to find the object local angles of rotation?

Look into quaternions. You can use that rotation matrix to extract a quat and then get eular angles (xyz).
There is a quaternion lib in my library.
There is also a function for extracting angles directly from a rotation matrix.

Share on other sites

In opengl I rotate objects in world space:

glRotatef(myObject.zRot, 0, 0, 1);
glRotatef(myObject.xRot, 1, 0, 0);
glRotatef(myObject.yRot, 0, 1, 0);

OpenGL does not work in world space. IF your modelview was still identity, the very first rotation will happen to in world space, but only because local and global are still the same. Every rotation after that is using the local coordinate system resulting from your previous transformations. If you want to use global coordinates, you have to change the order of the matrix multiplication (ie. do it manually, because OpenGL will always do modelview = rotationMatrix * modelview, when what you want is modelview = modelview * rotationMatrix; ).

Share on other sites

[quote name='Alessandro' timestamp='1318032168' post='4870317']
In opengl I rotate objects in world space:

glRotatef(myObject.zRot, 0, 0, 1);
glRotatef(myObject.xRot, 1, 0, 0);
glRotatef(myObject.yRot, 0, 1, 0);

OpenGL does not work in world space. IF your modelview was still identity, the very first rotation will happen to in world space, but only because local and global are still the same. Every rotation after that is using the local coordinate system resulting from your previous transformations. If you want to use global coordinates, you have to change the order of the matrix multiplication (ie. do it manually, because OpenGL will always do modelview = rotationMatrix * modelview, when what you want is modelview = modelview * rotationMatrix; ).
[/quote]

Sorry for the confusion. Yes opengl works in local space. I do have a quaternion library but I don't know the math of how would I go from local angles to world space, using matrices. Any chance to have some pseudo-code?

Share on other sites
Here is the code I came up with. I'm still not sure I'm extracting angles correctly from the final step.<br><br>

 float xRot=45.0*DEG_TO_RAD; float yRot=30.0*DEG_TO_RAD; float zRot=22.0*DEG_TO_RAD; // build rotateX matrix matX= new float[16]; matX[5] = cosf(xRot); matX[6] = -sinf(xRot); matX[9] = -matX[6]; matX[10] = matX[5]; // build rotateY matrix matY= new float[16]; matY[0] = cosf(yRot); matY[2] = sinf(yRot); matY[8] = -matY[2]; matY[10] = matY[0]; // build rotateZ matrix matZ= new float[16]; matZ[0] = cosf(zRot); matZ[1] = sinf(zRot); matZ[4] = -matZ[1]; matZ[5] = matZ[0]; matXY=new float[16]; matXYZ=new float[16]; matXY= matrixMultiply(matX, matY); matXYZ=matrixMultiply(matXY, matZ); //calculate final rotation matrix matXYZ float *modelview; modelview= new float[16]; glGetFloatv( GL_MODELVIEW_MATRIX, modelview ); // Get the current MODELVIEW matrix from OpenGL float *worldRotMatrix; worldRotMatrix=new float[16]; worldRotMatrix=matrixMultiply(modelview,matXYZ); // this should be the final rotation matrix, in world space angle_y = -asin( worldRotMatrix[2]); /* Calculate Y-axis angle */ float C = cos( angle_y ); if ( fabs( C ) > 0.005 ) /* Gimball lock? */ { tr_x = worldRotMatrix[10] / C; /* No, so get X-axis angle */ tr_y = -worldRotMatrix[6] / C; angle_x = atan2( tr_y, tr_x ) ; tr_x = worldRotMatrix[0] / C; /* Get Z-axis angle */ tr_y = -worldRotMatrix[1] / C; angle_z = atan2( tr_y, tr_x ) ; } else /* Gimball lock has occurred */ { angle_x = 0; /* Set X-axis angle to zero */ tr_x = worldRotMatrix[5]; /* And calculate Z-axis angle */ tr_y = worldRotMatrix[4]; angle_z = atan2( tr_y, tr_x ) ; } 

Share on other sites
Forgot to show the matrixMultiply function:

 float* matrixMultiply(float* m1, float* m2) { float *finalMat; finalMat=new float[16]; matrixIdentity(finalMat); // Fisrt Column finalMat[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; finalMat[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; finalMat[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; finalMat[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; // Second Column finalMat[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; finalMat[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; finalMat[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; finalMat[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; // Third Column finalMat[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; finalMat[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; finalMat[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; finalMat[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; // Fourth Column finalMat[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; finalMat[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; finalMat[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; finalMat[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15]; return finalMat; } 

Share on other sites
If you understand the dot product and know how to use it to find angles between vectors:

After you do those 3 global rotations you get a matrix that shows the new x,y,z vectors for your object. So by drawing your object with the identity matrix it is probably aligned with the global vectors (right = x, y = top, forward = z or negative z). Those 3 vectors now equal the 3 columns in your matrix after doing global rotations. In otherwords, The identity matrix gives you x,y,z axis, what do they map to now: column0,1,2 of your matrix. So do a dot product between the old x and new x, old y and new y, old z and new z. And you can figure out that but.

I assume that is what you want, but you should be knowing the local rotations (yaw,pitch,roll). I do what you do, I align all models on the z axis, that way I can do z rotation first, and then the x,y rotations are the ones the figure out the heading direction of the object. I think I just dont understand your problem though.

Share on other sites
Sorry, instead of writing code perhaps I had to explain more in detail what I'm trying to do.
I have a simple opengl application where I load and display .obj files. The application allows also to position, scale and rotate those models using the mouse. All those transformations happen in local space.
The application allows to export the above data in a .txt file, with the following scheme:

obj file | xRot | yRot | zRot | xPos | yPos | zPos

Later on, in a separate, commercial application, I read this .txt file and I recreate the scene, loading sequentually the obj's files and applying the transformation values read from the .txt file.
Problem is, that the commercial application perform rotations in world space, while the angles that I "exported" are in local space.

So, what I'm trying to do is to convert those angles from local to world space so that the objects are properly rotated in the commercial application.

I hope I could explain myself better...

Share on other sites
You should be able to use the local xyz rotations to compute what the object would draw like relative to its own Identity/Local space, Then apply the transform that makes the object be a certain way globally. Should be able to just multiply both matrices. That would give you the final matrix it should look like to draw with given the vertex data in local space. With that matrix, you could just dot product all vectors in that matrix (column0,1,2) with the regular world space vectors (1,0,0 0,1,0, 0,0,1) with their new representations column0,1,2 and that would give you the angle that the object is drawing at relative to the regular world axis.

Share on other sites
Thanks dpadam450, so the pseudo-code would look like this:

1) build the object local space matrix
2) get the current MODELVIEW matrix from OpenGL
3) build final matrix multiplying the MODELVIEW by the local space matrix (and I think I arrived at this point in previous code I posted)
4) dot product the vectors defined by columns 0,1,2 of the final matrix, by the corresponding regular world space vectors (1,0,0 0,1,0, 0,0,1)
5) extract euler angles from this last resulting matrix.

Would that work? Any comments also from others?

• Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 9
• 11
• 15
• 21
• 26