Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1326 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [c++ / qt] freefly camera problème souris

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[c++ / qt] freefly camera problème souris

n°1978849
shadow_hea​rt
Posté le 30-03-2010 à 12:39:15  profilanswer
 

salut, j'essaie de faire un camera free fly en qt, ça marche presque mais un détail bug encore:
 
quand je fais un QCursor::setPos(x, y) pour pas que ma souris atteigne le bord de l'écran, il semble que ça interrompt le mouvement de la souris et du coup le déplacement accuse un accoup. Est-ce que quelqu'un à une idée pour régler ce problème??
 
voilà le code en cause :

Citation :


void COGLSpace::paintGL()
{
 glMatrixMode( GL_PROJECTION );
 glLoadIdentity( );
 gluPerspective(21.5, 1.0 ,0.001,10000);
 
 glEnable(GL_DEPTH_TEST);
 
 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 
 glMatrixMode( GL_MODELVIEW );
 glLoadIdentity( );
 
 
// QPoint globalCursorPos = QCursor::pos();
 QPoint localCursorPos = this->mapFromGlobal(QCursor::pos());
 
 double newX = localCursorPos.x();
 
 double newY = localCursorPos.y();
 
 
 double relativeX = newX - m_mouseX;
 std::cout << newX << " - " << m_mouseX << " = " << relativeX << "\n";
 double relativeY = newY - m_mouseY;
 std::cout << newY << " - " << m_mouseY << " = " << relativeY << "\n";
 
 m_fpsCamera->updateDir(relativeX, relativeY);
 
 if(width()/4 < newX && newX < (3*width())/4 && height()/4 < newY && newY < (3*height())/4){
  m_mouseX = newX;
  m_mouseY = newY;
 }else{
  setMouseTracking(false);
  QCursor::setPos(this->mapToGlobal(QPoint(width()/2, height()/2)));
  setMouseTracking(true);
  this->grabMouse();
  m_mouseX = width()/2;
  m_mouseY = height()/2;
 }
 
 m_fpsCamera->updatePos(m_fpsCameraMoves);
// m_fpsCamera->updateDir(m_relativeX, m_relativeY);
 const double* cameraPosition = m_fpsCamera->getPosition();
 const double* cameraDirection = m_fpsCamera->getDirection();
 
// std::cout << "in paint gl pos = " << cameraPosition[0] << "/"
//   << cameraPosition[1] << "/" << cameraPosition[2] << "\n";
// std::cout << "in paint gl dir = " << cameraDirection[0] << "/"
//   << cameraDirection[1] << "/" << cameraDirection[2] << "\n";
 
 gluLookAt(cameraPosition[0], cameraPosition[1], cameraPosition[2],
     cameraPosition[0]+cameraDirection[0], cameraPosition[1]+cameraDirection[1], cameraPosition[2]+cameraDirection[2],
     0, 0, 1);
 
 glLineWidth(3.0);
 glBegin(GL_LINES);
 glColor3f(1.0f,0.0f,0.0f);     // red x axis
 glVertex3f(0.0,0.0,0.0);
 glVertex3f(0.1,0.0,0.0);
 glColor3f(0.0f,1.0f,0.0f);     // green y axis
 glVertex3f(0.0,0.0,0.0);
 glVertex3f(0.0,0.1,0.0);
 glColor3f(0.0f,0.0f,1.0f);     // blue z axis
 glVertex3f(0.0,0.0,0.0);
 glVertex3f(0.0,0.0,0.1);
 glEnd();
 
 
 
 if ( m_pOGLTiles != NULL )
 {
  glPushMatrix();
  glTranslatef(-m_cloudCenter[0], -m_cloudCenter[1], -m_cloudCenter[2]);
  displayCloud( m_pOGLTiles );
  if ( m_bPickState ){
   if ( m_iID > -1 && m_iID < m_pOGLTiles->m_iNbrPoints ){
    displayPickObjects();
   }
  }
  glPopMatrix();
 }
 
 
 glFlush();
 
}


 
merci d'avance pour vos réponses!

mood
Publicité
Posté le 30-03-2010 à 12:39:15  profilanswer
 

n°1979136
breizhbugs
Posté le 30-03-2010 à 18:11:06  profilanswer
 

Bonjour,
Je ne m'y connais pas en Qt, mais je dirais que la gestion de la souris n'a rien a faire dans la fonction Paint!
 
Si tu as une fonction qui gère les mouvements de la souris (comme glutMouseFunc(mouse) avec la GLUT), enregistre sa position dans une variable globale (pour qu'elle soit accessible de ta fonction qui remet le monde a jour) et remet la a sa place de suite.


Message édité par breizhbugs le 30-03-2010 à 18:12:26
n°1979177
shadow_hea​rt
Posté le 30-03-2010 à 20:01:04  profilanswer
 

ça change rien.
 
à mon avis c'est vraiment le QCursor::setPos() qui interfère avec le mouvement de la souris, mais je sais pas comment changer ça...

n°1979428
breizhbugs
Posté le 31-03-2010 à 12:44:48  profilanswer
 


Citation :


void COGLSpace::paintGL()
{
 
// QPoint globalCursorPos = QCursor::pos();
 QPoint localCursorPos = this->mapFromGlobal(QCursor::pos());
 
 double newX = localCursorPos.x();
 
 double newY = localCursorPos.y();
 
 
 double relativeX = newX - m_mouseX;
 std::cout << newX << " - " << m_mouseX << " = " << relativeX << "\n";
 double relativeY = newY - m_mouseY;
 std::cout << newY << " - " << m_mouseY << " = " << relativeY << "\n";
 
...
 if(width()/4 < newX && newX < (3*width())/4 && height()/4 < newY && newY < (3*height())/4){
  m_mouseX = newX;
  m_mouseY = newY;
 }else{
  setMouseTracking(false);
  QCursor::setPos(this->mapToGlobal(QPoint(width()/2, height()/2)));
  setMouseTracking(true);
  this->grabMouse();
  m_mouseX = width()/2;
  m_mouseY = height()/2;
 }
 
...
}


En faite je trouve ta gestion de la souris bizarre:
Si j'ai bien compris, tu n'initialises pas la souris au centre au début et tu ne l'y replaces que lorsqu'elle s'approche trop du centre!
 
Je crois que ce qu'il faut faire a chaque boucle:
1- positionner la souris au milieu de la fenetre
2- calculer deltax et deltay, correspondant a la nouvelle position de la souris - la position au centre de la fenetre
3- repositionner la souris au centre de la fenetre
4- utiliser deltax et deltay pour gerer la camera
 

n°1980645
shadow_hea​rt
Posté le 03-04-2010 à 14:26:07  profilanswer
 

c'est ce que je voulais faire au début, mais ça marche pas : rien ne bouge, deltaX et deltaY sont toujours égal à 0. je pense que c'est du à la façon dont Qt gère la souris...

n°1980647
breizhbugs
Posté le 03-04-2010 à 14:56:07  profilanswer
 


"c'est ce que je voulais faire au début, mais ça marche pas : rien ne bouge, deltaX et deltaY sont toujours égal à 0. je pense que c'est du à la façon dont Qt gère la souris... "
 
Je pourrais pas tester mais je voudrais bien voir le code...


Message édité par breizhbugs le 03-04-2010 à 14:57:55
n°1982029
shadow_hea​rt
Posté le 08-04-2010 à 15:18:39  profilanswer
 

voilà ça devait être à peu près ça :
 

Citation :

void COGLSpace::paintGL()
{
 glMatrixMode( GL_PROJECTION );
 glLoadIdentity( );
 gluPerspective(21.5, 1.0 ,0.001,10000);
 
 glEnable(GL_DEPTH_TEST);
 
 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
 
 glMatrixMode( GL_MODELVIEW );
 glLoadIdentity( );
 
 
// QPoint globalCursorPos = QCursor::pos();
 QPoint localCursorPos = this->mapFromGlobal(QCursor::pos());
 
 double newX = localCursorPos.x();
 
 double newY = localCursorPos.y();
 
 
 double relativeX = newX - m_mouseX;
 std::cout << newX << " - " << m_mouseX << " = " << relativeX << "\n";
 double relativeY = newY - m_mouseY;
 std::cout << newY << " - " << m_mouseY << " = " << relativeY << "\n";
 
 m_fpsCamera->updateDir(relativeX, relativeY);
 
  QCursor::setPos(this->mapToGlobal(QPoint(width()/2, height()/2)));
  m_mouseX = width()/2;
  m_mouseY = height()/2;
 }
 
 m_fpsCamera->updatePos(m_fpsCameraMoves);
// m_fpsCamera->updateDir(m_relativeX, m_relativeY);
 const double* cameraPosition = m_fpsCamera->getPosition();
 const double* cameraDirection = m_fpsCamera->getDirection();
 
// std::cout << "in paint gl pos = " << cameraPosition[0] << "/"
//   << cameraPosition[1] << "/" << cameraPosition[2] << "\n";
// std::cout << "in paint gl dir = " << cameraDirection[0] << "/"
//   << cameraDirection[1] << "/" << cameraDirection[2] << "\n";
 
 gluLookAt(cameraPosition[0], cameraPosition[1], cameraPosition[2],
     cameraPosition[0]+cameraDirection[0], cameraPosition[1]+cameraDirection[1], cameraPosition[2]+cameraDirection[2],
     0, 0, 1);
 
 glLineWidth(3.0);
 glBegin(GL_LINES);
 glColor3f(1.0f,0.0f,0.0f);     // red x axis
 glVertex3f(0.0,0.0,0.0);
 glVertex3f(0.1,0.0,0.0);
 glColor3f(0.0f,1.0f,0.0f);     // green y axis
 glVertex3f(0.0,0.0,0.0);
 glVertex3f(0.0,0.1,0.0);
 glColor3f(0.0f,0.0f,1.0f);     // blue z axis
 glVertex3f(0.0,0.0,0.0);
 glVertex3f(0.0,0.0,0.1);
 glEnd();
 
 
 
 if ( m_pOGLTiles != NULL )
 {
  glPushMatrix();
  glTranslatef(-m_cloudCenter[0], -m_cloudCenter[1], -m_cloudCenter[2]);
  displayCloud( m_pOGLTiles );
  if ( m_bPickState ){
   if ( m_iID > -1 && m_iID < m_pOGLTiles->m_iNbrPoints ){
    displayPickObjects();
   }
  }
  glPopMatrix();
 }
 
 
 glFlush();
 
}


 
en fait c'est la même chose sans tester si la souris est encore dans la fenêtre avant de la reseter...

n°1982067
breizhbugs
Posté le 08-04-2010 à 16:07:31  profilanswer
 

En fait on utilise une fonction idle qui est appelée quand il n'y a aucun autre message à traiter. Ci dessous est une partie d'un programme utilisant la glut montrant le principe: lorsque le programme n'a pas de message à traiter, motion() est appelée et recalcule l'angle de la caméra en fonction de la position de la souris.  A la fin on demande une mise à jour de l'affichage (et donc appel indirect a display() ). Le curseur de la souris (visible) saute une peu mais l'animation est fluide.
Par contre, le repositionnement souris est fait par les fonctions de l'api windows directement. Et toi es tu sous windows, linux? fais tu ton programme pour qu'il soit indépendant du système? Si non essai la gestion de la souris avec api native?
 

Code :
  1. // les variables globales
  2. int oldx, oldy;
  3. float anglexz = 270;
  4. float angleyz = 0;
  5. float ex=100.0, ey=120.0, ez=-100.0;
  6. float viewx=100.0, viewy=120.0, viewz=-110.0;
  7. int DISTANCE = 10;
  8. bool lighton = false;
  9. GLfloat nuit[]    = {0.2, 0.2, 0.2, 1.0};
  10. GLfloat jour[]    = {0.9, 0.9, 0.9, 1.0};
  11. GLfloat light_colambn[]    = {0.6, 0.6, 0.6, 1.0};
  12. GLfloat light_colambj[]    = {0.2, 0.2, 0.2, 1.0};
  13. POINT ptOld;                // previous cursor location
  14. ...
  15. void display()
  16. // la fonction qui dessine la monde
  17. {
  18.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  19.   glLoadIdentity();
  20.   glPushMatrix();
  21.     //pour la camera
  22.     gluLookAt(ex, ey, ez, viewx, viewy, viewz, 0.0, 1.0, 0.0);
  23.     //  printf("(vx, vy, vz)=(%f, %f, %f)\n", viewx-ex, viewy-ey, viewz-ez);
  24.     glDisable(GL_LIGHTING);
  25.       glBegin(GL_LINES);
  26.       glColor3f(1.0, 0.0, 0.0);
  27.       glVertex3f(0.0, 0.0, 0.0);
  28.       glVertex3f(5.0, 0.0, 0.0);
  29.       glColor3f(0.0, 1.0, 0.0);
  30.       glVertex3f(0.0, 0.0, 0.0);
  31.       glVertex3f(0.0, 5.0, 0.0);
  32.       glColor3f(0.0, 0.0, 1.0);
  33.       glVertex3f(0.0, 0.0, 0.0);
  34.       glVertex3f(0.0, 0.0, 5.0);
  35.     glEnd();
  36.     glEnable(GL_LIGHTING);
  37.     if(lighton)
  38.     {
  39.       glEnable(GL_LIGHT0);
  40.     }
  41.     else
  42.     {
  43.       glDisable(GL_LIGHT0);
  44.     }
  45.     glPushMatrix();
  46.       glTranslatef(90.0, 220.0, -180.0);
  47.       glutWireCube(10.0);
  48.     glPopMatrix();
  49.   drawMur();
  50.   glTranslatef(300.0, 0.0, 0.0);
  51.   glRotatef(-90, 0.0, 1.0, 0.0);
  52.   drawMur();
  53.   glPopMatrix();
  54.   glutSwapBuffers();
  55. }
  56. void motion()
  57. // cette fonction est appelée automatiquement quand il n'y a rien d'autre a faire
  58. {
  59.   POINT pt;
  60.   GetCursorPos(&pt); // on obtient la position du curseur
  61.   float deltax=((float)(ptOld.x - pt.x))/2; // je sais plus pourquoi on divise par deux... pour que ca aille moins vite peut etre?
  62.   float deltay=((float)(ptOld.y - pt.y))/2;
  63.   float angleradiansx;
  64.   float angleradiansy;
  65.   //pour la translation
  66.   anglexz=(anglexz-deltax);
  67.   angleyz=(angleyz+deltay);
  68.   // on regarde en haut ou en bas, mais on fait pas le "tour"
  69.   if (angleyz<-89.9)
  70.     angleyz=-89.9;
  71.   else if (angleyz>89.9)
  72.     angleyz=89.9;
  73.   angleradiansx = anglexz * M_PI / 180;
  74.   angleradiansy = angleyz * M_PI / 180;
  75.   viewx=ex+cos(angleradiansx)*cos(angleradiansy)*DISTANCE;
  76.   viewz=ez+sin(angleradiansx)*cos(angleradiansy)*DISTANCE;
  77.   viewy=ey+sin(angleradiansy)*DISTANCE;
  78.   SetCursorPos(ptOld.x, ptOld.y); // repositionnement du curseur - ptold est initialisé au milieu de la fenêtre
  79.   glutPostRedisplay(); // on demande une mise a jour d l'affichage
  80. }
  81. void mouse(int button, int , int x, int y)
  82. //on detecte le clic de souris pour lancer/stopper la fonction de l'animation
  83. {
  84.   //oldx=x;
  85. // oldy=y;
  86.   //on positionne le curseur au milieu
  87.   SetCursorPos(glutGet(GLUT_WINDOW_X)+(glutGet(GLUT_WINDOW_WIDTH)/2),glutGet(GLUT_WINDOW_Y)+(glutGet(GLUT_WINDOW_HEIGHT)/2));
  88.   //on enregistre sa position (au milieu)
  89.   GetCursorPos(&ptOld);
  90.   if (button == GLUT_RIGHT_BUTTON)
  91.     glutIdleFunc(motion); // on démarre la fonction idle
  92.   else
  93.     glutIdleFunc(NULL); // ou on l'arrête si c'est pas le bouton droit qui a cliquer
  94. }
  95. void reshape(int w, int h)
  96. // si on redimensionne la fenêtre, on corrige la camera
  97. {
  98.   glViewport(0, 0, (GLsizei)w, (GLsizei)h);
  99.   glMatrixMode(GL_PROJECTION);
  100.   glLoadIdentity();
  101.   //pour conserver l'aspect:
  102.   if (w <= h)
  103.       glFrustum(-1.0, 1.0,
  104.                 -1.0*(GLfloat)h/(GLfloat)w,1.0*(GLfloat)h/(GLfloat)w,
  105.                  1.0, 5000.0);
  106.    else
  107.       glFrustum(-1.0*(GLfloat)w/(GLfloat)h,1.0*(GLfloat)w/(GLfloat)h,
  108.                 -1.0, 1.0,
  109.                  1.0, 5000.0);
  110.   glMatrixMode(GL_MODELVIEW);
  111.   glLoadIdentity();
  112. }
  113. int _tmain(int argc, _TCHAR* argv[])
  114. {
  115.   glutInit(&argc, argv);
  116.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  117.   glutInitWindowSize(500, 500);
  118.   glutInitWindowPosition(100, 100);
  119.   glutCreateWindow(argv[0]);
  120.   init();
  121.   glutDisplayFunc(display);
  122.   glutReshapeFunc(reshape);
  123. ...
  124.   glutMouseFunc(mouse); //pour détecter clic de souris  
  125.   glutMainLoop();
  126.   return 0;
  127. }


Message édité par breizhbugs le 08-04-2010 à 16:11:15
n°1983635
shadow_hea​rt
Posté le 13-04-2010 à 15:00:48  profilanswer
 

merci pour ta réponse, je suis sur mac osx mais je sais pas a priori sur quel système le soft va être utilisé donc il doit impérativement être multiplateforme, d'où l'utilisation de Qt.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [c++ / qt] freefly camera problème souris

 

Sujets relatifs
Problème variable dans une arborescenceproblème de compréhension pour ce code
Problème de rotation d'un clip en AS3commande sed problème
[fpdf] Probleme d'encodageMenu CSS déroulant, problème IE8
problème dans une boucle (masquer les lignes vides)Problème avec preg_match et expressions régulières
[resolu] Problème API Google maps / file_get_contents disabledProblème de copie d'image avec curl
Plus de sujets relatifs à : [c++ / qt] freefly camera problème souris


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR