0

I am trying to implement a FPS camera using C++, OpenGL and GLM.

What I did until now:

I have a cameraPosition vector for the camera position, and also cameraForward (pointing to where the camera looks at), cameraRight and cameraUp, which are calculated like this:

inline void controlCamera(GLFWwindow* currentWindow, const float& mouseSpeed, const float& deltaTime)
{
    double mousePositionX, mousePositionY;
    glfwGetCursorPos(currentWindow, &mousePositionX, &mousePositionY);

    int windowWidth, windowHeight;
    glfwGetWindowSize(currentWindow, &windowWidth, &windowHeight);

    m_cameraYaw += (windowWidth / 2 - mousePositionX) * mouseSpeed;
    m_cameraPitch += (windowHeight / 2 - mousePositionY) * mouseSpeed;
    lockCamera();

    glfwSetCursorPos(currentWindow, windowWidth / 2, windowHeight / 2);

    // Rotate the forward vector horizontally. (the first argument is the default forward vector)
    m_cameraForward = rotate(vec3(0.0f, 0.0f, -1.0f), m_cameraYaw, vec3(0.0f, 1.0f, 0.0f));

    // Rotate the forward vector vertically.
    m_cameraForward = rotate(m_cameraForward, -m_cameraPitch, vec3(1.0f, 0.0f, 0.0f));

    // Calculate the right vector. First argument is the default right vector.
    m_cameraRight = rotate(vec3(1.0, 0.0, 0.0), m_cameraYaw, vec3(0.0f, 1.0f, 0.0f));

    // Calculate the up vector.
    m_cameraUp = cross(m_cameraRight, m_cameraForward);
}

Then I "look at" like this:

lookAt(m_cameraPosition, m_cameraPosition + m_cameraForward, m_cameraUp)

The problem: I seem to be missing something, because my FPS camera works as it is supposed to be until I move forward and get behind Z(0.0) (z becomes negative).. then my vertical mouse look flips and when I try to look up my application looks down...

The same question was asked here: glm::lookAt vertical camera flips when z <= 0 , but I didn't understand what the issue is and how to solve it.

EDIT: The problem is definitely in the forward, up and right vectors. When I calculate them like this:

        m_cameraForward = vec3(
            cos(m_cameraPitch) * sin(m_cameraYaw),
            sin(m_cameraPitch),
            cos(m_cameraPitch) * cos(m_cameraYaw)
        );

        m_cameraRight = vec3(
            sin(m_cameraYaw - 3.14f/2.0f),
            0,
            cos(m_cameraYaw - 3.14f/2.0f)
        );

        m_cameraUp = glm::cross(m_cameraRight, m_cameraForward);

Then the problem goes away, but then m_cameraPitch and m_cameraYaw don't match... I mean if m_cameraYaw is 250 and I make a 180 flip m_cameraYaw is 265... I can't restrict leaning backwards for example like that? Any ideas?

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Just out of curiosity, can we see your implementation of `vec3::operator +` ? It is the only place in the code where you are using position... (unless `m_cameraYaw` or `m_cameraPitch` is computed using position; if that is the error, from your description I'd bet on pitch) – Martin Prazak Nov 27 '14 at 23:47
  • I'm not entirely sure what "get behind Z(0.0)" means, but from the sounds of things this is what happens when you have two out of your three axes parallel. If your up and forward vectors are both parallel, then there are actually two possible identical mathematical representations of your orientation (one pointing up and one pointing down). Quaternions can be used to avoid this, but you generally don't need to do that sort of thing in an FPS camera - people don't usually bend over backwards in firstperson so you can restrict angles from ever reaching pure vertical ;) – Andon M. Coleman Nov 27 '14 at 23:57
  • @martin_pr I am computing the yaw and the pitch by setting them to 0 at the beginning and then adding centerOfScreen - mousePosition each frame... what do you mean by implementation of vec3? This is glm::vec3 :D (sorry if I just said something incredibly stupid). I just checked their values and they are fine... I am using matrices to do this and I have read somewhere that not using quaternions may cause errors... not really into this stuff. Should I post more code? – Людмил Григоров Nov 28 '14 at 00:04
  • @Andon M. Coleman They shouldn't be parralel... I Have a forward and a right vector which always have 90 degree angle between them and the up vector is being calculated every frame as the cross product of them both... – Людмил Григоров Nov 28 '14 at 00:09

0 Answers0