Search code examples
opengl3drotationglm-mathprojection-matrix

How to rotate a cube by its center


I am trying to rotate a "cube" full of little cubes using keyboard which works but not so great.

I am struggling with setting the pivot point of rotation to the very center of the big "cube" / world. As you can see on this video, center of front (initial) face of the big cube is the pivot point for my rotation right now, which is a bit confusing when I rotate the world a little bit.

To explain it better, it looks like I am moving initial face of the cube when using keys to rotate the cube. So the pivot point might be okay from this point of view, but what is wrong in my code? I don't understand why it is moving by front face, not the entire cube by its very center?

In case of generating all little cubes, I call a function in 3 for loops (x, y, z) and the function returns cubeMat so I have all cubes generated as you can see on the video.

cubeMat = scale(cubeMat, {0.1f, 0.1f, 0.1f});
cubeMat = translate(cubeMat, {positioning...);

For rotation itself, a short example of rotation to left looks like this:

mat4 total_rotation; //global variable - never resets
mat4 rotation;       //local variable

if(keysPressed[GLFW_KEY_LEFT]){
            timer -= delta;
            rotation = rotate(mat4{}, -delta, {0, 1, 0});
}
... //rest of key controls
total_rotation *= rotation;

And inside of those 3 for cycles is also this:

program.setUniform("ModelMatrix", total_rotation * cubeMat);
cube.render();

I have read that I should use transformation to set the pivot point to the middle but in this case, how can I set the pivot point inside of little cube which is in center of world? That cube is obviously x=2, y=2, z=2 since in for cycles, I generate cubes starting at x=0.


Solution

  • You are accumulating the rotation matrices by right-multiplication. This way, all rotations are performed in the local coordinate systems that result from all previous transformations. And this is why your right-rotation results in a turn after an up-rotation (because it is a right-rotation in the local coordinate system).

    But you want your rotations to be in the global coordinate system. Thus, simply revert the multiplication order:

    total_rotation = rotation * total_rotation;