Piles de matrices (Direct3D 9)

Notes

La bibliothèque d’utilitaireS D3DX est déconseillée. Nous vous recommandons d’utiliser DirectXMath à la place avec cet en-tête de GitHub.

La bibliothèque d’utilitaireS D3DX fournit l’interface ID3DXMATRIXStack . Il fournit un mécanisme pour permettre aux matrices d’être poussées et extraites d’une pile de matrices. L’implémentation d’une pile de matrices est un moyen efficace de suivre les matrices lors de la traversée d’une hiérarchie de transformation.

La bibliothèque d’utilitaires D3DX utilise une pile de matrices pour stocker les transformations en tant que matrices. Les différentes méthodes de l’interface ID3DXMATRIXStack traitent de la matrice actuelle ou de la matrice située au-dessus de la pile. Vous pouvez effacer la matrice actuelle avec la méthode ID3DXMATRIXStack::LoadIdentity . Pour spécifier explicitement une certaine matrice à charger comme matrice de transformation actuelle, utilisez la méthode ID3DXMATRIXStack::LoadMatrix . Vous pouvez ensuite appeler la méthode ID3DXMATRIXStack::MultMatrix ou la méthode ID3DXMATRIXStack::MultMatrixLocal pour multiplier la matrice actuelle par la matrice spécifiée.

La méthode ID3DXMATRIXStack::P op vous permet de revenir à la matrice de transformation précédente et la méthode ID3DXMATRIXStack::P ush ajoute une matrice de transformation à la pile.

Les matrices individuelles de la pile de matrices sont représentées sous la forme de matrices homogènes 4x4, définies par la structure D3DX utility library D3DXMATRIX .

La bibliothèque d’utilitaireS D3DX fournit une pile matricielle via un objet COM (Component Object Model).

Implémentation d’une hiérarchie de scènes

Une pile de matrice simplifie la construction de modèles hiérarchiques, dans lesquels les objets complexes sont construits à partir d’une série d’objets plus simples.

Une hiérarchie de scène ou de transformation est généralement représentée par une structure de données d’arborescence. Chaque nœud de la structure de données d’arborescence contient une matrice. Une matrice particulière représente la modification des systèmes de coordonnées du parent du nœud au nœud. Par exemple, si vous modélisez un bras humain, vous pouvez implémenter la hiérarchie illustrée dans le diagramme suivant.

diagramme de la hiérarchie d’un bras humain

Dans cette hiérarchie, la matrice Body place le corps dans le monde. La matrice UpperArm contient la rotation de l’épaule, la matrice LowerArm la rotation du coude et la matrice Main contient la rotation du poignet. Pour déterminer où la main est par rapport au monde, vous multipliez toutes les matrices de Corps vers le bas à Main ensemble.

La hiérarchie précédente est trop simpliste, car chaque nœud n’a qu’un seul enfant. Si vous commencez à modéliser la main plus en détail, vous ajouterez probablement des doigts et un pouce. Chaque chiffre peut être ajouté à la hiérarchie en tant qu’enfants de Hand, comme illustré dans le diagramme suivant.

diagramme de la hiérarchie d’une main humaine

Si vous parcourez le graphe complet du bras dans le premier ordre de profondeur (en parcourant aussi loin que possible un chemin d’accès avant de passer au chemin suivant) pour dessiner la scène, vous effectuez une séquence de rendu segmenté. Par exemple, pour restituer la main et les doigts, vous implémentez le modèle suivant.

  1. Poussez la matrice Hand sur la pile de matrices.
  2. Dessinez la main.
  3. Pousser la matrice Thumb sur la pile de matrices.
  4. Dessinez le pouce.
  5. Placez la matrice Thumb hors de la pile.
  6. Poussez la matrice Finger 1 sur la pile de matrices.
  7. Dessinez le premier doigt.
  8. Faire apparaître la matrice Finger 1 hors de la pile.
  9. Poussez la matrice Finger 2 sur la pile de matrices. Vous continuez de cette manière jusqu’à ce que tous les doigts et le pouce soient rendus.

Une fois que vous avez terminé le rendu des doigts, vous faites apparaître la matrice Main hors de la pile.

Vous pouvez suivre ce processus de base dans le code avec les exemples suivants. Lorsque vous rencontrez un nœud lors de la recherche en profondeur d’abord dans la structure de données d’arborescence, envoyez la matrice en haut de la pile de matrices.

MatrixStack->Push();

MatrixStack->MultMatrix(pNode->matrix);

Lorsque vous avez terminé avec un nœud, placez la matrice en haut de la pile de matrice.

MatrixStack->Pop();

De cette façon, la matrice située en haut de la pile représente toujours la transformation mondiale du nœud actuel. Par conséquent, avant de dessiner chaque nœud, vous devez définir la matrice Direct3D.

pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(0), *MatrixStack->GetTop());

Pour plus d’informations sur les méthodes spécifiques que vous pouvez effectuer sur une pile matricielle D3DX, consultez la rubrique de référence ID3DXMATRIXStack .

Vertex Pipeline