For anyone who has played with OpenGL ES, its really hard work (iOS or Android). I have spent many hours on OpenGL ES 1.0 and 2.0, making my own frameworks etc.
Apple introduced GLKit in iOS 5 if I remembered correctly and it was designed to make the maths side easier. One of the things I struggle with is object picking, this is touching the screen and turning that in to a 3D position in the OpenGL world. Generally there is 2 ways to do this, Colour picking and Ray Picking.
Colour picking is when the user touches the screen, every object is rendered as a different colour and then you detect what colour that person touched to work out where they touched.
Ray Picking, is where you fire off a ray and work out what the first object is that it hits. This requires quite a bit of maths which people have already done for you but in different programming languages.
However, the point of this article is that I discovered that Apple have added functions to help with Ray Picking namely GLKMathUnproject
Code based from this StackOverFlow post http://stackoverflow.com/questions/20214498/updating-opengl-es-touch-detection-ray-tracing-for-ipad-retina
This works out when you touch the floor (self.plane) and then puts self.cube at that position
- (BOOL)didTouchObject: (CGPoint) tapLoc
tapLoc.x *= [UIScreen mainScreen].scale;
tapLoc.y *= [UIScreen mainScreen].scale;
GLKVector3 nearPt = GLKMathUnproject(GLKVector3Make(tapLoc.x, (tapLoc.y-viewport)*-1, 0.0), _baseModelViewMatrix, _projectionMatrix, &viewport , &testResult);
GLKVector3 farPt = GLKMathUnproject(GLKVector3Make(tapLoc.x, (tapLoc.y-viewport)*-1, 1.0), _baseModelViewMatrix, _projectionMatrix, &viewport , &testResult);
//farPt = GLKVector3Subtract(farPt, nearPt);
float xDif = (farPt.x – nearPt.x) / 1000;
float yDif = (farPt.y – nearPt.y) / 1000;
float zDif = (farPt.z – nearPt.z) / 1000;
for (int i = 0; i < 100; i ++)
if ((nearPt.x + (xDif * i)) > self.plane.position.x – self.plane.scale.x && (nearPt.x + (xDif * i)) < self.plane.position.x + self.plane.scale.x &&
(nearPt.y + (yDif * i)) > self.plane.position.y – self.plane.scale.y && (nearPt.y + (yDif * i)) < self.plane.position.y + self.plane.scale.y &&
(nearPt.z + (zDif * i)) > self.plane.position.z – self.plane.scale.z && (nearPt.z + (zDif * i)) < self.plane.position.z + self.plane.scale.z)
self.cube.position = GLKVector3Make(nearPt.x + (xDif * i), nearPt.y + (yDif * i), nearPt.z + (zDif * i));