Axis to Angles

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 28, 2005 at 17:13

Do you excuse my slowness, but is there a formula that converts the axis euler in the classical angles [[PITCH] [YAW] [ROLL]] ? :sad:

Do you know which the correct sequence of rotation is?
That is, RX RY RZ or RZ RX RY? :rolleyes:

thanks!

27 Replies

Please log in or register to post a reply.

F7a4a748ecf664f189bb704a660b3573
0
anubis 101 Jun 28, 2005 at 19:39

first question : why do you need to get that information ?

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 28, 2005 at 20:14

@anubis

first question : why do you need to get that information ? [snapback]18450[/snapback]

I have need to know how they rotate some polygons of a model in physical way, not from matrix or from glRotatef () of opengl, in this way that I can update, in base to the rotated vertexes, the new normal, tangent and binormal, which are passed then to the shaders arb.
For the surfaces of the bsp, I don’t have to do this, but for the models and sub-models unfortunately I don’t see (I don’t know) other solution (this always in base to my scarce knowledge). :blush:

F7a4a748ecf664f189bb704a660b3573
0
anubis 101 Jun 28, 2005 at 21:47

this sounds fishy to me… extracting angles from matrices is a pretty unusual operation. anyway…i’d figure you should be able to get the rotation angles bye using the atan2 function.

you should basically get your angles like this :

pitch = asin(m21)
head = atan2(-m20, m22)
roll = atan2(-m01, m11)

something along those lines anyway… i might be completely wrong. it’s almost 1 am, which is kind of the wrong time to get my head around math problems :)

edit : i think this is actually right now

F7a4a748ecf664f189bb704a660b3573
0
anubis 101 Jun 28, 2005 at 22:05

unregardless of the correctnes getting these angles from a matrix is error prone… gimbal lock… jadajada

F7a4a748ecf664f189bb704a660b3573
0
anubis 101 Jun 28, 2005 at 22:08

oh yeah… and i assume rotation order is x y z

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 28, 2005 at 22:13

this is the matrix where the 3 axis and the translation are set.

obj_m[0] = e->axis[0][0];
obj_m[1] = e->axis[0][1];
obj_m[2] = e->axis[0][2];
obj_m[4] = e->axis[1][0];
obj_m[5] = e->axis[1][1];
obj_m[6] = e->axis[1][2];
obj_m[8] = e->axis[2][0];
obj_m[9] = e->axis[2][1];
obj_m[10] = e->axis[2][2];
obj_m[3] = 0;
obj_m[7] = 0;
obj_m[11] = 0;
obj_m[12] = e->origin[0];
obj_m[13] = e->origin[1];
obj_m[14] = e->origin[2];
obj_m[15] = 1.0;

Which can it be, in explicit way, the formula for to reconstruct the angles PITCH YAW ROLL ?

F7a4a748ecf664f189bb704a660b3573
0
anubis 101 Jun 28, 2005 at 22:15

i modified the thing for you so the names are more meaningful :)

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 28, 2005 at 22:17

once that I get the pitch,yaw,roll I can rotate the polygons in this way:

 _RotateX(inVertsArray[i], vout, DEG2RAD(aout[ROLL]));
 VectorCopy(vout, inVertsArray[i]);
 _RotateY(inVertsArray[i], vout, DEG2RAD(aout[PITCH]));
 VectorCopy(vout, inVertsArray[i]);
 _RotateZ(inVertsArray[i], vout, DEG2RAD(aout[YAW]));
 VectorCopy(vout, inVertsArray[i]);

inline void _RotateX(vec3_t pin, float *pout, float angle)
{
    pout[0] = pin[0];
    pout[1] = (sin(angle)*pin[1]) + (cos(angle)*pin[2]);
    pout[2] = (cos(angle)*pin[1]) - (sin(angle)*pin[2]);
}
inline void _RotateY(vec3_t pin, float *pout, float angle)
{
    pout[0] = (sin(angle)*pin[0]) + (cos(angle)*pin[2]);
    pout[1] = pin[1];
    pout[2] = (cos(angle)*pin[0]) - (sin(angle)*pin[2]);
}
inline void _RotateZ(vec3_t pin, float *pout, float angle)
{
    pout[0] = (cos(angle)*pin[0]) - (sin(angle)*pin[1]);
    pout[1] = (sin(angle)*pin[0]) + (cos(angle)*pin[1]);
    pout[2] = pin[2];
}
80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 28, 2005 at 22:51

Gulp! asin2 () I don’t find it! :blush:

065f0635a4c94d685583c20132a4559d
0
Ed_Mack 101 Jun 29, 2005 at 05:11

<cmath> has the following defined:

 asin(float __x);
 asin(long double __x);
F7a4a748ecf664f189bb704a660b3573
0
anubis 101 Jun 29, 2005 at 05:36

corrected…

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 29, 2005 at 06:56

:sad:
if I rotate with head in this way:

head = atan2(-axis[1][0], axis[1][1]);
...
...
 _RotateZ(inVertsArray[i], vout, head);
 VectorCopy(vout, inVertsArray[i]);

it works, but as soon as I put the others (I have tried different order of rotation) the gimbal lock happens… :dry:

I am desperate and discouraged, I don’t know more than thing to do.
I have also tried this function, taken by the sdk of rtcw, but….

void AxisToAngles( vec3_t axis[3], vec3_t angles ) {
    vec3_t right, roll_angles, tvec;

    // first get the pitch and yaw from the forward vector
    VecToAngles( axis[0], angles );

    // now get the roll from the right vector
    VectorCopy( axis[1], right );
    // get the angle difference between the tmpAxis[2] and axis[2] after they have been reverse-rotated
    RotatePointAroundVector( tvec, axis_identity[2], right, -angles[YAW] );
    RotatePointAroundVector( right, axis_identity[1], tvec, -angles[PITCH] );
    // now find the angles, the PITCH is effectively our ROLL
    VecToAngles( right, roll_angles );
    roll_angles[PITCH] = AngleNormalize180( roll_angles[PITCH] );
    // if the yaw is more than 90 degrees difference, we should adjust the pitch
    if (DotProduct( right, axis_identity[1] ) < 0) {
 if (roll_angles[PITCH] < 0)
    roll_angles[PITCH] = -90 + (-90 - roll_angles[PITCH]);
 else
    roll_angles[PITCH] = 90 + ( 90 - roll_angles[PITCH]);
    }

    angles[ROLL] = -roll_angles[PITCH];
}

… I don’t know if it is correct… :sad:

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 29, 2005 at 07:23

pitch = 0 :cool: no problem

arbpitch0.jpg

pitch over 44.99 :sad: problem
arbpitch1.jpg

pitch over -45.00 :rolleyes: no problem
arbpitch2.jpg

head = -(float)( (atan2(e->axis[1][0], e->axis[1][1])) );
pitch = (float)(atan2(e->axis[2][2]+e->axis[1][2], e->axis[0][2]));
roll = (float)(atan2(e->axis[2][2]+e->axis[0][2], e->axis[1][2]));

 for( i = 0; i < mesh->numverts; i++) {

 _RotateX(inVertsArray[i], vout, roll);
 VectorCopy(vout, inVertsArray[i]);
 _RotateY(inVertsArray[i], vout, pitch);
 VectorCopy(vout, inVertsArray[i]);
 _RotateZ(inVertsArray[i], vout, head);
 VectorCopy(vout, inVertsArray[i]);
 ...
 ...

as you see, the problem is in the pitch down over the 45 degrees. :sad:

…besides if I change order of rotation, gimbal lock appears :blink:

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 29, 2005 at 17:27

@anubis

unregardless of the correctnes getting these angles from a matrix is error prone… gimbal lock… jadajada [snapback]18456[/snapback]

I have spoken of matrix, but it is not necessary nevertheless.

Considering that I have:
axis[0] = vector FORWARD
axis[1] = vector RIGHT
axis[2] = vector UP

which would the formula be for extracting pitch, yaw, roll?

I have tried of everything, but I don’t know whether to reach the solution.
Help me. :unsure:

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jun 29, 2005 at 19:00

If you have normal, tangent, binormal vectors defined in local coordinates, you can just apply the same rotation matrix to them that you apply to the vertices of the model.

If in local coordinates the model faces +X, with +Y to its left and +Z up, and you have the desired forward, right, up vectors in world coordinates, then you can easily compute the rotation matrix:

[ fwd.x, -right.x, up.x ]
R = [ fwd.y, -right.y, up.y ]
  [ fwd.z, -right.z, up.z ]

If the local coordinates have the model facing +Y, with +X to the right and +Z up, then it is:

[ right.x, fwd.x, up.x ]
R = [ right.y, fwd.y, up.y ]
  [ right.z, fwd.z, up.z ]

This matrix will transform your normals/tangents/binormals into world space. There is no trigonometry needed.

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 29, 2005 at 20:05

Using an animate model, I calculate to every frame (animation) the TBN, putting them in relative arrays.
Every frame can involve translation or rotation of the polygons of the model.
Once that me performed the lerping between the old frame and the new one, rotates and I moves the model with this function:

void R_RotateForEntity( entity_t *e )
{
    mat4x4_t obj_m;

    if ( e->scale != 1.0f && e->model && (e->model->type == mod_brush) ) {
 obj_m[0] = e->axis[0][0] * e->scale;
 obj_m[1] = e->axis[0][1] * e->scale;
 obj_m[2] = e->axis[0][2] * e->scale;
 obj_m[4] = e->axis[1][0] * e->scale;
 obj_m[5] = e->axis[1][1] * e->scale;
 obj_m[6] = e->axis[1][2] * e->scale;
 obj_m[8] = e->axis[2][0] * e->scale;
 obj_m[9] = e->axis[2][1] * e->scale;
 obj_m[10] = e->axis[2][2] * e->scale;
    }
 else { // model
 obj_m[0] = e->axis[0][0];
 obj_m[1] = e->axis[0][1];
 obj_m[2] = e->axis[0][2];
 obj_m[4] = e->axis[1][0];
 obj_m[5] = e->axis[1][1];
 obj_m[6] = e->axis[1][2];
 obj_m[8] = e->axis[2][0];
 obj_m[9] = e->axis[2][1];
 obj_m[10] = e->axis[2][2];
    }

    obj_m[3] = 0;
    obj_m[7] = 0;
    obj_m[11] = 0;
    obj_m[12] = e->origin[0];
    obj_m[13] = e->origin[1];
    obj_m[14] = e->origin[2];
    obj_m[15] = 1.0;

    Matrix4_MultiplyFast( r_worldview_matrix, obj_m, r_modelview_matrix );

    qglLoadMatrixf( r_modelview_matrix );
}

The problem is that to the shaders the rotated vertexes arrive and correctly moved only, while for TBN it is everything confused, the light is not correct on the models.
While if I do as I have said above (you see images), the light correctly works, but I has the problem to perform the correct rotation as if it was done from matrix or from glrotatef.

Using the system that you recommend me, as do I do?

You excuse if I am pedantic…. :sad:

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jun 29, 2005 at 21:07

It looks to me as if the rotation matrix you are creating is the transpose of the one you want. Try replacing the e->axis[0][1] with e->axis[1][0], switch the indices on all of them.

Also, does the qglLoadMatrixf function transpose the matrix before sending it to glLoadMatrix? Remember that OpenGL accepts matrices in column-major order (first column, then second column, etc), while they are usually stored in memory in row-major order.

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 29, 2005 at 21:27

The code that I have put is normally that of qfusion and it works… :unsure:

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 29, 2005 at 22:20

OK! Well! I have succeeded there, I had all the formulas that served me to course of hand.
I thank you for your time for me. I have learned that I need of the others to discover little by little myself. Thanks of everything still.

Now touches to the sub-models…. but this is another adventure! :lol:

excuse me for my bad english! :blush:

the code is:

 vec3_t axis[3];

 Matrix_Transpose(e->axis, axis);
 
 for( i = 0; i < mesh->numverts; i++) {
    // Rotation
    Matrix_TransformVector(axis, inVertsArray[i], vout);
    // Translation
    VectorAdd(vout, e->origin, vout);
    // Final result
    VectorCopy(vout, inVertsArray[i]);
 }
 
 R_GetCurrentNormal( mesh->numverts, inVertsArray, mesh->stcoords, mesh->numtris, mesh->indexes);
 R_BuildTangentVectors( mesh->numverts, inVertsArray, mesh->stcoords, mesh->numtris, mesh->indexes, inSVectorsArray, inTVectorsArray );
 ...
 ...

thanks again! :wub:

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 30, 2005 at 06:27

md3q3dm0\_1.jpg
md3q3dm0\_2.jpg

Thanks Anubis & Reedbeta for your support! :lol:

065f0635a4c94d685583c20132a4559d
0
Ed_Mack 101 Jun 30, 2005 at 15:01

Neat - what was the mapping done in?

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 30, 2005 at 16:17

Do you intend to say that map is, or that shader I have used?
Excuse if I don’t understand well the English :blush:

F7a4a748ecf664f189bb704a660b3573
0
anubis 101 Jun 30, 2005 at 17:34

he’s asking for the tool that generated the normal maps… i guess :)

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 30, 2005 at 18:31

Currently use photoshop with the plugin of NVIDIA, but I don’t despise the things done to hand…. (don’t misunderstand me! :lol: )

these are for example done to hand…

without glossmap
senzagloss.jpg

with glossmap
congloss.jpg

065f0635a4c94d685583c20132a4559d
0
Ed_Mack 101 Jun 30, 2005 at 20:17

I mean where did you make the game world i.e., the buildings.

80a58d4b8c82de7ee25c067854fea766
0
mysticman 101 Jun 30, 2005 at 20:48

The map in question is q3dm0 of quake3.
For my maps I use the editor Quark :happy:

065f0635a4c94d685583c20132a4559d
0
Ed_Mack 101 Jul 01, 2005 at 04:14

Ah, cool