Stack di matrici (Direct3D 9)
Nota
La libreria di utilità D3DX è deprecata. È consigliabile usare invece DirectXMath insieme a questa intestazione da GitHub.
La libreria di utilità D3DX fornisce l'interfaccia ID3DXMATRIXStack . Fornisce un meccanismo per consentire il push delle matrici in e l'estrazione da uno stack di matrici. L'implementazione di uno stack di matrici è un modo efficiente per tenere traccia delle matrici durante l'attraversamento di una gerarchia di trasformazione.
La libreria di utilità D3DX usa uno stack di matrici per archiviare le trasformazioni come matrici. I vari metodi dell'interfaccia ID3DXMATRIXStack gestiscono la matrice corrente o la matrice situata sopra lo stack. È possibile cancellare la matrice corrente con il metodo ID3DXMATRIXStack::LoadIdentity . Per specificare in modo esplicito una determinata matrice da caricare come matrice di trasformazione corrente, usare il metodo ID3DXMATRIXStack::LoadMatrix . È quindi possibile chiamare il metodo ID3DXMATRIXStack::MultMatrix o il metodo ID3DXMATRIXStack::MultMatrixLocal per moltiplicare la matrice corrente per la matrice specificata.
Il metodo ID3DXMATRIXStack::P op consente di tornare alla matrice di trasformazione precedente e al metodo ID3DXMATRIXStack::P ush aggiunge una matrice di trasformazione allo stack.
Le singole matrici nello stack di matrici sono rappresentate come matrici omogenee 4x4, definite dalla struttura D3DXMATRIX della libreria di utilità D3DXMATRIX .
La libreria di utilità D3DX fornisce uno stack di matrici tramite un oggetto COM (Component Object Model).
Implementazione di una gerarchia della scena
Uno stack di matrici semplifica la costruzione di modelli gerarchici, in cui gli oggetti complessi vengono costruiti da una serie di oggetti più semplici.
Una scena, o trasformazione, gerarchia è in genere rappresentata da una struttura di dati dell'albero. Ogni nodo nella struttura dei dati dell'albero contiene una matrice. Una particolare matrice rappresenta la modifica nei sistemi di coordinate dall'elemento padre del nodo al nodo. Ad esempio, se si modella un braccio umano, è possibile implementare la gerarchia illustrata nel diagramma seguente.
In questa gerarchia, la matrice Corpo posiziona il corpo nel mondo. La matrice UpperArm contiene la rotazione della spalla, la matrice LowerArm contiene la rotazione del gomito e la matrice Hand contiene la rotazione del polso. Per determinare dove la mano è relativa al mondo, si moltiplicano tutte le matrici dal corpo verso il basso attraverso mano insieme.
La gerarchia precedente è eccessivamente semplicistica, perché ogni nodo ha un solo elemento figlio. Se si inizia a modellare la mano in modo più dettagliato, si aggiungeranno probabilmente le dita e un pollice. Ogni cifra può essere aggiunta alla gerarchia come elemento figlio di Hand, come illustrato nel diagramma seguente.
Se si attraversa il grafico completo del braccio in ordine di profondità, attraversando il più possibile verso il basso di un percorso prima di passare al percorso successivo, per disegnare la scena, si esegue una sequenza di rendering segmentato. Ad esempio, per eseguire il rendering della mano e delle dita, si implementa il modello seguente.
- Eseguire il push della matrice hand nello stack di matrici.
- Disegna la mano.
- Eseguire il push della matrice Thumb nello stack di matrici.
- Disegnare il pollice.
- Aprire la matrice Thumb dallo stack.
- Spingere la matrice del dito 1 nello stack di matrici.
- Disegnare il primo dito.
- Pop the Finger 1 matrix off the stack.
- Spingere la matrice del dito 2 nello stack di matrici. Si continua in questo modo fino a quando non viene eseguito il rendering di tutte le dita e del pollice.
Dopo aver completato il rendering delle dita, si aprirà la matrice hand dallo stack.
È possibile seguire questo processo di base nel codice con gli esempi seguenti. Quando si verifica un nodo durante la ricerca depth-first della struttura dei dati dell'albero, eseguire il push della matrice nella parte superiore dello stack di matrici.
MatrixStack->Push();
MatrixStack->MultMatrix(pNode->matrix);
Al termine di un nodo, aprire la matrice all'inizio dello stack di matrici.
MatrixStack->Pop();
In questo modo, la matrice nella parte superiore dello stack rappresenta sempre la trasformazione globale del nodo corrente. Pertanto, prima di disegnare ogni nodo, è necessario impostare la matrice Direct3D.
pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), *MatrixStack->GetTop());
Per altre informazioni sui metodi specifici che è possibile eseguire in uno stack di matrici D3DX, vedere l'argomento di riferimento ID3DXMATRIXStack .
Argomenti correlati