objective-c isgl3d 反射线拾取

来源:互联网 发布:golang os.exit 编辑:程序博客网 时间:2024/06/06 14:59

http://softwareprodigy.blogspot.com/2009/08/gluunproject-for-iphone-opengl-es.html

//-(CGPoint) getOGLPos:(CGPoint)winPos

//{

//    // I am doing this once at the beginning when I set the perspective view

//     glGetFloatv( GL_MODELVIEW_MATRIX, __modelview );

//     glGetFloatv( GL_PROJECTION_MATRIX, __projection );

//     glGetIntegerv( GL_VIEWPORT, __viewport );

//    

//    //opengl 0,0 is at the bottom not at the top

//    winPos.y = (float)__viewport[3] - winPos.y;

//    // float winZ;

//    //we cannot do the following in openGL ES due to tile rendering

//    // glReadPixels( (int)winPos.x, (int)winPos.y, 1, 1, GL_DEPTH_COMPONENT24_OES, GL_FLOAT, &winZ );

//    

//    float cX, cY, cZ, fX, fY, fZ;

//    //gives us camera position (near plan)

//    gluUnProject( winPos.x, winPos.y, 0, __modelview, __projection, __viewport, &cX, &cY, &cZ);

//    //far plane

//    gluUnProject( winPos.x, winPos.y, 1, __modelview, __projection, __viewport, &fX, &fY, &fZ);

//    

//    //We could use some vector3d class, but this will do fine for now

//    //ray

//    fX -= cX;

//    fY -= cY;

//    fZ -= cZ;

//    float rayLength = sqrtf(cX*cX + cY*cY + cZ*cZ);

//    //normalize

//    fX /= rayLength;

//    fY /= rayLength;

//    fZ /= rayLength;

//    

//    //T = [planeNormal.(pointOnPlane - rayOrigin)]/planeNormal.rayDirection;

//    //pointInPlane = rayOrigin + (rayDirection * T);

//    

//    float dot1, dot2;

//    

//    float pointInPlaneX = 0;

//    float pointInPlaneY = 0;

//    float pointInPlaneZ = 0;

//    float planeNormalX = 0;

//    float planeNormalY = 0;

//    float planeNormalZ = -1;

//    

//    pointInPlaneX -= cX;

//    pointInPlaneY -= cY;

//    pointInPlaneZ -= cZ;

//    

//    dot1 = (planeNormalX * pointInPlaneX) + (planeNormalY * pointInPlaneY) + (planeNormalZ * pointInPlaneZ);

//    dot2 = (planeNormalX * fX) + (planeNormalY * fY) + (planeNormalZ * fZ);

//    

//    float t = dot1/dot2;

//    

//    fX *= t;

//    fY *= t;

//    //we don't need the z coordinate in my case

//    

//    return CGPointMake(fX + cX, fY + cY);

    //}


别人源码,摘来分享,哈哈哈

CGPoint startLocation;


-(void ) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    NSLog(@"touches begin!!");


    NSEnumerator * enumerator = [touchesobjectEnumerator];

    UITouch * touch1 = [enumeratornextObject];

    startLocation = [m_pViewconvertUIPointToView:[touch1locationInView:touch1.view]];



//     glGetFloatv( GL_MODELVIEW_MATRIX, __modelview );

//     glGetFloatv( GL_PROJECTION_MATRIX, __projection );

//     glGetIntegerv( GL_VIEWPORT, __viewport );


    Isgl3dMatrix4 modelView =m_pView.scene.worldTransformation;

    Isgl3dMatrix4 projectiveMatrix =m_pView.camera.viewProjectionMatrix;

    CGRect viewPort =m_pView.viewport;

    float moV[16];

    // for( int i =0 ; i < 16 ; i++)

    {

        moV[0] = modelView.sxx;

        moV[1] = modelView.syx;

        moV[2] = modelView.szx;

        moV[3] = modelView.swx;

        

        moV[4] = modelView.sxy;

        moV[5] = modelView.syy;

        moV[6] = modelView.szy;

        moV[7] = modelView.swy;

        

        moV[8] = modelView.sxz;

        moV[9] = modelView.syz;

        moV[10] = modelView.szz;

        moV[11] = modelView.swz;

        

        moV[12] = modelView.tx;

        moV[13] = modelView.ty;

        moV[14] = modelView.tz;

        moV[15] = modelView.tw;

    }

    

    float pV[16];

    {

        pV[0] = projectiveMatrix.sxx;

        pV[1] = projectiveMatrix.syx;

        pV[2] = projectiveMatrix.szx;

        pV[3] = projectiveMatrix.swx;

        

        pV[4] = projectiveMatrix.sxy;

        pV[5] = projectiveMatrix.syy;

        pV[6] = projectiveMatrix.szy;

        pV[7] = projectiveMatrix.swy;

        

        pV[8] = projectiveMatrix.sxz;

        pV[9] = projectiveMatrix.syz;

        pV[10] = projectiveMatrix.szz;

        pV[11] = projectiveMatrix.swz;

        

        pV[12] = projectiveMatrix.tx;

        pV[13] = projectiveMatrix.ty;

        pV[14] = projectiveMatrix.tz;

        pV[15] = projectiveMatrix.tw;

    }

    

    int vP[4];

    vP[0] = viewPort.origin.x;

    vP[1] = viewPort.origin.y;

    vP[2] = viewPort.size.width;

    vP[3] = viewPort.size.height;

    float result[3];

    

    //gives us camera position (near plan)

    glhUnProjectf(startLocation.x,startLocation.y, 0, moV, pV, vP, result);

    fPoint3 start;

    start.x = result[0];

    start.y = result[1];

    start.z = result[2];

    

    //far plane

    glhUnProjectf(startLocation.x,startLocation.y, 1, moV, pV, vP, result);

    fPoint3 end;

    end.x = result[0];

    end.y = result[1];

    end.z = result[2];

    

    //射线求交点(与地面(x, y, 0))

    getCrossPoint(start, end,wordStart);

    

    //。。。。

    wordEnd.x =wordStart.x;

    wordEnd.y =wordStart.y;

    wordEnd.z =wordStart.z;    

}


int glhUnProjectf(float winx,float winy,float winz,float *modelview,float *projection,int *viewport, float *objectCoordinate)

{

    //Transformation matrices

    float m[16], A[16];

    float in[4], out[4];

    //float B[16];

    //Calculation for inverting a matrix, compute projection x modelview

    //and store in A[16]

    MultiplyMatrices4by4OpenGL_FLOAT(A, projection, modelview);

    //Now compute the inverse of matrix A

    if(glhInvertMatrixf2(A, m)==0)

        return 0;

    //Transformation of normalized coordinates between -1 and 1

    in[0]=(winx-(float)viewport[0])/(float)viewport[2]*2.0-1.0;

    in[1]=(winy-(float)viewport[1])/(float)viewport[3]*2.0-1.0;

    in[2]=2.0*winz-1.0;

    in[3]=1.0;

    //Objects coordinates

    MultiplyMatrixByVector4by4OpenGL_FLOAT(out, m,in);

    if(out[3]==0.0)

        return 0;

    out[3]=1.0/out[3];

    objectCoordinate[0]=out[0]*out[3];

    objectCoordinate[1]=out[1]*out[3];

    objectCoordinate[2]=out[2]*out[3];

    return 1;

}

//用来求取直线和地图平面的交点

bool getCrossPoint(fPoint3 startPoint,fPoint3 endPoint,fPoint3 &CrossPoint ){

    

    if(startPoint.z==endPoint.z)returnfalse;//没有交点

    

    float v0=endPoint.x-startPoint.x;

    float v1=endPoint.y-startPoint.y;

    float v2=endPoint.z-startPoint.z;

    

    float t= - startPoint.z/v2;

    

    //求取交点

    CrossPoint.x=v0*t+startPoint.x;

    CrossPoint.y=v1*t + startPoint.y;

    CrossPoint.z=0;

    returntrue;

}