飞行模拟器相机

Flight Simulator Camera

编辑: 我已将 video 上传到 youtube,显示现在发生的情况。当我旋转 60 度(俯仰或偏航)时,我会感到奇怪的晃动。如您所见,鼠标输入工作正常(没有不需要的滚动,并且 pitch/yaw 在滚动后在本地发生)

我正在尝试在我正在制作的 OpenGL 游戏中实现飞行模拟器相机。我已经按照 this 页面底部提到的内容进行操作,我对视图矩阵的计算结果是:

my = my * 0.001f; //per-frame delta
mx = mx * 0.001f; //per-frame delta

glm::vec3 pitchAxis = glm::normalize( glm::cross( cameraDirection, cameraUp ) );
glm::vec3 yawAxis = glm::normalize( cameraUp );

glm::quat pitchQuat = glm::angleAxis( (float)my, pitchAxis );
glm::quat yawQuat = glm::angleAxis( (float)mx, yawAxis );

glm::quat comp = yawQuat * pitchQuat;

cameraDirection = cameraDirection * comp;

pitchAxis = glm::cross( cameraDirection, cameraUp );
cameraUp = glm::cross( pitchAxis, cameraDirection );

return glm::lookAt( cameraPosition, cameraPosition + cameraDirection, cameraUp );

我根据鼠标输入计算增量 pitch/yaw 四元数,然后将其应用于相机的方向。然后我使用叉积基于新的俯仰轴重新计算相机的向上矢量。

当我测试它时,我没有在 90 度锁定任何相机,但如果我俯仰和偏航,相机也会开始滚动(不需要)。

this post 中接受的答案建议使用全局 pitch/yaw/roll 值,而不仅仅是我上面使用的增量值。所以我继续尝试这样做:

//using left-handed coordinate system
glm::vec3 yawAxis = glm::vec3( 0.0f, 1.0f, 0.0f );
glm::vec3 pitchAxis = glm::vec3( -1.0f, 0.0f, 0.0f );
//glm::vec3 rollAxis = glm::vec3( 0.0f, 0.0f, -1.0f );

glm::quat yawQuat = glm::angleAxis( yaw, yawAxis );
glm::quat pitchQuat = glm::angleAxis( pitch, pitchAxis );

glm::quat composite = yawQuat * pitchQuat;

cameraDirection = composite * glm::vec3( 0.0f, 0.0f, -1.0f );

glm::quat rollQuat = glm::angleAxis( roll, cameraDirection );
cameraUp = rollQuat * glm::vec3( 0.0f, 1.0f, 0.0f );

return glm::lookAt( cameraPosition, cameraPosition + cameraDirection, cameraUp );

如果鼠标移动,偏航角和俯仰角每帧都会增加。我仍然可以很好地环顾四周,但如果:

我认为第一个问题可以通过在俯仰 > 90 度或 <-90 度时翻转全局俯仰轴的情况来解决。但是我一直在解决第二个问题,因为我的直觉一直在尝试使用我尝试过的第一种方法。

我打算如何实现这款相机是否存在根本缺陷,或者我是否遗漏了一些明显的东西?

让 3D 相机做你想做的事情通常很棘手。由于 中的顺序,您应用您的更改会影响下一次更改。 当您尝试不同的方法时,可以更容易地在单独的步骤中应用俯仰、偏航和滚动的变化,如下所示:

编辑:添加有关本地摄像头的信息space

  • 将俯仰应用于相机方向和相机向上,使用相机本地 space(前向矢量是相机的方向,向上矢量是相机向上)
  • 将偏航应用到相机方向和相机向上,使用新的本地 space
  • 使用新的本地space
  • 将滚动应用于相机方向和相机向上
  • 现在将相机用于您的视图矩阵

这样您就可以在测试时注释掉不同的步骤。当您对结果感到满意时,您可以尝试将这些步骤移动到一起以提高性能,但更改的顺序可能会造成困难。