2009-12-09 7 views
6

Je suis en train de mettre en œuvre la rotation arcball/trackball mais j'ai un problème avec le centre de rotation. Je veux que le centre soit le centre de mon écran, peu importe quoi. Permettez-moi d'expliquer ce que j'ai fait jusqu'à présent.Comment faire pivoter autour du centre de l'écran en utilisant quaternions dans opengl?

J'avons créé un quaterion (axe de rotation: vector_start x vector_end, angle: vector_start * vector_end)

A partir de ce quaternion j'ai créé une matrice de rotation afin de l'utiliser avec glMultMatrixf (matrice) et obtenir la rotation désirée.

Le problème est que pendant que mon modèle semble faire tourner l'arcball comme il se doit, il tourne toujours autour de son origine locale. Comment pourrais-je faire pivoter autour du centre de mon écran , peu importe où se trouve son origine locale?

Je suppose qu'une solution à ce problème pourrait être de traduire l'axe de rotation complet au centre de l'écran puis d'appliquer la rotation mais est-ce possible? Est-ce que quelque chose me manque ici?

Répondre

1

Vous devriez pouvoir résoudre ce problème en appliquant des matrices de rotation et de traduction dans le bon ordre. Dans votre code, vous pouvez traduire vers l'origine T (-pos_x, -pos_y, -pos_z), appliquer votre rotation, et traduire à nouveau au centre de l'objet T (pos_x, pos_y, pos_z). Cela devrait fonctionner en général, indépendamment de la façon dont votre matrice de rotation est construite.

+0

Oui mais quand j'applique glMultMatrixf() opengl ne fait-il pas tourner le modèle autour de son origine locale? Donc si je traduis vers l'origine pivoter (pas en utilisant glRotatef() mais glMultMatrix()) et ensuite traduire à nouveau mon modèle sera à nouveau tourné autour de son origine et non comme si son origine était le centre de l'écran par exemple. –

+0

Traduisez avec glTranslatef(), puis multipliez avec votre matrice de rotation glMultMatrix(), et traduisez en utilisant glTranslatef(). Ceci par opposition à simplement appeler glMultMatrix(). Ça ne marche pas? – catchmeifyoutry

+0

Non, cela ne fonctionne pas. Ce qu'il fait est qu'il fait tourner le modèle comme indiqué par la matrice de rotation appliquée par glMultMatrixf mais autour de son origine locale. J'ai essayé de convertir le quaternion de rotation en angles d'Euler, puis j'applique glRotatef (Yaw, 0., 0., 1.); glototatef (Pich, 0., 1., 0.); glRotatef (Roll, 1., 0., 0.); Au lieu d'appliquer directement glMultMatrixf(), mais alors que la rotation était sur le centre de l'écran, il n'a rien à voir avec une rotation arcball ! –

0

Voici un code que j'ai écrit il y a quelques temps pour un lanceur de fusée à 3 étages. Je suis la plupart des informations de http://www.euclideanspace.com/maths/geometry/rotations

Note: lacet, tangage et roulis peuvent changer pour vous en fonction de la façon dont vous configurez votre système de coordonnées

 // Assuming the angles are in radians. 
      double p = curPitch * Math.PI/180.0/2.0; 
      double y = curYaw * Math.PI/180.0/2.0; 
      double r = curRoll * Math.PI/180.0/2.0; 

      double sinp = Math.sin(p); 
      double siny = Math.sin(y); 
      double sinr = Math.sin(r); 
      double cosp = Math.cos(p); 
      double cosy = Math.cos(y); 
      double cosr = Math.cos(r); 

      Vector3 axis = new Vector3(); 

      //here's the important part: how you get your quaternion vector! 
      axis.x = sinr * cosp * cosy - cosr * sinp * siny; 
      axis.y = cosr * sinp * cosy + sinr * cosp * siny; 
      axis.z = cosr * cosp * siny - sinr * sinp * cosy; 

      //now normalize the vector in case we want to use it again later 
      axis = Vector3.normalizeVector(axis); 

      orientation[1] = axis.x; 
      orientation[2] = axis.y; 
      orientation[3] = axis.z; 

      //w is omega: the angle to rotate about the quaternion 
      double w = cosr * cosp * cosy + sinr * sinp * siny; 

      w = Math.acos(w) * 2.0; 

      orientation[0] = w; 

      gl.glPushMatrix(); 

       //translate object first, then rotate it. 
       gl.glTranslated(curDisplacement[0] + saveDisplacement[0], -curDisplacement[1] + saveDisplacement[2], curDisplacement[2] + saveDisplacement[1]); 

       //this order might be messed up because I screwed up my coordinate system, but the idea is still there 
       gl.glRotated(orientation[0]*180/Math.PI, orientation[2]*180/Math.PI, orientation[3]*180/Math.PI, orientation[1]*180/Math.PI); 

      //place your objects 
      gl.glPopMatrix(); 

Hope this helps!

Questions connexes