2013-02-03 2 views
0

J'ai un plan dans un monde 3D et son orientation est enregistrée de quelque façon que ce soit (par exemple, tangage, lacet et roulis). Maintenant quand je veux que l'avion tourne à gauche, mais glRotatef ne fait pas le travail car il colle aux coordonnées globales et ne se soucie pas de la rotation de l'avion, et simplement changer le lacet n'aide pas non plus car ce n'est pas non plus par rapport aux plans de rotation réels et ne signifierait "gauche" que lorsque l'avion vole directement à l'horizon. Ce que je aurais besoin serait comme ceci:Activer un maillage en fonction de ses coordonnées locales

float pitch = 10 , yaw = 20, roll = 30;  //some initial values 
    Turn(&pitch, &yaw, &roll , 5, 0 , 0) //calculate new pitch, yaw and roll as if 
    //the plane had turned 5 degrees to the right (relative to its current orientation and roll!) 
    //pitch, yaw and roll are updated to reflect the new orientation. 

Beaucoup de gens suggèrent l'utilisation de Quaternions, mais je ne sais pas sur la façon de les mettre en œuvre une fonction Turn (un exemple de travail est Blitz3D, qui a une fonction « RotateEntity » pour la rotation globale comme glRotatef et « TurnEntity » pour la rotation en fonction de l'orientation) Je pense que la fonction fonctionne en interne comme ceci:

  • transform tangage, lacet, roulis à un Quaternion comme EulerToQuat dans OpenGL + SDL rotation around local axis
  • effectuer la rotation locale en utilisant Quaternio n mathématiques (aucune source trouvée)
  • transforment Quaternion retour à lacet, roulis, tangage (pas source trouvée)
+2

ce n'est pas le quaternion qui résout le problème c'est l'accumulation de petites rotations qui résout le problème, la raison pour laquelle les quaternions sont utilisées est qu'une matrice va obtenir des erreurs d'arrondis qui pourraient s'accumuler, tandis qu'un quaternion peut être normalisé facilement ... Cela pourrait expliquer mieux: http://www.arcsynthesis.org/gltut/Positioning/Tutorial%2008.html, lisez le chapitre et l'utilisation des quaternions pourrait devenir un peu plus claire, espoir cela aide = D –

+0

Merci Luke, le tutoriel a aidé un peu :-) (La force pourrait être avec vous ...) – Kenobi

+0

Bon, heureux d'aider ... –

Répondre

0

J'ai finalement résolu le problème en passant à la réalisation d'une matrice pour chaque navire tout le temps. Le tangage, le lacet et le roulis ne sont calculés qu'en cas de besoin, ce qui est rarement le cas. Enfin, glRotatef fait le travail - il vous suffit de l'appliquer à la matrice déjà tournée - et enregistrer le résultat, de sorte que la modification ne soit pas abandonnée.

Le code suivant est mon implémentation sur une structure de navire qui porte x, y, z, Matrix [16], dx, dy, dz. (Notez que tous les tableaux de bord doivent être initialisés avec le IdentityMatrix):

//*************************** Turn Ship ********************************** 
void TurnShip(long nr,float yaw, float pitch=0,float roll=0) { 
    //Turns ship by pitch, yaw and roll degrees. 
    glMatrixMode(GL_MODELVIEW); 

    glLoadMatrixf(&ship[nr].Matrix[0]); 
    glRotatef(yaw,0,1,0); 
    glGetFloatv(GL_MODELVIEW_MATRIX,&ship[nr].Matrix[0]); 

    glLoadMatrixf(&ship[nr].Matrix[0]); 
    glRotatef(pitch,1,0,0); 
    glGetFloatv(GL_MODELVIEW_MATRIX,&ship[nr].Matrix[0]); 

    glLoadMatrixf(&ship[nr].Matrix[0]); 
    glRotatef(roll,0,0,1); 
    glGetFloatv(GL_MODELVIEW_MATRIX,&ship[nr].Matrix[0]); 
} 

Qu'est-ce que la fonction n'est le chargement des navires matrice stockés dans un simple tableau flottant, manipuler puis enregistrer de nouveau au tableau. Dans la section graphique du jeu, ce tableau sera chargé avec glLoadMatrixf et sera donc appliqué au vaisseau sans aucun tracas ou mathématique.

//*************************** Accelerate Ship relative to own orientation ** 
void AccelerateShip(long nr,float speedx,float speedy, float speedz) 
{ //use speedz to move object "forward". 
ship[nr].dx+= speedx*ship[nr].Matrix[0]; //accelerate sidewards (x-vector) 
ship[nr].dy+= speedx*ship[nr].Matrix[1]; //accelerate sidewards (x-vector) 
ship[nr].dz+= speedx*ship[nr].Matrix[2]; //accelerate sidewards (x-vector) 

ship[nr].dx+= speedy*ship[nr].Matrix[4]; //accelerate upwards (y-vector) 
ship[nr].dy+= speedy*ship[nr].Matrix[5]; //accelerate upwards (y-vector) 
ship[nr].dz+= speedy*ship[nr].Matrix[6]; //accelerate upwards (y-vector) 

ship[nr].dx+= speedz*ship[nr].Matrix[8]; //accelerate forward (z-vector) 
ship[nr].dy+= speedz*ship[nr].Matrix[9]; //accelerate forward (z-vector) 
ship[nr].dz+= speedz*ship[nr].Matrix[10]; //accelerate forward (z-vector) 
} 

Ceci est la meilleure partie de ce que j'appris aujourd'hui - la partie des tutoriels souvent ne vous disent pas qu'ils sont tous sur les mathématiques - je peux tirer les vecteurs qui pointent vers le haut, à gauche et devant mon vaisseau sortira de la matrice et appliquera une accélération sur eux pour que mon vaisseau puisse avancer, reculer, accélérer et freiner à gauche, à droite, et glRotatef se soucie d'eux pour qu'ils soient toujours mis à jour et sans maths à nos côtés: -)

Questions connexes