Как простые вызовы Pitch () и Yaw () могут привести к тому, что камера в конце концов развернется ()? - PullRequest
2 голосов
/ 24 апреля 2009

Я кодирую основную игру 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 and Yaw, я не понимаю, как это возможно.

Вот код, который я использую для класса камеры: http://pastebin.com/m20d2b01e

Насколько я знаю, у меня не должно быть «прокручивания» камеры. Он должен просто отклоняться вверх или вниз или отклоняться влево и вправо. НЕ катит.

Что может быть причиной этого?

Ответы [ 6 ]

11 голосов
/ 24 апреля 2009

Поздравляем - вы открыли теорию групп Ли!

Да, это возможно. Исход серии преобразований зависит от порядка, в котором они выполняются. Делать шаг с последующим рысканием - это не то же самое, что делать рыскание с последующим на шаг. На самом деле в пределе бесконечно малых рысканий и шаг, разница составляет чистый рулон; генерал дело немного сложнее.

(Физики называют это «коммутационными Ротационная группа ".)

Если вы знакомы с матрицами вращения, вы можете решить их довольно легко

7 голосов
/ 24 апреля 2009

Вам, вероятно, потребуется использовать кватернионы для составления поворотов, если вы этого еще не сделали. Это позволяет избежать проблемы блокировки карданного подвеса , которую можно получить, ориентируя камеру, вращая вокруг 3 осей.

Вот как конвертировать между ними.

5 голосов
/ 24 апреля 2009

Ну, если вы начнете смотреть в горизонтальном направлении к горизонту, наклонитесь вверх на 90 градусов, затем поверните влево на 90 градусов, затем наклонитесь вниз на 90 градусов, вы будете смотреть в том же направлении, что и начали, но горизонт будет быть вертикальным (как если бы вы повернули на 90 градусов влево).

Редактировать : Я думаю, что проблема в том, что рыскание / тангаж / крен были бы уместными, если бы с камерой обращались как с самолетом. То, что вы, вероятно, хотите сделать, это рассматривать его как точку в сфере, отслеживая, где на сфере вы указываете камеру. Вместо рыскания / шага используйте сферические координаты, отслеживая тета (широта) и фи (долгота). Они могут звучать одинаково, но рассмотрим крайний случай, когда камера направлена ​​прямо вверх. С помощью рыскания / тангажа вы все еще можете свободно регулировать рыскание и тангаж в этом прямом направлении. С тэта / фи вы можете регулировать тэту только вниз, и независимо от того, насколько вы скорректировали фи, уменьшение тэты все равно даст вам камеру, параллельную горизонту. Вот как работает камера FPS (вы не можете смотреть так далеко, что смотрите позади себя).

Редактировать 2 : Глядя на код камеры, с которой вы связаны, вы хотите использовать функции rotLati(float angle) и rotLongi(float angle).

4 голосов
/ 24 апреля 2009

Математически причина этого в том, что вращения в трехмерном пространстве не коммутируют. Это означает, что pitch (), за которым следует yaw (), отличается от yaw (), за которым следует pitch (), но следствием этого факта является то, что три вида вращений неразрывно связаны, и вы не можете выполнять два из них, не получая часть третьего. Другими словами, любая последовательность pitch () и yaw () будет производить заметный эффект roll () с течением времени, если только вторая половина последовательности не является точной противоположностью первой. (В этом участвует много довольно сложной математики, но детали не особенно актуальны)

3 голосов
/ 24 апреля 2009

Я считаю, что это обстоятельство называется Gimbal Lock - пример этого с иллюстрациями на странице википедии.

3 голосов
/ 24 апреля 2009

Шаг / рыскание / крен все относительно ориентации вашего автомобиля. Когда вы наклоняетесь вверх / вниз, вы меняете ось рыскания. Точно так же, когда вы рыскаете, вы меняете ось высоты тона. Таким образом, вы можете изменить свою ориентацию способом, аналогичным маневру крена, только с помощью комбинации и маневров тангажа и рыскания.

...