opengl - 基于四元数的相机

标签 opengl graphics 3d directx quaternions

我尝试实现一个基于四元数数学的 FPS 相机。 我存储一个名为 _quat 的旋转四元数变量,并在需要时将其乘以另一个四元数。这是一些代码:

void Camera::SetOrientation(float rightAngle, float upAngle)//in degrees
{
    glm::quat q = glm::angleAxis(glm::radians(-upAngle), glm::vec3(1,0,0));
              q*= glm::angleAxis(glm::radians(rightAngle), glm::vec3(0,1,0));

    _quat = q;
}

void Camera::OffsetOrientation(float rightAngle, float upAngle)//in degrees
{
    glm::quat q = glm::angleAxis(glm::radians(-upAngle), glm::vec3(1,0,0));
              q*= glm::angleAxis(glm::radians(rightAngle), glm::vec3(0,1,0));

    _quat *= q;
}

应用程序可以通过GetOrientation请求方向矩阵,这只是将四元数转换为矩阵。

glm::mat4 Camera::GetOrientation() const
{
    return glm::mat4_cast(_quat);
}

应用程序通过以下方式更改方向:

int diffX = ...;//some computations based on mouse movement
int diffY = ...;

camera.OffsetOrientation(g_mouseSensitivity * diffX, g_mouseSensitivity * diffY);

这会导致围绕几乎所有轴的不良混合旋转。我做错了什么?

最佳答案

问题在于您累积旋转的方式。无论您使用四元数还是矩阵,这都是相同的。将表示俯仰和偏航的旋转与另一个旋转相结合将引入滚转。

到目前为止,实现 FPS 相机的最简单方法是简单地累积航向和俯仰的变化,然后在需要时转换为四元数(或矩阵)。我会将相机类中的方法更改为:

void Camera::SetOrientation(float rightAngle, float upAngle)//in degrees
{
    _rightAngle = rightAngle;
    _upAngle = upAngle;
}

void Camera::OffsetOrientation(float rightAngle, float upAngle)//in degrees
{
    _rightAngle += rightAngle;
    _upAngle += upAngle;
}

glm::mat4 Camera::GetOrientation() const
{
    glm::quat q = glm::angleAxis(glm::radians(-_upAngle), glm::vec3(1,0,0));
              q*= glm::angleAxis(glm::radians(_rightAngle), glm::vec3(0,1,0));
    return glm::mat4_cast(q);
}

关于opengl - 基于四元数的相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28530702/

相关文章:

c++ - glBindVertexArrays 与 glBindBuffer 的作用是什么,它们的关系是什么?

c++ - 如何确保 Qt Widget.repaint 已完成运行?

opencv - 从opencv中的视差图生成3D图像

c++ - 如何找到鼠标单击和 3D 网格的交集?

c++ - OpenGL:我可以将 glBindBuffer 与 glBindBufferARB 混合使用吗?

c++ - Opengl C++ : How do I make parts of a texture transparent?

r - 如何在 R 中的 ggplot2 中的瓷砖上放置标签?

java - BufferedImage 到数组

java - 关于removeChild()函数的问题

c++ - OpenGL 天空盒不显示