怎么可以简单地调用Pitch()和Yaw()导致相机最终Roll()?

时间:2009-04-24 03:50:56

标签: c++ opengl camera glut

我正在编写一个基本的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,所以我看不出这是怎么回事。

以下是我用于我的Camera类的代码:http://pastebin.com/m20d2b01e

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

导致这种情况的原因是什么?

6 个答案:

答案 0 :(得分:11)

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

是的,这是可能的。一系列变革的结果 取决于它们执行的顺序。做一个球场 接下来是偏航与做偏航不一样 一个球场。事实上,在无限小的雅司病的极限 和音高,差异相当于一个纯粹的滚动;一般 案件有点复杂。

(物理学家称之为“交换关系” 轮换组“。)

如果你熟悉旋转矩阵,你可以解决它 很容易

答案 1 :(得分:7)

如果你还没有这样做,你可能需要使用quaternions来组合旋转。这样可以避免在通过围绕3个轴旋转定向摄像机时可以获得gimbal lock的问题。

Here is how to convert between them.

答案 2 :(得分:5)

好吧,如果你开始向前看水平到地平线,向上倾斜90度,然后向左倾斜90度,然后向下倾斜90度,你将看到与你开始时相同的方向,但地平线将是垂直的(就好像你向左倾90度)。

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

编辑2 :查看您关联的相机代码,您希望使用 rotLati(float angle) rotLongi(float angle) < / strong>功能。

答案 3 :(得分:4)

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

答案 4 :(得分:3)

俯仰/偏航/侧倾都与您车辆的方向有关。当您向上/向下俯仰时,您可以改变偏航轴。同样,当您偏航时,您可以更改俯仰轴。因此,可以通过组合和俯仰和放大来改变您的方向,类似于滚动操作。偏航演习。

答案 5 :(得分:3)

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