Glm - Разложить mat4 на перевод и вращение?

Для целей lerping мне нужно разложить матрицу 4x4 на кватернион и vec3. Схват кватерниона прост, так как вы можете просто передать матрицу в конструктор, но я не могу найти способ захватить перевод. Конечно, должен быть способ?

Ответ 1

Похоже, что glm 0.9.6 поддерживает матричное разложение http://glm.g-truc.net/0.9.6/api/a00204.html

glm::mat4 transformation; // your transformation matrix.
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(transformation, scale, rotation, translation, skew, perspective);

Ответ 2

glm::vec3(m[3]) - это вектор положения (если m - glm::mat4)

Ответ 3

В версии glm-0.9.8.1 вы должны включить:

#include <glm/gtx/matrix_decompose.hpp>

Чтобы использовать его:

glm::mat4 transformation; // your transformation matrix.
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(transformation, scale, rotation, translation, skew,perspective);

Имейте в виду, что полученный кватернион неверен. Он возвращает его сопряженное!

Чтобы исправить это, добавьте это в свой код:

rotation=glm::conjugate(rotation);

Ответ 4

Я решил опубликовать обновленный и полный ответ на 2019 год. Кредит, где он должен, основан на ответе Valmo, включает в себя некоторые элементы из ответа Константиноса Родитакиса, а также дополнительную информацию, с которой я столкнулся.

В любом случае, начиная с версии 0.9.9 вы все еще можете использовать экспериментальную декомпозицию матрицы: https://glm.g-truc.net/0.9.9/api/a00518.html

Во-первых, и часть, которую я добавляю, потому что я ее больше нигде не вижу, состоит в том, что вы получите ошибку, если не определите следующее перед включением ниже:

#define GLM_ENABLE_EXPERIMENTAL

Далее вы должны включить:

#include <glm/gtx/matrix_decompose.hpp>

Наконец, пример использования:

glm::mat4 transformation; // your transformation matrix.
glm::vec3 scale;
glm::quat rotation;
glm::vec3 translation;
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(transformation, scale, rotation, translation, skew,perspective);

Кроме того, кватернион, как указано в ответе Константиноса Родитакиса, действительно неверен и может быть исправлен путем применения следующего:

rotation = glm::conjugate(rotation);

Ответ 5

Извините за опоздание. На самом деле причина, по которой вы должны сопрягать результирующий кват, заключается в неправильном порядке вычитания компонентов матрицы при вычислении x, y, z компонентов кватерниона.

Вот объяснение и пример кода того, как это должно быть.

Таким образом, в основном в glm, метод degpose(), файл matrix_decompose.inl:

У нас есть:

    orientation.x = root * (Row[1].z - Row[2].y);
    orientation.y = root * (Row[2].x - Row[0].z);
    orientation.z = root * (Row[0].y - Row[1].x);

Когда это должно быть:

    orientation.x = root * (Row[2].y - Row[1].z);
    orientation.y = root * (Row[0].z - Row[2].x);
    orientation.z = root * (Row[1].x - Row[0].y);

Также посмотрите это значение, которое выглядит очень близко к тому, что найдено в GLM, но является правильным.