OpenGL ES (iPhone) Touch Picking

前端 未结 3 1909
情书的邮戳
情书的邮戳 2021-01-18 06:43

Looking to do classic OpenGL mouse picking in ES. I\'d prefer not to use third party libs, GLU ports and OpenGL name stacks, etc, are out. This pretty much leaves inverse

3条回答
  •  野的像风
    2021-01-18 07:38

    I managed to fix it:

    -(void)view2WorldPoint:(CGPoint)point :(GLfloat*)worldPoint {
        // this is the inverse translation of the modelview
        GLfloat width = (GLfloat)backingWidth;
        GLfloat height = (GLfloat)backingHeight;
    
        float clickX = point.x;
        float clickY = point.y;
        float clickZ = 0.0f;
    
        NSLog(@"click point : x = %f, y = %f, z = %f", clickX, clickY, clickZ);
    
        //  NSLog(@"Me : x = %f, y = %f, z = %f", a[0], a[1], a[2]);
        //  NSLog(@"Dev : x = %f, y = %f, z = %f", squareX, squareY, squareZ);
    
        //viewport -> normalized device coord -> clip
        GLfloat n[] = {
            2 * clickX / width - 1,
            2 * (480-clickY) / height - 1,
            2 * clickZ - 1,
            1
        };
        //  NSLog(@"Obj : x = %f, y = %f, z = %f", rect.origin.x, rect.origin.y, -0.5);
        //  NSLog(@"N : x = %f, y = %f, z = %f", n[0], n[1], n[2]); 
    
        //I'm a viewing volume symmetric projection matrix
        //  GLfloat P[] = {
        //      near / right, 0, 0, 0,
        //      0, near / top, 0, 0,
        //      0, 0, -(far + near) / (far - near), (-2 * far * near) / (far - near),
        //      0, 0, -1, 0
        //  };
        GLfloat P[16];
        glGetFloatv(GL_PROJECTION_MATRIX, P);
        //  [self dumpMatrix:P :@"P"];
    
        GLfloat Pminus1[] = {
            1/P[0], 0, 0, 0,
            0, 1/P[5], 0, 0,
            0, 0, 0, 1/P[11],
            0, 0, 1/P[14], -(P[10]/ (P[11]*P[14]))
        };
    
        //  [self dumpMatrix:Pminus1 :@"P-1"];
    
        //clip -> view
        GLfloat v[] = {
            (Pminus1[0] * n[0]) + (Pminus1[1] * n[1]) + (Pminus1[2]  * n[2]) + (Pminus1[3] * n[3]),
            (Pminus1[4] * n[0]) + (Pminus1[5] * n[1]) + (Pminus1[6]  * n[2]) + (Pminus1[7] * n[3]),
            (Pminus1[8] * n[0]) + (Pminus1[9] * n[1]) + (Pminus1[10] * n[2]) + (Pminus1[11] * n[3]),
            (Pminus1[12] * n[0]) + (Pminus1[13] * n[1]) + (Pminus1[14] * n[2]) + (Pminus1[15] * n[3])
        };
    
        //  NSLog(@"v = [%f, %f, %f, %f]", v[0], v[1], v[2], v[3]);
    
    
        //  [self dumpMatrix:mv :@"mv"];
    
        //view -> world
        GLfloat Rt[] = {
            mv[0], mv[4], -mv[8],
            mv[1], mv[5], -mv[9],
            -mv[2], -mv[6], mv[10]
        };
    
        //  NSLog(@"Rt0 = [%f, %f, %f]", Rt[0], Rt[1], Rt[2]);
        //  NSLog(@"Rt1 = [%f, %f, %f]", Rt[3], Rt[4], Rt[5]);
        //  NSLog(@"Rt2 = [%f, %f, %f]", Rt[6], Rt[7], Rt[8]);
    
        GLfloat tPrime[] = {
            Rt[0] * mv[12] + Rt[1] * mv[13] + Rt[2] * mv[14],
            Rt[3] * mv[12] + Rt[4] * mv[13] + Rt[5] * mv[14],
            Rt[6] * mv[12] + Rt[7] * mv[13] + Rt[8] * mv[14]
        };
    
        //  NSLog(@"tPrime = [%f, %f, %f]", tPrime[0], tPrime[1], tPrime[2]);
    
        GLfloat Mminus1[] = {
            Rt[0], Rt[1], Rt[2], -(tPrime[0]),
            Rt[3], Rt[4], Rt[5], -(tPrime[1]),
            Rt[6], Rt[7], Rt[8], -(tPrime[2]),
            0, 0, 0, 1
        };
    
        //point in world space
        GLfloat w[] = {
            Mminus1[0] * v[0] + Mminus1[1] * v[1] + Mminus1[2] * v[2] + Mminus1[3] * v[3],
            Mminus1[4] * v[0] + Mminus1[5] * v[1] + Mminus1[6] * v[2] + Mminus1[7] * v[3],
            Mminus1[8] * v[0] + Mminus1[9] * v[1] + Mminus1[10] * v[2] + Mminus1[11] * v[3],
            Mminus1[12] * v[0] + Mminus1[13] * v[1] + Mminus1[14] * v[2] + Mminus1[15] * v[3]
        };
        NSLog(@"W : x = %f, y = %f, z = %f", w[0], w[1], w[2]);
        worldPoint[0] = w[0];
        worldPoint[1] = w[1];
        worldPoint[2] = w[2];
    }
    

提交回复
热议问题