2

指定されたワールド座標を中心にカメラの位置を回転させる opengl カメラを実装しようとしています。glm 数学ライブラリを使用してこれを実行しようとしています。私のコードは次のとおりです

void Camera::dolly(double angle_x, double angle_y, const double& loc_x, const double& loc_y, const double& loc_z, const double& dt) {

  glm::vec3 target = glm::vec3(loc_x,loc_y,loc_z);

  glm::quat Q;glm::vec3 axis0(0.0f,1.0f,0.0f);
  glm::quat R;glm::vec3 axis1(1.0f,0.0f,0.0f);

  position = position - target;

  //glm::normalize(axis0);
  glm::normalize(axis1);

  Q = glm::gtx::quaternion::angleAxis( float(angle_x ), axis0 );;
  R = glm::gtx::quaternion::angleAxis( float(andl_y ), axis1 );;

  glm::quat final =  R*Q;

  position =  final * position;

  position = position + target;
  cout << "\tPosition: " << position.x << " " << position.y << " " << position.z <<endl;
}

コードをテストすると、quat Q を使用した回転は正常に機能しますが、quat R は「ぎこちない」回転を引き起こします。私は何を間違っていますか?

4

2 に答える 2

4

注:ここから私の答えをコピーしました。

四元数を使用してオイラー角を効果的に実装しただけです。それは役に立ちません。

オイラー角の問題は、行列を計算するときに、各角度がその前の行列の回転に関連していることです。必要なのは、オブジェクトの現在の方向を取得し、何らかの軸に沿って回転を適用して、新しい方向を生成することです。

オイラー角ではそれができません。行列を使用することも、四元数を使用することもできます (それらは行列の回転部分に過ぎないため)。しかし、オイラー角のふりをしてそれを行うことはできません。

これは、角度をまったく保存しないことによって行われます。代わりに、オブジェクトの現在の向きを表す四元数があります。それに (ある軸によるある角度の) 回転を適用することにした場合、その軸の周りの角度でその回転を表すクォータニオンを作成します。次に、そのクォータニオンを現在の向きのクォータニオンで右乗算し、新しい現在の向きを生成します。

オブジェクトをレンダリングするときは、現在の方向を...方向として使用します。

于 2013-05-26T06:39:17.967 に答える
2

質問からコピー:

EDIT 05/26/2013 この問題をどのように解決したか:

私のコードの問題は、私が使用したシーンをレンダリングするときでした:

    matrix = glm::lookAt(position,looking_at, upDirection);

次に、このマトリックスを使用して、シーンをカメラの視点に入れました/基本的にカメラをレンダリングしました。ただし、「Camera::dolly」(カメラを回転させることを目的としているため、実際にはドリーと呼ぶべきではありません) 関数を呼び出すと、upDirection を回転/更新せずにカメラの位置を回転させました (これは (0, に初期化) 1,0) 変数. これにより、私が説明した "ぎこちない" 問題が発生しました。

glm::quat orient = glm::gtx::quaternion::angleAxis(float(0),0.0f, 0.0f, 1.0f);

void Camera::rotate(double angle_x, double angle_y, const double& loc_x, const double& loc_y, const double& loc_z, const double& dt) { glm::vec3 target = glm::vec3(loc_x,loc_y,loc_z);

position = position - target;

angle_x *= dt;
angle_y *= dt;

glm::quat old_orient = orient;

glm::normalize(orient);
glm::quat q_x_axis = glm::gtx::quaternion::angleAxis(float(angle_y),1.0f, 0.0f, 0.0f) ;
glm::quat q_y_axis = glm::gtx::quaternion::angleAxis(float(angle_x), 0.0f, 1.0f, 0.0f);

orient = orient * q_x_axis * q_y_axis;

upDirection = upDirection * orient;
position = position * (orient);

orient = old_orient;

position = position + target;
于 2016-05-23T20:01:42.937 に答える