0
votes

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 moveForwardfunction:

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 doubles that get incremented/decremented when the user presses an arrow key.

enter image description here

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?

enter image description here

1
A picture might be helpful here...Alnitak
@Alnitak pictures added.Fitzy
And how do you specify the camera? Do you calculate a view matrix?Nico Schertler
@NicoSchertler yes, a matrix is constructed with glm and returned to another function where it is multiplied by the model matrix and sent to a shader.Fitzy
Do you consider sharing this code, since that's the most likely part to contain the error?Nico Schertler

1 Answers

0
votes

If I understand you correctly, the problem you're experiencing is that your "up" vector is not always pointing vertically upwards with respect to the intended Y axis of your viewing plane.

Determining a correct "up" vector usually requires a combination of cross product operations against the vector you have against the viewport's X and Y axes.

You may find some useful hints in the documentation for the gluLookAt function whose purpose is to calculate a view matrix with desired orientation (i.e. without roll) given an eye position and the coordinates of the intended centre of the field.