(1) Recent demo
void getRayFromMouse(vec3 *step)
{
/*
* xclick - location of horizontal click in pixels
* yclick - location of vertical click in pixels
* screenHeight - screen height in pixels
* screenWidth - screen width in pixels
* player.camera - players camera location
* player.cameraFront - coordinates 1 unit away from player.camera in the direction the camera is facing
* player.up - 0,0,1
*/
//normalized device coordinates for the on-screen click
vec4 ray_NDC = {xclick/(float)(screenWidth/2.0)-1,yclick/(float)(screenHeight/2.0)-1, -1.0, 0.0f};
//create projection matrix (same as in UBO) and invert it
mat4 proj;
glm_perspective(degToRad(45.0f),(float)screenWidth/(float)screenHeight,0.1f,10000.0f,proj);
proj[1][1] *= -1;
mat4 invProjMat;
glm_mat4_inv(proj,invProjMat);
//project ray_NDC into the world space
vec4 eyeCoords;
glm_mat4_mulv(invProjMat, ray_NDC, eyeCoords);
eyeCoords[2] = -1.0f;
eyeCoords[3] = 0.0f;
//create view matrix (same as in UBO) and invert it
mat4 view;
glm_lookat(player.camera,player.cameraFront,player.up,view);
mat4 invViewMat;
glm_mat4_inv(view,invViewMat);
//Add camera orientation and location to the ray
vec4 rayWorld;
glm_mat4_mulv(invViewMat, eyeCoords, rayWorld);
glm_vec3_normalize(rayWorld);
//return vec3 ray
memcpy(step,rayWorld,sizeof(vec3));
}
(2) GetRayFromMouse function
/* Raytracing code
* thmem is an array of structs for terrain hitboxes
* struct MapTerrainHbox{
* vec3 p1; //position of triangle point 1
* vec3 p2; //position of triangle point 2
* vec3 p3; //position of triangle point 3
* vec3 n; //plane normal
* float d; //distance from origin to plane
* };
* lwm is the low watermark to find the closest triangle in the path of the ray
* closest is the array index of the result
*/
for(i=0;i < QUAD_CELL_COUNT*4;i++){
NdotRayDirection = -glm_vec3_dot(step,thmem[i].n);
t = (glm_vec3_dot(thmem[i].n,player.camera)-thmem[i].d)/NdotRayDirection;
if (t < 0)
break;
P[0] = step[0]*t+player.camera[0];
P[1] = step[1]*t+player.camera[1];
P[2] = step[2]*t+player.camera[2];
glm_vec3_sub(thmem[i].p2,thmem[i].p1,e1);
glm_vec3_sub(P,thmem[i].p1,vP1);
glm_vec3_cross(e1,vP1,C);
if(glm_vec3_dot(thmem[i].n,C)<0.0f){
break;
}
glm_vec3_sub(thmem[i].p3,thmem[i].p2,e2);
glm_vec3_sub(P,thmem[i].p3,vP2);
glm_vec3_cross(e2,vP2,C);
if(glm_vec3_dot(thmem[i].n,C)<0.0f){
break;
}
glm_vec3_sub(thmem[i].p1,thmem[i].p3,e3);
glm_vec3_sub(P,thmem[i].p3,vP3);
glm_vec3_cross(e3,vP3,C);
if(glm_vec3_dot(thmem[i].n,C)<0.0f){
break;
}
if(lwm>t){
lwm = t;
closest = i;
}
break;
}
(3) Raytracing code