问题
please help, this is my 4th question about this, I trying so hard I tried everything!
All I want to do is detect clicking on a object(cube) in a 3D World (3D world created).
This does it http://blog.nova-box.com/2010/05/iphone-ray-picking-glunproject-sample.html but has a completely different app structure and does a lot with render buffers etc.
I am trying to use using gluUnProject (someone has ported it).
On touch
CGPoint pos = [[touches anyObject] locationInView:self.view];
glGetIntegerv( GL_VIEWPORT, __viewport );
glGetFloatv( GL_MODELVIEW_MATRIX, __modelview );
glGetFloatv( GL_PROJECTION_MATRIX, __projection );
int i = 0;
for (NSDictionary *item in self.players) {
IMPoint3D playerPos;
playerPos.x = [[item objectForKey:@"posX"] floatValue];
playerPos.z = [[item objectForKey:@"posZ"] floatValue];
playerPos.y = 1.0f;
if([self checkCollission:pos object:playerPos])
{
NSLog(@"FIRE I LOVE YOU MAN %i", i);
}
i ++;
}
Collision function taken from other project
#define RAY_ITERATIONS 1000
#define COLLISION_RADIUS 0.1f
-(Boolean) checkCollission:(CGPoint)winPos object:(IMPoint3D) _object {
winPos.y = (float)__viewport[3] - winPos.y;
Point3D nearPoint;
Point3D farPoint;
Point3D rayVector;
//Retreiving position projected on near plan
gluUnProject( winPos.x, winPos.y , 0, __modelview, __projection, __viewport, &nearPoint.x, &nearPoint.y, &nearPoint.z);
//Retreiving position projected on far plan
gluUnProject( winPos.x, winPos.y, 1, __modelview, __projection, __viewport, &farPoint.x, &farPoint.y, &farPoint.z);
//Processing ray vector
rayVector.x = farPoint.x - nearPoint.x;
rayVector.y = farPoint.y - nearPoint.y;
rayVector.z = farPoint.z - nearPoint.z;
float rayLength = sqrtf(POW2(rayVector.x) + POW2(rayVector.y) + POW2(rayVector.z));
//normalizing ray vector
rayVector.x /= rayLength;
rayVector.y /= rayLength;
rayVector.z /= rayLength;
Point3D collisionPoint;
Point3D objectCenter = {_object.x, _object.y, _object.z};
//Iterating over ray vector to check collisions
for(int i = 0; i < RAY_ITERATIONS; i++)
{
collisionPoint.x = rayVector.x * rayLength/RAY_ITERATIONS*i;
collisionPoint.y = rayVector.y * rayLength/RAY_ITERATIONS*i;
collisionPoint.z = rayVector.z * rayLength/RAY_ITERATIONS*i;
//Checking collision
if([Tools poinSphereCollision:collisionPoint center:objectCenter radius:COLLISION_RADIUS])
{
return TRUE;
}
}
return FALSE;
}
If someone can work out the error, I will even paypal some cash over (if that's allowed), this has given me a headache for days. I think its something to do when I get the projection and modelview matrix
回答1:
I cant't be sure, but It seems that the coordinate system is wrong. I use (for 2D) something like this:
- (CGPoint) unProject: (CGPoint) point
{
GLfloat x=0, y=0, z=0;
GLfloat modelMatrix[16];
GLfloat projMatrix[16];
GLint viewport[4];
glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
glGetIntegerv(GL_VIEWPORT, viewport);
CGPoint result = { 0.0f/0.0f, 0.0f/0.0f };
if(gluUnProject(point.x, size.height-point.y, 0, modelMatrix, projMatrix, viewport, &x, &y, &z) == GL_TRUE) {
result.x = x;
result.y = y;
//Since we're using an ortho projection, we can ignore z.
UNUSED(z);
}
return result;
}
Note this: size.height-point.y
where size contains the size
of the screen. You have to remember that the default coordinate system of the screen in Core Animation for iOS is different from the one used by OpenGL.
If you have a translation applied, it is very difficult to figure out what's going on.
I use this implementation of gluUnProject: http://www.codng.com/2011/02/gluunproject-for-iphoneios.html (disclaimer: it is my personal blog).
I know this doesn't fully answer your question, but it might help.
回答2:
I posting this as the complete source of the class, I sure its something to do with the project matrix not working
#import "GLViewController.h"
#import "ConstantsAndMacros.h"
#import "OpenGLCommon.h"
#import "WorldAppDelegate.h"
#import "Tools.h"
#import "glu.h"
#define SPEED_MOVE 0.025
#define SPEED_TURN 0.05
#define MapSizeX 20
#define MapSizeZ 20
typedef struct
{
float x;
float y;
float z;
} IMPoint3D;
@interface GLViewController ()
- (void)updateData;
- (BOOL)checkCollisionWithX:(float)x andWithZ:(float)z;
- (void)loadTextures:(NSString *)textureName andWithIndex:(int)index;
- (void)handleTouches;
- (void)updateCoords;
- (void)setupPlayer;
- (void)addScene;
- (void)loadTextureList;
- (void)loadController;
- (Boolean) checkCollission:(CGPoint)winPos object:(IMPoint3D) _object;
- (CGPoint)getScreenCoorOfPoint:(IMPoint3D)_point3D;
@end
@implementation GLViewController
@synthesize deviceID, players, label,collisionArray, baseURL;
-(void)setupView:(GLView*)view {
const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 120.0;
GLfloat size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 8.0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
//Rotate the view
glRotatef(-90,0,0,1);
CGRect rect = self.view.bounds;
glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar);
glViewport(0, 0, rect.size.width, rect.size.height);
// Starting position
eye[0] = -0;
eye[1] = 3;
eye[2] = -10;
center[0] = 0;
center[1] = 1.5;
center[2] = 0;
[self loadTextureList];
[self loadController];
[self loadTextureList ];
[self addScene];
[self setupPlayer];
[self updateCoords];
}
// ...
- (void)drawView:(UIView *)theView {
// floor
const GLfloat floorVertices[] = {
-1, 0.0f, 1,
1, 0.0f, 1,
1, 0.0f, -1,
-1, 0.0f, -1
};
const GLshort floorTextureCoords[] = {
0, 1, // top left
0, 0, // bottom left
1, 0, //bottom right
1, 1 //top right
};
// Colour cube
static const GLubyte cubeNumberOfIndices = 36;
const GLubyte colourCubeFaceColors[] = {
0,255,0,255,
255,125,0,255,
255,0,0,255,
255,255,0,255,
0,0,255,255,
255,0,255,255
};
static const Vertex3D texturedVertices[]= {
{-1.0, 1.0, 1.0}, // vertices[0]
{1.0, 1.0, 1.0}, // vertices[1]
{-1.0, -1.0, 1.0}, // vertices[2]
{-1.0, -1.0, 1.0}, // vertices[3]
{1.0, 1.0, 1.0}, // vertices[4]
{1.0, -1.0, 1.0}, // vertices[5]
{-1.0, 1.0, 1.0}, // vertices[6]
{-1.0, 1.0, -1.0}, // vertices[7]
{-1.0, -1.0, 1.0}, // vertices[8]
{-1.0, -1.0, 1.0}, // vertices[9]
{-1.0, 1.0, -1.0}, // vertices[10]
{-1.0, -1.0, -1.0}, // vertices[11]
{-1.0, 1.0, -1.0}, // vertices[12]
{1.0, 1.0, -1.0}, // vertices[13]
{-1.0, -1.0, -1.0}, // vertices[14]
{-1.0, -1.0, -1.0}, // vertices[15]
{1.0, 1.0, -1.0}, // vertices[16]
{1.0, -1.0, -1.0},
{1.0, 1.0, 1.0},
{1.0, 1.0, -1.0},
{1.0, -1.0, 1.0},
{1.0, -1.0, 1.0},
{1.0, 1.0, -1.0},
{1.0, -1.0, -1.0},
{-1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0},
{1.0, 1.0, 1.0},
{1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0},
{1.0, 1.0, -1.0},
{-1.0, -1.0, 1.0},
{-1.0, -1.0, -1.0},
{1.0, -1.0, 1.0},
{1.0, -1.0, 1.0},
{-1.0, -1.0, -1.0},
{1.0, -1.0, -1.0},
};
static const GLubyte texturedCube[] = {
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14,
15, 16, 17,
18, 19, 20,
21, 22, 23,
24, 25, 26,
27, 28, 29,
30, 31, 32,
33, 34, 35,
};
static const GLfloat texturedCubeCoord[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 0.0,
1.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0, 1.0, 1.0, 1.0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[self handleTouches];
//view : prebaked in to OPenGL Template
gluLookAt(eye[0], eye[1], eye[2],center[0], center[1], center[2], 0.0, 1, 0.0);
// draw the floor
glPushMatrix();
//tell GL about our texture
glMatrixMode(GL_TEXTURE);
glScalef(20,20,1);
glBindTexture(GL_TEXTURE_2D, 3);
glMatrixMode(GL_MODELVIEW);
glScalef(20,1,20);
glTexCoordPointer(2, GL_SHORT, 0, floorTextureCoords);
glVertexPointer(3, GL_FLOAT, 0, floorVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glPopMatrix();
for (NSString *coords in self.collisionArray) {
NSArray *coordsArray = [coords componentsSeparatedByString:@","];
float x = [[coordsArray objectAtIndex:0] floatValue] ;
float z = [[coordsArray objectAtIndex:1] floatValue] ;
float width = ([[coordsArray objectAtIndex:2] floatValue] /2) ;
float length = ([[coordsArray objectAtIndex:3] floatValue] /2) ;
glPushMatrix();
//tell GL about our texture
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
if (width > length) {
glScalef(width, 3, length);
} else {
glScalef(length, 3, width);
}
glBindTexture(GL_TEXTURE_2D, ([[coordsArray objectAtIndex:4] floatValue]));
glMatrixMode(GL_MODELVIEW);
glTranslatef(x, 3, z);
glScalef(width, 3, length);
glVertexPointer(3, GL_FLOAT, 0, texturedVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texturedCubeCoord);
glDrawElements(GL_TRIANGLES,cubeNumberOfIndices , GL_UNSIGNED_BYTE, texturedCube);
glPopMatrix();
}
float x;
float z;
float playerRotation;
for (NSDictionary *item in self.players) {
x = [[item objectForKey:@"posX"] floatValue];
z = [[item objectForKey:@"posZ"] floatValue];
playerRotation = [[item objectForKey:@"rotation"] floatValue];
glPushMatrix();
glTranslatef(x, 1 , z);
glRotatef(playerRotation, 0, 1, 0);
//Reset textures
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glVertexPointer(3, GL_FLOAT, 0, texturedVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texturedCubeCoord);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &texturedCube[0]);
glBindTexture(GL_TEXTURE_2D, 4);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &texturedCube[6]);
int colorIndex = 0;
glBindTexture(GL_TEXTURE_2D, 0);
glColor4ub(colourCubeFaceColors[colorIndex], colourCubeFaceColors[colorIndex+1], colourCubeFaceColors[colorIndex+2], colourCubeFaceColors[colorIndex+3]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &texturedCube[12]);
glPopMatrix();
}
// GL teardown
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint pos = [[touches anyObject] locationInView:self.view];
int i = 0;
for (NSDictionary *item in self.players) {
IMPoint3D playerPos;
playerPos.x = [[item objectForKey:@"posX"] floatValue];
playerPos.z = [[item objectForKey:@"posZ"] floatValue];
playerPos.y = 1.0f;
if([self checkCollission:pos object:playerPos])
{
NSLog(@"FIRE I LOVE YOU MAN %i", i);
}
}
//left
if ( pos.x >= 35 && pos.x <= 80 && pos.y >= 0 && pos.y <= 40) {
action = ActionTurnLeft;
//right
} else if ( pos.x >= 35 && pos.x <= 80 && pos.y >= 80 && pos.y <= 120) {
action = ActionTurnRight;
//forward
} else if ( pos.x >= 80 && pos.x <= 120 && pos.y >= 32 && pos.y <= 82) {
action = ActionMoveForward;
//back
} else if ( pos.x >= 0 && pos.x <= 40 && pos.y >= 32 && pos.y <= 82) {
action = ActionMoveBackward;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
action = ActionNone;
}
#define RAY_ITERATIONS 1000
#define COLLISION_RADIUS 0.1f
-(Boolean) checkCollission:(CGPoint)winPos object:(IMPoint3D) _object {
glGetFloatv( GL_PROJECTION_MATRIX, __projection );
glGetFloatv( GL_MODELVIEW_MATRIX, __modelview );
glGetIntegerv( GL_VIEWPORT, __viewport );
winPos.y = (float)__viewport[3] - winPos.y;
Point3D nearPoint;
Point3D farPoint;
Point3D rayVector;
//Retreiving position projected on near plan
gluUnProject( winPos.x, winPos.y , 0, __modelview, __projection, __viewport, &nearPoint.x, &nearPoint.y, &nearPoint.z);
//Retreiving position projected on far plan
gluUnProject( winPos.x, winPos.y, 1, __modelview, __projection, __viewport, &farPoint.x, &farPoint.y, &farPoint.z);
//Processing ray vector
rayVector.x = farPoint.x - nearPoint.x;
rayVector.y = farPoint.y - nearPoint.y;
rayVector.z = farPoint.z - nearPoint.z;
float rayLength = sqrtf(POW2(rayVector.x) + POW2(rayVector.y) + POW2(rayVector.z));
//normalizing ray vector
rayVector.x /= rayLength;
rayVector.y /= rayLength;
rayVector.z /= rayLength;
Point3D collisionPoint;
Point3D objectCenter = {_object.x, _object.y, _object.z};
//Iterating over ray vector to check collisions
for(int i = 0; i < RAY_ITERATIONS; i++)
{
collisionPoint.x = rayVector.x * rayLength/RAY_ITERATIONS*i;
collisionPoint.y = rayVector.y * rayLength/RAY_ITERATIONS*i;
collisionPoint.z = rayVector.z * rayLength/RAY_ITERATIONS*i;
//Checking collision
if([Tools poinSphereCollision:collisionPoint center:objectCenter radius:COLLISION_RADIUS])
{
return TRUE;
}
}
return FALSE;
}
/* does not work
-(CGPoint)getScreenCoorOfPoint:(IMPoint3D)_point3D
{
GLfloat p[16]; // Where The 16 Doubles Of The Projection Matrix Are To Be Stored
glGetFloatv(GL_PROJECTION_MATRIX, p); // Retrieve The Projection Matrix
/*
Multiply M * point
*/
//GLfloat _p[] = {p[0]*_point3D.x +p[4]*_point3D.y +p[8]*_point3D.z + p[12],
// p[1]*_point3D.x +p[5]*_point3D.y +p[9]*_point3D.z + p[13],
// p[2]*_point3D.x +p[6]*_point3D.y +p[10]*_point3D.z+ p[14],
// p[3]*_point3D.x +p[7]*_point3D.y +p[11]*_point3D.z+ p[15]};
/*
divide by scale factor
*/
// CGPoint _p2D = {_p[0]/_p[3], _p[1]/_p[3]};
/*
get result in screen coordinates. In this case I'm in landscape mode
*/
//return (CGPoint) {_p2D.x*240.0f + 240.0f, (1.0f - _p2D.y) *160.0f};
}
*/
- (void)handleTouches {
if (action != ActionNone) {
GLfloat v[] = {center[0] - eye[0], center[1] - eye[1], center[2] - eye[2]};
switch (action) {
case ActionMoveForward:
eye[0] += v[0] * SPEED_MOVE;
eye[2] += v[2] * SPEED_MOVE;
center[0] += v[0] * SPEED_MOVE;
center[2] += v[2] * SPEED_MOVE;
if ((eye[2] > MapSizeZ || eye[0] > MapSizeX || eye[2] < -MapSizeZ || eye[0] < -MapSizeX) || [self checkCollisionWithX:eye[0] andWithZ:eye[2]]){
eye[0] -= v[0] * SPEED_MOVE;
eye[2] -= v[2] * SPEED_MOVE;
center[0] -= v[0] * SPEED_MOVE;
center[2] -= v[2] * SPEED_MOVE;
}
break;
case ActionMoveBackward:
eye[0] -= v[0] * SPEED_MOVE;
eye[2] -= v[2] * SPEED_MOVE;
center[0] -= v[0] * SPEED_MOVE;
center[2] -= v[2] * SPEED_MOVE;
if ((eye[2] > MapSizeZ || eye[0] > MapSizeX || eye[2] < -MapSizeZ || eye[0] < -MapSizeX) || [self checkCollisionWithX:eye[0] andWithZ:eye[2]] ){
eye[0] += v[0] * SPEED_MOVE;
eye[2] += v[2] * SPEED_MOVE;
center[0] += v[0] * SPEED_MOVE;
center[2] += v[2] * SPEED_MOVE;
}
break;
case ActionTurnLeft:
center[0] = eye[0] + cos(-SPEED_TURN)*v[0] - sin(-SPEED_TURN)*v[2];
center[2] = eye[2] + sin(-SPEED_TURN)*v[0] + cos(-SPEED_TURN)*v[2];
rotation -=2.865;
break;
case ActionTurnRight:
center[0] = eye[0] + cos(SPEED_TURN)*v[0] - sin(SPEED_TURN)*v[2];
center[2] = eye[2] + sin(SPEED_TURN)*v[0] + cos(SPEED_TURN)*v[2];
rotation +=2.865;
break;
}
}
}
- (void)loadTextures:(NSString *)textureName andWithIndex:(int)index {
// load image as a CG ref
CGImageRef textureImage = [UIImage imageNamed:textureName].CGImage;
// if failed, bail
if (!textureImage) {
NSLog(@"Error: failed to load texture");
return;
}
// figure out the width and height
int texWidth = CGImageGetWidth(textureImage);
int texHeight = CGImageGetHeight(textureImage);
// alloc space for the texture
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
// create a CA context ref
CGContextRef textureContext = CGBitmapContextCreate(
textureData, texWidth, texHeight, 8, texWidth * 4,
CGImageGetColorSpace(textureImage),
kCGImageAlphaPremultipliedLast
);
// draw the image to in-memory buffer
CGContextDrawImage(textureContext, CGRectMake(0,0,texWidth,texHeight), textureImage);
// done with context - release it
CGContextRelease(textureContext);
// have GL create handle for our texture
glGenTextures(1, &textures[index]);
// tell GL that the image is 2D
glBindTexture(GL_TEXTURE_2D, textures[index]);
// send our data down to GL, copy into graphics hardware
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
// free our in-memory copy of the data
free(textureData);
// specify min/max filters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// tell GL to turn on textures
glEnable(GL_TEXTURE_2D);
}
- (void)updateCoords {
self.players = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@UpdatePlayer.aspx?playerIndex=%@&posX=%f&posZ=%f&rotation=%f", baseURL, self.deviceID, eye[0], eye[2], rotation]]];
[self updateData];
}
- (void)updateData {
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateCoords) object:nil];
[[(WorldAppDelegate *)[[UIApplication sharedApplication] delegate] sharedOperationQueue] addOperation:op];
[op release];
}
- (void)setupPlayer {
// Device id
UIDevice *device = [UIDevice currentDevice];
self.deviceID = [device uniqueIdentifier];
NSDictionary *tempDict = [[[NSDictionary alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat: @"%@GetPlayerPosition.aspx?playerIndex=%@", baseURL, self.deviceID]]] autorelease];
eye[0] = [[tempDict objectForKey:@"posX"] floatValue];
eye[2] = [[tempDict objectForKey:@"posZ"] floatValue] ;
rotation = [[tempDict objectForKey:@"rotation"] floatValue];
}
- (void)addScene {
self.collisionArray = [[NSMutableArray alloc] init];
[self.collisionArray addObject:@"5,-4,4,4,1"];
[self.collisionArray addObject:@"5, 4,4,4,1"];
[self.collisionArray addObject:@"20,0,1,40,4"];
[self.collisionArray addObject:@"-20,0,1,40,4"];
[self.collisionArray addObject:@"0,-20,40,1,4"];
[self.collisionArray addObject:@"0,20,40,1,4"];
}
- (void)loadTextureList {
[self loadTextures:@"crate.png" andWithIndex:0];
[self loadTextures:@"brick.jpg" andWithIndex:1];
[self loadTextures:@"GrassTexture.png" andWithIndex:2];
[self loadTextures:@"swtexnew.png" andWithIndex:3];
}
- (void)loadController {
self.baseURL = @"http://burf2000.dyndns.org:90/Cubes/";
//Controler
UIImageView *joypadView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"StoneCompass.png"]];
joypadView.frame = CGRectMake(0, 0, 120, 120);
[self.view addSubview:joypadView];
[joypadView release];
}
- (BOOL)checkCollisionWithX:(float)x andWithZ:(float)z {
for (NSString *coords in self.collisionArray) {
NSArray *coordsArray = [coords componentsSeparatedByString:@","];
float x1 = [[coordsArray objectAtIndex:0] floatValue] - ([[coordsArray objectAtIndex:2] floatValue] /2) ;
float z1 = [[coordsArray objectAtIndex:1] floatValue] - ([[coordsArray objectAtIndex:3] floatValue] /2) ;
float x2 = [[coordsArray objectAtIndex:0] floatValue] + ([[coordsArray objectAtIndex:2] floatValue] /2) ;
float z2 = [[coordsArray objectAtIndex:1] floatValue] + ([[coordsArray objectAtIndex:3] floatValue] /2) ;
if ( x > x1 && x < x2 && z > z1 && z < z2 ) {
return YES;
}
}
return NO;
}
- (void)dealloc {
[deviceID release];
[players release];
[collisionArray release];
[label release];
[baseURL release];
[super dealloc];
}
@end
来源:https://stackoverflow.com/questions/4403228/iphone-opengl-using-gluunproject-port-and-detecting-clicking-on-an-object