I am implementing a first-person camera to move about a scene using the arrow keys on my keyboard. It seems to work OK when I am only rotating about a single axis (X or Y), however if I am rotating about both axes it also gives me rotation about the third, Z, axis. I am fairly sure that the problem is that my camera does not rotate about global axis but instead its local ones, resulting in 'roll' when I just want yaw and pitch. In my code I deduce a forward vector from the X and Y rotation, stored in two variables. The most relevant code snippet is as follows:
glm::mat4 CameraManager::rotateWorld(float angle, glm::vec3 rot){
static float yRot = 0.0f;
static float xRot = 0.0f;
glm::vec3 degrees = rot * angle;
glm::vec3 radians = glm::vec3(degrees.x * (M_PI/180.0f),
degrees.y * (M_PI/180.0f),
degrees.z * (M_PI/180.0f));
yRot += radians.y;
xRot += radians.x;
forwardVector = glm::vec3(sinf(yRot) * cosf(xRot),
-sinf(xRot),
-cosf(yRot) * cosf(xRot));
return glm::rotate(glm::mat4(1.0f), angle, rot);
}
the rotateWorld
function is complemented by the moveForward
function:
glm::mat4 CameraManager::moveForward(float dist){
glm::vec3 translation = forwardVector/glm::vec3(sqrt(forwardVector.x * forwardVector.x +
forwardVector.y * forwardVector.y +
forwardVector.z * forwardVector.z)) * dist;
return glm::translate(glm::mat4(1.0f), -translation);
}
where yRot
is equivalent to yaw and xRot
is equivalent to pitch.
The rotation and translation matrices are simply multiplied together in the main section of the program.
I then go on to multiply a distance d
by this vector to update the position.
xRot and yRot are static double
s that get incremented/decremented when the user presses an arrow key.
When the program starts, this is the view. The plane and the monkey head are facing the 'right way' up. incrementing/decrementing the pitch and yaw individually work as expected. But when I, say, increase the pitch and then yaw, the scene flips sideways! (Picture below.) Any ideas how to fix this?