2016-04-18 10 views
1

:赤い点は、通常のようなものの中心になるだろう私は空間の点、このようなものを中心にカメラを回転させるようにしようとしている

Rotating around an object

オブジェクト。

ユーザーはマウスを使ってカメラを回転させることができます。垂直方向の動きは垂直(x軸)、水平方向は水平方向(y軸)です。私はy軸に

回転を欲しい

は常にカメラの見かけ y軸にあり、かつXと同じ。たとえば、ユーザーがマウスを上に動かすと、カメラがフォーカスしているオブジェクトの上を移動しているように見えるはずです。ユーザーがマウスを左から右に動かすと、オブジェクトがそのy軸上で回転しているか、カメラがそのy軸を中心に動いているように見えるはずです。

ユーザーがマウスを左に少し動かしてから上に移動すると、新しい視点からオブジェクトの上を移動するように見えるはずです。世界の実際のx軸。

これは私が使用したほとんどの3Dソフトウェアでは標準的なようです。私はここに多くの質問の助けを借りて

を試してみた何

、私はかなり私が欲しいものに近いが、非常ない得ています。次のコードビットに対する

view_は、4×4ビュー行列でorigin_たちが周りを回転している画像のスポットになり、position_カメラが原点からどのくらい離れているかバック表す画像に青い線であります(またはカメラパンはまだ実装されていません)、pitch,yawおよびrollは、回転させたい量です(この場合、ロールは常にゼロです)。

私の最良の結果はこれまでとあった:

// rotation_ is a vec3 here 
rotation_ += glm::vec3(glm::radians(pitch), glm::radians(yaw), glm::radians(roll)); 
glm::mat4 rot = glm::rotate(glm::mat4(1.0f), rotation_.x, glm::vec3(1.0f, 0.0f, 0.0f)); 
rot = glm::rotate(rot, rotation_.y, glm::vec3(0.0f, 1.0f, 0.0f)); 
rot = glm::rotate(rot, rotation_.z, glm::vec3(0.0f, 0.0f, 1.0f)); 
view_ = glm::translate(glm::translate(glm::mat4(1.0f), position_) * rot, origin_); 

閉じるが、x軸に沿って〜90度回転すると、y軸周りの更なる回転は、z軸の周りにあることをを見える原因となります。私はy軸をx軸に再現することはできません。だから、実際にジンバルロックか何か他のものかどうか不思議です。この問題を解決するには

、私は四元としてrotation_を格納し、このように回転を取得しようとした:

// rotation_ is a quaternion here. 
rotation_ *= glm::fquat(glm::vec3(glm::radians(pitch), glm::radians(yaw), glm::radians(roll))); 
glm::vec3(1.0f, 0.0f, 0.0f)); 
view_ = glm::translate(glm::translate(glm::mat4(1.0f), position_) * rot, origin_); 

これは実際に悪いです。カメラの向きではなく、世界の軸に沿って常に回転しているように見えますが、これは私が望むものではありません。アップ/ダウン、マウスを移動するとき、それは縦に回転し、左/右を移動する際にそれのような常に外観は水平に回転のよう

は、どのように私はいつも見てカメラを得ることができますか?

+0

@immibisもしあなたがそれを見逃してしまった場合は、私は四元数解を試しました。答えに四元数が関係していると思われます。私はクォータニオンについて深く理解していないことを認めますが、私は基本を知っていて、これまで何度か使ってきました。 – Claytorpedo

答えて

3

私のクォータニオンを間違った順序で組み合わせていました。

// rotation_ is a quaternion here. 
rotation_ *= glm::fquat(glm::vec3(glm::radians(pitch), glm::radians(yaw), glm::radians(roll))); 
glm::vec3(1.0f, 0.0f, 0.0f)); 
view_ = glm::translate(glm::translate(glm::mat4(1.0f), position_) * rot, origin_); 

ライン

rotation_ *= glm::fquat(glm::vec3(glm::radians(pitch), glm::radians(yaw), glm::radians(roll))); 

ではなく、私はそれが期待されるように、クォータニオンソリューションが動作するこのよう

rotation_ = glm::fquat(glm::vec3(glm::radians(pitch), glm::radians(yaw), glm::radians(roll))) * rotation_; 

されている必要があります。

私が正しく理解しているのは、最初に新しいデルタローテーションにローテーションしてから、それに古いローテーションを追加したいからです。これにより、回転の残りの部分を考慮に入れる前に、新しい回転を最初にカメラの軸に適用することができます。

これを逆に実行すると、古い回転に回転して新しい回転が追加され、新しい回転が期待通りの方向に適用されなくなります。

関連する問題