ジェイソンL.マッケソンのオンライン「Learning Modern 3D Graphics Programming」本を読んでいます
今のところ、ジンバルロックの問題と、クォータニオンを使用してそれを解決する方法について説明しています。
ただし、ここ、クォータニオンページで。
問題の一部は、方向を一連の3つの累積軸回転として保存しようとしていることです。方向は回転ではなく方向です。そして、向きは確かに一連の回転ではありません。そのため、船の向きを特定の量としての向きとして扱う必要があります。
これは私が混乱し始める最初の場所だと思います。理由は、向きと回転の劇的な違いが見えないからです。また、方向が一連の回転で表現できない理由もわかりません...
また:
この目的に向けた最初の考えは、マトリックスとしての方向を維持することです。向きを変更するときが来たら、この行列に変換を適用し、結果を新しい現在の向きとして保存します。
これは、現在の方向に適用されるすべてのヨー、ピッチ、およびロールが、現在の方向に対して相対的であることを意味します。まさにそれが私たちに必要なものです。ユーザーが正のヨーを適用する場合、そのヨーは、ある固定座標系ではなく、現在のポインティングの位置を基準にして回転させます。
概念は理解していますが、行列変換の累積がこの問題の解決策である場合、前ページで示したコードがそれだけではないことを理解していません。
コードは次のとおりです。
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutil::MatrixStack currMatrix;
currMatrix.Translate(glm::vec3(0.0f, 0.0f, -200.0f));
currMatrix.RotateX(g_angles.fAngleX);
DrawGimbal(currMatrix, GIMBAL_X_AXIS, glm::vec4(0.4f, 0.4f, 1.0f, 1.0f));
currMatrix.RotateY(g_angles.fAngleY);
DrawGimbal(currMatrix, GIMBAL_Y_AXIS, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
currMatrix.RotateZ(g_angles.fAngleZ);
DrawGimbal(currMatrix, GIMBAL_Z_AXIS, glm::vec4(1.0f, 0.3f, 0.3f, 1.0f));
glUseProgram(theProgram);
currMatrix.Scale(3.0, 3.0, 3.0);
currMatrix.RotateX(-90);
//Set the base color for this object.
glUniform4f(baseColorUnif, 1.0, 1.0, 1.0, 1.0);
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(currMatrix.Top()));
g_pObject->Render("tint");
glUseProgram(0);
glutSwapBuffers();
}
私の理解では、著者は個々の回転変換をすべてスタックの一番上に格納されている1つのマトリックスに結合したため、彼がしていること(スタック上のマトリックスの変更)はマトリックスの累積とは考えていません。
マトリックスの私の理解は、それらが原点(たとえば...モデル)に相対的なポイントを取得し、別の原点(カメラ)に相対的にするために使用されるということです。これは安全な定義であると確信していますが、このジンバルロックの問題を理解するのを妨げている何かが足りないと感じています。
私にとって意味のないことの1つは、マトリックスが2つの「空間」の相対的な差を決定する場合、Y軸の周りの回転がどのように来るのか、たとえば、ロールはポイントを「ロール空間」に入れない「このロールに関連してもう一度変換できます...つまり、このポイントへのそれ以上の変換は、この新しい「ロールスペース」に関連してはならず、したがって、回転は前の「ジンバルロックを引き起こしているモデル空間」。
それがジンバルロックが正しく発生する理由です。これは、オブジェクトを独自の相対軸の周りに回転させるのではなく、X、Y、およびZ軸のセットの周りにオブジェクトを回転させるためです。それとも私は間違っていますか?
どうやら私がリンクしたこのコードはマトリックス変換の蓄積ではないので、この方法を使用したソリューションの例を教えてください。
要約すると:
- 回転と向きの違いは何ですか?
- コードがマトリックス変換の累積の例ではなくリンクされているのはなぜですか?
- 私が間違っていた場合、マトリックスの実際の特定の目的は何ですか?
- マトリックス変換の累積を使用してジンバルロック問題の解決策を実装するにはどうすればよいですか?
- また、ボーナスとして:回転後の変換が「モデル空間」に対して相対的なのはなぜですか?
- 別のボーナス:変換後に、現在の変換に関連してさらに変換が行われるという仮定は間違っていますか?
また、暗示されていない場合は、OpenGL、GLSL、C ++、およびGLMを使用しているため、これらの用語の例と説明は、必要でない場合は大歓迎です。
詳細が多ければ多いほど良い!
前もって感謝します。