Advertisement

Need help with 3d Picking

Started by October 23, 2002 09:18 PM
2 comments, last by Penance 22 years ago
I have a project due in which we have to have some 3d objects translate rotate, blah blah. I could go the lame route and have a sphere turning like every other person in the class but since I know how to do that already I wanted to do something new. I will have a scene of a table with a few objects on it. I want to be able to click on an object and have it be "picked up". When clicked, the object will move closer to the camera and you can then manipulate it by rotation, scale, etc. My question is, since I have to have multiple camera positions for the project, is it very hard to handle picking? If everything was static then I could handle the picks easily since I''d know the dimensions and location, but since I could be in front of the table, behind, to the side, slightly above and looking down....I won''t know where exactly on the screen something is, so I won''t know if the mouse being at some x,y will put it over a certain object. How should I handle it?
If it''s OpenGL, I made a small program in which you could drag things around on the screen in 3D space. Might be helpful.

NeHe -> Downloads -> D
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Advertisement
Hmmm, thanks. That has me halfways where I need to be hehe. Could you or someone else explain the underlying concept on how to do it? I see you grab matrices from openGL and do some projects and unprojects, but in general, what is the technique?
When the mouse is clicked, Pick is called with the mouse position. Pick is given a pointer to a function to call to do the drawing, and a pointer to an unsigned int to store the result. If an error occurs, it returns true, and you didn't click on anything.

When drawing with the function you pass to Pick, no drawing actually happens. It zooms onto the area where the mouse is, and it keeps track of which polys didn't get clipped away, and then uses the closest polygon. You need to call glLoadName before drawing each shape so you know what belongs to what. Pick will put the value you put in glLoadName in the unsigned int you give it.

For dragging, we use CalcPointDepth to find out how far into the screen a point (the position of whatever we clicked on) is, so that when we move the mouse it will stay at that depth, and just move parallel to the screen.

Once we have that value, we use GetMousePosition to find a point in 3d space at that depth, and then move whatever we are dragging to that position, and continue to do this until the user releases the mouse button. In theory you can change the depth to move whatever you are dragging toward or away from you, although I think it has to be between 0 and 1, 0 being your eye, and 1 being the back clipping plane where everything disappears, never to be seen again.

It's also possible to use glReadPixel to read the depth from the depth buffer so that the mouse will follow the surface of whatever is on the screen, but you need to be sure to draw whatever you are dragging last, and read the depth from the buffer before you draw it, otherwise it will get closer to you each frame until it's behind you, at which time it isn't rendered, and ends up at the depth of whatever is infront of you, where it happens again. My program doesn't read from the depth buffer, though.

It will probably look like this:

    // instead of using CalcPointDepth with a point in 3d space, use this with the mouses position on the screen.float CalcMouseDepth(int x, int y) {  int viewport[4];  float depth;  glGetIntegerv(GL_VIEWPORT, viewport);  glReadPixels(x, viewport[3]-y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);  return depth; }    


[edited by - smart_idiot on October 24, 2002 7:00:55 PM]
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.

This topic is closed to new replies.

Advertisement