2011-11-06 12 views
5

Sto provando a creare un grafico di scena per il mio gioco 3D in cui le trasformazioni di ogni oggetto sono relative al suo genitore. Ogni nodo del grafico ha un vettore Rotazione, Ridimensionamento e Traslazione.3D relativo alle trasformazioni assolute

Qual è il modo corretto di combinare le matrici di trasformazione relative per ottenere la trasformazione assoluta di un oggetto? Sarei felice se potessi anche spiegare la tua soluzione.


Ecco un esempio di farlo sbagliato:
Questo in realtà si è rivelata la soluzione:

Matrix GetAbsoluteTransformation() 
{ 
    if (!this.IsRoot()) 
    { 
     return this.Transformation * this.Parent.GetAbsoluteTransformation(); 
    } 
    else 
    { 
     return this.Transformation; 
    } 
} 

In questo caso, quando il nodo padre viene ruotato, ridimensionato o spostato, il bambino viene trasformato nella stessa quantità, che è un comportamento corretto! Ma il bambino ruoterà solo attorno alla propria origine e non si muoverà attorno all'origine del genitore.


Applicazioni:

c'è un modello di auto a quattro ruote. Le ruote sono relative posizionate attorno all'origine dell'auto. Le ruote possono ruotare proprio come fanno le ruote reali. Se ora ruoto la macchina, le ruote dovrebbero rimanere sempre attaccate ad essa. In questo caso l'auto è la radice e le ruote sono i nodi figlio.

Un altro esempio potrebbe essere un modello del sistema solare. I pianeti ruotano intorno al proprio asse, si muovono intorno al sole e le lune si muovono attorno ai pianeti.

+0

Scopriamo che la mia prima idea di come farlo, che ho poi considerato non adatto, era in realtà la soluzione! Ho passato le ultime ore a cercare di risolvere questo problema. * facepalm * Grazie a tutti per l'aiuto rapido e preciso! – Lucius

risposta

3

Per quanto riguarda il vostro "come farlo sbagliato", odio romperlo a voi, ma non è male; piuttosto, è incompleto. È necessario eseguire questo tipo di lavoro indipendentemente dalla relazione genitore/figlio.

Ecco un esempio di questo: La ruota è attaccata alla macchina proprio come hai detto tu. Se si traduce o si ruota l'auto, non è necessario toccare le ruote: si trovano nella stessa posizione relativa all'auto. Tuttavia, quando si tenta di ottenere la nuova posizione della ruota nel 'mondo reale', è necessario attraversare l'albero, applicando le trasformazioni della matrice man mano che si procede. Tutto funziona, giusto?

Quando si ruota un oggetto, ruota attorno alla sua origine PROPRIA. Quindi una ruota dovrebbe probabilmente ruotare attorno al suo asse ye un pianeta attorno al suo asse z. Ma ora se hai bisogno di spostare un pianeta "attorno al sole", stai facendo qualcosa di completamente diverso. Questo deve essere calcolato separatamente. Questo non vuol dire che non sarà facilitato usando parte della stessa partita che hai già (anche se non posso dirlo con certezza senza fare il calcolo da solo) ma è completamente diverso.

Stai guardando effettivamente cambiando lo stato dell'oggetto. Questa è la bellezza del grafico della scena! Se non avevi un grafico di scena, dovresti calcolare tutti i vari valori fino alla scena principale e poi fare tutti i tipi di matematica. Qui, devi solo fare un po 'di trigge e algebra per muoverti nel pianeta (puoi google la meccanica celeste) e spostare il pianeta rispetto alla sua stella. La prossima volta che la scena principale chiede dove si trova il pianeta, andrà giù nel grafico della scena! :-D

+0

Scelgo questa come la migliore risposta. Il mio approccio originale era corretto e ora non so perché l'ho considerato sbagliato (troppo semplice? D) Hai anche ragione riguardo alla rotazione planetaria: ora ho incluso un nodo aggiuntivo che gestisce la rotazione attorno al sole. Grazie mille! – Lucius

+0

Se il sole ruota, i pianeti ruotano anche in questa algebra della matrice. Cinematica in avanti .. – stefan

+0

@Stefan quindi ovviamente il sole dovrebbe semplicemente essere un bambino del sistema solare come il pianeta e centrato all'origine. – corsiKa

1

Penso che questo sia il comportamento corretto.

Non penso che ruotare attorno all'origine del genitore sia qualcosa che può essere realizzato con un semplice stack matrix. Penso che puoi solo propagare dai genitori ai bambini.

Si potrebbe provare invece a impostare la rotazione relativa e la trasformazione in base agli offset dall'origine assoluta del genitore, anche se si tratta di calcoli molto più di un semplice push su uno stack di matrici.

Ecco una domanda simile: Getting absolute position and rotation from inside a scene graph?

+0

Grazie! Anche corretto! :) – Lucius

1

Dipende se si sta utilizzando OpenGL o Direct3D. In OpenGL, le trasformazioni vengono applicate da destra a sinistra, mentre in Direct3D si applicano da sinistra a destra. Sono entrambi modi perfettamente validi per progettare il sistema di trasformazione, ma significa che devi pensarci diversamente.

Trovo più facile pensare nel sistema di OpenGL, ma al contrario. Invece di pensare a come i vertici di un oggetto si muovono mentre le trasformazioni vengono applicate da destra a sinistra, immagino il sistema di coordinate dell'oggetto trasformato in un ordine da sinistra a destra. Ogni trasformazione viene applicata in relazione al nuovo sistema di coordinate locale, non relativo al mondo.

Nel caso delle ruote della vettura, ci sono tre trasformazioni coinvolte: la posizione dell'auto nello spazio, l'origine di una ruota rispetto all'auto e l'orientamento della ruota rispetto alla sua posizione neutra. Applicateli semplicemente nell'ordine da sinistra a destra (o viceversa per Direct3D). Per disegnare quattro ruote, applica prima la trasformazione dell'auto, quindi ricorda la trasformazione corrente, quindi applica la posizione e le trasformazioni di orientamento a turno, tornando alla trasformazione auto memorizzata dopo ciascuna.

+0

Non sono sicuro che questa risposta soddisfi completamente la mia domanda. Ma ancora, non sapevo ancora questa differenza, quindi grazie! :) – Lucius

+0

Credo che questi siano i valori predefiniti, e puoi girarli se necessario. Almeno sono abbastanza sicuro che tu sia in OpenGL. –

+0

@user la cosa migliore da togliere alla risposta di Marcelos è che ci sono un sacco di framework che sono in uso da centinaia di migliaia (forse milioni?) Di sviluppatori, e che dovresti prendere in considerazione l'utilizzo di uno di quelli per fare il pesante sollevamento in il tuo sistema. Non solo ti faranno risparmiare molte ore di debugging (nota, molte più ore di quelle necessarie per crearne di tue) ma avrai anche una capacità molto redditizia e lucrativa nel tuo curriculum! – corsiKa

Problemi correlati