2013-06-01 58 views
1

當我旋轉鼠標時,屏幕上的物體將按CCW旋轉,反之亦然。這不是一個巨大的錯誤,但它似乎是錯誤的。小四元相機錯誤? (在Z軸上稍微旋轉)

我正在使用Eigen四元數和向量,所以這個問題應該屬於我發佈的代碼。

攝像頭:

#include <Eigen/Dense> 
#include <cstring> 
#include <math.h> 

typedef Eigen::Vector3f vec3; 
typedef Eigen::Quaternionf Quaternion; 

namespace vec 
{ 
    // 
    // Constants 
    // 
    const vec3 i(1, 0, 0); 
    const vec3 j(0, 1, 0); 
    const vec3 k(0, 0, 1); 
    const vec3 zero(0, 0, 0); 
    const vec3 ones(1, 1, 1); 
} 

class Camera 
{ 
void init(); 

void moveX(float dist); 
void moveY(float dist); 
void moveZ(float dist); 

void rotateX(float radians); //yaw 
void rotateY(float radians); //pitch 
void rotateZ(float radians); //roll 

void moveLeft(float dist); 
void moveForward(float dist); 
void moveUp(float dist); 

void rotateLeft(float radians); //yaw 
void rotateUp(float radians); //pitch 
void rollLeft(float radians); //roll 

void setPosition(const vec3 &pos); 
void setDirection(const vec3 &dir); 
void lookAt(const vec3 &pos); //changes direction 

// Camera Vectors 
vec3 left() const; 
vec3 right() const; 
vec3 up() const; 
vec3 down() const; 
vec3 forward() const; 
vec3 backward() const; 
const vec3 &pos() const; 

protected: 
    Quaternion mRotation; 
    vec3 mPos; 

    void rotateL(float radians, const vec3 &axis); 
    void rotateR(float radians, const vec3 &axis); 
}; 

實現:

void Camera::init() 
{ 
    mPos.setZero(); 
    mRotation.setIdentity(); 
} 

inline void Camera::rotateL(float radians, const vec3 &axis) 
{ 
    Quaternion q(Eigen::AngleAxis<float>(radians, axis)); 
    mRotation = (q * mRotation).normalized(); 
} 

inline void Camera::rotateR(float radians, const vec3 &axis) 
{ 
    Quaternion q(Eigen::AngleAxis<float>(radians, axis)); 
    mRotation = (mRotation * q).normalized(); 
} 

void Camera::moveX(float dist) 
{ 
    mPos.x() += dist; 
} 

void Camera::moveY(float dist) 
{ 
    mPos.y() += dist; 
} 

void Camera::moveZ(float dist) 
{ 
    mPos.z() += dist; 
} 

void Camera::rotateX(float radians) 
{ 
    rotateL(radians, vec::i); 
} 

void Camera::rotateY(float radians) 
{ 
    rotateL(radians, vec::j); 
} 

void Camera::rotateZ(float radians) 
{ 
    rotateL(radians, vec::k); 
} 

void Camera::moveLeft(float dist) 
{ 
    mPos += dist * left(); 
} 

void Camera::moveUp(float dist) 
{ 
    mPos += dist * up(); 
} 

void Camera::moveForward(float dist) 
{ 
    mPos += dist * forward(); 
} 

void Camera::rotateLeft(float radians) 
{ 
    rotateL(radians, up()); 
} 

void Camera::rotateUp(float radians) 
{ 
    rotateL(radians, left()); 
} 

void Camera::rollLeft(float radians) 
{ 
    rotateL(radians, forward()); 
} 

void Camera::setPosition(const vec3 &pos) 
{ 
    mPos = pos; 
} 

void Camera::setDirection(const vec3 &dir) 
{ 
    mRotation.setFromTwoVectors(vec::k, dir); 
    mRotation.normalize(); 
} 

void Camera::lookAt(const vec3 &pos) 
{ 
    setDirection(mPos - pos); 
} 

// Camera Vectors 
vec3 Camera::left() const 
{ 
    return mRotation._transformVector(vec::i); 
} 

vec3 Camera::right() const 
{ 
    return -left(); 
} 

vec3 Camera::up() const 
{ 
    return mRotation._transformVector(vec::j); 
} 

vec3 Camera::down() const 
{ 
    return -up(); 
} 

vec3 Camera::forward() const 
{ 
    return mRotation._transformVector(vec::k); 
} 

vec3 Camera::backward() const 
{ 
    return -forward(); 
} 

const vec3 &Camera::pos() const 
{ 
    return mPos; 
} 

更新功能:

void App::onMouseMotion(int x, int y, int dx, int dy) 
{ 
    cam.rotateUp(dy * ROTATE_SCALE); 
    cam.rotateLeft(-dx * ROTATE_SCALE); 
} 


void App::update() 
{ 
    cam.moveLeft(((int)Keyboard::isKeyDown('a')) * MOVE_SCALE * mDt); 
    cam.moveLeft(((int)Keyboard::isKeyDown('d')) * -MOVE_SCALE * mDt); 
    cam.moveForward(((int)Keyboard::isKeyDown('w')) * MOVE_SCALE * mDt); 
    cam.moveForward(((int)Keyboard::isKeyDown('s')) * -MOVE_SCALE * mDt); 

    cam.rollLeft(((int)Keyboard::isKeyDown('q')) * -ROLL_SCALE * mDt); 
    cam.rollLeft(((int)Keyboard::isKeyDown('e')) * ROLL_SCALE * mDt); 
} 

心中已經請注意,有些問題是由於將四元數組合在不正確的一側上造成的,例如Q R而不是R Q.如建議的here切換X軸絕對沒有幫助。

我也很感激任何建議與我的實施。我已經考慮切換到矩陣旋轉,但正常化和組合它們更昂貴。

回答

2

這是在重複應用旋轉時的正常行爲。你可以在一些允許自由旋轉的應用程序或遊戲中看到它。

  1. 握住你的手臂在你面前。 「前進」是你的手指。 「Up」是你的手背。
  2. 向上傾斜約30 °。
  3. 從它的新的方向,傾斜它左約30 °。
  4. 從它的新方向,傾斜下來約30 °。
  5. 從它的新方向,向右傾斜約30 °。

你看到的是,手現在面對大致相同的方向,但逆時針方向稍微卷動。

這對人類來說可能看起來很陌生,因爲我們習慣了固定的向上方向。

+0

我想我在自由旋轉的遊戲中沒有太多的經驗。由於你總是在移動,因此無法分辨這是否是飛行模擬中的問題。我想我想像它離開X/Y的方式......但它們對我來說是相對的。 – ffhighwind

+0

即使交換後旋轉X和旋轉Y它仍然有問題...所以我認爲這是別的。將嘗試單個浮動偏航/俯仰/滾動或僅使用具有最小/最大俯仰的歐拉。 – ffhighwind