5

向きを変えようとすると、カメラがポイントを中心に回転します。たとえば、カメラをY軸で30度回転させると、カメラを右に30度見るのではなく、カメラが見ていた点を中心に回転します。

o is the camera, A and B are 3D models. The lines show line-of-sight.
This is what I expect:
     A    B
     | > /
     |  /
     | /
     |/
     o

This is what actually happens:
     A    B
     |\
     | \
     |  \
     | > \
          o

さて、私の理解では、カメラを動かすには、その量の逆数で世界を動かさなければなりません。したがって、Z軸で+1を移動したい場合は、Z軸でワールド-1を移動します。四元数を使用して方向を表すため、カメラの四元数の逆数を使用して(方向は常に単位四元数であるため、逆数を計算する代わりに共役を使用して最適化します)、世界を適切な量だけ回転させます。

クォータニオンを行列に変換する方法は次のとおりです。ここで、qは逆クォータニオンです。

[1 - 2 * (q.y * q.y + q.z * q.z)   2 * (q.x * q.y - q.w * q.z)       2 * (q.x * q.z + q.w * q.y)         0]
|2 * (q.x * q.y + q.w * q.z)       1 - 2 * (q.x * q.x + q.z * q.z)   2 * (q.y * q.z - q.w * q.x)         0|
|2 * (q.x * q.z - q.w * q.y)       2 * (q.y * q.z + q.w * q.z)       1 - 2 * (q.x * q.x + q.y * q.y)     0|
[0                                 0                                 0                                   1]

その後、マトリックスの変換コンポーネントを設定します。

[...   ...   ...  -x]
|...   ...   ...  -y|
|...   ...   ...  -z|
[0     0     0     1]

そして最後に、それをモデルビューマトリックススタックに乗算してから、すべてのオブジェクトをレンダリングします。この計算は正しいと確信していますが、期待した結果は得られません。明らかに順ベクトルと右ベクトルが問題なので、私の唯一の質問は、なぜそれらが間違っているのか、そして私が期待する結果を得たい場合、それらをどのように設定する必要があるのか​​ということです。ありがとう。

編集:私はこの男のクォータニオンカメラクラスから解決策を見つけました。最初に、以前と同じように回転行列を作成しますが、次に、行列の列ベクトルを1番目、2番目、3番目の列(それぞれxa、ya、za)から取得します。次に、マトリックスの並進コンポーネントを次のように設定します。

[...  ...  ...  -xa.dotProduct(cameraPos)]
|...  ...  ...  -ya.dotProduct(cameraPos)|
|...  ...  ...  -za.dotProduct(cameraPos)|
[...  ...  ...  ...                      ]

次に、結果のマトリックスをmodelviewマトリックススタックに乗算でき、完全に機能します。

4

2 に答える 2

2

編集:私はこの男のクォータニオンカメラクラスから解決策を見つけました。最初に、以前と同じように回転行列を作成しますが、次に、行列の列ベクトルを1番目、2番目、3番目の列(それぞれxa、ya、za)から取得します。次に、マトリックスの並進コンポーネントを次のように設定します。

[...  ...  ...  -xa.dotProduct(cameraPos)]
|...  ...  ...  -ya.dotProduct(cameraPos)|
|...  ...  ...  -za.dotProduct(cameraPos)|
[...  ...  ...  ...                      ]

次に、結果のマトリックスをmodelviewマトリックススタックに乗算でき、完全に機能します。

はい、これは私が提案したものとまったく同じですが、少しだけ異なります。OpenGLにはカメラがないことを理解する必要がありますが、代わりに世界を反対方向に移動するだけなので、逆変換行列を見つける必要があります。

カメラが回転して動くだけです。これにより、物事が非常に簡単になります。平行移動の逆行列は、符号が反対の同じベクトルであり、回転行列の逆行列は、転置(列と行が交換される)です。次に、OpenGLがそれらを使用するような同種の変換行列を見てください。

R t
0 1

左上の3×3は回転部分、右端の列は平行移動ベクトルです。私はあなたがすでにあなた自身を理解した残りの部分だと思います。

于 2012-02-02T08:45:43.063 に答える
0

正直なところ、モジュールビューの行列に乗算する行列を見つけようとすると、非常に複雑になり、エラーが発生しやすくなります。多くの混乱と特別な場合があります。たとえば、90度上を見ている場合、2つの軸は同じになります。論理的な問題はこれです:あなたが頭を後ろに転がしているので、あなたがトップポイントを通過するなら、あなたのアップベクトルは逆にされるべきですよね?しかし、0.0001度それを逃した場合はどうなりますか?次に、そのポイントの周りに頭を向けて、アップベクトルがまだアップしているようにする必要があります。

私の意見では、最善の方法は別の観点から問題に取り組むことです。2つのケースを想定しましょう。

  • 逆さまにすることは不可能です:
    • カメラの位置と方向の緯度/経度のポイントを保持します。単純なsin/cos操作で、方向ベクトルを取得できます。あなたのアップベクトルは(0、1、0)です
    • 旋削とは、緯度と経度を変更することです。
  • 逆さまの可能性:
    • カメラの位置に加えて、アップベクトルとターゲットベクトルの両方を保持します。
    • 回転するときは、right = target x upを計算してから、targetをx * right + y*upに変更します。
    • 次に、ターゲットベクトルを正規化し、新しい計算を行う必要があります。ただし、処理するケースはたくさんあります。

これらすべての後で、単にを呼び出しますgluLookAt

于 2012-02-02T02:01:04.247 に答える