converting screen coordinates to 3D coordinates

Started by
12 comments, last by Kaesebrot 21 years, 10 months ago
hi.. I want to write a small editor and now I need to convert the Cursor-Coordinatesn in 3D-Coordinates.. no matter what perspective is set.. I just want to know which point of the near-clipping plane is projected to the cursor-position... I hope you know what I mean...
Advertisement
This is taken from my sources, I've notated it a bit


      void ScreenToWorld(Vector3 &out,const ViewParameters& view,float x,float y){ Vector3 ax(view.viewMatrix(0,0),view.viewMatrix(0,1),view.viewMatrix(0,2)); Vector3 ay(view.viewMatrix(1,0),view.viewMatrix(1,1),view.viewMatrix(1,2)); Vector3 az(view.viewMatrix(2,0),view.viewMatrix(2,1),view.viewMatrix(2,2)); float xmul = x * view.nearPlane * tan( (view.fov/2.0) * 3.14/180.0); float ymul = y * ((view.nearPlane * tan( (view.fov/2.0) * 3.14/180.0))/( (float)view.w/(float)view.h)); out.Set(0,0,0); out += ax * xmul; out += ay * (-ymul); out += -az * (view.nearPlane + 0.001); // 0.001 is an epsilon, probably not needed. out += view.viewPoint;}      


view.viewMatrix is a 3X3 matrix representing the 'tumble' of the world about the camera (the top row gives the x axis pointing right, the middle row gives the y axis pointing up and the bottom row gives the z axis, pointing away from the view vector) and is consistent with OpenGL.

view.viewPoint is a 3 vector representing the camera position.

view.nearPlane is a float value for the distance of the near plane along the view vector (ie the -ve z row of the viewMatrix).

ax,ay,az then represent the three rows of the matrix (extracted by the element accessors viewMatrix(row,col) ).

out is the point on the near plane.

x and y are the NDC space coordinates and range from -1.0 to 1.0 across the screen. The centre of the screen is at (0,0), (-1.0,-1.0) is the top left of the screen.

view.fov is the field of view

view.w, view.h are the width and height of the viewport in pixels (these are float values).

[edited by - JuNC on June 9, 2002 10:24:20 AM]

[edited by - JuNC on June 9, 2002 10:25:37 AM]
thx.. I will try it.
I figured out my own function and compared it with JuNC's function. I think they are mostly the same. It works fine until I use glTranslate or glRotate. I don't find the error, maybe my extraction of the achsis-vectors is wrong.. does anyone see my fault?


      TVector vXAchsis, vYAchsis, vZAchsis, vViewPos;  float   vViewMatrix[16];  float   vAspect = vFrontView->vWidth / vFrontView->vHeight;  float   vFOV = 45.0f * (PI / 180.0f) / 2.0f;  float   vNearPlane = 20.0f;//0.01 * 50.1f;  float   vXPos, vYPos;  vXPos = (float)(X - vFrontView->vWidth / 2) / (float)(vFrontView->vWidth / 2);  vYPos = -(float)(Y - vFrontView->vHeight / 2) / (float)(vFrontView->vHeight / 2);  glGetFloatv(GL_MODELVIEW_MATRIX, vViewMatrix);  vXAchsis = TVector(vViewMatrix[ 0], vViewMatrix[ 1], vViewMatrix[ 2]);  vYAchsis = TVector(vViewMatrix[ 4], vViewMatrix[ 5], vViewMatrix[ 6]);  vZAchsis = TVector(vViewMatrix[ 8], vViewMatrix[ 9], vViewMatrix[10]);  vViewPos = TVector(vViewMatrix[12], vViewMatrix[13], vViewMatrix[14]);  v3DPos = vViewPos +           vZAchsis * (vNearPlane * -1.0f) +           vXAchsis * (tan(vFOV) * vXPos * vNearPlane) +           vYAchsis * ((vYPos * tan(vFOV) * vNearPlane) / vAspect);    


[edited by - Kaesebrot on June 9, 2002 2:05:03 PM]
If it''s screwing up with glRotate it might be the case that you need to transpose the 3X3 matrix indices, OpenGL uses the rows of the matrix for the axes and stores it in column major format:

[ a1 a5 a9 a13 ]
[ a2 a6 a10 a14 ]
[ a3 a7 a11 a15 ]
[ a4 a8 a12 a16 ]

(Which I assume you know from the extraction of the view pos)

Thus you should be using [0] [4] [8] for the x axis etc. unless anyone can see different.

I think the glTranslate should work correctly when used on it''s own.
I got it

If I call glTranslate it transforms the world not the position of the camera. I just have to invert my extractet vector of the viewpos. The problem with glRotate can be solved the same way.


  vXAchsis = TVector(vViewMatrix[ 0], -vViewMatrix[ 1], -vViewMatrix[ 2]);  vYAchsis = TVector(-vViewMatrix[ 4], vViewMatrix[ 5], -vViewMatrix[ 6]);  vZAchsis = TVector(-vViewMatrix[ 8], -vViewMatrix[ 9], vViewMatrix[10]);  vViewPos = TVector(-vViewMatrix[12], -vViewMatrix[13], -vViewMatrix[14]);  
Just use gluUnProject(). It takes the current modelview matrix, projection matrix, viewport and screen coords and returns object coords. You get the point on the near plane if you pass 0.0f for winz.
And invert your current y-screen-coord as following: viewport.bottom - y

Gero Gerber
this is exactly what I''m looking for..
I implemented it and it works perfectly

thx
thx! I just wanted to ask the same...
no problem

This topic is closed to new replies.

Advertisement