Archived

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

Mouse Coords working w/ a 3d plane

This topic is 5042 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a program where the user is free to rotate on the x and y axis around the fixed point of (0, 0, 0), right? Well, when you click the mouse, you have an x and y, but I need to know exactly where you clicked in that 3d plane. Basically what I''m saying is if I have, for example, a bunch of cubes floating around that point, and the user has the camera rotated at an odd angle, how do I tell what the user is clicking on? This is probably confusing, sorry. Videege

Share this post


Link to post
Share on other sites
Your demo is of great help, but I was wondering about a section of your code. When you check to see if they clicked on the cube, the only reasoning you have is if depth != 1.0f, because the cube is the only object on the screen apart from the axes, lines, and what not. While your code is perfect for your program, what if I have many, many, many objects on the screen and I only want certain objects to be moved?

EDIT:
I also want the user to be able to drag objects on all 3 axis, but I'm not sure how to do this. Once again thank you for the demo on your site, it has been greatly helpful.



[edited by - Videege on February 22, 2004 12:38:30 PM]

Share this post


Link to post
Share on other sites
Maybe I''m having some trouble understanding.
Can someone tell me how exactly you use the UnProject function, using a normal openGL rendering context in windowed mode? I can''t seem to get my things to move left and right, only on the y and z axis.

Share this post


Link to post
Share on other sites
First of all videege, you''ve given me a great idea - when I have a chance I''ll modify that demo to have 5 or 6 cubes on the XZ plane, but some of them can *not* be moved. Later, I''ll modify it in such a way that the user can choose to drag along the XZ plane or the plane x = (wherever the cube is) or the plane z = (wherever the cube is). I''m pretty sure it will work and be simple.

To answer your simple question, gluUnProject converts an (x,y) point on the screen to an (x,y,z) point in 3D space. Period. Don''t confuse the tool with the solution - gluUnProject is just a means to an end. You might like to check Article 13 on the main NeHe page - below the tutorials are a list of articles.

gluProject is, as you might guess, the opposite of gluUnProject. gluProject takes a 3D point and returns a 2D point plus a depth, in other words, it tells you where on the 2D screen it is and how deep *into* the screen it is.

Okay - as long as we''re dealing with cubes or rectangular prisms that can NOT intersect each other, I think we can come up with a pretty straightforward algorithm to solve this problem. First let''s tackle dragging everything along the XZ plane only, then we''ll extend it to other planes.

Let''s suppose we have several prisms sitting on the XZ plane, some can be moved, some cannot.

The user clicks on the screen. You construct the ray from the front to the back. If you only intersect one prism and it''s movable, GREAT!!!!! You got it.

If you intersect more than one prism, then what we need to do is figure out which one is in *front*. I believe that to accomplish this, you can use gluProject. Call gluProject for each of the 6 corners of each prism we intersected. I believe we can assume that the largest nonnegative depth is one that''s furthest to the front. If that prism is movable, GREAT!!!! you got it.

For more general shapes, this could suddenly become extremely difficult, but I believe that for just prisms that don''t intersect each other this approach will work.



Now let''s talk about moving in more than 2 directions. In a nutshell, you must accept that a 2D surface has 2 degrees of freedom. You cannot let the user drag something in 3 dimensions with 3 degrees of freedom - it is a physical and logical impossibility. The best you can hope for is to map the 2D window to a parametric surface, i.e. a dome or any other plane.

In other words, you can drag along the XZ plane *or* the YZ plane *or* the XY plane, just not all 3.

You can drag along a line by doing a little extra math to ignore one of the two window coordinates, i.e. suppose you have a line that extends from (10, 0, 10) to (20, 0, 10). You could say, if the mouse is all the way over to the left then your cube is at x=10, if it''s all the way to the right it''s at x=20, if it''s in the middle it''s at 15 etc.

I''ll say one more thing about this - you can drag and drop objects from one object to another using the "same depth value" approach. Say you have a book sitting on a table and you want to drag it to another table. When the user clicks on the book you detect it using the ray collision method, and as it''s being dragged you recalculate its new point using the mouse''s *new* X and Y and the *old* depth value from before. As the mouse is being dragged, use the ray collision method to see if we''re pointed at the new table. If we are, drop the book like a hot potato!

If a lot of this doesn''t make sense it''s because it was typed when I should have been sleeping . But the bottom line is:

1. gluProject, gluUnProject, glReadPixels, and ray/polygon collision are simply tools in a toolbox. It''s up to you to figure out how to put them together to solve your problem.
2. You can only move things with at most 2 degrees of freedom.

Hope this helps, because I fried myself typing it all

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