基本的に、クォータリオン (qx、qy、qz、qw) が与えられた場合...どうすればそれを OpenGL 回転行列に変換できますか? また、どのマトリックス行が「上」、「右」、「前方」などであるかにも興味があります...ベクトルで必要な四元数のカメラ回転があります...
4 に答える
次のコードはクォータニオン (qw、qx、qy、qz) に基づいており、順序は Boost クォータニオンに基づいています。
boost::math::quaternion<float> quaternion;
float qw = quaternion.R_component_1();
float qx = quaternion.R_component_2();
float qy = quaternion.R_component_3();
float qz = quaternion.R_component_4();
まず、クォータニオンを正規化する必要があります。
const float n = 1.0f/sqrt(qx*qx+qy*qy+qz*qz+qw*qw);
qx *= n;
qy *= n;
qz *= n;
qw *= n;
次に、マトリックスを作成できます。
Matrix<float, 4>(
1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f,
2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f,
2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
マトリックス クラスによっては、OpenGL に渡す前に転置する必要がある場合があります。
視覚化するのが非常に簡単な方法の 1 つは、クォータニオンで指定された回転を基底ベクトル (1,0,0)、(0,1,0)、および (0,0,1) に適用することです。 . 回転された値は、元のシステムに対する回転されたシステムの基底ベクトルを提供します。これらのベクトルを使用して、回転行列の行を形成します。結果の行列とその転置は、元のシステムと回転したシステムの間の順変換と逆変換を表します。
私は OpenGL で使用される規則に慣れていないので、他の誰かがあなたの質問のその部分に答えることができるかもしれません...
glm を使用すると、キャスト演算子を簡単に使用できます。したがって、matrix4 からクォータニオンに変換するには、単純に次のように記述します。
glm::mat4_cast(quaternion_name)
回転行列をまったく処理する必要がない場合があります。行列に変換してベクトルを乗算するよりも高速に見える方法を次に示します。
// move vector to camera position co (before or after rotation depending on the goal)
v -= co;
// rotate vector v by quaternion q; see info [1]
vec3 t = 2 * cross(q.xyz, v);
v = v + q.w * t + cross(q.xyz, t);
[1] http://mollyrocket.com/forums/viewtopic.php?t=833&sid=3a84e00a70ccb046cfc87ac39881a3d0