2014-04-28 3 views
4

Я пытаюсь сохранить свою матрицу вращения как кватернион, а затем, когда я хочу использовать ее для преобразования, преобразуйте ее обратно. Я использую библиотеку glm, которая предоставляет для них mat4_cast и quat_cast. Однако, когда я выполняю следующий код:Ошибка преобразования матрицы в кватернион и обратно

glm::mat4 origTest = glm::lookAt(position, lookAtPt, up); 
glm::quat quatTest = glm::quat_cast(origTest); 
glm::mat4 mat4Test = glm::mat4_cast(quatTest); 

Я получаю разные значения для origTest и mat4Test. Я что-то упустил? позиция, lookAtPt и выше - glm :: vec3.

+0

Как другой? Будет ошибка округления. –

+0

Нет, это не ошибка округления. 4-я строка матрицы полностью отличается для значений, которые я пробовал: это позиция (0, 0, 5); lookAtPt (0, 0, 0) и вверх (0,1, 0) – shaveenk

+0

Мне удалось выяснить это частично. То, как работает преобразование, не учитывало параметр позиции. Поэтому вместо предоставления какого-либо смещения позиции от начала координат я предоставил позицию vec3 (0) и сделал обратный перевод на lookAtPt. Теперь как origTest, так и mat4Test предоставляют одинаковые значения. Но мне действительно нужно, чтобы он учитывал всю матрицу 4x4, чтобы она была полезной – shaveenk

ответ

6

Я смог понять это. Кватернион сохраняет вращение объекта в локальном пространстве. Следовательно, чтобы получить полную матрицу вида, которую вы можете получить из glm :: lookAt(), вам сначала нужно преобразовать кватернион в локальное пространство в матрицу. Затем вы перевели бы идентификационную матрицу по желаемой позиции, и вы бы выполнили умножение SRT для получения окончательной матрицы представлений. В этом случае вам нужно, чтобы инвертировать матрицу перевода, так как мы делаем обратный перевод на камеру, а также вы бы использовать соответствующий «LookAt» вектор, который находится в том же направлении (lookAtPt - положение)

/* Mat4 to Quat */ 
glm::vec3 lookAtPt = direction; 
glm::mat4 rotMatrix = glm::lookAt(glm::vec3(0), lookAtPt, up); 
glm::quat rotation = glm::quat_cast(rotMatrix); 

/* Quat to Mat4 */  
glm::mat4 identityMat = glm::mat4(1.0f); 
glm::mat4 rotMatrix = glm::mat4_cast(rotation); //rotation is glm::quat 
glm::mat4 transMatrix = glm::translate(identityMat, position); 
glm::mat4 viewMatrix = rotMatrix * glm::inverse(transMatrix);