Archived

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

waterLINK

gluUnProject()

Recommended Posts

Hi! In transforming 2D screen coordinaes to a 3D space coordinates I have read, is a good chance to use the function gluUnProject. But the doc tell to make to calls to this function, one with screen z value to 0.0f, and the second call with screen z value to 1.0f. Then I ask, with 2 calls, I get 2 results. Which is the good one, or if the 2 ar valid, who then I use them to obtain the 3D space coordiante? Thanks, to this forums funs. Bye Hi. My mind is similar to yours, but I know where you are.

Share this post


Link to post
Share on other sites
Neither of them are the "right one".

Think about it: a 2D coordinate unprojected doesn''t define a 3D point. It can''t, after all; it doesn''t have enough information. If you point to a box drawn in your world, how should the computer know whether you''re pointing to the surface of the box, the inside of the box, or a point two feet in front of the box?

The two Z-values give you two points, and two points make a line. Find whatever object of interest intersects this line, and you''ll know what you''re pointing at.



Don''t listen to me. I''ve had too much coffee.

Share this post


Link to post
Share on other sites
Hi Sneftel.

I''m coding a very basic 3D editor, to make maps and later show thems in first person.
Think about a 3D editor, 3D Studio MAX for example, and then think about the 3D perspective viewport, where you can move the mouse and you can see on a status bar the 3D world space coordinate you are pointing to, just with z value of 3D, truncated to 0.0f.

That''s what I''m looking for. Just without painting (perhaps), and only moving over the viewport I can se the 3D space coordinate.

But now, as you say, if nothing is drawn, openGL can''t know how far is the point i''m aiming to. So I think I could draw some kind of invisible big plane, with z=0 (z is vertical axis for me, like 3D Studio MAX) and over that plane calculate the intersection of the line that I get with the 2 calls to gluUnProject(), just to know exactly the famous 3D point.

Jeje, do you know, how to render that kind of invisible plane I refer to? Or you think that''s not a good chance for my porpuse.

Thanks.

Hi.
My mind is similar to yours, but I know where you are.

Share this post


Link to post
Share on other sites
Rendering an invisible plane won''t help you. OpenGL isn''t smart enough to remember what it''s drawn, and then point at it. You could possibly accomplish this by locking the Z-buffer and retrieving the value at the pixel in question; but this is slow, and doesn''t work on all hardware.

What I would suggest you do is read up on how gluUnProject works; it''s not that difficult, if you understand linear algebra. Write your own custom function that can unproject a point, given a specific Y-value.

Alternatively, you could take the points returned from gluUnProject, and find the point where the line they define intersects your plane equation. That would probably be easier.



Don''t listen to me. I''ve had too much coffee.

Share this post


Link to post
Share on other sites
Simple as ........ nothing, jajaja. I did it!!!

I have taken my institute math book and look for:

- Line equation having to points.
- Plane and Lines interseccion.

Then I did some general ecuations and the result is this:

GLdouble x_obj1,y_obj1,z_obj1,
x_obj2,y_obj2,z_obj2;

GLdouble x_AB, y_AB, z_AB; // Algebra variables
GLdouble factor_t; // for parametric line
// equation
GLdouble space_x,space_y,space_z;

gluUnProject(screenPoint.x,view_height-screenPoint.y,0.0,
modelMatrix,
projMatrix,
viewport,
&x_obj1,&y_obj1,&z_obj1);

gluUnProject(screenPoint.x,view_height-screenPoint.y,1.0,
modelMatrix,
projMatrix,
viewport,
&x_obj2,&y_obj2,&z_obj2);

x_AB = (x_obj2 - x_obj1);
y_AB = (y_obj2 - y_obj1);
z_AB = (z_obj2 - z_obj1);

factor_t = - (y_obj2 / (y_AB));

space_x = x_obj2 + (factor_t * x_AB);
space_y = y_obj2 + (factor_t * y_AB);
space_z = z_obj2 + (factor_t * z_AB);

What I do is to retrieve 2 points, with 2 calls to gluUnProject() the firts with screen_z=0.0f, and the second with screen_z=1.0f. Thus, I have prepare the parametric equation from a line with to 3D points. And then calculate the intersectioin point.

Basicaly, as I know that my plane is at height y = 0, the normal vector is (0,1,0).

Plane equation: Ax + By + Cz + D = 0; As the distance to the origin is 0, then D = 0; Therefore my plane equation is this:

My plane equation: By = 0;

The parametric equation of a line is like this:

x = x1 + ta;
y = y1 + tb; -> The important one to substitute at plane eq.
z = z1 + tc;

In the code it corresponds with this:

space_x = x_obj2 + (factor_t * x_AB);
space_y = y_obj2 + (factor_t * y_AB);
space_z = z_obj2 + (factor_t * z_AB);

Easy to calculate factor_t.

The results are, incredibly precise. Just without painting any kind of invisble plane



Hi.
My mind is similar to yours, but I know where you are.

Share this post


Link to post
Share on other sites