Thursday, September 22, 2016

Projecting 3D Point to Screen in Android OpenGL ES 2.0/3.0 Engine (Rajawali)

Project a 3D point to screen is a common task in OpenGL-alike platform. It will go through two matrices: pose matrix and projection matrix. In Rajawali, this function can be implemented as the follows:

        

        poseMatrix.toArray(valuePos);
        double[] valueProj = new double[16];
        projectionMatrix.toArray(valueProj);
        outputV2 = new Vector3(0, 0, 0);


        // To follow the example of gluProject
        double[] temp = new double[8];
        temp[0] = valuePos[0]*inputV.x+valuePos[4]*inputV.y+valuePos[8]*inputV.z+valuePos[12];
        temp[1] = valuePos[1]*inputV.x+valuePos[5]*inputV.y+valuePos[9]*inputV.z+valuePos[13];
        temp[2] = valuePos[2]*inputV.x+valuePos[6]*inputV.y+valuePos[10]*inputV.z+valuePos[14];
        temp[3] = valuePos[3]*inputV.x+valuePos[7]*inputV.y+valuePos[11]*inputV.z+valuePos[15];

        temp[4] = valueProj[0]*temp[0]+valueProj[4]*temp[1]+valueProj[8]*temp[2]+valueProj[12]*temp[3];
        temp[5] = valueProj[1]*temp[0]+valueProj[5]*temp[1]+valueProj[9]*temp[2]+valueProj[13]*temp[3];
        temp[6] = valueProj[2]*temp[0]+valueProj[6]*temp[1]+valueProj[10]*temp[2]+valueProj[14]*temp[3];
        temp[7] = -temp[2]; // The row of ProjectionMatrix is 0,0,-1,0

        if(temp[7]==0.0) //The w value
        {
            outputV2.x = 0;
            outputV2.y = 0;
        }

        temp[7]=1.0/temp[7];
        //Perspective division
        temp[4]*=temp[7];
        temp[5]*=temp[7];
        temp[6]*=temp[7];
        outputV2.x = temp[4];
        outputV2.y = temp[5];


Pose matrix can be obtained as

poseMatrix = getCurrentCamera().getViewMatrix();


Projection matrix can be obtained as

projectionMatrix = ScenePoseCalculator.calculateProjectionMatrix(
                intrinsics.width, intrinsics.height,
                intrinsics.fx, intrinsics.fy, intrinsics.cx, intrinsics.cy);