Initial upload
This commit is contained in:
174
external/cglm/ray.h
vendored
Normal file
174
external/cglm/ray.h
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c), Recep Aslantas.
|
||||
*
|
||||
* MIT License (MIT), http://opensource.org/licenses/MIT
|
||||
* Full license can be found in the LICENSE file
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions:
|
||||
CGLM_INLINE bool glm_ray_triangle(vec3 origin,
|
||||
vec3 direction,
|
||||
vec3 v0,
|
||||
vec3 v1,
|
||||
vec3 v2,
|
||||
float *d);
|
||||
CGLM_INLINE bool glm_ray_sphere(vec3 origin,
|
||||
vec3 dir,
|
||||
vec4 s,
|
||||
float * __restrict t1,
|
||||
float * __restrict t2)
|
||||
CGLM_INLINE void glm_ray_at(vec3 orig, vec3 dir, float t, vec3 point);
|
||||
*/
|
||||
|
||||
#ifndef cglm_ray_h
|
||||
#define cglm_ray_h
|
||||
|
||||
#include "vec3.h"
|
||||
|
||||
/*!
|
||||
* @brief Möller–Trumbore ray-triangle intersection algorithm
|
||||
*
|
||||
* @param[in] origin origin of ray
|
||||
* @param[in] direction direction of ray
|
||||
* @param[in] v0 first vertex of triangle
|
||||
* @param[in] v1 second vertex of triangle
|
||||
* @param[in] v2 third vertex of triangle
|
||||
* @param[in, out] d distance to intersection
|
||||
* @return whether there is intersection
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_ray_triangle(vec3 origin,
|
||||
vec3 direction,
|
||||
vec3 v0,
|
||||
vec3 v1,
|
||||
vec3 v2,
|
||||
float *d) {
|
||||
vec3 edge1, edge2, p, t, q;
|
||||
float det, inv_det, u, v, dist;
|
||||
const float epsilon = 0.000001f;
|
||||
|
||||
glm_vec3_sub(v1, v0, edge1);
|
||||
glm_vec3_sub(v2, v0, edge2);
|
||||
glm_vec3_cross(direction, edge2, p);
|
||||
|
||||
det = glm_vec3_dot(edge1, p);
|
||||
if (det > -epsilon && det < epsilon)
|
||||
return false;
|
||||
|
||||
inv_det = 1.0f / det;
|
||||
|
||||
glm_vec3_sub(origin, v0, t);
|
||||
|
||||
u = inv_det * glm_vec3_dot(t, p);
|
||||
if (u < 0.0f || u > 1.0f)
|
||||
return false;
|
||||
|
||||
glm_vec3_cross(t, edge1, q);
|
||||
|
||||
v = inv_det * glm_vec3_dot(direction, q);
|
||||
if (v < 0.0f || u + v > 1.0f)
|
||||
return false;
|
||||
|
||||
dist = inv_det * glm_vec3_dot(edge2, q);
|
||||
|
||||
if (d)
|
||||
*d = dist;
|
||||
|
||||
return dist > epsilon;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief ray sphere intersection
|
||||
*
|
||||
* returns false if there is no intersection if true:
|
||||
*
|
||||
* - t1 > 0, t2 > 0: ray intersects the sphere at t1 and t2 both ahead of the origin
|
||||
* - t1 < 0, t2 > 0: ray starts inside the sphere, exits at t2
|
||||
* - t1 < 0, t2 < 0: no intersection ahead of the ray ( returns false )
|
||||
* - the caller can check if the intersection points (t1 and t2) fall within a
|
||||
* specific range (for example, tmin < t1, t2 < tmax) to determine if the
|
||||
* intersections are within a desired segment of the ray
|
||||
*
|
||||
* @param[in] origin ray origin
|
||||
* @param[out] dir normalized ray direction
|
||||
* @param[in] s sphere [center.x, center.y, center.z, radii]
|
||||
* @param[in] t1 near point1 (closer to origin)
|
||||
* @param[in] t2 far point2 (farther from origin)
|
||||
*
|
||||
* @returns whether there is intersection
|
||||
*/
|
||||
CGLM_INLINE
|
||||
bool
|
||||
glm_ray_sphere(vec3 origin,
|
||||
vec3 dir,
|
||||
vec4 s,
|
||||
float * __restrict t1,
|
||||
float * __restrict t2) {
|
||||
vec3 dp;
|
||||
float r2, ddp, dpp, dscr, q, tmp, _t1, _t2;
|
||||
|
||||
glm_vec3_sub(s, origin, dp);
|
||||
|
||||
ddp = glm_vec3_dot(dir, dp);
|
||||
dpp = glm_vec3_norm2(dp);
|
||||
|
||||
/* compute the remedy term for numerical stability */
|
||||
glm_vec3_mulsubs(dir, ddp, dp); /* dp: remedy term */
|
||||
|
||||
r2 = s[3] * s[3];
|
||||
dscr = r2 - glm_vec3_norm2(dp);
|
||||
|
||||
if (dscr < 0.0f) {
|
||||
/* no intersection */
|
||||
return false;
|
||||
}
|
||||
|
||||
dscr = sqrtf(dscr);
|
||||
q = (ddp >= 0.0f) ? (ddp + dscr) : (ddp - dscr);
|
||||
|
||||
/*
|
||||
include Press, William H., Saul A. Teukolsky,
|
||||
William T. Vetterling, and Brian P. Flannery,
|
||||
"Numerical Recipes in C," Cambridge University Press, 1992.
|
||||
*/
|
||||
_t1 = q;
|
||||
_t2 = (dpp - r2) / q;
|
||||
|
||||
/* adjust t1 and t2 to ensure t1 is the closer intersection */
|
||||
if (_t1 > _t2) {
|
||||
tmp = _t1;
|
||||
_t1 = _t2;
|
||||
_t2 = tmp;
|
||||
}
|
||||
|
||||
*t1 = _t1;
|
||||
*t2 = _t2;
|
||||
|
||||
/* check if the closest intersection (t1) is behind the ray's origin */
|
||||
if (_t1 < 0.0f && _t2 < 0.0f) {
|
||||
/* both intersections are behind the ray, no visible intersection */
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief point using t by 𝐏(𝑡)=𝐀+𝑡𝐛
|
||||
*
|
||||
* @param[in] orig origin of ray
|
||||
* @param[in] dir direction of ray
|
||||
* @param[in] t parameter
|
||||
* @param[out] point point at t
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_ray_at(vec3 orig, vec3 dir, float t, vec3 point) {
|
||||
vec3 dst;
|
||||
glm_vec3_scale(dir, t, dst);
|
||||
glm_vec3_add(orig, dst, point);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user