Is there a way to calculate the 3d coord from screen coord?

Hello,
I know OpenGL first calculates the 3D coordinates and then transform them into screen coordinates in order to render. My question is, is there a way to find the 3D coordinate of one point, privided its screen(relative to the window) coordinate and the Z value are given?

For example, my mouse click on a point which has the 2D coordinate of (50,50) relative to the window, and I want to know the 3D coordinate of this point inside OpenGL's internal system, with the Z value being -100.

Is there a way to find it?

Thanks in advance for any helps.

Coco

Here ya go, in BASIC. Crap. I can’t remember if this is 2D->3D or 3D->2D:

Global projectedx#
Global projectedy#
Global projectedz#
Global projectedw#

Function CameraProject(x#,y#,z#)
glRasterPos3f x,y,z
buffer=CreateBank(1)
glGetBooleanv GL_CURRENT_RASTER_POSITION_VALID,buffer
boolean=PeekByte(buffer,0)
FreeBank buffer
If boolean
buffer=CreateBank(16)
glGetFloatv GL_CURRENT_RASTER_POSITION,buffer
ProjectedX#=PeekFloat(buffer,0)
ProjectedY#=PeekFloat(buffer,4)
ProjectedZ#=PeekFloat(buffer,8)
ProjectedW#=PeekFloat(buffer,12)
FreeBank buffer
Return True
Else
Return False
EndIf
End Function

Function ProjectedX#()
Return ProjectedX
End Function

Function ProjectedY#()
Return ProjectedY
End Function

Function ProjectedZ#()
Return ProjectedZ
End Function

Function Projectedw#()
Return Projectedw
End Function

[This message has been edited by halo (edited 12-21-2003).]

Originally posted by Coconut_Crab:
[b]Hello,
I know OpenGL first calculates the 3D coordinates and then transform them into screen coordinates in order to render. My question is, is there a way to find the 3D coordinate of one point, privided its screen(relative to the window) coordinate and the Z value are given?

For example, my mouse click on a point which has the 2D coordinate of (50,50) relative to the window, and I want to know the 3D coordinate of this point inside OpenGL's internal system, with the Z value being -100.
Is there a way to find it?

Thanks in advance for any helps.

Coco[/b]

see here
http://users.frii.com/martz/oglfaq/selection.htm

and also I like articles ( the math not dx ) from here
http://www.mvps.org/directx/articles/rayproj.htm

to Halo:

Sorry, but I don’t understand BASIC.

to SergeVrt:

I read that article you provided. It assumed there was already a vertex, or object in the 3D space and what I do is to “select” it. But my problem is I want to find the 3D coordinate even if there was originally no object/vertex there.

What I want to do is not to select an object, but rather to find the 3D coordinate from the 2D coordinate, so I may construct my own object at the specific 3D coordinate from my mouse’s position.

I confess I don’t quite understand how gluPickMatrix() and gluPerspective() work to limit the drawing area, since I never see change in the viewing direction like with gluLookat(). Maybe if I understand the concept I will be able to achieve my goal with the knowledge on the webpage you provided. Can someone please enlighten me a little bit?

Thanks in advance for any helps.

Coco

A 2D point maps to a 3D line (all points on that line project to the same 2D point).
If you want to unproject from a 2D point to a 3D point, you need to decide on a depth value.
Find that either by intersecting the line with an existing 3D object, or let the user pick the depth somehow (for a modeller you could use a movable “current depth” plane).

Hello, zeckensack

Which OpenGL functions I can I use to find the the vector(or math function) of that line? Can you please give a code example, or perhaps point to me to a place that has this specific code example?

Thanks.

Coco

Hi, SergeVrt,

I read the article to do the reverse of view matrix with DirectX which you provided. It's very helpful. But do you know the functions in OpenGL that can do the same thing, namely, what DirectX can do with these 2 functions:

lpDevice->GetTransform(D3DTRANSFORMSTATE_VIEW,&viewMatrix);
D3DMath_MatrixInvert(invMatrix,viewMatrix);

Thank you.

Coco

Ah, I think I almost get it. Have to experiment a little bit.

Originally posted by Coconut_Crab:
[b]
lpDevice->GetTransform(D3DTRANSFORMSTATE_VIEW,&viewMatrix);
D3DMath_MatrixInvert(invMatrix,viewMatrix);

[/b]

seems that http://users.frii.com/martz/oglfaq/glu.htm#0070

gluUnProject() - takes an XYZ window coordinate and returns the back-transformed XYZ object coordinate equivalent.

is what you need.

also you might search ( google) for inverting matrixes ( invert matrix) and see how to get model view matrix with glGet and GL_MODELVIEW_MATRIX param ( though there are ways to keep track on current view matrix … see different open scene graphs code how )

such as http://openscenegraph.sourceforge.net/ http://www.terrainengine.com/

as far as I could remember they had relevant code

you don’t understand basic? how is this possible… and also, it’s REALLY a problem, since we all LOVE basic here, right?

sorry g

Jan

If you need this for simple cases (clicking, etc) and don’t call it hundreds of times per frame, I’d suggest using Get() on the matrices and viewport, and passing that into gluUnProject(). It’s easy, simple, and works. Look at the man page for gluUnProject() and it’ll probably have a usage example.

Originally posted by Coconut_Crab:
lpDevice->GetTransform(D3DTRANSFORMSTATE_VIEW,&viewMatrix);
D3DMath_MatrixInvert(invMatrix,viewMatrix);

To get back from the screen to world space don’t you need to go through the inverse projection matrix and then the inverse view matrix?

to SergeVrt:

I have a question. For the coordinates returned by gluUnProject(), what are their units? I mean, say that I get the returned values of X, Y, and Z, can I then use the same values of X, Y, Z to directly draw a vertex with glBegin?

If so, it would be very convenient; if not, what other calculations do I need to do to transform the unit returned by gluUnProject() to the unit which I draw?

Thank you for your help, and I really appreciate it.


to Jwatte:

Thank you, I will try as you suggested.

ok, I’ll ask my question more precisely this way.

After I get my XYZ values from gluUnProject(), are they the values relative to the current MODELVIEW matrix, meaning they can be used directly like glVertex3f(X,Y,Z);, or are they the coordinates of a MODELVIEW matrix aquired from glTranslate()?

Thank you.

Coco

[This message has been edited by Coconut_Crab (edited 12-22-2003).]

Just get transformation matrix, invert, and multiply by coord column(row)