Archived

This topic is now archived and is closed to further replies.

uber_n00b

Mouse coords to 3d?

Recommended Posts

int RetrieveObjectID(int x, int y) { int objectsFound = 0; // This will hold the amount of objects clicked int viewportCoords[4] = {0}; // We need an array to hold our view port coordinates unsigned int selectBuffer[32] = {0}; glSelectBuffer(32, selectBuffer); // Setup our selection buffer to accept object ID's glGetIntegerv(GL_VIEWPORT, viewportCoords); // Get the current view port coordinates glMatrixMode(GL_PROJECTION); // We want to now effect our projection matrix glPushMatrix(); // We push on a new matrix so we don't effect our 3D projection glRenderMode(GL_SELECT); // Allows us to render the objects, but not change the frame buffer glLoadIdentity(); // Reset our projection matrix gluPickMatrix(x, viewportCoords[3] - y, 2, 2, viewportCoords); gluPerspective(P,(float)g_rRect.right/(float)g_rRect.bottom,0.1f,2048.0f); glMatrixMode(GL_MODELVIEW); // Go back into our model view matrix DrawGLScene(); // Now we render into our selective mode to pinpoint clicked objects objectsFound = glRenderMode(GL_RENDER); // Return to render mode and get the number of objects found glMatrixMode(GL_PROJECTION); // Put our projection matrix back to normal. glPopMatrix(); // Stop effecting our projection matrix glMatrixMode(GL_MODELVIEW); // Go back to our normal model view matrix if (objectsFound > 0) { unsigned int lowestDepth; int selectedObject; if(selectBuffer[3]!=99) { lowestDepth = selectBuffer[1]; selectedObject = selectBuffer[3]; } else { lowestDepth = selectBuffer[5]; selectedObject = selectBuffer[7]; } for(int i = 1; i < objectsFound; i++) { if(selectBuffer[(i*4)+3]!=99) { if(selectBuffer[(i * 4) + 1] < lowestDepth) { lowestDepth = selectBuffer[(i * 4) + 1]; selectedObject = selectBuffer[(i * 4) + 3]; } } } return selectedObject; } return 0; } Anyway the problem is that if the object is on the screen, then the function returns the objects ID (instead of it just returning when the mouse is over it). Ideas? Sorry if the code turns out messy. Edit: Thanks to DigiBen for this code. It makes sense I just can't get it to work right with my program [edited by - uber_n00b on April 22, 2004 11:45:37 PM]

Share this post


Link to post
Share on other sites
Since you''re a fan of DigiBen, I recommend that you check out his line/polygon collision tutorials. glNames is all well and good but as you''ve noticed it''s not very flexible. All you have to do is use gluUnProject to get the points on the front and back of the frustum and then you''ve got a line, and you can intersect it with any polygon using DigiBen''s idea, and BOOYAH! Mouseover, mousemove, picking, dragging, you got it..

I have a demo on my site that implements dragging a cube around the XZ plane that should illustrate this concept.

Hope this helps.

Love means nothing to a tennis player

My nothing-to-write-home-about OpenGL webpage. (please pardon the popups!)

Share this post


Link to post
Share on other sites
Sorry I did not thank you sooner, but yes.. that ^_^. Although your suggestion of gluunproject() does not seem to work in my case because I deal with a group of polygons in arbitrary shapes, it did launch me into looking into exactly how projection matrices and glupickmatrix actually work and well, the results are what I'd been hoping for. I must thank you for indirectly causing this outcome.

[edited by - uber_n00b on April 26, 2004 7:57:39 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Hello,
I didnt look after your code, but there is the solution i found for myself to convert your 2D-coordinates to 3D-coordinates (from mouse to real dimensions) :
- create an array with your screen dimensions: screen[WIDTH][HEIGHT]
- suppose you clicked at (xP,yP) ;
- draw your scene in glRenderMode(GL_FEEDBACK) mode :
- when you draw, as example, a TRIANGLE, the 2D-coordinates go directly in your buffer ;
- now, for all pixels (x,y) included in each of your triangles : screen[x][y]=index of your triangle

So:
In order to know which triangle you selected, you just have to read the value of : screen[xP][yP], and so on get the 3D-coordinates of your triangle.

That is, it works with any kind of objects.
Hope that ll help you.
Contact me if you are interested by this way and still have problems.
bilbonec@yahoo.fr

Share this post


Link to post
Share on other sites
Thanks for all your help, guys. The problem was that in glRenderScene() I changed the picked matrix from a 2 by 2 matrix back to the full screen through a call to glResize() (not seen in the code), and therefore if the object was displayed on the screen normally it would be returned through the function. silly me

Share this post


Link to post
Share on other sites