我尝试实现一个基于四元数数学的 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/