Jump to content
  • Advertisement

Archived

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

Kaesebrot

converting screen coordinates to 3D coordinates

This topic is 5855 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

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...

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]);

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!