回答:
カメラの回転に関するいくつかのヒントを次に示します(マウスルック)。ゼロからカメラクラスをナイーブに実装した後、適切な回転動作のためにいくつかの追加調整が必要であることがわかりました。
マウスが画面の境界に引っ掛からないように、各フレームでマウスの座標を画面の中心にリセットします
カメラの「アップ」ベクトルを維持し(ロールを許可しない)、「横向き」ベクトルを再計算する
垂直+ y軸を超えて上を見たり、-y軸を超えて下を見たりすることはできません(あまりにも上/下)
正しい回転順序を取得します(最初に上/下、次に左/右)
各フレームで「アップ」、「エイム」、「サイドウェイ」ベクトルを再正規化する
うまくいけば、このコードのいくつかをあなたの利益のために使うことができます:
const int mouseDeltaX = mouseAxisX * (input.GetMouseX() - int(app.GetWidth()/2));
const int mouseDeltaY = -mouseAxisY * (input.GetMouseY() - int(app.GetHeight()/2)); // mouse y-offsets are upside-down!
// HACK: reset the cursor pos.:
app.SetCursorPosition(app.GetWidth()/2, app.GetHeight()/2);
float lookRightRads = mouseDeltaX * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
float lookUpRads = mouseDeltaY * CAMERA_ANGULAR_SPEED_DEG * DEG_TO_RAD;
// Limit the aim vector in such a way that the 'up' vector never drops below the horizon:
static const float zenithMinDeclination = DEG_TO_RAD * MIN_UPWARDS_TILT_DEG;
static const float zenithMaxDeclination = DEG_TO_RAD * (180.0f - MIN_UPWARDS_TILT_DEG);
const float currentDeclination = std::acosf(camera.aim_.y_); ///< declination from vertical y-axis
const float requestedDeclination = currentDeclination - lookUpRads;
// Clamp the up/down rotation to at most the min/max zenith:
if(requestedDeclination < zenithMinDeclination)
lookUpRads = currentDeclination - zenithMinDeclination;
else if(requestedDeclination > zenithMaxDeclination)
lookUpRads = currentDeclination - zenithMaxDeclination;
// Rotate both the "aim" vector and the "up" vector ccw by
// lookUpRads radians within their common plane -- which should
// also contain the y-axis: (i.e. no diagonal tilt allowed!)
camera.aim_.rotateAboutAxis(camera.right_, lookUpRads);
camera.up_.rotateAboutAxis(camera.right_, lookUpRads);
ASSERT_ORTHONORMAL(camera.aim_, camera.up_, camera.right_);
// Rotate both the "aim" and the "up" vector ccw about the vertical y-axis:
// (again, this keeps the y-axis in their common plane, and disallows diagonal tilt)
camera.aim_.rotateAboutAxis(Y_AXIS, -lookRightRads);
camera.up_.rotateAboutAxis(Y_AXIS, -lookRightRads);
camera.updateRightAxis();
ご了承ください:
mouseAxisXとmouseAxisYは、x軸またはy軸のマウスルックを反転させるかどうかに応じて、+ /-1に定義されます。通常、ゲームは少なくとも垂直軸に対してこのオプションを提供します。
MIN_UPWARDS_TILT_DEGは1.0度に定義されています(したがって、視聴者は-89度から上向きに+89度まで見ることができます。これは、完全な180度の垂直範囲に非常に納得のいくように見えます。 。
camera.aim_、camera.right_、およびcamera.up_はもちろん3Dベクトルであり、rotateAboutAxis()メソッドはウィキペディアおよび任意の数のオンラインソースから一緒にまとめることができます。Y_AXISは固定定数(0,1,0)ベクトルです。
ASSERT_ORTHONORMAL()はデバッグモード専用の健全性チェックであり、最適化/リリースモードでコンパイルされることはありません。
Cスタイルのコードを事前におApび申し上げます...それから、ここではMediocritusという名前の男性からアドバイスを受けています!; ^)
このついて行くのいくつかの方法は、(チュートリアルを参照してくださいがあり、ここで、こことここにグーグルを介してインターネット上でより多くの利用可能なたっぷり使って、例えば)。オンラインで見つかるリソースで使用されるテクノロジーは(D3D、XNA、OpenGLなどに関して)わずかに異なる場合がありますが、基本的な原則は同じです。
必要に応じて、ベクトルを直接保存するか、基礎となるビュー行列を毎回再計算するかを選択できます。この手法には柔軟性が非常に高いため、これらの一般的な手順以外にヘルプが必要な場合は、より具体的なクエリを使用して新しい質問を投稿することをお勧めします。
Direct3Dを使用したカメラシステムの実装に関する具体的なリファレンスについては、http://www.toymaker.info/Games/html/camera.htmlの記事をお勧めします。著者は、実装を拡張するために使用できる他の方法と機能についても説明しています。