4

OpenGL でフリー フライト カメラを作成しようとしています。私の問題は、Y 軸の回転です。カメラは、ローカル方向ではなく、常に Y ワールド軸で回転する必要があります。いくつかの行列乗算を試しましたが、すべて結果がありません。と

camMatrix = camMatrix  * yrotMatrix 

ローカル軸に沿ってカメラを回転させます。そして

camMatrix = yrotMatrix * camMatrix

ワールド軸に沿ってカメラを回転しますが、常に原点を中心に回転します。ただし、回転中心はカメラである必要があります。誰かアイデア?

4

4 に答える 4

7

3Dプログラミングのよりトリッキーな側面の1つは、複雑な変換を正しく行うことです。

OpenGLでは、すべてのポイントがモデル/ビューマトリックスで変換され、次にプロジェクションマトリックスで変換されます。

モデルビューマトリックスは各ポイントを取得し、それをカメラの視点からのあるべき場所に変換します。投影行列は、X座標とY座標をウィンドウに簡単にマッピングできるように、ポイントの座標を変換します。

モード/ビューマトリックスを正しく取得するには、単位行列(頂点を変更しないもの)から始めて、カメラの位置と方向に変換を適用し、次にオブジェクトの位置と方向に逆の順序で変換を適用する必要があります。

もう1つ覚えておく必要があるのは、回転は常に原点(0,0,0)を中心とする軸を中心に行われるということです。したがって、カメラに回転変換を適用する場合、カメラを回転させるか(頭を回転させるように)、原点を中心に周回するか地球が太陽を周回するように)は、以前に平行移動変換を適用したかどうかによって異なります。

したがって、カメラの回転と周回の両方を行う場合は、次のことを行う必要があります。

  1. 回転を適用してカメラの向きを調整します
  2. 翻訳を適用して配置します
  3. 回転を適用して、カメラを原点の周りに周回させます
  4. (オプションで)平行移動を適用して、カメラを設定された方向に移動し、(0,0,0)以外のポイントの周りの軌道にカメラを移動します。

たとえば、カメラを(0,0,0)以外のポイントに向け、そのポイントを設定された距離で周回させ、同時にカメラをピッチングまたはヨーイングしたい場合は、状況がさらに複雑になる可能性があります。WebGLの例については、ここを参照してください。を探しGLViewerBase.prototype.displayます。

レッドブック では、変換についてさらに詳しく説明しています

また、回転を使用せずにカメラ何かに向けるために使用できるgluLookAtにも注意してください。

于 2012-04-08T08:42:17.557 に答える
3

n行列を使用してこれを行うよりも、位置と直交法線、uおよびv軸を格納するカメラ クラスを作成し、それらを適切に回転させる方が簡単な場合があります。たとえば、次を参照してください。

https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/GUI/Camera.java

https://github.com/sgolodetz/hesperus2/blob/master/Shipwreck/MapEditor/Math/MathUtil.java

次に、次のようなものを書きます。

if(m_keysDown[TURN_LEFT])
{
    m_camera.rotate(new Vector3d(0,0,1), deltaAngle);
}

カメラのビューを設定するときは、次のようにします。

gl.glLoadIdentity();
glu.gluLookAt(m_position.x, m_position.y, m_position.z,
              m_position.x + m_nVector.x, m_position.y + m_nVector.y, m_position.z + m_nVector.z,
              m_vVector.x, m_vVector.y, m_vVector.z);

のような任意の軸を中心に回転する方法を知りたい場合は、上記のコード(0,0,1)を参照してください。MathUtil.rotate_about_axis

于 2012-04-06T19:22:30.173 に答える
2

前のフレームのカメラに基づいて変換したくない場合は、行列の合成を破棄してフレームごとに再計算することをお勧めします。平行移動と回転が一緒に保存されるため、単一のマトリックスで必要なことを行う方法はないと思います。

ピッチ/ヨー カメラのみが必要な場合は、それらの値を 2 つの float として保存し、それに基づいてマトリックスを再構築するだけだと思います。おそらく疑似コードのようなもの:

onFrameUpdate() {
  newPos = camMatrix * (0,0,speed) //move forward along the camera axis
  pitch += mouse_move_x;
  yaw += mouse_move_y;

  camMatrix = identity.translate(newPos)
  camMatrix = rotate(camMatrix, (0,1,0), yaw)
  camMatrix = rotate(camMatrix, (1,0,0), pitch)
}
于 2012-04-06T19:13:05.673 に答える
0

カメラをワールド軸に沿って回転させますが、常に原点を中心に回転させます。ただし、回転中心はカメラである必要があります。誰かアイデア?

この方法で行列がメモリに格納されていると仮定します(行列が線形1次元配列の場合、数値は要素インデックスを表します)。

0   1   2   3    //row 0
4   5   6   7    //row 1
8   9   10  11   //row 2
12  13  14  15   //row 3

解決策

  1. カメラ行列の最後の行を一時変数に格納します。
  2. カメラマトリックスの最後の行を(0、0、0、1)に設定します
  3. 使用するcamMatrix = yrotMatrix * camMatrix
  4. 一時変数からカメラ行列の最後の行を復元します。
于 2012-04-08T08:52:05.743 に答える