Bonjour :p.
Voilà j'ai actuellement un petit problème pour traduire des coordonnées 2D (donc x, y, que je récupère suivant le clique de la souris), en coordonnées 3D.
Je pense que ça doit être une histoire de matrices et je pense que c'est expliqué dans le livre de math que je me suis acheté récemment, mais pas encore eu le temps de le lire, et j'ai besoin d'une solution pour l'instant. J'ai donc récupéré un code sur Internet, que voici :
C'est un code que j'ai trouvé plusieurs fois sur le net, il a l'air correct, toutefois les valeurs renvoyées sont bizarre.
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 CVector & ScreenToWorld (int screenx, int screeny, int screenz) { GLint viewport[4]; GLdouble modelview[16]; GLdouble projection[16]; GLfloat winX, winY, winZ; GLdouble posX, posY, posZ; glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); glGetDoublev( GL_PROJECTION_MATRIX, projection ); glGetIntegerv( GL_VIEWPORT, viewport ); winX = (float)screenx; winY = (float)viewport[3] - (float)screeny; gluUnProject (winX, winY, screenz, modelview, projection, viewport, &posX, &posY, &posZ); return CVector ((posX), (posY), (posZ)); }
Ma première utilisation, c'est de dessiner un point quand on clique avec la souris :
Ici, pas de soucis, le point est dessiné exactement à la bonne position. Toutefois, dans la seconde utilisation que j'en fais, je rencontre un problème. En fait je souhaite gérer, via le moteur Newton, les objets via la souris (les prendre, les jeter,...), et plutôt que de faire une technique habituelle comme celle expliquée dans les tutos de la librairie, j'ai préféré en essayer une autre, qui consiste à créer un joint invisible pile à l'endroit du clique, et "attacher" le corps à ce joint, ce qui va ainsi l'arrêter. Voici comment je procède :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 MouseState = SDL_GetMouseState (&x, &y); if (MouseState & SDL_BUTTON(SDL_BUTTON_LEFT)) { CVector coordinates = ScreenToWorld (x, y, 0); glBegin (GL_POINTS); glVertex3f (coordinates.x, coordinates.y, coordinates.z); glEnd (); }
1) Je récupère la position x, y du clique, et je converti pour avoir les coordonnées 3D puis j'envoie un rayon (raycast) et je vérifie que le rayon est touché un corps, si oui, j'ajoute le joint à l'endroit desirée.
La position du début du lancer de rayon est obtenue comme ceci :
CVector p0 = ScreenToWorld (x, y, 0.0f);
Et la position d'arrivée :
CVector p1 = ScreenToWorld (x, y, 1.0f);
Bref, tout ceci devrait fonctionner normalement mais en pratique, le joint ne se place pas au bonne endroit, et pour cause, en ayant vérifié les valeurs renvoyées par ScreenToWorld, les valeurs sont très étranges :
Ainsi, en cliquant sur le bord droit maximum de l'écran, j'obtient comme valeur pour p0.x environ 0.076 et à gauche -0.076, ce qui est totalement pas normal étant donné que la largeur de ma boîte qui prend à peine en largeur 1/10 de l'écran à déjà une longueur d'une unité, en tout logique je devrais me trouver vers 9-10 lorsque je clique à droite et -9 -10 à gauche...
Après avoir reculé la caméra via gluLookAt de 30 unités, j'obtient exactement les mêmes résultats ! (-0.076 et 0.076),...
Bref, je voudrais savoir comment récupérer les vrais positions dans les coordonnées globales. Par exemple, mon cube est placé à la position 0.0, et puisqu'il fait 1.0 de largeur, en toute logique si je clique sur son extrêmité droite je devrais obtenir pour p0.x 0.5, alors que j'obtient 0.004 actuellement :/...
Mais le plus étrange c'est que pour dessiner le point sous la souris, ben là ça marche correctement, le point est bien dessiné sous la souris,... Bref, si quelqu'un a une idée...
Partager