Since I'm using a perspective view, I needed to translate those coordinates into world coordinates. In my case, on the current project I'm working on, I would finally want to know which button the user click from a grid.
I got the gluUnProject code from MESA. However the code needed some minor adjustments, namely converting everything from double to float:
- any GLdouble had to be replaced with GLfloat
- any double numbers, e.g. 0.0 or 1.0 I converted them to their respective float counterpart, e.g. 0.0f or 1.0f
- and math functions which accepted/returned double, I replaced them with their float versions, e.g. fabs -> fabsf
So I thought to use the value of zero, but in effect it was always giving the coordinates of the center of the screen. In reality it was giving me the coordinates of the camera position. When I tried 1 instead of 0, it was giving me coordinates that made more sense but still not 100% precise.
The solution was to unproject twice, one time at the near plane (z = 0) and one time at the far plane (z = 1) as discussed in a forum. That gives you a ray which can then be used to make an intersection with a plane and get the exact coordinates. Thus converting from 2d to 3d.
Here's the method I have used which uses the migrated gluUnProject using just floats:
-(CGPoint) getOGLPos:(CGPoint)winPos
{
// I am doing this once at the beginning when I set the perspective view
// glGetFloatv( GL_MODELVIEW_MATRIX, __modelview );
// glGetFloatv( GL_PROJECTION_MATRIX, __projection );
// glGetIntegerv( GL_VIEWPORT, __viewport );
//opengl 0,0 is at the bottom not at the top
winPos.y = (float)__viewport[3] - winPos.y;
// float winZ;
//we cannot do the following in openGL ES due to tile rendering
// glReadPixels( (int)winPos.x, (int)winPos.y, 1, 1, GL_DEPTH_COMPONENT24_OES, GL_FLOAT, &winZ );
float cX, cY, cZ, fX, fY, fZ;
//gives us camera position (near plan)
gluUnProject( winPos.x, winPos.y, 0, __modelview, __projection, __viewport, &cX, &cY, &cZ);
//far plane
gluUnProject( winPos.x, winPos.y, 1, __modelview, __projection, __viewport, &fX, &fY, &fZ);
//We could use some vector3d class, but this will do fine for now
//ray
fX -= cX;
fY -= cY;
fZ -= cZ;
float rayLength = sqrtf(cX*cX + cY*cY + cZ*cZ);
//normalize
fX /= rayLength;
fY /= rayLength;
fZ /= rayLength;
//T = [planeNormal.(pointOnPlane - rayOrigin)]/planeNormal.rayDirection;
//pointInPlane = rayOrigin + (rayDirection * T);
float dot1, dot2;
float pointInPlaneX = 0;
float pointInPlaneY = 0;
float pointInPlaneZ = 0;
float planeNormalX = 0;
float planeNormalY = 0;
float planeNormalZ = -1;
pointInPlaneX -= cX;
pointInPlaneY -= cY;
pointInPlaneZ -= cZ;
dot1 = (planeNormalX * pointInPlaneX) + (planeNormalY * pointInPlaneY) + (planeNormalZ * pointInPlaneZ);
dot2 = (planeNormalX * fX) + (planeNormalY * fY) + (planeNormalZ * fZ);
float t = dot1/dot2;
fX *= t;
fY *= t;
//we don't need the z coordinate in my case
return CGPointMake(fX + cX, fY + cY);
}
31 comments:
Can you post your conversion of gluUnProject?
Hi, I've converted the gluUnProject (I hope) and I'm trying to use your code to work out the actual coordinates in the 3D world, but the result I get back is 0,0. Any thoughts where I should check first, is it likely to be my conversion of UnProject?
Thanks for any help Paul
I am having some problem getting valid gluUnProject point values as I am also implementing a glLookAt function. Anybody faced similar problems?
llias - my problems were firstly in my conversion and finally in the way I was saving the viewport data. My app allows the user to move the view around and herefore the viewport can change, I moved the storing of the viewport into the main draw code and all works ok
man this conversion tough i am going use it for my custom term papers it is going to be tough explaining this thanks for this blog
For gluUnProject, have a look at http://code.google.com/p/iphone-glu/ (not that I've personally tested this yet, but there's a function in there!)
Question: Do you get the model view matrix after you perform your gluLookAt()?
Hi Xenon!
It would be possible that you post a download link to the modified libGlu.a and libGLU_arm.a?
I tried to compile by myself but I really don't know how to do it.
Really thanks for your post.
Regards.
Hi Xenon!
Finally I managed to compile the modified GLU library and use your code to convert the screen coordinates to world coordinates.
Thanks for your post again!
Maybe you can use a ray between camera position and only one point from glUnProject with zfar.
There are certainly a lot of details like that to take into consideration. That is a great point to bring up. I offer the thoughts above as general inspiration but clearly there are questions like the one you bring up where the most important thing will be working in honest good faith. I don?t know if best practices have emerged around things like that, but I am sure that your job is clearly identified as a fair game.
Term papers
I used this sample to build a working sample for iPhone implementing gluUnproject :
http://blog.nova-box.com/2010/05/iphone-ray-picking-glunproject-sample.html#comment-form
I think the interesting part of the project can be found in the glu.h / glu.c files and EAGLView.m.
College Term Paper
iPhone is really the best.
PMP
The gluUnProject for iPhone / OpenGL ES is really one that looks so much good, I think that the given information about it is really good one to see and has so much to get know about.
College Term Papers
I always like The I-phone, And gluUn Project for i Phone is really good one for the Users of I-phone. And The Information is really great. I am thinking to forward it to my brother.
College Term Papers
Thanks for doing such a thorough research work. I must say all the tips you have mentioned here are useful. So, I have saved the page. Hope it will help me in my future endeavors.
College Term Papers
hi ,
i got a question regarding multiple objects drawn using push/ pop stack.something similar to this.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x,y,z);
glRotate(r,1,0,0);
glTranslate(-x,-y,-z);
for (i=0 to 20) objects
glpushMatrix();
draw_object
glpopMatrix();
end
each object is a unit cube (textured to sphere) with its own transformation. In such a case how does ray picking work. How should i keep track of center point of the object to calculate ray intersection. i really appreciate any help.
Thanks
Sowmya
Incidentally, I like the way you have structured your site, it is super and very easy to follow. I have bookmarked you and will be back regularly. Thank you
Study Consultants | Study Agent
Thannk you for providing a thourough explanation for OpenGL. I am trying to fix a glitch that stops it from my iPhone.-spiritual gifts
I really agree with the facts that you have shared on this post. An interesting topic like this really enhances reader's mind to have more effective decisions over a certain issue.
CCTV Karachi
College term papers
No dispute with the text, agree with you. The features are really appreciable.
Valuable information and excellent design you got here! I would like to thank you for sharing your thoughts and time into the stuff you post!! Thumbs up
karachi online shopping
Unproject twice to create a ray, ofcourse!!! Thanks =)
I creating a top down rpg, and want to click where the player is to move. So I create the ray, then find X and Y where Z = 0. Works great =)
This is a fantastic feature, other features are really fabulous though.
Custom written term papers
Beautiful job! I just think they are brilliant. Thanks for this nice post.
cheap hotels in kansas city mo
Interesting post. It is so awesome seeing young people love the world. Thanks for your thought and effort.
carry on luggage sizes
what would the code be to get the Z coordinate?
what would the code be to get the Z coordinate?
I never read such beautiful article before. This article is very unique and full of surprise. I never read this kind of article that is straightforward when regarding to the topic. Very intense kind of writing. Keep up the good and unique article writing.
business plan service business plan writing service
Can I have the same code for android.???
Post a Comment