Estou desenhando uma cena em que a câmera se move livremente sobre o universo. A classe câmera mantém o controle do ponto de vista (ou olhada ponto), a posição da câmera, eo vetor para cima. Esses vetores / pontos são passados para o gluLookAt.
A panorâmica e o zoom são quase triviais de implementar. No entanto, eu estou achando rotação sobre o olhar ponto a ser muito mais de um problema. Eu quero escrever uma função Camera.rotate que tem 2 ângulos, um que gira para cima / baixo e outro que gira para a esquerda / direita ao longo de uma esfera imaginária que é centralizada na aparência do ponto.
Existe uma maneira fácil de fazer isso?
Eu (brevemente) li sobre quaternions, mas queria ver se havia uma solução mais fácil, dada a construção relativamente simples da minha cena.
Respostas:
O que você está pedindo é chamado rotação de Arcball. Quaternions são a solução fácil somente se você entender como eles funcionam. Você pode conseguir o mesmo sem quaternions.
Pré-requisitos
Você sabe como girar objetos em geral? Digamos que você tenha um objeto na origem. Você sabe como você o gira (dica: multiplique por alguma matriz de rotação)? Se sim, suponho que você saiba o que acontecerá se você traduzir o objeto primeiro e depois girá-lo?
Você deve saber como calcular uma matriz de rotação a partir do eixo angular (fácil como torta, veja a infinidade de equações on-line, muitas delas fornecem o código também)
Solução
Ressalvas
Você terá que procurar certos casos ou singularidades nas quais sua câmera irá parar de funcionar. Olhando para baixo / para cima, por exemplo. Vou deixar você descobrir como lidar com isso.
EDIT1: Como recalcular os vetores ortonormais da câmera
Você já sabe a direção da câmera ((cameraPos - focusPoint) .normalize ()). Agora suponha que a câmera esteja acima de + Y (ou seja, o eixo superior atual do seu mundo é ... depende de você). Agora simplesmente cruze a direção com a seta para cima para acertar . Feito? Não! Seu vetor ativo não é mais ortogonal aos outros dois. Para corrigir isso, cruz direita com direção e você obter o seu novo -se .
Observe que o Gram-Schmidt é realmente o que deve ser usado para ortonormalizar vetores.
Novamente, tome nota das advertências, pois isso não funcionará em alguns casos (a direção é paralela à alta, por exemplo).
fonte
normalize(up ^ camFocusVector)
(ou seu oposto se for canhoto).O que você precisa é de uma câmera ArcBall típica, que é basicamente uma câmera que mantém um local de destino e permite que você mova a câmera de uma maneira "esférica" em torno desse alvo.
Está no XNA, mas no IIRC já usei essa implementação antes e funcionou muito bem:
http://roy-t.nl/index.php/2010/02/21/xna-simple-arcballcamera/
fonte
Aqui está o meu código para girar em torno de um ponto, encontrei-me reutilizando-o bastante.
fonte
Este algoritmo muito simples para conseguir isso é incrível:
Sendo P o ponto central sobre o qual você deseja girar (o ponto "olhar" ou "alvo"):
Eu usei e é legal.
Fonte encontrada no stackoverflow no site da irmã: /programming/287655/opengl-rotating-a-camera-around-a-point
fonte