Como poderia simplesmente chamar de Pitch () e Yaw () causa a câmera para, eventualmente, rolo (o)?

StackOverflow https://stackoverflow.com/questions/784445

  •  16-09-2019
  •  | 
  •  

Pergunta

Eu estou codificação um jogo básico OpenGL e eu tenho algum código que lida com o mouse em termos de mover a câmera.

Eu estou usando o seguinte método:

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();

}

No entanto, depois de olhar ao redor em círculos você encontrará a câmera começa a "roll" (girar). Desde que eu só estou chamando Pitch and Yaw, eu não vejo como isso é possível.

Aqui está o código que estou usando para minha classe Camera: http://pastebin.com/m20d2b01e

Tanto quanto eu sei, a minha câmera "rolando" não deve acontecer. Ele deve simplesmente lançar para cima e para baixo ou guinar para a esquerda e direita. NÃO rolo.

O que poderia estar causando isso?

Foi útil?

Solução

Parabéns - você descobriu a teoria do grupo Lie!

Sim, é possível. O resultado de uma série de transformações depende da ordem em que são executados. Fazendo um passo seguido por uma guinada não é o mesmo que um fazendo uma guinada, seguido por um arremesso. Na verdade, no limite do infinitamente pequeno bouba e resinas, os valores de diferença para um rolo puro; o general caso é um pouco mais complicado.

(físicos chamam isso de "relações de comutação de o grupo de rotação".)

Se você estiver familiarizado com matrizes de rotação, você pode trabalhar com isso com bastante facilidade.

Outras dicas

Você provavelmente terá que usar quaternions para compor rotações, se você não está fazendo isso já . Isso evita o problema da cardan bloqueio que você pode começar quando orientando uma câmera por rotação em torno de 3 eixos .

Aqui é como converter entre eles.

Bem, se você começar ansioso horizontal para o horizonte, pitch até 90 graus, em seguida, guinada deixou 90 graus, em seguida, afinação para baixo 90 graus, você estaria olhando na mesma direção que você começou, mas o horizonte faria ser vertical (como se você tivesse rolado 90 graus à esquerda).

Editar : Eu acho que o problema é que a guinada / inclinação / rotação seria apropriado se a câmera está sendo tratado como um avião. O que você provavelmente quer fazer é tratá-la como um ponto em uma esfera, mantendo o controle de onde na esfera você está apontando a câmera. Em vez de guinada / passo, usar coordenadas esféricas manter o rasto de teta (latitude) e phi (longitude). Eles podem parecer semelhantes, mas considere o caso extremo em que a câmera está apontando diretamente para cima. Com guinada / campo, você ainda pode livremente ajustar a guinada e passo daquela direção straight-up. Com teta / phi, você só poderia ajustar teta para baixo, e não importa o quanto você ajustado phi, diminuindo theta ainda lhe daria uma câmera que é paralelo ao horizonte. Isto é como FPS trabalho de câmera (você pode não parecer tão longe que você está procurando atrás de você).

Editar 2 : Olhando o código da câmera é ligada ao, você quer estar usando o rotLati(float angle) e rotLongi(float angle) funções

Matematicamente a razão para isso é que as rotações no espaço 3D não comutar. O que isto significa é que pitch () seguido de guinada () não é o mesmo que a guinada () seguido de pitch (), mas uma consequência desse fato é que os três tipos de rotações são indissociáveis ??e você não pode executar qualquer dois deles sem ficar algum do terceiro. Em outras palavras, qualquer sequência de arremesso (es) e de guinada () s produzirá um efeito perceptível rolo () ao longo do tempo, a menos que a segunda metade da sequência é o inverso exacta da primeira metade. (Há muita matemática bastante complexa envolvida nisso, mas os detalhes não são particularmente relevantes)

Passo / guinada / roll são todos relativos à orientação do seu veículo. Quando você lançar para cima / baixo, você muda seu eixo de guinada. Da mesma forma, quando você guinada, você muda seu eixo campo. Portanto, é possível mudar a sua orientação de uma forma semelhante a uma manobra do rolo apenas por uma combinação e Pitch & guinada manobras.

Eu acredito que esta circunstância é chamado Gimbal Bloqueio - há um exemplo disso com ilustrações sobre a página da Wikipedia.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top