在OpenGL ES 2.0 for iOS中尝试使用光线投射实现拾取时,哪里出了问题?

在OpenGL ES 2.0 for iOS中尝试使用光线投射实现拾取时,哪里出了问题?,ios,opengl-es,opengl-es-2.0,glkit,ray-picking,Ios,Opengl Es,Opengl Es 2.0,Glkit,Ray Picking,我试图在OpenGL ES 2.0中为iPad应用程序实现光线投射拾取。具体地说,我想知道用户点击的是由不同高度的方形单元组成的类似地雷船的地图的哪个单元。但是,我的代码找不到与任何单元格的交点 在我的手势识别器方法中,我首先得到点和视口的尺寸 UITapGestureRecognizer* tapRecognizer = (UITapGestureRecognizer*) recognizer; CGPoint tapLoc = [tapRecognizer locationInView: s

我试图在OpenGL ES 2.0中为iPad应用程序实现光线投射拾取。具体地说,我想知道用户点击的是由不同高度的方形单元组成的类似地雷船的地图的哪个单元。但是,我的代码找不到与任何单元格的交点

在我的手势识别器方法中,我首先得到点和视口的尺寸

UITapGestureRecognizer* tapRecognizer = (UITapGestureRecognizer*) recognizer;
CGPoint tapLoc = [tapRecognizer locationInView: self.view];

GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
然后我翻转x轴,因为我的应用程序处于横向模式,openGL坐标从不同于窗口坐标的角开始

tapLoc.x = viewport[2] -  tapLoc.x;
并使用GLKitMathUnproject对z=0和z=1值执行取消投影,然后将结果向量传递到函数中,该函数将返回用户作为结构基点点击的单元格坐标(只有两个整数,x和y)。地图目前没有变换,所以我假设我应该使用单位矩阵进行变换,投影矩阵是用glkmatrix4makeperspective生成的

GLKVector3 nearPt = GLKMathUnproject(GLKVector3Make(tapLoc.x, tapLoc.y, 0.0), GLKMatrix4Identity, [BPGlobalEnv globalVars].cameraMatrix, &viewport[0] , &testResult);

GLKVector3 farPt = GLKMathUnproject(GLKVector3Make(tapLoc.x, tapLoc.y, 1.0), GLKMatrix4Identity, [BPGlobalEnv globalVars].cameraMatrix, &viewport[0] , &testResult);

BPPoint destination = [gameEngine.currMap gridForPoint: farPt fromPoint: nearPt];
这是该方法的主体。我基本上只是循环并重新生成地图每个正方形顶部的几何体(我知道效率很低),方法与我最初将几何体传递到VBO中绘制它时使用的方法相同

-(BPPoint) gridForPoint: (GLKVector3) ray fromPoint: (GLKVector3) cameraCoords

{
size_t i = 0;
size_t j;

GLfloat* buffer = malloc(sizeof(GLfloat) * squareSize);

for (NSArray* row in self.mapCells) {

    j = 0;

    for (BPGridCell* cell in row) {

        GLfloat a[3];
        a[0] = i * tileSize;
        a[1] = cell.height * step;
        a[2] = j * tileSize;
        GLfloat b[3];
        b[0] = (i + 1) * tileSize;
        b[1] = cell.height * step;
        b[2] = (j + 1) * tileSize;

        [self squareForPoint:a point:b pointer: buffer];

        GLKVector3 v1 = GLKVector3Make(buffer[0], buffer[1], buffer[2]);
        GLKVector3 v2 = GLKVector3Make(buffer[3], buffer[4], buffer[5]);
        GLKVector3 v3 = GLKVector3Make(buffer[6], buffer[7], buffer[8]);
        GLKVector3 v21 = GLKVector3Make(buffer[9], buffer[10], buffer[11]);
        GLKVector3 v22 = GLKVector3Make(buffer[12], buffer[13], buffer[14]);
        GLKVector3 v23 = GLKVector3Make(buffer[15], buffer[16], buffer[17]);

        if ([self ray: ray fromCamera: cameraCoords intersectsTriangleWithV1: v1 V2: v2 V3: v3] ||
            [self ray: ray fromCamera: cameraCoords intersectsTriangleWithV1: v21 V2: v22 V3: v23]) {

            NSLog(@"found intersection");
            free(buffer);
            BPPoint toReturn;
            toReturn.x = i;
            toReturn.y = j;
            NSLog(@"%ld, %ld", i, j);
            return toReturn;
        }

        j += 1;
    }

    i += 1;
}

free(buffer);
BPPoint toReturn;
toReturn.x = i;
toReturn.y = j;
NSLog(@"%ld, %ld", i, j);
return toReturn;
}
测试三角形相交的代码,我从这里()转换为objc,如下所示:

-(BOOL) ray: (GLKVector3) ray fromCamera: (GLKVector3) camera intersectsTriangleWithV1: (GLKVector3) v1 V2: (GLKVector3) v2 V3: (GLKVector3) v3
{

GLKVector3 e1 = GLKVector3Subtract(v2, v1);
GLKVector3 e2 = GLKVector3Subtract(v3, v1);

GLKVector3 h = GLKVector3CrossProduct(ray, e2);

float det = GLKVector3DotProduct(e1, h);

if (det > -0.00001 && det < 0.00001) {

    return NO;
}

float invDet = 1.0/det;
GLKVector3 s = GLKVector3Subtract(camera, v1);

float u =  GLKVector3DotProduct(s, h) * invDet;

if (u < 0.0 || u > 1.0) {

    return NO;
}

GLKVector3 q = GLKVector3CrossProduct(s, e1);

float v = invDet * GLKVector3DotProduct(ray, q);

if (v < 0.0 || u + v > 1.0) {

    return NO;
}

    return YES;
}
-(BOOL)光线:(GLKVector3)来自摄影机的光线:(GLKVector3)摄影机与v1:(GLKVector3)v1 V2:(GLKVector3)V2 V3:(GLKVector3)V3相交角度
{
GLKVector3 e1=GLKVector3子域(v2,v1);
GLKVector3 e2=GLKVector3子域(v3,v1);
GLKVector3 h=GLKVector3交叉乘积(射线,e2);
浮点数=GLKVector3DotProduct(e1,h);
如果(数据量>-0.00001&&det<0.00001){
返回否;
}
浮点数=1.0/det;
GLKVector3 s=GLKVector3子域(摄像机,v1);
浮点数u=GLKVector3DotProduct(s,h)*invDet;
如果(u<0.0 | | u>1.0){
返回否;
}
GLKVector3 q=GLKVector3交叉积(s,e1);
浮点数v=invDet*GLKVector3DotProduct(光线,q);
如果(v<0.0 | | u+v>1.0){
返回否;
}
返回YES;
}

当我使用10x10地图运行此程序时,它会打印10,10的坐标,而通常不会找到交点。我在概念上或在实现这两个方面哪里搞砸了?

我找到了解决方案:glgetintegerv调用返回翻转的值,可能是因为设备处于横向模式。我还必须从远点减去近点,以获得光线的正确方向向量