Search code examples
c++openglmatrixrotationglm-math

How to correctly write rotation matrices by hand using glm::mat4?


I am writing an OpenGL program, and for that program, I am trying to write some rotation matrices by hand (I know about glm::rotate, but this is for a class, and so I cannot use that function), but it doesn't appear to be working like I am intending.

I am drawing a scene with a parking lot and car with tires drawn separately, and the tires are moving with the camera instead of staying put: car As you can see, the tires are rotated slightly in towards the camera, it looks like.

EDIT: In addition, it seems to skew other objects (that are rotated) when they are drawn:

skewed Notice the highly skewed building.

As far as I understand, this is how rotation matrices are supposed to look:

matrices

And this is what I have done in code (parts about translation and scaling left out for brevity):

//glm::mat4 rotXMatrix = glm::rotate(rotation.x, glm::vec3(1, 0, 0));
glm::mat4 rotXMatrix = glm::mat4(1.0f);
rotXMatrix[1][1] = cos(rotation.x);
rotXMatrix[1][2] = sin(rotation.x);
rotXMatrix[2][1] = -sin(rotation.x);
rotXMatrix[2][2] = cos(rotation.x);
//glm::mat4 rotYMatrix = glm::rotate(rotation.y, glm::vec3(0, 1, 0));
glm::mat4 rotYMatrix = glm::mat4(1.0f);
rotXMatrix[0][0] = cos(rotation.y);
rotXMatrix[0][2] = -sin(rotation.y);
rotXMatrix[2][0] = sin(rotation.y);
rotXMatrix[2][2] = cos(rotation.y);
//glm::mat4 rotZMatrix = glm::rotate(rotation.z, glm::vec3(0, 0, 1));
glm::mat4 rotZMatrix = glm::mat4(1.0f);
rotXMatrix[0][0] = cos(rotation.z);
rotXMatrix[0][1] = sin(rotation.z);
rotXMatrix[1][0] = -sin(rotation.z);
rotXMatrix[1][1] = cos(rotation.z);

glm::mat4 rotMatrix = rotZMatrix * rotYMatrix * rotXMatrix;
return posMatrix * rotMatrix * scaleMatrix;

It works correctly when I don't do it by hand (using glm::rot as shown in the commented out parts, so I'm wondering what I am misunderstanding about the way the rotation matrices are constructed. I am pretty sure that the order of the []'s is correct, because I can hand-construct the matrices for translation and scaling using the same notation, and it correctly scales and moves the objects.

EDIT: Note that these transformation matrices are for the objects, and not the camera.


Solution

  • You are modifying the wrong matrices

    glm::mat4 rotYMatrix = glm::mat4(1.0f);
    rotXMatrix[0][0] = cos(rotation.y);
    rotXMatrix[0][2] = -sin(rotation.y);
    rotXMatrix[2][0] = sin(rotation.y);
    rotXMatrix[2][2] = cos(rotation.y);
    

    You are constructing rotYMatrix but modify rotXMatrix.