2010-10-04 2 views
0

J'essaie actuellement de faire fonctionner mon trackball virtuel sous tous les angles. Quand je le regarde depuis l'axe z, ça semble fonctionner correctement. Je maintiens ma souris vers le bas, et déplace la souris vers le haut ... la rotation se déplacera en conséquence. Maintenant, si je change d'angle de vue/position de mon appareil photo et que j'essaie de déplacer ma souris. La rotation se produira comme si je regardais depuis l'axe z. Je ne peux pas trouver un bon moyen de faire fonctionner ça.Obtenir une boule de commande virtuelle pour travailler à partir de n'importe quel angle de vue

Voici le code:

void Renderer::mouseMoveEvent(QMouseEvent *e) 
{ 

     // Get coordinates 
     int x = e->x(); 
     int y = e->y(); 

     if (isLeftButtonPressed) 
     { 
       // project current screen coordinates onto hemi sphere 
       Point sphere = projScreenCoord(x,y); 

       // find axis by taking cross product of current and previous hemi points 
       axis = Point::cross(previousPoint, sphere); 

       // angle can be found from magnitude of cross product 
       double length = sqrt(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z); 

       // Normalize 
       axis = axis/length; 

       double lengthPrev = sqrt(previousPoint.x * previousPoint.x + previousPoint.y * previousPoint.y + previousPoint.z * previousPoint.z); 
       double lengthCur = sqrt(sphere.x * sphere.x + sphere.y * sphere.y + sphere.z * sphere.z); 
       angle = asin(length/(lengthPrev * lengthCur)); 
       // Convert into Degrees 
       angle = angle * 180/M_PI; 

       // 'add' this rotation matrix to our 'total' rotation matrix 
       glPushMatrix(); // save the old matrix so we don't mess anything up 
       glLoadIdentity(); 
       glRotatef(angle, axis[0], axis[1], axis[2]); // our newly calculated rotation 
       glMultMatrixf(rotmatrix); // our previous rotation matrix 
       glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*) rotmatrix); // we've let OpenGL do our matrix mult for us, now get this result & store it 
       glPopMatrix(); // return modelview to its old value; 

}

// Project screen coordinates onto a unit hemisphere 
Point Renderer::projScreenCoord(int x, int y) 
{ 
     // find projected x & y coordinates 
     double xSphere = ((double)x/width)*2.0 - 1.0; 
     double ySphere = (1 - ((double)y/height)) * 2.0 - 1.0; 
     double temp = 1.0 - xSphere*xSphere - ySphere*ySphere; 

     // Do a check so you dont do a sqrt of a negative number 
     double zSphere; 
     if (temp < 0){ zSphere = 0.0;} 
     else 
     {zSphere = sqrt(temp);} 

     Point sphere(xSphere, ySphere, zSphere); 



     // return the point on the sphere 
     return sphere; 
} 

Je suis encore assez nouveau à ce sujet. Désolé pour le problème et merci pour toute l'aide =)

+0

Voir la question en double ici: http://stackoverflow.com/questions/4039664/trackball-rotation-in-opengl/4676910#4676910 –

Répondre

0

La manière habituelle implique des quaternions. Par exemple, dans sample code à l'origine de SGI.

Questions connexes