glm lookAt Камера FPS переворачивает вертикальный взгляд мыши, когда Z ‹ 0

Я пытаюсь реализовать камеру FPS, используя C++, OpenGL и GLM.

Что я сделал до сих пор:

У меня есть вектор cameraPosition для положения камеры, а также cameraForward (указывающий, куда смотрит камера), cameraRight и cameraUp, которые вычисляются следующим образом:

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);
}

Затем я «смотрю» так:

lookAt(m_cameraPosition, m_cameraPosition + m_cameraForward, m_cameraUp)

Проблема: мне кажется, что я что-то упускаю, потому что моя камера FPS работает так, как должна быть, пока я не сдвинусь вперед и не окажусь позади Z (0,0) (z становится отрицательным).. тогда мой вертикальный вид мыши переворачивается, и когда я пытаюсь искать мое приложение смотрит вниз...

Тот же вопрос был задан здесь: glm::lookAt вертикальная камера переворачивается, когда z ‹= 0 , но я не понял в чем проблема и как ее решить.

РЕДАКТИРОВАТЬ: Проблема определенно в прямом, верхнем и правом векторах. Когда я вычисляю их так:

        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);

Затем проблема исчезает, но тогда m_cameraPitch и m_cameraYaw не совпадают... Я имею в виду, если m_cameraYaw равно 250, и я делаю переворот на 180, m_cameraYaw равно 265... Я не могу ограничить наклон назад, например, вот так? Есть идеи?


person Людмил Григоров    schedule 27.11.2014    source источник
comment
Просто из любопытства, можем ли мы увидеть вашу реализацию vec3::operator +? Это единственное место в коде, где вы используете позицию... (если только m_cameraYaw или m_cameraPitch не вычисляются с использованием позиции; если это ошибка, из вашего описания я бы поставил на поле)   -  person Martin Prazak    schedule 28.11.2014
comment
Я не совсем уверен, что означает отстать от Z (0,0), но, судя по всему, это то, что происходит, когда у вас параллельны две из трех осей. Если ваши векторы вверх и вперед параллельны, то на самом деле существует два возможных идентичных математических представления вашей ориентации (одно указывает вверх, а другое — вниз). Чтобы избежать этого, можно использовать кватернионы, но, как правило, вам не нужно делать такие вещи в камере FPS - люди обычно не наклоняются назад от первого лица, поэтому вы можете ограничить углы от достижения чистой вертикали ;)   -  person Andon M. Coleman    schedule 28.11.2014
comment
@martin_pr Я вычисляю рыскание и шаг, устанавливая их в 0 в начале, а затем добавляя centerOfScreen - mousePosition в каждом кадре ... что вы подразумеваете под реализацией vec3? Это glm::vec3 :D (извините, если я только что сказал что-то невероятно глупое). Я только что проверил их значения, и они в порядке... Я использую для этого матрицы, и я где-то читал, что неиспользование кватернионов может вызвать ошибки... не совсем в этом. Должен ли я опубликовать больше кода?   -  person Людмил Григоров    schedule 28.11.2014
comment
@Андон М. Коулман Они не должны быть параллельны ... У меня есть прямой и прямой вектор, между которыми всегда есть угол 90 градусов, а восходящий вектор вычисляется в каждом кадре как перекрестное произведение их обоих ...   -  person Людмил Григоров    schedule 28.11.2014