2015-01-03 5 views
1

Для проекта кодирования, который я выполняю, мне был предоставлен класс Quaternion, чтобы облегчить поворот камеры и решить проблему блокировки Gimbal.Использование класса OpenGL Quaternion

Я не так хорошо разбираюсь в использовании кватернионов, поэтому мне было интересно, как я буду применять его в своем классе камеры.

В настоящее время для поворота камеры я использую встроенную функцию glRotatef.

Функции камеры

void Camera::Pitch(float aAngle) 
{ 
    m_fPitchAngle += aAngle; 
} 

void Camera::Roll(float aAngle) 
{ 
    //aAngle = 5.0f; 
    m_fRollAngle += aAngle; 
} 

void Camera::Yaw(float aAngle) 
{ 
    m_fYawAngle += aAngle; 
} 

void Camera::MoveForward(float aDistance) 
{ 
    m_vPosition.z += aDistance; 
} 

void Camera::Strafe(float aDistance) 
{ 
    m_vPosition.x += aDistance; 
} 

Эти переменные используются внутри функции визуализации камеры.

Рендер функция Внутри камеры

// Yaw 
glRotatef(m_fYawAngle, m_vUp.x, m_vUp.y, m_vUp.z); 

// Pitch 
glRotatef(m_fPitchAngle, m_vRight.z, m_vRight.y, m_vRight.z); 

//Roll 
glRotatef(m_fRollAngle, m_vFacing.x, m_vFacing.y, m_vFacing.z); 

//angleBetween = cosf(m_fYawAngle) + m_vPosition.z; 

// Move Forward 
glTranslatef(m_vPosition.x, m_vPosition.y, m_vPosition.z); 

которые в настоящее время используются в функции обновления камеры, внутри переключателя заявление.

Обновление камеры функция

case SDLK_a: 
     Yaw(-kAngleToTurn); 
break; 

case SDLK_d: 
     Yaw(kAngleToTurn); 
break; 

И так далее для других переменных. Вот основной файл заголовка Quaternion, который мне дал.

Quaternion.h

struct Quaternion 
{ 
    float w; 
    Vector3D vec; 

    Quaternion() 
    { 
     vec.x = 0.0f; 
     vec.y = 0.0f; 
     vec.z = 0.0f; 
    } 

    Quaternion(float startW, Vector3D startVec) 
    { 
     vec.x = startVec.x; 
     vec.y = startVec.y; 
     vec.z = startVec.z; 
    } 
}; 

class QuaternionMath 
{ 
public: 
    ~QuaternionMath(); 

    static QuaternionMath* Instance(); 

    void QuaternionToMatrix(Quaternion* q, float m[4][4]); 
    void MatrixToQuaternion(float m[4][4], Quaternion* q); 
    void EulerToQuaternion(float roll, float pitch, float yaw, Quaternion* q); 

    void Multiply(Quaternion* q1, Quaternion* q2, Quaternion* resultingQuaternion); 
    void RotateVector(Quaternion* q, Vector3D* v, Vector3D* resultingVector); 

private: 
    QuaternionMath(); 

private: 
    static QuaternionMath* mInstance; 

}; 

ответ

1

Вместо того чтобы использовать цепочку glRotate вызовов, извлекать 4 × 4 матрицу из экземпляра кватернионов с помощью MatrixToQuaternion и умножить, что на матрицу на вершине стека с glMultMatrix ,

На следующем шаге вы должны избавиться от использования любого кода с использованием стека матриц фиксированной функции OpenGL и использовать что-то вроде GLM или аналогичного.

+0

Как получить доступ к матрице для кватерниона? В настоящее время в моем заголовке камеры у меня есть: 'Quaternion * m_Quaternion;' При входе в СРР через m_Quaternion-> он дает мне 2 варианта: VEC (х, у, г) или ж (с плавающей точкой). – TheCoder95

+0

@ TheCoder95: Если вам нужно задать этот вопрос, он вернется на C++ 101 для вас. Существует класс 'QuaternionMath', он имеет функцию-член MatrixToQuaternion, взяв в себе кватернион и указатель на буфер для матрицы. Вы изображаете остальных. * Честно говоря, стиль кода, данный вам, очень, _very_ плохой. Что такое 'QuaternionMath', гораздо лучше подходит как пространство имен вместо класса. Или было бы разумно дать классу «Quaternion» функцию-член 'toMatrix'. * Вы можете попросить свою TA использовать GLM или принять хороший стиль. – datenwolf

Смежные вопросы