0
\$\begingroup\$

I'm having heavly troubles with setting up a View Matrix and a Projection Matrix. It simply doesnt work. So I think my problem is related to my rotationMatrix function. I'm using this tutorial to learn some basics about Matrix maths.

This method works fine to rotate a object in 3 angles, but I think it have a bug or something like that. So I need your help just to know if this method is doing hes job right, if so, I'll try to rewrite again all my Camera code to see if I made something wrong (I've do this 2 times already).

public static Matrix4 rotationMatrix(float x, float y, float z){
    //Set as Identity Matrix;
    float[] result = {
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f
        };

    /*              
                      Row-Major Matrix
                  ----------------------------
                 |  1       0       0       0 | 
            Rx = |  0       cos(X)  -sin(X) 0 |
                 |  0       sin(X)  cos(X)  0 |
                 |  0       0       0       1 |
                  ----------------------------          
                 |  cos(Y)  0       sin(Y)  0 |
            Ry = |  0       1       0       0 |
                 |  -sin(Y) 0       cos(Y)  0 |
                 |  0       0       0       1 |
                  ----------------------------
                 |  cos(Z)   sin(Z) 0       0 |
            Rz = |  -sin(Z)  cos(Z) 0       0 |
                 |  0        0      1       0 |
                 |  0        0      0       1 |
                  ----------------------------
     */

    float cos, sin;

    if (x != 0.0f){ //If it has a X value, lets compute the Matrix.
        cos = (float) Math.cos(x);
        sin = (float) Math.sin(x);

        result[0] += 1.0f;
        result[5] += cos;
        result[6] -= sin;
        result[9] += sin;
        result[10] += cos;
        result[15] += 1.0f;
    }

    if (y != 0.0f){//If it has a Y value, lets compute the Matrix.
        cos = (float) Math.cos(y);
        sin = (float) Math.sin(y);

        result[0] += cos;
        result[2] += sin;
        result[5] += 1.0f;
        result[8] -= sin;
        result[10] += cos;
        result[15] += 1.0f;
    }

    if (z != 0.0f){//If it has a Z value, lets compute the Matrix.
        cos = (float) Math.cos(z);
        sin = (float) Math.sin(z);

        result[0] += cos;
        result[1] -= sin;
        result[4] += sin;
        result[5] += cos;
        result[10] += 1.0f;
        result[15] += 1.0f;
    }

    return new Matrix4(result);
}

Also I think this rotation Matrix is in row-major (I dont have sure). I send this Matrix to a Vertex Shader and it multiplies by the Vec3 position, so I think if I got any problem, is with this method.

Thanks for reading it!

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

You're adding the three X, Y, Z rotations together. You need to multiply them, instead. Compute three separate matrices using those three formulas, and multiply them together. (Note that you might have to multiply them in reverse order, Z * Y * X - it depends on what convention you want for your Euler angles.)

Also, you have an incorrect negative sign in your Z rotation matrix. Compare against Wikipedia. Also, you're storing your matrices in row-major order, but OpenGL accepts them in column-major order, so you should transpose them.

The matrices shown on Wikipedia are written for using column vectors, i.e. multiplying matrix * vector, not vector * matrix. (Note that this is an entirely separate issue from whether the matrices are stored in row-major or column-major order.) It sounds like matrix * vector is what you're doing, but if not, the matrices should be transposed again.

\$\endgroup\$
2
  • \$\begingroup\$ But how can I setup by hand a Column-Major Matrix? The bellow Matrix is using Column-Major layout? Matrix4 matrixZ = new Matrix4(new float[]{ cos, -sin, 0.0f, 0.0f, sin, cos, 0,0f, 0.0f, 0.0f, 0.0f, 1,0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }); \$\endgroup\$ Commented Jun 17, 2013 at 16:58
  • \$\begingroup\$ That would be a row-major layout of the correct Z-rotation matrix as shown on Wikipedia, since you're writing down the entries left-to-right then top-to-bottom. To make a column-major layout, just transpose it - write down the entries top-to-bottom then left-to-right. \$\endgroup\$ Commented Jun 17, 2013 at 17:38
1
\$\begingroup\$

As Nathan Reed said. Your adding the matrices, when you need to be multiplying them. He also mentions the row/column major issue.

But, for references sake, when multiplyed together you get the matrix:

 cos(y)cos(z)  -cos(x)sin(z) + sin(x)sin(y)cos(z)   sin(x)sin(z) + cos(x)sin(y)cos(z)
 cos(y)sin(z)   cos(x)cos(z) + sin(x)sin(y)sin(z)  -sin(x)cos(z) + cos(x)sin(y)sin(z)
-sin(y)         sin(x)cos(y)                        cos(x)cos(y)

Which should produce what you want in that function. But I would suggjest you instead make 3 functions. rotX(float), rotY(float), and rotZ(float). Since that would give you more control over transformations at little to no cost of performance.

Even better, you could make the rotations form about an arbitrary axis! to do that you use the matrix:

x*x * (cos(t) - 1) + cos(t)    x*y * (cos(t) - 1) + (z*sin(t))  x*z * (cos(t) - 1) - (y*sin(t))
x*y * (cos(t) - 1) - z*sin(t)  y*y * (cos(t) - 1) + cos(t)      y*z * (cos(t) - 1) + (x*sin(t))
x*z * (cos(t) - 1) + y*sin(t)  y*z * (cos(t) - 1) - (x*sin(t))  z*z * (cos(t) - 1) + cos(t)

where t = rotation amount, xyz = 3D rotation axis (3D vector). in a functions that called something like Rotate(float t, float x, float y, float z)

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .