OpenGl - локально вверх и вправо от матрицы 4х4? - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть матрица преобразования 4x4, построенная следующим образом:

glm::mat4 matrix;
glm::quat orientation = toQuaternion(rotation);
matrix*= glm::mat4_cast(orientation);
matrix= glm::translate(matrix, position);
matrix= glm::scale(matrix, scale);

orientation = toQuaternion(localRotation);
matrix*= glm::mat4_cast(orientation);
matrix= glm::scale(matrix, localScale);

где вращение, положение, масштаб, localRotation и localScale - все vector3. Согласно совету по множеству разных вопросов на разных форумах, должно быть в состоянии выловить локальные направления из полученной матрицы следующим образом:

right   = glm::vec3(matrix[0][0], matrix[0][1], matrix[0][2]);
up      = glm::vec3(matrix[1][0], matrix[1][1], matrix[1][2]);
forward = glm::vec3(matrix[2][0], matrix[2][1], matrix[2][2]);

, где все эти направления нормализованы. Затем я использую эти указания, чтобы получить матрицу вида примерно так:

glm::lookAt(position, position + forward, up);

Все это прекрасно работает, ЗА ИСКЛЮЧЕНИЕМ: когда я летаю по сцене, правый и верхний векторы абсолютно ошибочны. Направление вперед всегда именно так, как и должно быть. Когда я в 0, 0, -1 смотрю на 0,0,0, все направления верны. Но когда я смотрю в разные стороны (за исключением обратного взгляда на начало координат от 0,0, -1), право и вверх несовместимы. Они не являются векторами мира и не являются локальными векторами. Они кажутся почти случайными. Куда я иду не так? Как я могу получить согласованные локальные восходящие и локальные правые векторы из матрицы преобразования 4x4?

1 Ответ

0 голосов
/ 29 апреля 2018

matrix - это локальное преобразование, в то время как матрица представления является мир-локальной, что означает, что в этом случае matrix является обратной матрицы представления. Код, который у вас есть, работает только для матрицы просмотра. Просто замените строки и столбцы:

right   = glm::vec3(matrix[0][0], matrix[1][0], matrix[2][0]);
up      = glm::vec3(matrix[0][1], matrix[1][1], matrix[2][1]);
forward = glm::vec3(matrix[0][2], matrix[1][2], matrix[2][2]);

Возможная причина, по которой он работает для (0, -1, 0), заключается в том, что часть поворота / масштабирования матрицы вида выглядит следующим образом:

1 0 0
0 0 1
0 1 0

Соответствующая часть matrix является обратной к вышеупомянутой, что, конечно, идентично. Попробуйте это в другом направлении.

...