I want to rotate a cube using keys. This is a part of the code. When I press LEFT key, cube rotates to left, etc. My goal is to rotate cube all around, so I have to rotate it by x
and y
axis which causes a problem.
I have defined mat4 rotation;
and used it to assign a rotation when I press and hold a key. When I hold the key, it is rotating, for example to left. Then I release the key and the object gets back to initial position (camera gets back to initial position, since object is not moving). I think this problem is causing the auto rotateMat = rotation;
line which is defined below the key functions.
What am I doing wrong?
mat4 rotation; //global
if(keysPressed[GLFW_KEY_LEFT]){
timer -= delta;
rotation = rotate(mat4{}, timer * 0.5f, {0, 1, 0});
}
if(keysPressed[GLFW_KEY_RIGHT]){
timer += delta;
rotation = rotate(mat4{}, timer * 0.5f, {0, 1, 0});
}
if(keysPressed[GLFW_KEY_UP]){
timer += delta;
rotation = rotate(mat4{}, timer * 0.5f, {1, 0, 0});
}
if(keysPressed[GLFW_KEY_DOWN]){
timer -= delta;
rotation = rotate(mat4{}, timer * 0.5f, {1, 0, 0});
}
...
program.setUniform("ModelMatrix", rotation* cubeMat);
cube.render();
UPDATE:
So the problem to this was solved when I used matrix variable as global variable, not local.
There are multiple ways how such an interaction can be implemented. One of the easier ones is to create a relative translation in every frame instead of a global one and add it to the current rotation:
For this, one has to store the sum of all rotations in a global varialbe
//Global variable
mat4 total_rotate;
And calculate the relative translation in every frame:
//In the function
mat4 rotation;
if(keysPressed[GLFW_KEY_LEFT]){
rotation = rotate(mat4{}, delta, {0, 1, 0});
}
if(keysPressed[GLFW_KEY_RIGHT]){
rotation = rotate(mat4{}, -delta, {0, 1, 0});
}
if(keysPressed[GLFW_KEY_UP]){
rotation = rotate(mat4{}, delta, {1, 0, 0});
}
if(keysPressed[GLFW_KEY_DOWN]){
rotation = rotate(mat4{}, -delta, {1, 0, 0});
}
total_rotate = total_rotate * rotation;
...
program.setUniform("ModelMatrix", total_rotate * cubeMat);
cube.render();
As an alternative, you could store the two rotation angles instead and calculate the matrix in every frame:
//Global variables
float rot_x = 0.0f, rot_y = 0.0f;
//In every frame
if(keysPressed[GLFW_KEY_LEFT]){
rot_x += delta;
}
if(keysPressed[GLFW_KEY_RIGHT]){
rot_x -= delta;
}
//Same for y
auto rotation = rotate(rotate(mat4{}, rot_y, {0, 1, 0}), rot_x, {1, 0, 0}
...
program.setUniform("ModelMatrix", rotation * cubeMat);
cube.render();