Камера OpenGL и трансформации - PullRequest
0 голосов
/ 28 апреля 2020

tl; dr: трансляция визуализированного объекта с использованием ввода с клавиатуры всегда использует локальные оси (относящиеся к перспективе камеры), а не мировые оси, и я бы хотел, чтобы он использовал мировые оси

Здравствуйте,

У меня есть камера, использующая OpenGL. У меня есть входы, настроенные так, чтобы я мог перемещать камеру, а также визуализировать куб и треугольник. Расположение треугольника не зависит от ввода и константы, куб может перемещаться с помощью клавиш WASD.

Пока все работает почти так, как задумано. Камера настроена так, чтобы всегда смотреть на начало координат, и два объекта в сцене вращаются должным образом при движении камеры. Однако, когда камера перемещается (и, как результат, вращается), входные данные для движения куба становятся немного искаженными.

Например, если мы рассматриваем одно лицо как "переднее", а другое как " задняя часть куба, затем, когда камера видит «переднюю» грань, W перемещает куб вверх, S вниз, D вправо, A влево. Поэтому имеет смысл, что когда камера обращена назад, с нашей точки зрения мы увидим, что WASD работает так же, за исключением того, что теперь D перемещает куб слева от нас, а A справа. Конечно, куб все еще движется по той же действительной мировой оси (ie: D перемещает куб постепенно по положительной оси x). Это поведение, которое мы ожидаем.

Однако наше реальное поведение не совсем так. Независимо от того, в каком направлении вращается камера, куб всегда перемещается в локальном (а не в мировом пространстве) WASD - то есть, независимо от ориентации, W всегда находится в верхнем положении, A всегда остается в левом положении, et c et c.

Мой актуальный соответствующий код приведен ниже:

Перспектива камеры:

inline glm::mat4 GetViewProjection() const
    {
        return m_perspective * glm::lookAt(m_position, glm::vec3(0,0,0), m_up);
    }

Данная модель преобразования модели:

inline glm::mat4 GetModel() const
    {
        glm::mat4 posMatrix = glm::translate(position);
        glm::mat4 rotXMatrix = glm::rotate(rotation.x, glm::vec3(1, 0, 0));
        glm::mat4 rotYMatrix = glm::rotate(rotation.y, glm::vec3(0, 1, 0));
        glm::mat4 rotZMatrix = glm::rotate(rotation.z, glm::vec3(0, 0, 1));
        glm::mat4 scaleMatrix = glm::scale(scale);

        glm::mat4 rotMatrix = rotZMatrix * rotYMatrix * rotXMatrix;

        return posMatrix * rotMatrix * scaleMatrix;
    }

И затем эти оба метода используются функцией обновления шейдера:

void Shader::Update()
{
    glm::mat4 model = entity->GetComponent<Transform>().GetModel() *activeCamera->GetViewProjection();

    glUniformMatrix4fv(m_uniforms[TRANSFORM_U], 1, GL_FALSE, &model[0][0]);
}

Я знаю, что OpenGL не распознает истинную камеру, обязательно говорящую так же, как это можно представить в Unity, например. Однако я все еще хотел бы это исправить. Любая помощь будет оценена! Спасибо

...