我正在尝试实现一个围绕原点旋转的相机,在该相机中,我已经成功实现了使用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我不确定此处讨论的数学是否直接转换过来,因此如果错误请纠正我。
最佳答案
这可能是一个解释问题。您的代码看起来正确,但是pitch
可能没有您认为的含义。
当pitch
为0
时,照相机位于球(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)