如何将相机俯仰原点

时间:2018-11-08 17:39:00

标签: c++ opengl camera rotation eigen

我正在尝试实现一个围绕原点旋转的摄像机,在该摄像机中,我已经成功实现了使用gluLookat函数进行偏航的功能。我正在尝试实现俯仰,但是结果有一些问题(俯仰仅在我偏航到某个点然后俯仰时才起作用)。

到目前为止,这是我的尝试:

float distance, // radius (from origin) updated by -, + keys
      pitch,    // angle in degrees updated from W, S keys (increments of +- 10)
      yaw;      // angle in degrees updated from A, D keys (increments of +- 10)


view = lookAt(
        Eigen::Vector3f(distance * sin(toRadians(pitch)) * cos(toRadians(yaw)), distance * sin(toRadians(pitch)) * sin(toRadians(yaw)), distance * cos(toRadians(pitch))),
        Eigen::Vector3f(0.0f, 0.0f, 0.0f),
        Eigen::Vector3f(0.0f, 0.0f, 1.0f));

proj = perspective(toRadians(90.0f), static_cast<float>(width) / height, 1.0f, 10.0f);

我觉得我的问题是Up向量,但是我不确定如何正确更新(同时我认为它很好,因为我一直希望相机的方向保持不变,我真的只是想移动相机的位置)

编辑:我想补充一点,我正在计算此处的基于位置的信息:http://tutorial.math.lamar.edu/Classes/CalcIII/SphericalCoords.aspx我不确定此处讨论的数学是否可以直接转换过来,所以请纠正我如果有错。

1 个答案:

答案 0 :(得分:2)

这可能是一个解释问题。您的代码看起来正确,但是pitch可能没有您认为的含义。

pitch0时,相机位于球体(0, 0, 1)的北极处。这有点问题,因为您的上矢量和视图方向变为平行,并且您将无法获得有效的变换。然后,当pitch增大时,摄像机向南移动,直到pitch=PI到达南极为止。您的代码应该可以在任何不重要的地方工作。您可能想交换sin(pitch)cos(pitch)以在pitch=0时从赤道开始(并支持正负音高)。

实际上,我更喜欢将这类相机更直接地建模为矩阵的组合:

view = Tr(0, 0, -distance) * RotX(-pitch) * RotY(-yaw)

Tr是一个平移矩阵,RotX是绕x轴的旋转,而RotY是绕y轴的旋转。假设y轴朝上。如果要使另一个轴上升,则只需添加一个相应的旋转矩阵即可。例如,如果您希望z轴朝上,则

view = Tr(0, 0, -distance) * RotX(-pitch) * RotY(-yaw) * RotX(-Pi/2)