一人称カメラをどのように実装すればよいですか?


12

私は初心者プログラマーであり、一人称カメラで部屋を歩き回ることができるプロジェクトを作成しています。これまでのところ、建物が描かれていますが、今は立ち往生しており、歩き回るために一人称カメラを作成する方法がわかりません。

誰かが私が使用できるカメラクラス、またはいくつかの有用なコードに私を向けることができますか?


これをご覧
Archmede

回答:


7

カメラの回転に関するいくつかのヒントを次に示します(マウスルック)。ゼロからカメラクラスをナイーブに実装した後、適切な回転動作のためにいくつかの追加調整が必要であることがわかりました。

  1. マウスが画面の境界に引っ掛からないように、各フレームでマウスの座標を画面の中心にリセットします

  2. カメラの「アップ」ベクトルを維持し(ロー​​ルを許可しない)、「横向き」ベクトルを再計算する

  3. 垂直+ y軸を超えて上を見たり、-y軸を超えて下を見たりすることはできません(あまりにも上/下)

  4. 正しい回転順序を取得します(最初に上/下、次に左/右)

  5. 各フレームで「アップ」、「エイム」、「サイドウェイ」ベクトルを再正規化する

うまくいけば、このコードのいくつかをあなたの利益のために使うことができます:

    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という名前の男性からアドバイスを受けています!; ^)


あなたは何について話していますか?Cスタイルのコードは、ハッカーの精神の基礎です!8
blissfreak

5

このついて行くのいくつかの方法は、(チュートリアルを参照してくださいがあり、ここでここここにグーグルを介してインターネット上でより多くの利用可能なたっぷり使って、例えば)。オンラインで見つかるリソースで使用されるテクノロジーは(D3D、XNA、OpenGLなどに関して)わずかに異なる場合がありますが、基本的な原則は同じです。

  • カメラオブジェクトはその位置と方向を維持し、オプションで、方向と並んでカメラの座標系の直交基底を形成する別のベクトルのペアを維持します。
  • カメラのパブリックAPIは、ヨーイング、ピッチング、およびオプションでカメラを基本ベクトルの周りに回転させるためのメソッドを公開します。カメラの向きを調整する行為により、後で使用するために基本ベクトルが更新されます。

必要に応じて、ベクトルを直接保存するか、基礎となるビュー行列を毎回再計算するかを選択できます。この手法には柔軟性が非常に高いため、これらの一般的な手順以外にヘルプが必要な場合は、より具体的なクエリを使用して新しい質問を投稿することをお勧めします。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.