2011-11-06 5 views
5

J'essaie de créer un graphe de scène pour mon jeu 3D dans lequel les transformations de chaque objet sont relatives à son parent. Chaque noeud du graphe a un vecteur Rotation, Scaling et Translation.3D par rapport aux transformations absolues

Quelle est la bonne façon de combiner les matrices de transformation relatives pour obtenir la transformation absolue d'un objet? Je serais heureux si vous pouviez également expliquer votre solution.


Voici un exemple de faire mal:
Cela en fait avéré être la solution:

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

Dans ce cas, lorsque le nœud parent est mis en rotation, mis à l'échelle ou déplacé, l'enfant est transformé le même montant, ce qui est un comportement correct! Mais l'enfant tourne uniquement autour de sa propre origine et ne se déplace pas autour de l'origine du parent.


Applications:

Il y a un modèle de voiture à quatre roues. Les roues sont positionnées de manière relative autour de l'origine de la voiture. Les roues peuvent tourner comme les vraies roues. Si je fais maintenant tourner la voiture, les roues devraient toujours rester attachées. Dans ce cas, la voiture est la racine et les roues sont les nœuds de l'enfant.

Un autre exemple serait un modèle du système solaire. Les planètes tournent autour de leur propre axe, se déplacent autour du soleil, et les lunes se déplacent autour des planètes.

+0

Il s'avère que ma première idée de comment le faire, que j'ai alors considérée comme inadaptée, était en fait la solution! J'ai passé ces dernières heures à essayer de résoudre ça. * facepalm * Merci à tous pour l'aide rapide et précise! – Lucius

Répondre

3

En ce qui concerne votre « comment faire mal », je déteste le rompre pour vous, mais ce n'est pas mal; c'est plutôt incomplet. Vous devez faire ce genre de travail indépendamment de la relation parent-enfant.

Voici un exemple: La roue est attachée à la voiture comme vous l'avez mentionné. Si vous traduisez ou faites tourner la voiture, vous n'avez pas besoin de toucher les roues - elles sont au même endroit par rapport à la voiture. Cependant, lorsque vous essayez d'obtenir le nouvel emplacement de la roue dans le «monde réel», vous devez traverser l'arbre en appliquant les transformations matricielles au fur et à mesure. Tout cela fonctionne, non?

Lorsque vous faites pivoter un objet, il pivote autour de son origine. Donc, une roue devrait probablement tourner autour de son axe y, et une planète autour de son axe z. Mais maintenant, si vous devez déplacer une planète "autour du soleil", vous faites quelque chose de complètement différent. Cela doit être calculé séparément. Cela ne veut pas dire qu'il ne va pas être assoupli en utilisant un peu le même match que vous avez déjà, (bien que je ne puisse pas dire avec certitude sans faire moi-même les calculs) mais c'est complètement différent.

Vous cherchez à changer l'état de l'objet. C'est la beauté du graphique de la scène! Si vous n'aviez pas de graphique de scène, vous deviez calculer toutes les différentes valeurs jusqu'à la scène principale, puis faire toutes sortes de calculs. Ici, il suffit de faire un peu de trig et d'algèbre pour se déplacer autour de la planète (vous pouvez google sur la mécanique céleste) et déplacer la planète par rapport à son étoile. La prochaine fois que la scène principale demandera où se trouve la planète, elle descendra le graphe de la scène! :-D

+0

Je prends cela comme la meilleure réponse. Mon approche originale était correcte et je ne sais pas pourquoi je la considérais comme erronée (trop simple?: D) Vous avez également raison sur la rotation planétaire: j'ai maintenant inclus un nœud supplémentaire qui gère la rotation autour du soleil. Merci beaucoup! – Lucius

+0

Si le soleil tourne, les planètes tourneront aussi avec cette algèbre matricielle. Cinématique avant .. – stefan

+0

@Stefan alors évidemment le soleil devrait simplement être un enfant du système solaire comme la planète est, et centré à l'origine. – corsiKa

1

Je pense que c'est le comportement correct.

Je ne pense pas que tourner autour de l'origine du parent est quelque chose qui peut être accompli avec une pile de matrice simple. Je pense que vous ne pouvez que propager des parents aux enfants.

Vous pouvez plutôt définir la rotation et la transformation relatives en fonction des décalages de l'origine absolue du parent, bien que ce soit beaucoup plus de calculs que de simplement pousser sur une pile de matrices.

Voici une question similaire: Getting absolute position and rotation from inside a scene graph?

+0

Merci! Aussi correct! :) – Lucius

1

Cela dépend si vous utilisez OpenGL ou Direct3D. En OpenGL, les transformations sont appliquées de droite à gauche, alors que dans Direct3D, elles s'appliquent de gauche à droite. Ils sont tous deux des moyens parfaitement valables de concevoir le système de transformation, mais cela signifie que vous devez y penser différemment. Je trouve qu'il est plus facile de penser dans le système OpenGL, mais en sens inverse. Au lieu de penser à la façon dont les sommets d'un objet se déplacent lorsque les transformations sont appliquées de droite à gauche, j'imagine le système de coordonnées de l'objet en cours de transformation dans un ordre de gauche à droite. Chaque transformation est appliquée par rapport au nouveau système de coordonnées local, et non par rapport au monde. Dans le cas des roues de la voiture, il y a trois transformations: la position de la voiture dans l'espace, l'origine de la roue par rapport à la voiture et l'orientation de la roue par rapport à sa position neutre. Appliquez-les simplement dans l'ordre de gauche à droite (ou vice-versa pour Direct3D). Pour dessiner les quatre roues, appliquez d'abord la transformation de la voiture, puis rappelez-vous la transformation actuelle, puis appliquez les transformations d'emplacement et d'orientation à tour de rôle, en revenant à la transformée de voiture mémorisée après chacune.

+0

Je ne suis pas sûr si cette réponse correspond complètement à ma question. Mais encore, je ne connaissais pas encore cette différence, alors merci! :) – Lucius

+0

Je crois que ce sont les valeurs par défaut, et vous pouvez les retourner si nécessaire. Au moins, je suis sûr que vous pouvez en OpenGL. –

+0

@user La meilleure chose à retenir de la réponse de Marcelos est qu'il y a beaucoup de frameworks utilisés par des centaines de milliers (peut-être des millions?) De développeurs, et que vous devriez envisager d'en utiliser un pour faire le gros du travail. votre système. Non seulement ils vous épargneront de nombreuses heures de débogage (notez, beaucoup plus d'heures qu'il n'en faudrait pour faire le vôtre), mais vous aurez aussi un ensemble de compétences très lucratives et lucratives sur votre CV! – corsiKa

Questions connexes