飞行模拟器相机

时间:2016-05-30 03:43:00

标签: camera game-engine quaternions

编辑:我已经向youtube上传了video,其中显示了现在正在发生的事情。当我旋转60度(俯仰或偏航)时,我会发出奇怪的震动。正如您所看到的,鼠标输入工作正常(没有不需要的滚动,滚动后本地发生俯仰/偏航)

我试图在我制作的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 );

我根据鼠标输入计算增量俯仰/偏航四元数,然后将其应用到摄像机的方向。然后,我使用交叉产品基于新的俯仰轴重新计算相机的向上矢量。

当我测试它时,我不会在90度处获得任何相机锁,但如果我俯仰和偏转,那么相机也会开始滚动(不想要)。

this帖子中接受的答案建议使用全局音高/偏航/横摇值,而不仅仅是我上面使用的增量值。所以我继续尝试这样做:

//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度并继续前进它似乎相机翻转/翻转。
  • 我首先滚动,俯仰/偏航仍然是关于全局轴(这是代码所期望的)而不是我认为它应该是的本地摄像机轴,这就是我尝试第一种方法的原因。 ..

我认为第一个问题可以用一个翻转全局pitchAxis的情况来解决,当音高&gt; 90度或<-90度。但是我坚持修复第二个问题,因为我的直觉一直在尝试使用我尝试过的第一个方法。

我是如何实施这款相机的一个根本缺陷,还是我错过了一些明显的东西?

1 个答案:

答案 0 :(得分:2)

让3D相机做你想做的事通常很棘手。因为女巫的顺序你应用你的变化会对下一次变化产生影响。 当你尝试不同的方法时,可以更容易地在不同的步骤中应用俯仰,偏航和滚动的变化,如下所示:

编辑:添加有关相机本地空间的信息

  • 使用摄像机局部空间向摄像机方向和摄像机应用俯仰(向前矢量是摄像机方向,向上矢量是摄像机)
  • 使用新的本地空间
  • 向摄像机方向和摄像机应用偏航
  • 使用新的本地空间
  • 向相机方向和相机应用滚动
  • 现在将相机用于视图矩阵

这样,您可以在测试时注释掉不同的步骤。当您对结果感到满意时,您可以尝试将步骤一起移动以获得性能,但更改的顺序可能会使其变得困难。