ray: ray sphere intersection

This commit is contained in:
Recep Aslantas
2024-03-20 07:22:36 +03:00
parent f1d4aea69b
commit aa45d081fc
7 changed files with 167 additions and 9 deletions

View File

@@ -20,7 +20,15 @@ glmc_ray_triangle(vec3 origin,
vec3 v1,
vec3 v2,
float *d);
CGLM_EXPORT
bool
glmc_ray_sphere(vec3 origin,
vec3 dir,
vec4 s,
float * __restrict t1,
float * __restrict t2);
#ifdef __cplusplus
}
#endif

View File

@@ -7,12 +7,17 @@
/*
Functions:
CGLM_INLINE bool glm_line_triangle_intersect(vec3 origin,
vec3 direction,
vec3 v0,
vec3 v1,
vec3 v2,
float *d);
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)
*/
#ifndef cglm_ray_h
@@ -31,7 +36,6 @@
* @param[in, out] d distance to intersection
* @return whether there is intersection
*/
CGLM_INLINE
bool
glm_ray_triangle(vec3 origin,
@@ -74,4 +78,70 @@ glm_ray_triangle(vec3 origin,
return dist > epsilon;
}
/*!
* @brief ray sphere intersection
*
* @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)
*/
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;
/* ensure dir is normalized */
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;
}
#endif

View File

@@ -41,6 +41,7 @@ extern "C" {
#include "struct/sphere.h"
#include "struct/curve.h"
#include "struct/affine2d.h"
#include "struct/ray.h"
#ifdef __cplusplus
}

59
include/cglm/struct/ray.h Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (c), Recep Aslantas.
*
* MIT License (MIT), http://opensource.org/licenses/MIT
* Full license can be found in the LICENSE file
*/
#ifndef cglms_ray_h
#define cglms_ray_h
#include "../common.h"
#include "../types-struct.h"
#include "../ray.h"
/* api definition */
#define glms_ray_(NAME) CGLM_STRUCTAPI(ray, NAME)
/*!
* @brief MöllerTrumbore 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
glms_ray_(triangle)(vec3s origin,
vec3s direction,
vec3s v0,
vec3s v1,
vec3s v2,
float *d) {
return glm_ray_triangle(origin.raw, direction.raw, v0.raw, v1.raw, v2.raw, d);
}
/*!
* @brief ray sphere intersection
*
* @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)
*/
CGLM_INLINE
bool
glms_ray_(sphere)(vec3s origin,
vec3s dir,
vec4s s,
float * __restrict t1,
float * __restrict t2) {
return glm_ray_sphere(origin.raw, dir.raw, s.raw, t1, t2);
}
#endif /* cglms_ray_h */

View File

@@ -9,5 +9,21 @@ glmc_ray_triangle(vec3 origin,
vec3 v1,
vec3 v2,
float *d) {
return glm_ray_triangle(origin, direction, v0, v1, v2, d);
return glm_ray_triangle(origin, direction, v0, v1, v2, d);
}
CGLM_EXPORT
bool
glmc_ray_sphere(vec3 origin,
vec3 dir,
vec4 s,
float * __restrict t1,
float * __restrict t2) {
return glm_ray_sphere(origin, dir, s, t1, t2);
}
CGLM_EXPORT
void
glmc_ray_at(vec3 orig, vec3 dir, float t, vec3 point) {
glm_ray_at(orig, dir, t, point);
}

View File

@@ -253,6 +253,7 @@
<ClInclude Include="..\include\cglm\struct\plane.h" />
<ClInclude Include="..\include\cglm\struct\project.h" />
<ClInclude Include="..\include\cglm\struct\quat.h" />
<ClInclude Include="..\include\cglm\struct\ray.h" />
<ClInclude Include="..\include\cglm\struct\sphere.h" />
<ClInclude Include="..\include\cglm\struct\vec2-ext.h" />
<ClInclude Include="..\include\cglm\struct\vec2.h" />

View File

@@ -729,5 +729,8 @@
<ClInclude Include="..\include\cglm\struct\ivec4.h">
<Filter>include\cglm\struct</Filter>
</ClInclude>
<ClInclude Include="..\include\cglm\struct\ray.h">
<Filter>include\cglm\struct</Filter>
</ClInclude>
</ItemGroup>
</Project>