1

2D/3D ゲーム エンジンを開発しています。https ://github.com/crakouille/ngengine から入手できます。

ライブラリ 3D カメラ クラスは、include/video/D3/camera/camera.h で定義されています。

必要なベクトルを gluLookAt に保存します。

glm::vec3 _position;
glm::vec3 _target;
glm::vec3 _normal;

examples/05_3D では、FreeFly カメラの実装 (ライブラリ 3D カメラの拡張) が記述されており、球座標が使用されています。それはうまくいきます。

examples/06_CameraQuat では、別の FreeFly カメラの実装が記述されており、クォータニオンが使用されています。そして、私の問題はそこにあります。

軸を中心に回転するとうまくいきますが、(マウスで円を描くことによって) 2 つの軸を中心に回転すると、カメラがターゲット軸を中心に回転し、問題が発生します。

バグなし (05_3D の例):

バグなし (05_3D 例)

ターゲット軸の回転(06_CameraQuat)のバグあり。

バグあり(06_CameraQuat)

カメラのコードは次のとおりです。

FreeFly.h:

class FreeFly : public nge::video::D3::Camera {

  public:

    ...

    void rotateForward(double angle); // rotate around on the forward axis
    void rotateLeft(double angle); // rotate around on the left axis
    void rotateNormal(double angle); // rotate around on the normal axis

  private:

    void updateVectRel(); // update _targetRel, _leftRel and _normalRel

    glm::quat _quat; // the quaternion which contains the rotations

    glm::vec3 _targetRel; // the target vector, normalized, relative to _position
    glm::vec3 _leftRel; // the left vector, normalized
    glm::vec3 _normalRel; // the normal vector (up), normalized
};

FreeFly.cpp:

#include <06_CameraQuat/FreeFly.h>
#include <glm/gtx/quaternion.hpp>

......

void FreeFly::rotateForward(double angle)
{
  glm::quat q2 = glm::angleAxis((float) -angle, _targetRel);
  q2 = glm::normalize(q2);

  // q2 represents the rotation around the forward axis

  _quat = _quat * q2; // adding the rotation to _quat

  this->updateVectRel(); // updating the vectors

}

void FreeFly::rotateLeft(double angle)
{
  // idem with left axis
  glm::quat q2 = glm::angleAxis((float) -angle, _leftRel);
  q2 = glm::normalize(q2);
  _quat = _quat * q2;//glm::cross(_quat, q2);

  this->updateVectRel();
}

void FreeFly::rotateNormal(double angle)
{
  // idem with normal axis
  glm::quat q2 = glm::angleAxis((float) -angle, _normalRel);
  _quat = _quat * q2; //glm::cross(_quat, q2);

  this->updateVectRel();
}

void FreeFly::updateVectRel()
{ 
  _targetRel = glm::dvec3(1., 0., 0.);
  _leftRel = glm::dvec3(0., -1., 0.);
  _normalRel = glm::dvec3(0., 0., 1.);

  _quat = glm::normalize(_quat);

  _targetRel =  _targetRel * _quat;
  _leftRel = _leftRel * _quat;
  _normalRel = _normalRel * _quat;

  _target = _position + _targetRel;
  _normal = _normalRel;
}

編集:

カメラがターゲット軸を中心に回転するのはなぜですか?

注: マウスで時計回り/反時計回りに円を描くと、ターゲット軸の周りの回転もそれぞれ時計回り/反時計回りになります。

4

0 に答える 0