2

我正在编写一个基本的 OpenGL 游戏,并且我有一些代码可以在移动相机方面处理鼠标。

我正在使用以下方法:

int windowWidth = 640;
int windowHeight = 480;

int oldMouseX = -1;
int oldMouseY = -1;

void mousePassiveHandler(int x, int y)
{
    int snapThreshold = 50;

    if (oldMouseX != -1 && oldMouseY != -1)
    {
        cam.yaw((x - oldMouseX)/10.0);
        cam.pitch((y - oldMouseY)/10.0);


        oldMouseX = x;
        oldMouseY = y;

        if ((fabs(x - (windowWidth / 2)) > snapThreshold) || (fabs(y - (windowHeight / 2)) > snapThreshold))
        {
            oldMouseX = windowWidth / 2;
            oldMouseY = windowHeight / 2;
            glutWarpPointer(windowWidth / 2, windowHeight / 2);
        }
    }
    else
    {
        oldMouseX = windowWidth / 2;
        oldMouseY = windowHeight / 2;
        glutWarpPointer(windowWidth / 2, windowHeight / 2);
    }


    glutPostRedisplay();

}

但是,环顾四周后,您会发现相机开始“滚动”(旋转)。因为我只打电话给 Pitch 和 Yaw,我不明白这是怎么可能的。

这是我用于我的相机类的代码:http: //pastebin.com/m20d2b01e

据我所知,我的相机“滚动”不应该发生。它应该简单地上下俯仰或左右偏航。不滚动。

这可能是什么原因造成的?

4

6 回答 6

11

恭喜——你发现了李群理论!

是的,这是可能的。一系列转换的结果取决于它们的执行顺序。做一个俯仰然后偏航不同于做一个偏航,然后是俯仰。事实上,在无限小的偏航和俯仰范围内,差异相当于一个纯粹的横滚。一般情况要复杂一些。

(物理学家称其为“旋转群的交换关系”。)

如果您熟悉旋转矩阵,则可以很容易地计算出来。

于 2009-04-24T04:09:05.423 回答
7

如果您还没有这样做,您可能需要使用四元数来组成旋转。这避免了在通过围绕 3 个轴旋转来定位相机时可能会遇到的云台锁定问题。

以下是它们之间的转换方法。

于 2009-04-24T04:10:27.980 回答
5

好吧,如果你开始看向地平线,向上俯仰 90 度,然后向左偏航 90 度,然后向下俯仰 90 度,你会看到与开始时相同的方向,但地平线将是垂直的(好像你向左滚了 90 度)。

编辑:我认为问题在于,如果将相机视为飞机,偏航/俯仰/滚动将是合适的。您可能想要做的是将其视为球体中的一个点,跟踪您将相机指向球体的哪个位置。使用球坐标来跟踪 theta(纬度)和 phi(经度),而不是偏航/俯仰。它们可能听起来很相似,但请考虑相机直接指向上方的极端情况。使用偏航/俯仰,您仍然可以从该笔直方向自由调整偏航和俯仰。使用 theta/phi,您只能向下调整 theta,无论您调整多少 phi,减小 theta 仍然会给您一个平行于地平线的相机。这就是 FPS 相机的工作方式(你不能往下看太远以至于你在后面看)。

编辑 2:查看您链接到的相机代码,您想要使用rotLati(float angle)androtLongi(float angle)功能。

于 2009-04-24T03:57:57.853 回答
4

从数学上讲,其原因是 3D 空间中的旋转不会通勤。这意味着 pitch() 后跟 yaw() 与 yaw() 后跟 pitch() 不一样,但事实的结果是这三种旋转是密不可分的,你不能执行任何其中两个没有得到第三个。换句话说,任何 pitch()es 和 yaw()s 序​​列都会随着时间的推移产生明显的 roll() 效果,除非序列的后半部分与前半部分完全相反。(这涉及到很多相当复杂的数学,但细节并不是特别相关)

于 2009-04-24T04:14:24.897 回答
3

俯仰/偏航/滚动都与您的车辆方向有关。当你向上/向下俯仰时,你会改变你的偏航轴。同样,当你偏航时,你会改变你的俯仰轴。因此,可以通过组合以及俯仰和偏航操作以类似于滚动操作的方式改变您的方向。

于 2009-04-24T04:02:18.950 回答
3

我相信这种情况被称为Gimbal Lock - 在维基百科页面上有一个带有插图的示例。

于 2009-04-24T04:08:15.410 回答