OpenGL Quaternion类的用法

时间:2015-01-03 23:21:01

标签: c++ opengl camera quaternions

对于我正在进行的编码项目,我获得了一个Quaternion类,用于使我的相机旋转更容易并解决万向节锁。

我没有那么精通使用Quaternions所以我想知道如何将它实现到我的相机类中。

目前使用内置的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 个答案:

答案 0 :(得分:1)

不使用glRotate调用链,而是使用MatrixToQuaternion从四元数实例中检索4×4矩阵,然后使用glMultMatrix将其乘以堆栈顶部的矩阵。

在进一步的步骤中,你应该摆脱使用OpenGL固定函数矩阵堆栈的任何代码,并使用像GLM或类似的东西。