web-dev-qa-db-ja.com

glm-mat4を平行移動と回転に分解しますか?

Lerpingの目的で、4x4行列をクォータニオンとvec3に分解する必要があります。行列をコンストラクターに渡すだけなので、クォータニオンを取得するのは簡単ですが、変換を取得する方法が見つかりません。確かに方法があるに違いありませんか?

19
Silverlan

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

glm::vec3(m[3])は位置ベクトルです(mglm::mat4であると仮定)

21
kerim

バージョン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);

2019年の更新された完全な回答を投稿すると思いました。期限が来たクレジットは、valmoの回答に基づいており、Konstantinos Roditakisの回答からのいくつかの項目と、私が遭遇したいくつかの追加情報が含まれています。

とにかく、バージョン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);

また、Konstantinos Roditakisの回答に記載されているように、Quaternionは実際には正しくなく、次のように適用することで修正できます。

rotation = glm::conjugate(rotation);
4
Travis Vroman

遅刻してすみません。実際、結果のquatを共役にする必要がある理由は、クォータニオンのx、y、z成分を計算するときに行列成分の減算順序が間違っているためです。

ここ はそれがどうあるべきかについての説明とサンプルコードです。

したがって、基本的にglmでは、decompose()メソッド、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);

また これを参照 implはGLMで見つかったものに非常に近いように見えますが、これは正しいものです。

0
Michael IV