|
|
|
|
@ -74,53 +74,34 @@ cameraUnproject(camera& cam, int x, int y, int vp_width, int vp_height)
|
|
|
|
|
v3f |
|
|
|
|
cameraCreateRay(camera& cam, v2i vp_coords, v2i vp_dims) |
|
|
|
|
{ |
|
|
|
|
#if 0 |
|
|
|
|
float x = 2.f * vp_coords.x / vp_dims.x - 1.f; |
|
|
|
|
float y = 2.f * vp_coords.y / vp_dims.y - 1.f; |
|
|
|
|
glm::vec4 ray_start_ndc = glm::vec4(x, y, -1.f, 1.f); |
|
|
|
|
glm::vec4 ray_end_ndc = glm::vec4(x, y, 0, 1.f); |
|
|
|
|
|
|
|
|
|
glm::mat4 M = glm::inverse(cam.projection * cam.view); |
|
|
|
|
glm::vec4 ray_start_world = M * ray_start_ndc; |
|
|
|
|
glm::vec4 ray_end_world = M * ray_end_ndc; |
|
|
|
|
ray_start_world /= ray_start_world.w; |
|
|
|
|
ray_end_world /= ray_end_world.w; |
|
|
|
|
|
|
|
|
|
glm::vec3 ray_origin = glm::vec3(ray_start_world); |
|
|
|
|
glm::vec3 ray_dir = glm::normalize(glm::vec3(ray_end_world - ray_start_world)); |
|
|
|
|
return v3f(ray_dir.x, ray_dir.y, ray_dir.z); |
|
|
|
|
#else |
|
|
|
|
// http://antongerdelan.net/opengl/raycasting.html
|
|
|
|
|
// NOTE: http://antongerdelan.net/opengl/raycasting.html
|
|
|
|
|
float x = 2.f * vp_coords.x / vp_dims.x - 1.f; |
|
|
|
|
float y = 2.f * vp_coords.y / vp_dims.y - 1.f; |
|
|
|
|
glm::vec4 ray_clip = glm::vec4(x, y, -1.f, 1.f); |
|
|
|
|
glm::vec4 ray_eye = glm::inverse(cam.projection) * ray_clip; |
|
|
|
|
ray_eye = glm::vec4(ray_eye.x, ray_eye.y, -1.f, 0); // NOTE: reset as ray
|
|
|
|
|
glm::vec4 ray_world = glm::normalize(glm::inverse(cam.view) * ray_eye); |
|
|
|
|
|
|
|
|
|
return v3f(ray_world.x, ray_world.y, ray_world.z); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool |
|
|
|
|
cameraIntersectPlane(camera& cam, v3f ray, v3f plane_origin, v3f plane_normal, v3f& intersection) |
|
|
|
|
{ |
|
|
|
|
// NOTE: https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-plane-and-ray-disk-intersection
|
|
|
|
|
glm::vec3 c_o = cam.position; |
|
|
|
|
glm::vec3 r = convertv3f(ray); |
|
|
|
|
//glm::vec3 r = cam.forward;
|
|
|
|
|
glm::vec3 p_o = convertv3f(plane_origin); |
|
|
|
|
glm::vec3 p_n = convertv3f(plane_normal); |
|
|
|
|
float divisor = glm::dot(r, p_n); |
|
|
|
|
|
|
|
|
|
if (divisor <= 0.000001f && divisor >= -0.000001f) // NOTE: ray and plane are co-planar
|
|
|
|
|
return false; |
|
|
|
|
#if 1 |
|
|
|
|
|
|
|
|
|
float distance = glm::dot((p_o - c_o), p_n) / divisor; |
|
|
|
|
glm::vec3 xsect = c_o + (r * distance); |
|
|
|
|
#else |
|
|
|
|
float distance = glm::dot(n, (p_o - c_o)) / glm::dot(n, r); |
|
|
|
|
glm::vec3 xsect = c_o + r * distance; |
|
|
|
|
#endif |
|
|
|
|
intersection = v3f(xsect.x, xsect.y, xsect.z); |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|