OpenGL ES (iPhone) Touch Picking

前端 未结 3 1908
情书的邮戳
情书的邮戳 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:18

    Okay, okay that was still a bit buggy. Here is what is MOSTLY working now:

    -(void)view2WorldPoint:(CGPoint)point :(GLfloat*)worldPoint {
        float clickX = point.x;
        float clickY = point.y;
        float clickZ = -near;
    
        //viewport -> normalized device coord -> clip
        GLint viewport[4];
        glGetIntegerv(GL_VIEWPORT, viewport);
    
        GLfloat n[] = {
            (clickX - (float)viewport[0]) / (float)viewport[2] * 2.0 - 1.0,
            -((clickY - (float)viewport[1]) / (float)viewport[3] * 2.0 - 1.0),
            2.0 * clickZ - 1.0,
            1.0
        };
    
        GLfloat MP[16], MPInv[16];
        MatMatMultiply(MP, projMat, modelMat);
        GenerateInverseMatrix4f(MPInv, MP); // replace this one with the whole 1/p thang?
    
        GLfloat w[] = {
            (MPInv[0]  * n[0]) + (MPInv[4]  * n[1]) + (MPInv[8]  * n[2]) + (MPInv[12] * n[3]),
            (MPInv[1]  * n[0]) + (MPInv[5]  * n[1]) + (MPInv[9]  * n[2]) + (MPInv[13] * n[3]),
            (MPInv[2]  * n[0]) + (MPInv[6]  * n[1]) + (MPInv[10] * n[2]) + (MPInv[14] * n[3]),
            (MPInv[3]  * n[0]) + (MPInv[7]  * n[1]) + (MPInv[11] * n[2]) + (MPInv[15] * n[3])
        };
    
        worldPoint[0] = w[0] / w[3];
        worldPoint[1] = w[1] / w[3];
        worldPoint[2] = w[2] / w[3];
    }
    
    
    float Determinant4f(const float m[16])
    {
        return
        m[12]*m[9]*m[6]*m[3]-
        m[8]*m[13]*m[6]*m[3]-
        m[12]*m[5]*m[10]*m[3]+
        m[4]*m[13]*m[10]*m[3]+
        m[8]*m[5]*m[14]*m[3]-
        m[4]*m[9]*m[14]*m[3]-
        m[12]*m[9]*m[2]*m[7]+
        m[8]*m[13]*m[2]*m[7]+
        m[12]*m[1]*m[10]*m[7]-
        m[0]*m[13]*m[10]*m[7]-
        m[8]*m[1]*m[14]*m[7]+
        m[0]*m[9]*m[14]*m[7]+
        m[12]*m[5]*m[2]*m[11]-
        m[4]*m[13]*m[2]*m[11]-
        m[12]*m[1]*m[6]*m[11]+
        m[0]*m[13]*m[6]*m[11]+
        m[4]*m[1]*m[14]*m[11]-
        m[0]*m[5]*m[14]*m[11]-
        m[8]*m[5]*m[2]*m[15]+
        m[4]*m[9]*m[2]*m[15]+
        m[8]*m[1]*m[6]*m[15]-
        m[0]*m[9]*m[6]*m[15]-
        m[4]*m[1]*m[10]*m[15]+
        m[0]*m[5]*m[10]*m[15];
    }
    
    BOOL GenerateInverseMatrix4f(float i[16], const float m[16])
    {
        float x=Determinant4f(m);
        if (x==0) return FALSE;
    
        i[0]= (-m[13]*m[10]*m[7] +m[9]*m[14]*m[7] +m[13]*m[6]*m[11]
               -m[5]*m[14]*m[11] -m[9]*m[6]*m[15] +m[5]*m[10]*m[15])/x;
        i[4]= ( m[12]*m[10]*m[7] -m[8]*m[14]*m[7] -m[12]*m[6]*m[11]
               +m[4]*m[14]*m[11] +m[8]*m[6]*m[15] -m[4]*m[10]*m[15])/x;
        i[8]= (-m[12]*m[9]* m[7] +m[8]*m[13]*m[7] +m[12]*m[5]*m[11]
               -m[4]*m[13]*m[11] -m[8]*m[5]*m[15] +m[4]*m[9]* m[15])/x;
        i[12]=( m[12]*m[9]* m[6] -m[8]*m[13]*m[6] -m[12]*m[5]*m[10]
               +m[4]*m[13]*m[10] +m[8]*m[5]*m[14] -m[4]*m[9]* m[14])/x;
        i[1]= ( m[13]*m[10]*m[3] -m[9]*m[14]*m[3] -m[13]*m[2]*m[11]
               +m[1]*m[14]*m[11] +m[9]*m[2]*m[15] -m[1]*m[10]*m[15])/x;
        i[5]= (-m[12]*m[10]*m[3] +m[8]*m[14]*m[3] +m[12]*m[2]*m[11]
               -m[0]*m[14]*m[11] -m[8]*m[2]*m[15] +m[0]*m[10]*m[15])/x;
        i[9]= ( m[12]*m[9]* m[3] -m[8]*m[13]*m[3] -m[12]*m[1]*m[11]
               +m[0]*m[13]*m[11] +m[8]*m[1]*m[15] -m[0]*m[9]* m[15])/x;
        i[13]=(-m[12]*m[9]* m[2] +m[8]*m[13]*m[2] +m[12]*m[1]*m[10]
               -m[0]*m[13]*m[10] -m[8]*m[1]*m[14] +m[0]*m[9]* m[14])/x;
        i[2]= (-m[13]*m[6]* m[3] +m[5]*m[14]*m[3] +m[13]*m[2]*m[7]
               -m[1]*m[14]*m[7] -m[5]*m[2]*m[15] +m[1]*m[6]* m[15])/x;
        i[6]= ( m[12]*m[6]* m[3] -m[4]*m[14]*m[3] -m[12]*m[2]*m[7]
               +m[0]*m[14]*m[7] +m[4]*m[2]*m[15] -m[0]*m[6]* m[15])/x;
        i[10]=(-m[12]*m[5]* m[3] +m[4]*m[13]*m[3] +m[12]*m[1]*m[7]
               -m[0]*m[13]*m[7] -m[4]*m[1]*m[15] +m[0]*m[5]* m[15])/x;
        i[14]=( m[12]*m[5]* m[2] -m[4]*m[13]*m[2] -m[12]*m[1]*m[6]
               +m[0]*m[13]*m[6] +m[4]*m[1]*m[14] -m[0]*m[5]* m[14])/x;
        i[3]= ( m[9]* m[6]* m[3] -m[5]*m[10]*m[3] -m[9]* m[2]*m[7]
               +m[1]*m[10]*m[7] +m[5]*m[2]*m[11] -m[1]*m[6]* m[11])/x;
        i[7]= (-m[8]* m[6]* m[3] +m[4]*m[10]*m[3] +m[8]* m[2]*m[7]
               -m[0]*m[10]*m[7] -m[4]*m[2]*m[11] +m[0]*m[6]* m[11])/x;
        i[11]=( m[8]* m[5]* m[3] -m[4]*m[9]* m[3] -m[8]* m[1]*m[7]
               +m[0]*m[9]* m[7] +m[4]*m[1]*m[11] -m[0]*m[5]* m[11])/x;
        i[15]=(-m[8]* m[5]* m[2] +m[4]*m[9]* m[2] +m[8]* m[1]*m[6]
               -m[0]*m[9]* m[6] -m[4]*m[1]*m[10] +m[0]*m[5]* m[10])/x;
    
        return TRUE;
    }
    
    void MatMatMultiply(GLfloat *result, GLfloat *matrix1, GLfloat *matrix2)
    {
        result[0]=matrix1[0]*matrix2[0]+
        matrix1[4]*matrix2[1]+
        matrix1[8]*matrix2[2]+
        matrix1[12]*matrix2[3];
        result[4]=matrix1[0]*matrix2[4]+
        matrix1[4]*matrix2[5]+
        matrix1[8]*matrix2[6]+
        matrix1[12]*matrix2[7];
        result[8]=matrix1[0]*matrix2[8]+
        matrix1[4]*matrix2[9]+
        matrix1[8]*matrix2[10]+
        matrix1[12]*matrix2[11];
        result[12]=matrix1[0]*matrix2[12]+
        matrix1[4]*matrix2[13]+
        matrix1[8]*matrix2[14]+
        matrix1[12]*matrix2[15];
        result[1]=matrix1[1]*matrix2[0]+
        matrix1[5]*matrix2[1]+
        matrix1[9]*matrix2[2]+
        matrix1[13]*matrix2[3];
        result[5]=matrix1[1]*matrix2[4]+
        matrix1[5]*matrix2[5]+
        matrix1[9]*matrix2[6]+
        matrix1[13]*matrix2[7];
        result[9]=matrix1[1]*matrix2[8]+
        matrix1[5]*matrix2[9]+
        matrix1[9]*matrix2[10]+
        matrix1[13]*matrix2[11];
        result[13]=matrix1[1]*matrix2[12]+
        matrix1[5]*matrix2[13]+
        matrix1[9]*matrix2[14]+
        matrix1[13]*matrix2[15];
        result[2]=matrix1[2]*matrix2[0]+
        matrix1[6]*matrix2[1]+
        matrix1[10]*matrix2[2]+
        matrix1[14]*matrix2[3];
        result[6]=matrix1[2]*matrix2[4]+
        matrix1[6]*matrix2[5]+
        matrix1[10]*matrix2[6]+
        matrix1[14]*matrix2[7];
        result[10]=matrix1[2]*matrix2[8]+
        matrix1[6]*matrix2[9]+
        matrix1[10]*matrix2[10]+
        matrix1[14]*matrix2[11];
        result[14]=matrix1[2]*matrix2[12]+
        matrix1[6]*matrix2[13]+
        matrix1[10]*matrix2[14]+
        matrix1[14]*matrix2[15];
        result[3]=matrix1[3]*matrix2[0]+
        matrix1[7]*matrix2[1]+
        matrix1[11]*matrix2[2]+
        matrix1[15]*matrix2[3];
        result[7]=matrix1[3]*matrix2[4]+
        matrix1[7]*matrix2[5]+
        matrix1[11]*matrix2[6]+
        matrix1[15]*matrix2[7];
        result[11]=matrix1[3]*matrix2[8]+
        matrix1[7]*matrix2[9]+
        matrix1[11]*matrix2[10]+
        matrix1[15]*matrix2[11];
        result[15]=matrix1[3]*matrix2[12]+
        matrix1[7]*matrix2[13]+
        matrix1[11]*matrix2[14]+
        matrix1[15]*matrix2[15];
    }
    

提交回复
热议问题