2013-03-22 11 views
5

Ho bisogno di alcuni suggerimenti sull'approccio migliore per un'attività di rotazione in OpenGL. So come ruotare gli oggetti nello spazio 3D usando i quaternioni, posso tradurli, tutto bene e bene.Come raggruppare più oggetti allo scopo di ruotarli come un'unità?

Ma voglio sapere il modo migliore per trattare una raccolta di oggetti diversi come una singola entità ai fini della rotazione. Ad esempio, supponiamo di avere una scrivania con degli oggetti. Ognuno ha la sua traduzione e rotazione, ma ora voglio ruotare l'intera scrivania e tutto su di essa, mantenendo gli altri oggetti nella stanza in posizione. Ciò significa che gli oggetti sul bordo esterno della scrivania ruotano e si traducono anche attorno al centro della scrivania, mentre gli oggetti al centro potrebbero semplicemente ruotare ma altrimenti rimanere in posizione, o semplicemente non tradursi tanto, a seconda della loro distanza dal asse di rotazione.

Sembra che un modo piuttosto inelegante per farlo è quello di ruotare e tradurre individualmente ogni oggetto sulla scrivania, così come la scrivania stessa, sapendo dove si trova l'asse di rotazione. Forse questo è l'unico buon modo per farlo, ma esiste una tecnica per "raggruppare" oggetti disparati per questo scopo?

+2

Se stai chiedendo di OpenGL ES, * non usare * il tag OpenGL. –

+1

Le tecniche di rotazione e matrice in questo esempio si applicano a OpenGL e OpenGL ES. Che dire di questa domanda è specifica per OpenGL ES? – johnbakers

+0

Con quella logica, non si tratta di * qualsiasi * forma di OpenGL, dal momento che qualsiasi API grafica 3D utilizza le stesse tecniche. Pertanto, non dovrebbe avere * qualsiasi * tag OpenGL. –

risposta

3

Quello che stai cercando sono le gerarchie di trasformazione. Gli oggetti sulla scrivania sono posizionati rispetto alla scrivania o, in altre parole, nel sistema di coordinate della scrivania. Quindi, consente di designare M_Desk come la trasformazione che definisce il posizionamento della scrivania e il sistema di coordinate locale di esso. Quindi lascia che sia M_Pencilbox la trasformazione della scatola di matite in piedi sulla scrivania in relazione alla scrivania. E una matita nella scatola delle matite sarebbe posizionata in relazione alla scatola delle matite.

Quindi la matita passa attraverso una gerarchia di trasformazioni. Ricorda che nella colonna la notazione principale usata dalle cose OpenGL "scorre" attraverso la catena di trasformazione dall'ultima trasformazione a prima (o da destra a sinistra quando viene scritta).

Ogni trasformazione, come M_Desk per esempio, è una matrice 4 × 4 che può essere costruito il solito modo: Rotazioni, traduzioni, scaglie, ecc

Quindi, per trasformare i vertici di una matita che ci si applicano

la seguente trasformazione

… · M_Desk · M_Pencilbox · v_Pencil 

Ovviamente la scrivania potrebbe essere in relazione a qualcosa di diverso, come una stanza. All'inizio di quella catena di trasformazione sarebbe la trasformazione della vista. In modo efficace stiamo costruendo una matrice modelview qui.

In termini di moderno OpenGL, ogni volta che si incontra un ramo nella gerarchia di trasformazione (si pensi alle directory in un file system), si crea una copia della catena di trasformazione costruita finora, in modo da non avere riavviare da capo per ogni ramo.

Fatemi sapere se avete bisogno di ulteriori clearification.

+0

questo è molto interessante e utile; Devo pensarci un po 'di più e provare a sperimentare e poi farti sapere qualsiasi domanda. Apprezzo molto la spiegazione. – johnbakers

+0

Ok penso di averlo capito, puoi confermare. Supponiamo che abbia trasformato la scrivania, ha una matrice 'M_Desk'. Ora voglio posizionare il pencilbox su di esso. Nel mio vertex shader, ho solo un'uniforme per la matrice modelview, quindi invio a quella uniforme una matrice creata per la prima volta come 'M_Pencilbox * M_Desk' - in questo ordine, poiché questo è nel codice C++ non nello shader. Dopo questa chiamata, prendo una copia di questa matrice combinata, chiamiamola 'M_Copy' e applicala a ciascuna matita come' M_Pencil * M_Copy' e invialo allo shader come modelview prima di renderizzare ogni matita. Corretta? – johnbakers

+0

@SebbyJohanns: Sì, ma l'ordine dovrebbe essere associativo, ovvero la trasformazione aggiuntiva da applicare va a destra. Ovviamente con matrici di trattamento OpenGL usate da alcune altre librerie come trasposte l'ordine può scambiare (A · B = trasposto (B) · trasposto (A)); come probabilmente sapete, la moltiplicazione della matrice non è commutativa (cioè A · B =/= B · A). – datenwolf

3

Ciò è generalmente ottenuto utilizzando una sorta di grafico di scena che incorpora una gerarchia di trasformazione.

Una versione minima semplice sarebbe avere un albero in cui ogni nodo contiene un oggetto, una trasformazione e un elenco di nodi figlio. La trasformazione è relativa al nodo genitore.

Quindi gli oggetti sulla scrivania sarebbero i bambini della scrivania stessa.

La trasformazione per ogni dato oggetto è la concatenazione della trasformazione di quell'oggetto con tutti i suoi genitori nell'albero.Ci sono molti modi per farlo, ma la funzionalità GL "vecchia scuola" fornisce uno stack di matrici per questo scopo. Si moltiplica la matrice locale per un nodo, si disegna la geometria per quel nodo, si disegnano in modo ricorsivo tutti i nodi figli e quindi si spegne la matrice.

+0

Molto apprezzato. Ci penserò su questo fine settimana. – johnbakers

+0

Poiché utilizzo gli shader, non gli stack di matrici, e eseguirò la gerarchia di trasformazione in C++ e quindi invierò la trasformazione finale a un vertex shader, dovrei invece fare qualcosa in C++ come nell'esempio ma con 'childMatrix * parentMatrix' e quindi invia quella matrice singola completata da C++ come singola matrice modelview allo shader – johnbakers

+0

Sì. Tuttavia, per archiviare/elaborare le matrici, l'approccio generale prevede che la CPU comprima la gerarchia prima di passare la geometria e la matrice finale alla GPU. GL ha usato una pila, spesso memorizzo la matrice globale nell'albero e/o ho una matrice pre-elaborata di matrici che può essere riempita e acceduta in modo efficiente. – JasonD