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 =)
Voir la question en double ici: http://stackoverflow.com/questions/4039664/trackball-rotation-in-opengl/4676910#4676910 –