diff --git a/include/cglm/call/ray.h b/include/cglm/call/ray.h
index 1fff055..02fe632 100644
--- a/include/cglm/call/ray.h
+++ b/include/cglm/call/ray.h
@@ -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
diff --git a/include/cglm/ray.h b/include/cglm/ray.h
index ced1ad6..ec993c6 100644
--- a/include/cglm/ray.h
+++ b/include/cglm/ray.h
@@ -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
diff --git a/include/cglm/struct.h b/include/cglm/struct.h
index 030f45a..1426589 100644
--- a/include/cglm/struct.h
+++ b/include/cglm/struct.h
@@ -41,6 +41,7 @@ extern "C" {
#include "struct/sphere.h"
#include "struct/curve.h"
#include "struct/affine2d.h"
+#include "struct/ray.h"
#ifdef __cplusplus
}
diff --git a/include/cglm/struct/ray.h b/include/cglm/struct/ray.h
new file mode 100644
index 0000000..4eea68d
--- /dev/null
+++ b/include/cglm/struct/ray.h
@@ -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ö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
+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 */
diff --git a/src/ray.c b/src/ray.c
index 973c059..9592b83 100644
--- a/src/ray.c
+++ b/src/ray.c
@@ -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);
}
diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj
index 949c994..dcca926 100644
--- a/win/cglm.vcxproj
+++ b/win/cglm.vcxproj
@@ -253,6 +253,7 @@
+
diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters
index 71143f5..f200fb2 100644
--- a/win/cglm.vcxproj.filters
+++ b/win/cglm.vcxproj.filters
@@ -729,5 +729,8 @@
include\cglm\struct
+
+ include\cglm\struct
+
\ No newline at end of file