static void Get_Selection_Ray(int x, int y, float *_p, float *_q)
{
//printf("Mouse clicked at (%i, %i)", x, y);
//Convert x, y from (0, width; 0, height) into a (-1, 1; -1, 1) range
float x_p = (2.0f*x) / screen_width - 1;
float y_p = 1 - (2.0f*y) / screen_height;
printf("Mouse clicked at (%.2f, %.2f)\n", x_p, y_p);
//Calculate the inverse of GL_PROJECTION_MATRIX
float M[16];
glGetFloatv(GL_PROJECTION_MATRIX, M);
//M is in column-major!
/*printf("[%.2f %.2f %.2f %.2f]\n[%.2f %.2f %.2f %.2f]\n[%.2f %.2f %.2f %.2f]\n[%.2f %.2f %.2f %.2f]\n\n",
M[0], M[4], M[8], M[12],
M[1], M[5], M[9], M[13],
M[2], M[6], M[10], M[14],
M[3], M[7], M[11], M[15]);*/
float inv_M[16];
memset(inv_M, 0, sizeof(float)*16);
inv_M[0]=1/M[0];
inv_M[5]=1/M[5];
inv_M[14]=1/M[14];
inv_M[11]=-1;
inv_M[15]=M[10]/M[14];
//inv_m is in row-major!
/*printf("[%.2f %.2f %.2f %.2f]\n[%.2f %.2f %.2f %.2f]\n[%.2f %.2f %.2f %.2f]\n[%.2f %.2f %.2f %.2f]\n\n",
inv_m[0], inv_m[1], inv_m[2], inv_m[3],
inv_m[4], inv_m[5], inv_m[6], inv_m[7],
inv_m[8], inv_m[9], inv_m[10], inv_m[11],
inv_m[12], inv_m[13], inv_m[14], inv_m[15]);*/
//Calculate rx, ry, rz
float p1[4];
float p2[4];
p1[0] = inv_M[0] * x_p;
p1[1] = inv_M[5] * y_p;
p1[2] = inv_M[11] * 1;
p1[3] = inv_M[14] * 1 + inv_M[15] * 1;
p2[0] = inv_M[0] * x_p;
p2[1] = inv_M[5] * y_p;
p2[2] = inv_M[11] * 1;
p2[3] = inv_M[14] * -1 + inv_M[15] * 1;
//Convert two vectors into two 3D points (homogeneous)
for (int i = 0; i <= 3; i ++) {
p1[i] = p1[i]/p1[3];
p2[i] = p2[i]/p2[3];
}
printf("p1 =\n[%.2f]\n[%.2f]\n[%.2f]\n[%.2f]\n\n", p1[0], p1[1], p1[2], p1[3]);
printf("p2 =\n[%.2f]\n[%.2f]\n[%.2f]\n[%.2f]\n\n", p2[0], p2[1], p2[2], p2[3]);
//Convert these 3D points (homogeneous) from the eye space into the world space.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(target[0], target[1], target[2]);
glRotatef(-swing_angle, 0, 1, 0);
glRotatef(-elevate_angle, 1, 0, 0);
glTranslatef(0, 0, zoom);
//gluLookAt(0, 0, -zoom, 0, 0, 0, 0, -1, 0);
memset(inv_M, 0, sizeof(float)*16);
glGetFloatv(GL_MODELVIEW_MATRIX, inv_M);
/*printf("inv_M = \n%.2f %.2f %.2f %.2f\n%.2f %.2f %.2f %.2f\n%.2f %.2f %.2f %.2f\n%.2f %.2f %.2f %.2f\n\n",
inv_M[0], inv_M[4], inv_M[8], inv_M[12],
inv_M[1], inv_M[5], inv_M[9], inv_M[13],
inv_M[2], inv_M[6], inv_M[10], inv_M[14],
inv_M[3], inv_M[7], inv_M[11], inv_M[15]);*/
p1[0] = inv_M[0] * p1[0] + inv_M[4] * p1[1] + inv_M[8] * p1[2] + inv_M[12] * p1[3];
p1[1] = inv_M[1] * p1[0] + inv_M[5] * p1[1] + inv_M[9] * p1[2] + inv_M[13] * p1[3];
p1[2] = inv_M[2] * p1[0] + inv_M[6] * p1[1] + inv_M[10] * p1[2] + inv_M[14] * p1[3];
p1[3] = inv_M[3] * p1[0] + inv_M[7] * p1[1] + inv_M[11] * p1[2] + inv_M[15] * p1[3];
p2[0] = inv_M[0] * p2[0] + inv_M[4] * p2[1] + inv_M[8] * p2[2] + inv_M[12] * p2[3];
p2[1] = inv_M[1] * p2[0] + inv_M[5] * p2[1] + inv_M[9] * p2[2] + inv_M[13] * p2[3];
p2[2] = inv_M[2] * p2[0] + inv_M[6] * p2[1] + inv_M[10] * p2[2] + inv_M[14] * p2[3];
p2[3] = inv_M[3] * p2[0] + inv_M[7] * p2[1] + inv_M[11] * p2[2] + inv_M[15] * p2[3];
//Convert them from the homogenous space into 3D space
_p[0] = p1[0]/p1[3];
_p[1] = p1[1]/p1[3];
_p[2] = p1[2]/p1[3];
_q[0] = p2[0]/p2[3];
_q[1] = p2[1]/p2[3];
_q[2] = p2[2]/p2[3];
//printf("p =\n[%.2f]\n[%.2f]\n[%.2f]\n[%.2f]\n", _p[0], _p[1], _p[2], _p[3]);
//printf("q =\n[%.2f]\n[%.2f]\n[%.2f]\n[%.2f]\n", _q[0], _q[1], _q[2], _q[3]);
}