シーンの説明を含むファイルをロードし、OpenGL を使用して表示するプログラムを作成しています。私はすべての数学演算に GLM を使用しています。シーン ファイル内の回転は、クォータニオン形式で保存されます。私のシーン管理システムはオブジェクトの回転をオイラー角の形式で取得し、これらの角度は後で描画時に回転マトリックスに変換されます。
したがって、ロード プロセスはクォータニオン回転を取得し、それらをオブジェクト クラスに格納するためにオイラー角に変換し、次にこれらのオイラー角を描画用の回転行列に変換します。glm::eulerAngles と glm::eulerAngleYXZ 関数を (それぞれ) 使用して、これら 2 つの操作を実行しています。
ただし、間違った結果が得られます。たとえば、クォータニオン {0.500 -0.500 0.500 0.500} (これは WXYZ) を正しく理解していれば、+Z 軸から +Y 軸への矢印の回転を表す必要があります。しかし、プログラムを実行すると、+X 軸に沿った矢印が表示されます。
四元数の理解に何らかの欠陥があると思いますが、中間のオイラー角形式をスキップすることで、期待どおりの結果を得ることができます。glm::toMat4 を使用してクォータニオンを回転行列に直接変換することで、+Z 矢印が +Y を指す回転が得られます。
どちらの方法も単純で正しいように見えるため、これら 2 つの異なる出力を調整するのに苦労しています。私の質問を簡単にするために、これらの 2 つの一見同等の方法が異なる結果をもたらすのはなぜですか。
glm::quat q(.5, -.5, .5, .5);
glm::vec3 euler = glm::eulerAngles(q) * 3.14159f / 180.f; // eulerAngleYXZ takes radians but eulerAngles returns degrees
glm::mat4 transform1 = glm::eulerAngleYXZ(euler.y, euler.x, euler.z);
// transform1 rotates a +Z arrow so that it points at +X
glm::quat q(.5, -.5, .5, .5);
glm::mat4 transform2 = glm::toMat4(q);
// transform2 rotates a +Z arrow so that it points at +Y