2012-02-02 11 views
5

La mia fotocamera ruota attorno a un punto quando provo a cambiare l'orientamento. Se ruoto la mia macchina fotografica, diciamo, 30 gradi sull'asse Y, invece di guardare la fotocamera di 30 gradi a destra, la fotocamera ruota attorno al punto che stava guardando.Perché la mia fotocamera ruota attorno a un punto con questa matematica?

o is the camera, A and B are 3D models. The lines show line-of-sight. 
This is what I expect: 
    A B 
    | >/
    |/
    |/
    |/ 
    o 

This is what actually happens: 
    A B 
    |\ 
    | \ 
    | \ 
    | > \ 
      o 

Ora, dalla mia comprensione, al fine di spostare la telecamera devo muovere il mondo per l'inverso di tale importo. Quindi, se voglio spostare +1 sull'asse Z, traduco il mondo -1 nell'asse Z. Dal momento che sto usando i quaternioni per rappresentare gli orientamenti, io uso l'inverso del quaternio della telecamera (poiché gli orientamenti sono sempre quaternioni di unità, io ottimizzo usando il coniugato invece di calcolare l'inverso) per ruotare il mondo della giusta quantità.

Ecco come convertire un quaternione di una matrice, in cui q è il quaternione invertita:

[1 - 2 * (q.y * q.y + q.z * q.z) 2 * (q.x * q.y - q.w * q.z)  2 * (q.x * q.z + q.w * q.y)   0] 
|2 * (q.x * q.y + q.w * q.z)  1 - 2 * (q.x * q.x + q.z * q.z) 2 * (q.y * q.z - q.w * q.x)   0| 
|2 * (q.x * q.z - q.w * q.y)  2 * (q.y * q.z + q.w * q.z)  1 - 2 * (q.x * q.x + q.y * q.y)  0| 
[0         0         0         1] 

Dopodiché, ho impostato la quota di traslazione della matrice:

[... ... ... -x] 
|... ... ... -y| 
|... ... ... -z| 
[0  0  0  1] 

Infine Lo moltiplico sullo stack di matrici modello-view, quindi eseguo il rendering di tutti i miei oggetti. Sono abbastanza sicuro che questa matematica sia corretta, ma non produce i risultati che mi aspettavo. Chiaramente i vettori forward e right sono il problema, quindi la mia unica domanda è perché sbagliano e come dovrebbero essere impostati se voglio ottenere i risultati che mi aspetto. Grazie.

MODIFICA: Ho trovato la soluzione da this guy's quaternion camera class. Per prima cosa costruisco una matrice di rotazione come facevo prima, ma poi prendo i vettori di colonna della matrice dalla prima, seconda e terza colonna (rispettivamente xa, ya e za). Poi ho impostato il componente di traslazione della matrice in questo modo:

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

quindi la matrice risultante può essere moltiplicato in pila matrice modelview, e funziona perfettamente.

+0

Trasforma la tua soluzione in una soluzione e accettala. Ecco come contrassegniamo le domande risolte da queste parti. Inoltre penso che ti meriti qualche spiegazione su cosa sta succedendo. Scriverò una risposta per questo. – datenwolf

risposta

1

EDIT: Ho trovato la soluzione dalla classe di quaternion di questo ragazzo. Per prima cosa costruisco una matrice di rotazione come facevo prima, ma poi prendo la colonna vettori della matrice dalla prima, seconda e terza colonna (xa, ya e za rispettivamente). Poi ho impostato il componente traslazionale del matrice simili:

[... ... ... -xa.dotProduct(cameraPos)] 
|... ... ... -ya.dotProduct(cameraPos)| 
|... ... ... -za.dotProduct(cameraPos)| 
[... ... ... ...      ] 

quindi la matrice risultante può essere moltiplicato sulla matrice modelview pila, e funziona perfettamente.

Sì, questo è esattamente ciò che avrei suggerito, solo un po 'diverso. Devi capire che OpenGL non ha una videocamera, ma invece devi semplicemente spostare il mondo nella direzione opposta, quindi devi trovare la matrice di trasformazione inversa.

Una telecamera ruota e si muove. Questo rende le cose molto semplici. Il rovescio della traduzione è lo stesso vettore con il segno opposto e l'inverso di una matrice di rotazione è la sua trasposizione (colonna e righe scambiate). Ora guardare una matrice di trasformazione omogenea come OpenGL li usa:

R t 
0 1 

La parte superiore sinistra 3 × 3 è la parte di rotazione, la colonna più a destra è il vettore di traslazione. Penso che il resto ti sia già immaginato.

0

Per essere onesti, provare a trovare una matrice da moltiplicare per la matrice vista modulo è davvero complicato e molto soggetto a errori. C'è molta confusione e casi speciali. Ad esempio, se si guarda a 90 gradi in alto, due degli assi diventano gli stessi. Un problema logico è questo: se stai ruotando la testa all'indietro, in modo da passare attraverso il punto in alto, il tuo vettore verso l'alto dovrebbe essere invertito, giusto? Ma cosa succede se ti manca da un grado 0,0001? allora dovresti girare la testa intorno a quel punto in modo che il tuo vettore sia ancora attivo.

A mio parere, il modo migliore è quello di affrontare il problema da un'altra prospettiva. Supponiamo due casi:

  • Upside down impossibile:
    • Tenere un punto per la posizione della telecamera e la latitudine/longitudine per la direzione. Con le operazioni sin/cos semplici di è possibile ottenere un vettore di direzione. Il tuo up vettore è (0, 1, 0)
    • svolta è semplicemente cambiando la latitudine e la longitudine
  • Upside down possibile:
    • Oltre alla posizione della fotocamera, tenere entrambe e vettori di destinazione.
    • Durante la svolta, calcolare a destra = target x su e quindi modificare target su x * right + y * su
    • È quindi necessario normalizzare il vettore di destinazione e calcolare di nuovo. Molti casi per gestire lo .

Dopo tutti questi, è sufficiente chiamare gluLookAt.

+0

"Per essere onesti, provare a trovare una matrice da moltiplicare alla matrice vista modulo è davvero complicato e molto incline agli errori." No non lo è. Le matrici sono il modo più efficace per riflettere sugli orientamenti relativi delle coordinate. Ciascuna delle prime 3 colonne è uno dei vettori di base del sistema di coordinate trasformato. La quarta colonna è la traduzione relativa. È molto più semplice scrivere una macchina fotografica dalla vista e dai vettori di destinazione, quindi con tutta la trigonometria in mezzo. – datenwolf

+0

Lo so. Quello che sto dicendo è che, se ad esempio hai 3 diversi tipi di movimenti (ad esempio, sposta, gira e scorri) fino al prossimo fotogramma, è molto più facile farlo con la posizione/latitudine/longitudine e infine convertirlo in una matrice, che cercare di applicare ogni operazione alla matrice del precedente. – Shahbaz

Problemi correlati