Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have been given the following Maya camera data:

trans X: 1.542
trans y: 3.319
trans z: -1.821

rot X: 117.882
rot Y: 2.189
rot Z: 154.074

scale X: 1
scale Y: 1
scale Z: 1

What is the formula for converting this to a 4 x 4 transformation matrix?

share|improve this question
add comment

3 Answers

I don't have time currently to give a complete answer here, because it's fairly in-depth and I'm short on time, but the information I do have time to give is too much to fit in a comment, so I'll give what I can, for whatever it's worth.

First of all, it appears that Rot X, Y, and Z are in euler angles (degrees rotated around an axis). It would depend on which way that rotation goes (clockwise or counterclockwise). And it depends if Maya represents the degrees between 0 and 360, or -180 and 180, if it's -180 to 180 then just add 180 to whatever output Maya gives.

You'll need to convert degrees to radians for each of them by multiplying them by PI / 360. Then convert the radians to an euler angle to determine the rotation's fwd, up, and right vector's. The forward will be represented by Z in most coordinate systems, right represented by X, and up represented by Y, although if you're exporting for a different coordinate system this may differ.

Once rotation is represented by three vectors, it becomes the first three columns (or rows in some systems) or your 4x4 matrix.

The 4th column is the position/translation vector.

Depending on the system using the matrix, I believe the entire matrix's diagonal can be used for scale, or sometimes just the Translation's W coordinate.

An identity matrix would look something like below, giving a rotation in which an object's forward is along Z, its right is along X, and its up is along Y, and it's at position (0, 0, 0).

      Rot Rgt   Rot Up    Rot Fwd   Translation

X     1         0         0         0

Y     0         1         0         0

Z     0         0         1         0

W     0         0         0         1
share|improve this answer
1  
You don't need to add 180. Trig functions work just as well with negative angles. :) And in any case, it would be adding 360 to negative angles, not 180 to all angles. Also, what is "convert radians to an Euler angle"? The rotation angles from Maya are Euler angles. –  Nathan Reed May 3 '12 at 4:38
    
@NicFoster, actually all I need to know is the order of matrix concatenation. I have my own 3D rendering system into which I am importing the above raw data. So can I assume it is (ignoring scale) T * Rx * Ry * Rz where T is translation(x,yz) and Rx is rotation about the x-axis? –  dugla May 3 '12 at 13:33
    
I believe the order is dependent upon the engine. I've seen Yaw, Pitch, Roll. I've also seen Pitch, Yaw, Roll, like you just mentioned. –  Nic Foster May 3 '12 at 14:50
add comment

Assuming you know how to construct the individual matrices, I believe the correct order of transformations - going from a node's coordinates to its parent's coordinates - is scale, then rotation in X, Y, Z order, then translation.

Depending on whether your system uses row vectors or column vectors, that will be S * Rx * Ry * Rz * T, or T * Rz * Ry * Rx * S, respectively.

A note on rotation order: Maya doesn't have a concept of "roll", "pitch", or "yaw". It deals with rotations just in terms of axes, and assumes that rotations are always applied in X, Y, Z order. So the natural interpretation would be X = roll, Y = pitch, and Z = yaw.

share|improve this answer
add comment

The matrix I'm using is a row-major matrix used by OpenGL. Here's what it looks like:

[ X1 Y1 Z1 WX ]
[ X2 Y2 Z2 WY ]
[ X3 Y3 Z3 WZ ]
[ TX TY TZ CZ ]

What you have is actually three matrices: a rotation matrix, a scale matrix and a translate matrix. This is because virtually any 4x4 matrix can be broken down to two or more matrices that together form the original matrix. A matrix concatenation looks like this:

mat4x4 m0, m1, m2

m2[X1] = (m1[X1] * m0[X1]) + (m1[Y1] * m0[X2]) + (m1[Z1] * m0[X3]) + (m1[WX] * m0[TX]);
m2[Y1] = (m1[X1] * m0[Y1]) + (m1[Y1] * m0[Y2]) + (m1[Z1] * m0[Y3]) + (m1[WX] * m0[TY]);
m2[Z1] = (m1[X1] * m0[Z1]) + (m1[Y1] * m0[Z2]) + (m1[Z1] * m0[Z3]) + (m1[WX] * m0[TZ]);
m2[WX] = (m1[X1] * m0[WX]) + (m1[Y1] * m0[WY]) + (m1[Z1] * m0[WZ]) + (m1[WX] * m0[CZ]);

m2[X2] = (m1[X2] * m0[X1]) + (m1[Y2] * m0[X2]) + (m1[Z2] * m0[X3]) + (m1[WY] * m0[TX]);
m2[Y2] = (m1[X2] * m0[Y1]) + (m1[Y2] * m0[Y2]) + (m1[Z2] * m0[Y3]) + (m1[WY] * m0[TY]);
m2[Z2] = (m1[X2] * m0[Z1]) + (m1[Y2] * m0[Z2]) + (m1[Z2] * m0[Z3]) + (m1[WY] * m0[TZ]);
m2[WY] = (m1[X2] * m0[WX]) + (m1[Y2] * m0[WY]) + (m1[Z2] * m0[WZ]) + (m1[WY] * m0[CZ]);

m2[X3] = (m1[X3] * m0[X1]) + (m1[Y3] * m0[X2]) + (m1[Z3] * m0[X3]) + (m1[WZ] * m0[TX]);
m2[Y3] = (m1[X3] * m0[Y1]) + (m1[Y3] * m0[Y2]) + (m1[Z3] * m0[Y3]) + (m1[WZ] * m0[TY]);
m2[Z3] = (m1[X3] * m0[Z1]) + (m1[Y3] * m0[Z2]) + (m1[Z3] * m0[Z3]) + (m1[WZ] * m0[TZ]);
m2[WZ] = (m1[X3] * m0[WX]) + (m1[Y3] * m0[WY]) + (m1[Z3] * m0[WZ]) + (m1[WZ] * m0[CZ]);

m2[TX] = (m1[TX] * m0[X1]) + (m1[TY] * m0[X2]) + (m1[TZ] * m0[X3]) + (m1[CZ] * m0[TX]);
m2[TY] = (m1[TX] * m0[Y1]) + (m1[TY] * m0[Y2]) + (m1[TZ] * m0[Y3]) + (m1[CZ] * m0[TY]);
m2[TZ] = (m1[TX] * m0[Z1]) + (m1[TY] * m0[Z2]) + (m1[TZ] * m0[Z3]) + (m1[CZ] * m0[TZ]);
m2[CZ] = (m1[TX] * m0[WX]) + (m1[TY] * m0[WY]) + (m1[TZ] * m0[WZ]) + (m1[CZ] * m0[CZ]);

So let's get down to business. First, we have the scale matrix:

sx = 1.0
sy = 1.0
sz = 1.0

mat4x4 mat_scale =
    [  sx, 0.0, 0.0, 0.0 ]
    [ 0.0,  sy, 0.0, 0.0 ]
    [ 0.0, 0.0,  sz, 0.0 ]
    [ 0.0, 0.0, 0.0, 1.0 ]

The rotational matrix can be further broken down to a matrix on the x-, y- and z-axis.

Rotation over x-axis:

cx = cos(deg_to_rad(117.882))
sx = sin(deg_to_rad(117.882))

mat4x4 mat_x =
    [ 1.0, 0.0, 0.0, 0.0 ]
    [ 0.0,  cx,  sx, 0.0 ]
    [ 0.0, -sx,  cx, 0.0 ]
    [ 0.0, 0.0, 0.0, 1.0 ]

Rotation over y-axis:

cy = cos(deg_to_rad(2.189))
sy = sin(deg_to_rad(2.189))

mat4x4 mat_y =
    [  cy, 0.0, -sy, 0.0 ]
    [ 0.0, 1.0, 0.0, 0.0 ]
    [  sy, 0.0,  cy, 0.0 ]
    [ 0.0, 0.0, 0.0, 1.0 ]

Rotation over z-axis:

cz = cos(deg_to_rad(154.074))
sz = sin(deg_to_rad(154.074))

mat4x4 mat_z =
    [  cz, -sz, 0.0, 0.0 ]
    [  sz,  cz, 0.0, 0.0 ]
    [ 0.0, 0.0, 1.0, 0.0 ]
    [ 0.0, 0.0, 0.0, 1.0 ]

So our final rotation matrix becomes:

mat4x4 mat_rotation = mat_x * mat_y * mat_z;

Finally, the translation matrix:

tx = 1.542
ty = 3.319
tz = -1.821

mat4x4 mat_translation =
    [ 1.0, 0.0, 0.0, 0.0 ]
    [ 0.0, 1.0, 0.0, 0.0 ]
    [ 0.0, 0.0, 1.0, 0.0 ]
    [  tx,  ty,  tz, 1.0 ]

Putting it all together:

mat4x4 mat_transform = mat_scale * mat_rotation * mat_translation;

If you want, you can write out all the concatenations and get a valid matrix. But I believe it's easier to keep it in either separate matrices like I've done or in matrix operations (AddRotationX, Scale, etc.)

share|improve this answer
    
I think you went too far here in terms of low level detail. –  bobobobo Jul 2 '12 at 8:50
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.