# Local to World rotation angles.

I’m developing a plugin for an application called Daz Studio (more info here, if you are curious: INFINITO plugin), using QT and OpenGL.

In the plugin glWidget, my object rotates using the local coordinate system. I need to convert those angles into world coordinate system (because the main application opengl viewport expect objects to work that way).

Matrices, math in general is my pet hate, any help greatly appreciated.

Well, a rotation in a local system won’t be (in general) also only a single rotation in the global system. But it will generally be a rotation (with different axis and different angle) plus a translation.

Let’s say M is the matrix that makes the transformation from the global system to the local system you want.

If you apply a rotation R (as a 4*4 matrix) in the local system, the results of this rotation of a point P in the local system will be:
P’ = R * P.

If you want it in the global system, it will then be
P" = M * R * P

From these results, you can then deduce the 3 axis (3 column-vectors, let’s say v1,v2,v3) and the translation (last column-vector). [note: use the matrix M*R for this]

I think you can then check the angles between v1 and i (1,0,0), v2 and j (0,1,0) and v3 and k (0,0,1). You then have the 3 angles around the 3 axis expressed in the global system, plus the required translation.

It should be doable but I never did that before…

Thank you very much, will try this…

Here is the code I came up with. It still doesn’t work, because the world rotation angles do not produce the same rotation as the local ones.

``````

// build rotation matrix
float A       = cos(xRot);
float B       = sin(xRot);
float C       = cos(yRot);
float D       = sin(yRot);
float E       = cos(zRot);
float F       = sin(zRot);
float AD      =   A * D;
float BD      =   B * D;

matXYZ  =   C * E;
matXYZ  =  -C * F;
matXYZ  =  -D;
matXYZ  = -BD * E + A * F;
matXYZ  =  BD * F + A * E;
matXYZ  =  -B * C;
matXYZ  =  AD * E + B * F;
matXYZ  = -AD * F + B * E;
matXYZ =   A * C;
matXYZ  =  matXYZ = matXYZ = matXYZ = matXYZ = matXYZ = 0;   matXYZ =  1;

float *modelview;
modelview= new float;
glGetFloatv( GL_MODELVIEW_MATRIX, modelview );  // Get the current MODELVIEW matrix from OpenGL

float *worldRotMatrix;
worldRotMatrix=new float;
worldRotMatrix=matrixMultiply(modelview,matXYZ); // this should be the final rotation matrix, in world space

angle_y = -asin( worldRotMatrix); /* Calculate Y-axis angle */
float C = cos( angle_y );
if ( fabs( C ) > 0.005 ) /* Gimball lock? */
{
tr_x = worldRotMatrix / C; /* No, so get X-axis angle */
tr_y = -worldRotMatrix / C;
angle_x = atan2( tr_y, tr_x ) ;
tr_x = worldRotMatrix / C; /* Get Z-axis angle */
tr_y = -worldRotMatrix / 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; /* And calculate Z-axis angle */
tr_y = worldRotMatrix;
angle_z = atan2( tr_y, tr_x ) ;
}

``````
``````
float* matrixMultiply(float* m1, float* m2)
{
float *finalMat;
finalMat=new float;
matrixIdentity(finalMat);

// Fisrt Column
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;

// Second Column
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;

// Third Column
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;

// Fourth Column
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;
finalMat = m1*m2 + m1*m2 + m1*m2 + m1*m2;

return finalMat;
}

``````

Maybe I should have given more info about what I’m trying to accomplish, I’ve the feeling I’ve created a chaotic thread and instead of posting/asking code I should have explained more in detail what I need 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…

Arts, when you write M, you mean I should do the following?

``````float *M;
M= new float;
glGetFloatv( GL_MODELVIEW_MATRIX, M ); 	// Get the current MODELVIEW matrix from OpenGL
``````

Thanks

It was just mathematics. Don’t forget that when you set your view with gluLookAt or with other means, this transforms the modelview matrix too.

I’m totally confused.
What drives me crazy is that I’m so dumb to figure out what it seems to be such an easy problem.
I mean, let’s forget opengl for a moment.

I have an object rotated in local space as follows:

pitch=45, yaw=30, roll=15

Given that world axis are [1,0,0] [0,1,0] [0,0,1]

Now, let’s calculate world angles out of it… what is the math beyond it?

If M is the matrix that transforms from world space to your local space (translation + rotation + scaling for example), and you have the matrix R that does your rotation in this local space, then the matrix M*R makes the both transformations at once. Let’s call this matrix A.

A is then in the form:

``````
a0  a1  a2  a3
a4  a5  a6  a7
a8  a9  a10 a11
0   0   0   1

``````

Generally, the last line is (0,0,0,1).

Then, the vectors v0 (a0, a4, a8), v1 (a1, a5, a9) and v2 (a2, a6 and a10) are the eigenvectors of this matrix, which means they represent the 3 axis vectors of the local system.

It then seems to be possible to extract the angles (see http://www.codeguru.com/forum/archive/index.php/t-329530.html for example). It’s different from what I guessed however.

Thinking a bit about your topic, I’d like to add: if the rotation center in the local space is the same than the object’s space center, then you don’t need math at all. In this way, what you have to do is simply use the ‘local-space’ angles as world-space angles and rotate objects before translating them into their position.