I decided to post a video of what i get now:
You will see there that sometimes ray isn't computed properly (most of times when reaching corners of the screen)
And full code:
TRay RayFromScreen(int x, int y, int sw, int sh, float fov, float z_near, float z_far, float aspect)
{
mat4 mvm = CAM_MODEL * CAM_VIEW;
mvm.Transpose(); <- i have a code that gets up and right vector from oglmatrix modelview so i just transpose it here
vec3 dirX, dirY;
dirX.x = mvm.m[0];
dirX.y = mvm.m[4];
dirX.z = mvm.m[8];
//
//
dirY.x = mvm.m[1];
dirY.y = mvm.m[5];
dirY.z = mvm.m[9];
TRay res;
// cot(x) = 1/tan(x)
// x = z_near / ctg(a);
float a = fov / 2.0;
float cotangent = 1.0 / tan( a * imopi );
float ax = z_near / cotangent;
float screen_w = 2.0*ax;
float yratio = 1.0 / aspect;
float screen_h = screen_w * yratio;
float scr_coord_x = float(x) / float(sw);
float scr_coord_y = float(sh - y) / float(sh);
vec3 dir = FPP_CAM->ReturnFrontVector();
//move to lower left corner
vec3 start_pos = (FPP_CAM->pos + dir * z_near) + (-dirX * (screen_w / 2.0)) + (-dirY * (screen_h/2.0));
res.start = start_pos + (dirX * (screen_w * scr_coord_x)) + (dirY * (screen_h * scr_coord_y));
//compute the world position on the other end since its a perspective projection
ax = z_far / cotangent;
screen_w = 2.0*ax;
screen_h = screen_w * yratio;
start_pos = (FPP_CAM->pos + dir * z_far) + (-dirX * (screen_w / 2.0)) + (-dirY * (screen_h/2.0));
res.end = start_pos + (dirX * (screen_w * scr_coord_x)) + (dirY * (screen_h * scr_coord_y));
return res;
}
//this function calls the frist one
t3dpoint<int> CellFromScreenCPU(int x, int y, int sw, int sh, float fov, float z_near, float z_far, float aspect)
{
TRay ray = RayFromScreen(x, y, sw, sh, fov, z_near, z_far, aspect);
}
actual call:
t3dpoint<int> cell = CellFromScreenCPU(x,y, SCREEN_WIDTH, SCREEN_HEIGHT, 90.0, 2.0, 28.0 * 1000.0, float(SCREEN_WIDTH) / float(SCREEN_HEIGHT));