Bonjour à tous,

Je viens vers vous car j'ai un petit soucis de rotation d'objet sous OpenGL en cpp. Pour info je suis sous windows 7 et je code via l'IDE Code::Blocks.

Pour faire simple, je veux faire tourner un objet dans mon espace. Cet objet est une série de triangles, soit un modèle de reconstruction (Marching Cube) 3D utilisé en imagerie médicale pour avoir la structure externe de l'objet notamment.

J'ai essayé d'implémenter cette rotation de deux manières différentes, et bien sur les deux ont encore des soucis que je n'arrive plus à résoudre :

- La première via les touches z, s, q et d :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
void Clavier(GLubyte touche, GLint x, GLint y)
{
	switch(touche){
	case 'z' : ;
	{
		if (save_rotation == 1){
			rotateAngle = 1;
			rotatex = 1;
			rotatey = 0;
		}
		else{
			rotateAngle ++;
			rotatex = 1;
		}
		save_rotation = 0;
		break;
	}
 
	case 's' : ;
	{
		if (save_rotation == 1){
			rotateAngle = -1;
			rotatex = 1;
			rotatey = 0;
		}
		else{
			rotateAngle --;
			rotatex = 1;
		}
		save_rotation = 0;
		break;
	}
 
	case 'q' : ;
	{
		if (save_rotation == 0){
			rotateAngle = -1;
			rotatex = 0;
			rotatey = 1;
		}
		else{
			rotateAngle --;
			rotatey = 1;
		}
 
		save_rotation = 1;
		break;
	}
 
	case 'd' : ;
	{
		if (save_rotation == 0){
			rotateAngle = 1;
			rotatex = 0;
			rotatey = 1;
		}
		else{
			rotateAngle ++;
			rotatey = 1;
		}
		save_rotation = 1;
		break;
	}
 
	default : break;
  }
 
  //strength display a new time
	glutPostRedisplay();
}
Sur cette solution, lorsque je passe de z à s (soit sur le même axe) je n'ai aucun problème. Par contre lorsque je passe de z à q (d'un axe à l'autre) mon objet reprend sa position initiale avant d'effectuer la rotation q ... Or j'aimerais qu'il reste en place et je ne sais pas vraiment comment faire. La fonction du dessin est plus bas.

- la deuxième solution, via la souris :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 
 
void ClicSouris (int bouton, int etat, int x, int y)
{
	save_pos_x = x;
	save_pos_y = y;
	save_bouton = bouton;
	save_etat = etat;
}
 
 
void MouvementSourisAvecClic(int x, int y)
{
	//initialize
	float d0, d1, d2, v0, v1, v2, angle_horizontal, angle_vertical, t0, t1, t2;
 
	int deplacement_x = x - save_pos_x;
	int deplacement_y = y - save_pos_y;
 
	save_pos_x = x;
	save_pos_y = y;
 
	angle_horizontal = deplacement_x * (Pi/1000);
	angle_vertical = deplacement_y * (Pi/1000);
 
	switch (save_bouton){
               case GLUT_MIDDLE_BUTTON :
                    if (deplacement_y != 0 and deplacement_x == 0)
                    {
		          rotateAngle += deplacement_y;
                          rotatex = 1;
			  rotatey = 0;
                     }
		     else if (deplacement_y != 0 )
                     {
			  rotateAngle += deplacement_y;
			  rotatex = 1;
		     }
		     if (deplacement_x != 0 and deplacement_y == 0)
                    {
                          rotateAngle += deplacement_x;
                          rotatex = 0;
			   rotatey = 1;
                    }
		     else if (deplacement_x != 0)
                    {
			  rotateAngle += deplacement_x;
			  rotatey = 1;
		     }
                    break;
	}
	glutPostRedisplay();
 
}
Ici le problème est que la rotation fonctionne mais elle n'est pas tout à fait comme on l'attendrait au déplacement de la souris ... J'ai cherché un moment, j'ai supposé un problème d'angle mais je n'ai pas trouvé la solution.

Voici la fonction dessin de ma scène
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 
void Dessiner(){
	//clear the buffer and Z-buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    //choose the MODELVIEW matrix
    glMatrixMode(GL_MODELVIEW);
    //initialize a new time the matrix
    glLoadIdentity();
 
    //background color
    glClearColor(0,200,255, 0);
 
	//initial location of us view
    gluLookAt(obs.position[0], obs.position[1], obs.position[2],
	obs.position[0] + obs.direction[0],
	obs.position[1] + obs.direction[1],
	obs.position[2] + obs.direction[2],
	obs.verticale[0], obs.verticale[1],obs.verticale[2]);
 
    //landmark
    glBegin(GL_LINES);
        glColor3f(1.0,0.0,0.0);
        glVertex2i(0,0);glVertex2i(50,0);//red
        glColor3f(0.0,1.0,0.0);
        glVertex2i(0,0);glVertex2i(0,50);//green
        glColor3f(0.0,0.0,1.0);
        glVertex2i(0,0);glVertex3i(0,0,50);//blue
    glEnd();
 
       //application de la rotation qu'a mon objet
	if (rotateAngle != 0){
		glTranslatef(moyx, moyy, moyz);
		glRotatef(rotateAngle, rotatex, rotatey, rotatez);
		glTranslatef(-moyx, -moyy, -moyz);
	}
 
       //triangle de mon objet (Marching Cube)
	for (int i=0;i<ntri;i++) {
          glBegin(GL_TRIANGLES);
           for (int k=0;k<3;k++)  {
			glColor3ub(tri[i].ndg, tri[i].ndg, tri[i].ndg);
			glVertex3d(tri[i].p[k].x, tri[i].p[k].y, tri[i].p[k].z);
           }
           glEnd();
	}
 
    glutSwapBuffers();
    //calculation a new time the picture
    glutPostRedisplay();
}
Autre point non mentionné, les variables non déclarées au long de ce code, sont en réalité des variables globales (d'où le fait que vous les retrouviez dans plusieurs fonctions).
Je crois n'avoir rien oublié, merci à ceux qui ont eu le courage de me lire en tout cas