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

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

View File

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

View File

@@ -41,6 +41,7 @@ extern "C" {
#include "struct/sphere.h" #include "struct/sphere.h"
#include "struct/curve.h" #include "struct/curve.h"
#include "struct/affine2d.h" #include "struct/affine2d.h"
#include "struct/ray.h"
#ifdef __cplusplus #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

@@ -11,3 +11,19 @@ glmc_ray_triangle(vec3 origin,
float *d) { 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\plane.h" />
<ClInclude Include="..\include\cglm\struct\project.h" /> <ClInclude Include="..\include\cglm\struct\project.h" />
<ClInclude Include="..\include\cglm\struct\quat.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\sphere.h" />
<ClInclude Include="..\include\cglm\struct\vec2-ext.h" /> <ClInclude Include="..\include\cglm\struct\vec2-ext.h" />
<ClInclude Include="..\include\cglm\struct\vec2.h" /> <ClInclude Include="..\include\cglm\struct\vec2.h" />

View File

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