あなたが求めているのは、アークボール回転です。四元数は、それらがどのように機能するかを理解している場合にのみ簡単なソリューションです。ただし、クォータニオンがなくても同じことができます。
前提条件
一般的なオブジェクトの回転方法を知っていますか?原点にオブジェクトがあるとしましょう。回転方法を知っていますか(ヒント:回転行列を掛けます)?はいの場合、オブジェクトを最初に翻訳してから回転するとどうなるか知っていると思いますか?
角度軸から回転行列を計算する方法を知っている必要があります(パイのように簡単、オンラインで無数の方程式を見てください。それらの多くがコードも提供します)
解決
- カメラの取得アップと右のベクトルを。それらは正規化する必要があることに注意してください。
- 焦点からカメラまでのベクトルを取得します(camPosition-Focus)。これは、回転させるベクトルです。これをcamFocusVectorと呼びましょう。
- カメラに対してヨー/ピッチでどれだけ回転させるかを決定します
- 2つの回転行列を作成します。1番目の回転行列は、カメラのアップを、決定した軸とヨー角として使用します。2番目の回転マトリックスは、カメラの右側を、決定した軸とピッチ角として使用します。
- 次に、新しい回転行列でcamFocusVectorを回転します。これは、原点に対するカメラの新しい位置です。もちろん、フォーカスポイントに相対的なものにしたい...
- フォーカスポイントの位置をcamFocusVectorに追加します。これがカメラの新しい位置になりました。それに応じてカメラを翻訳します。
- 最後に、lookAt()関数を呼び出して、カメラにフォーカスポイントに焦点を合わせるように依頼します
注意事項
カメラが機能しなくなる特定のケースまたは特異点に注意する必要があります。たとえば、まっすぐ見下ろす。それらに対処する方法を考えてみましょう。
EDIT1:カメラの正規直交ベクトルを再計算する方法
カメラの方向はすでにわかっています((cameraPos-focusPoint).normalize())。ここで、カメラのアップが+ Yであると仮定します(または、ワールドの現在のアップ軸が...それはあなた次第です)。正しい方向に進むには、上に向かって方向を横切ります。できた?いや!アップベクトルは、他の2つと直交しなくなりました。その、クロス修正する権利を持つ方向を、あなたはあなたの新しい取得アップ。
Gram-Schmidtは、ベクトルの正規化に実際に使用する必要があることに注意してください。
再び、(いくつかの場合には機能しないであろう。このような警告のメモを取る方向に平行なアップなど)。