Souris en 3D

nicographx Messages postés 21 Date d'inscription mardi 3 juin 2003 Statut Membre Dernière intervention 22 juin 2009 - 31 juil. 2005 à 14:49
cs_keil Messages postés 52 Date d'inscription jeudi 22 mai 2003 Statut Membre Dernière intervention 25 octobre 2005 - 10 août 2005 à 09:47
Bonjour

Dans un programme en 2D, il est facile de connaitre la correspondance entre la map et la souris : il suffit de connaitre la position de la souris, et on en deduit immediatement la position sur la map.

Mais comment faut-il proceder en 3d ? (j'utilise opengl avec glut)
Je n'arrive pas a calculer la position de ma souris par rapport à ma map.
Il faut bien sur prendre en compte la position de la camera, mais je n'y arrive pas.

Si quelqu'un pouvais me filer un coup de main, ca serait sympa ;)

Merci d'avance

10 réponses

mondrone Messages postés 246 Date d'inscription mercredi 5 janvier 2005 Statut Membre Dernière intervention 11 mars 2012
31 juil. 2005 à 15:42
va voir , je pense que ca peut t'aider. La question à plus ou moins deja été posée !

<hr size="2" width="100%"> Qui ne tente rien...

Ne risque pas d'avoir grand chose !!!

<hr siz="">
0
nicographx Messages postés 21 Date d'inscription mardi 3 juin 2003 Statut Membre Dernière intervention 22 juin 2009
31 juil. 2005 à 21:13
Oui, j'avais deja lu cet article, mais merci qd meme
Mais j'ai toujours un soucis :
ma selection ne bouge pas sous ma souris (seulement a certains endroits) et plus on s'eloigne du 0, plus ma selection prend de l'avance.

Voici mon code :

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 = (int)xsouris;
winY = (int)viewport[3]-(int)ysouris;

glReadPixels( (int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

plan((int)posX, 0, (int)posZ, SELECTION);
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
1 août 2005 à 15:49
Il te faut faire du picking (Google):
La matrice de projection te donne le point 2D qui correspond au point 3D du terrain.
Toi, tu veux les point 3D a partir du point 2D de l`ecran.
Or, la matrice de projection n`est pas inversible car un point 2D peut "venir" de plusieurs points 3D.

POINT ptCursor;
GetCursorPos( &ptCursor );
ScreenToClient( m_hWnd, &ptCursor );


// Compute the vector of the pick ray in screen space
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * ptCursor.x ) / m_d3dsdBackBuffer.Width ) - 1 ) / m_matProj._11;
v.y = -( ( ( 2.0f * ptCursor.y ) / m_d3dsdBackBuffer.Height ) - 1 ) / m_matProj._22;
v.z = 1.0f;


// Get the inverse view matrix
D3DXMATRIX m;
D3DXMatrixInverse( &m, NULL, &m_matView );


// Transform the screen space pick ray into 3D space
vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;
D3DXVec3Normalize(&vPickRayDir,&vPickRayDir);
vPickRayOrig.x = m._41;
vPickRayOrig.y = m._42;
vPickRayOrig.z = m._43;

Voila, maintenant tu as le rayon 3D recherche.
Bon, c`est du DirectX mais l`equivalent opengl est facile a deduire.
L`exemple complet DirectX est ici:

http://www.mvps.org/directx/articles/pick.zip
0
cs_keil Messages postés 52 Date d'inscription jeudi 22 mai 2003 Statut Membre Dernière intervention 25 octobre 2005
4 août 2005 à 14:12
sinon ca vient du fait que t'as initialiser avec autre chose que glOrtho(...).

Parce qu'en effet les gluPerspective(...) posent probleme dans ce genre de situation

KS
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
nicographx Messages postés 21 Date d'inscription mardi 3 juin 2003 Statut Membre Dernière intervention 22 juin 2009
5 août 2005 à 10:24
Oui, j'ai justement utilisé des gluPerspective...
Ca viens surement de ca, mais existe t-il un moyen pour que ca marche qd meme ?
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
5 août 2005 à 12:23
Pourquoi n`utilises-tu pas la methode que j`ai decrite plus haut ? Elle fonctionne, je l`ai utilise.

Variables:
m_hWnd handle de la fenetre
ptCursor position du curseur en pixel relative au coin haut-gauche de la fenetre
m_d3dsdBackBuffer structure de description du back buffer
m_matProj la matrice qui a servit a projeter les meshes

vPickRayDir direction du vecteur
vPickRayOrig origine du vecteur
Ce vecteur est le vecteur recherche: il passe par tous les points qui se projete sous la souris avec la matrice m_matProj

C`est du DirectX, mais bon, il n`y a quasiment rien a changer pour OpenGL
0
cs_keil Messages postés 52 Date d'inscription jeudi 22 mai 2003 Statut Membre Dernière intervention 25 octobre 2005
8 août 2005 à 22:06
Ecoute Galmiza; je pense qu'il a besoin de réponse concrète donc plutot
que de lui donner une reponse en directX donnes lui une réponse en
openGL.

Tu penses qu'il n'y a rien a changer parce que tu doit pas trop
connaitre l'openGL, mais si ca se trouve, lui ne connait pas du tout directX

KS
0
Galmiza Messages postés 573 Date d'inscription samedi 16 novembre 2002 Statut Membre Dernière intervention 9 avril 2008 1
9 août 2005 à 13:11
Excuse moi, mais le changement de taille de texte est involontaire. Il y a comme un bug. Il y a ecrit taille 3 par defaut. Lorsque je copie-colle des trucs, ca passe a 2, donc je remets a 3 la suite, mais ca devient trop grand. (une fois poste seulement)

C`est vrai je n`y connais rien a l`OpenGL, c`est pour ca que je ne donne que l`algorithme.

Age inconnu pour NicographX, donc je ne sais pas si seul un copier-coller de ce qu`il faut ecrire est satisfaisant, ou alors l`algorithme. Cependant la source est toujours valable. Il n`y a pas trop de DirectX dedans. Seule une connaissance du C/C++ est necessaire pour la decrypter.

J`avais pas mal galere au debut pour trouver un algorithme. J`en avais fait un presque parfait mais il y avait toujours quelques pixels de difference. J`ai donc repris l`algorithme DirectX.
0
nicographx Messages postés 21 Date d'inscription mardi 3 juin 2003 Statut Membre Dernière intervention 22 juin 2009
9 août 2005 à 15:02
Scusez moi pour ne pas avoir repondu avant, j'étais un peu debordé ces derniers jours.

en effet, je ne connait pas du tout directx. J'ai apris le c++ durant toute l'annee, et je commence tout seul a apprendre l'opengl (ca fai a peu pres 2 mois que je suis dedans)

mais je ne connai pas toutes les fonctions... mais j'ai trouver 2-3 trucs sur le net qui parlais d'une fonction pour le faire, sinon, je serais parti dans les calculs de maths.. mdrrr

Voila
Merci pour vos reponses qui finiront j'en suis sur par m'aider
0
cs_keil Messages postés 52 Date d'inscription jeudi 22 mai 2003 Statut Membre Dernière intervention 25 octobre 2005
10 août 2005 à 09:47
POINT ptCursor;
GetCursorPos( &ptCursor );
ScreenToClient( m_hWnd, &ptCursor );

------> recuperation des coordonnes de la souris




// Compute the vector of the pick ray in screen space
D3DXVECTOR3 v;

-------> <=> structure de 3 float





v.x = ( ( ( 2.0f * ptCursor.x ) / m_d3dsdBackBuffer.Width ) - 1 ) / m_matProj._11;
v.y = -( ( ( 2.0f * ptCursor.y ) / m_d3dsdBackBuffer.Height ) - 1 ) / m_matProj._22;
v.z = 1.0f;

--------->
m_d3dsdBackBuffer.Width
m_d3dsdBackBuffer.Height = resolution de ta fenetre

--------->
m_matProj._11 et
m_matProj._22 : il faut que tu recupere la matrice de projection. (il existe une fonction openGL pour ca)

---------> m_matProj._11 <=> matrix_projection[1][1]

---------> m_matProj._22 <=> matrix_projection[2][2]






// Get the inverse view matrix
D3DXMATRIX m;
D3DXMatrixInverse( &m, NULL, &m_matView );

---------> copie de la matrice MODEL_VIEW puis inversion
(il existe des fonctions openGL pour ca)



// Transform the screen space pick ray into 3D space
vPickRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
vPickRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
vPickRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;

---------> aucune idee, testes et tu verras (a mon avis cette partie ne sert a rien)



D3DXVec3Normalize(&vPickRayDir,&vPickRayDir);

---------> je suppose que c'est pour normaliser ta variable '
vPickRayDir'


vPickRayOrig.x = m._41; //
-------->
translation en x
vPickRayOrig.y = m._42;
//
-------->
translation en y


vPickRayOrig.z = m._43;
//--------> translation en z


---------> en théorie c'est pour faire une translation



---> conclusion, tu dois peut etre te retrouver avec ce que tu cherches

KS
0