2015-11-21 1 views
1

Je tente de faire un appareil photo qui peut pivoter lorsque les touches fléchées sont enfoncées. Toutefois, lorsque j'allume l'appareil photo et que j'essaie de le faire pivoter, il ne tourne pas autour de l'axe correct.Rotation de l'appareil photo avec des quaternions

Par exemple, mon vecteur haut est (0, 1, 0). Je peux parfaitement faire pivoter ma caméra gauche et droite car ce vecteur est constant. Là où mon appareil photo ne fonctionne pas, c'est lorsque je tente de tourner autour de son axe droit. Si je tourne mon appareil photo vers la gauche ou vers la droite et tourne autour de l'axe droit, il traite souvent l'axe dans une direction étrange qui n'est pas correcte. Cela ne devrait pas être le cas car je peux toujours bouger correctement mon appareil photo, il ne tourne pas correctement.

Ci-dessous figure le code correspondant. Je ne suis pas sûr que la rotation tourne autour de l'axe des y et pas d'autres.

// m_rotation is a Quaternion and rotation is a 4x4 view matrix 

// Rotate around y-axis when left arrow pressed 
// This works perfectly 
if (Input::IsKeyDown(Input::KEY_LEFT_ARROW)) { 
    Rotate(Vector3<float>(0, -1, 0), m_sensitivity); 
} 

// When down arrow is pressed, rotate around right axis 
// This rotates around strange axis 
if (Input::IsKeyDown(Input::KEY_DOWN_ARROW)) { 
    Rotate(m_rotation.GetRight(rotation), m_sensitivity); 
} 

// Rotate methods 
void Camera::Rotate(const Vector3<float> &axis, float angle) { 
    Rotate(Quaternion(axis, angle)); 
} 

void Camera::Rotate(const Quaternion &quaternion) { 
    m_rotation = Quaternion((quaternion * m_rotation).Normalized()); 
} 

// Quaternion code 
Quaternion(const Vector3<float> &vect, float angle) { 
    float sinAngle = sinf(angle/2.0f); 
    float cosAngle = cosf(angle/2.0f); 

    (*this)[ 0 ] = vect[ 0 ] * sinAngle; 
    (*this)[ 1 ] = vect[ 1 ] * sinAngle; 
    (*this)[ 2 ] = vect[ 2 ] * sinAngle; 
    (*this)[ 3 ] = cosAngle; 
} 

inline Quaternion operator*(const Quaternion &quat) const { 
    Quaternion ret; 

    ret[ 3 ] = ((*this)[ 3 ] * quat[ 3 ]) - ((*this)[ 0 ] * quat[ 0 ]) - ((*this)[ 1 ] * quat[ 1 ]) - ((*this)[ 2 ] * quat[ 2 ]); 
    ret[ 0 ] = ((*this)[ 3 ] * quat[ 0 ]) + ((*this)[ 0 ] * quat[ 3 ]) + ((*this)[ 1 ] * quat[ 2 ]) - ((*this)[ 2 ] * quat[ 1 ]); 
    ret[ 1 ] = ((*this)[ 3 ] * quat[ 1 ]) + ((*this)[ 1 ] * quat[ 3 ]) + ((*this)[ 2 ] * quat[ 0 ]) - ((*this)[ 0 ] * quat[ 2 ]); 
    ret[ 2 ] = ((*this)[ 3 ] * quat[ 2 ]) + ((*this)[ 2 ] * quat[ 3 ]) + ((*this)[ 0 ] * quat[ 1 ]) - ((*this)[ 1 ] * quat[ 0 ]); 

    return ret; 
} 

inline Vector3<float> GetRight(const Matrix4<float> &viewMatrix) const { 
    return Vector3<float>(rotation[ 0 ][ 0 ], rotation[ 1 ][ 0 ], rotation[ 2 ][ 0 ]); 
} 

Toute aide ou conseil est grandement apprécié. Merci.

Répondre

1

Après quelques jours d'essai de toutes sortes de choses, j'ai trouvé le problème. J'ai oublié que les quaternions sont non commutatifs lorsqu'ils sont multipliés. Cela a fait tourner la caméra de façon étrange. Donc, pour résoudre le problème, tout ce que j'avais à faire était de changer ce code.

void Camera::Rotate(const Quaternion &quaternion) { 
    m_rotation = Quaternion((quaternion * m_rotation).Normalized()); 
} 

A cette ...

void Camera::Rotate(const Quaternion &quaternion) { 
    m_rotation = Quaternion((m_rotation * quaternion).Normalized()); 
} 

Je voulais poster ce dans l'espoir qu'il aide quelqu'un à l'avenir.