From c67f7a14a1dd010d4315aafd1b744442aa02ed03 Mon Sep 17 00:00:00 2001 From: Uwila Date: Mon, 30 Mar 2020 23:44:00 +0200 Subject: [PATCH] Add ray-triangle intersection check --- Makefile.am | 9 ++++-- docs/source/api.rst | 1 + docs/source/ray.rst | 31 +++++++++++++++++++ include/cglm/call.h | 1 + include/cglm/call/ray.h | 22 ++++++++++++++ include/cglm/cglm.h | 1 + include/cglm/ray.h | 66 ++++++++++++++++++++++++++++++++++++++++ src/ray.c | 8 +++++ win/cglm.vcxproj | 3 ++ win/cglm.vcxproj.filters | 9 ++++++ 10 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 docs/source/ray.rst create mode 100644 include/cglm/call/ray.h create mode 100644 include/cglm/ray.h create mode 100644 src/ray.c diff --git a/Makefile.am b/Makefile.am index 46b90b5..f6b4a21 100644 --- a/Makefile.am +++ b/Makefile.am @@ -63,7 +63,8 @@ cglm_HEADERS = include/cglm/version.h \ include/cglm/ease.h \ include/cglm/curve.h \ include/cglm/bezier.h \ - include/cglm/applesimd.h + include/cglm/applesimd.h \ + include/cglm/ray.h cglm_calldir=$(includedir)/cglm/call cglm_call_HEADERS = include/cglm/call/mat4.h \ @@ -84,7 +85,8 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \ include/cglm/call/sphere.h \ include/cglm/call/ease.h \ include/cglm/call/curve.h \ - include/cglm/call/bezier.h + include/cglm/call/bezier.h \ + include/cglm/call/ray.h cglm_simddir=$(includedir)/cglm/simd cglm_simd_HEADERS = include/cglm/simd/intrin.h \ @@ -147,7 +149,8 @@ libcglm_la_SOURCES=\ src/sphere.c \ src/ease.c \ src/curve.c \ - src/bezier.c + src/bezier.c \ + src/ray.c test_tests_SOURCES=\ test/runner.c \ diff --git a/docs/source/api.rst b/docs/source/api.rst index b157716..717b61c 100644 --- a/docs/source/api.rst +++ b/docs/source/api.rst @@ -52,3 +52,4 @@ Follow the :doc:`build` documentation for this curve bezier version + ray diff --git a/docs/source/ray.rst b/docs/source/ray.rst new file mode 100644 index 0000000..c5faf33 --- /dev/null +++ b/docs/source/ray.rst @@ -0,0 +1,31 @@ +.. default-domain:: C + +ray +==== + +Header: cglm/ray.h + +This is for collision-checks used by ray-tracers and the like. + +Table of contents (click to go): +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Functions: + +1. :c:func:`glm_ray_triangle` + +Functions documentation +~~~~~~~~~~~~~~~~~~~~~~~ + +.. c:function:: bool glm_ray_triangle(vec3 origin, vec3 direction, vec3 v0, vec3 v1, vec3 v2, float *d) + + Möller–Trumbore ray-triangle intersection algorithm + + Parameters: + | *[in]* **origin** origin of ray + | *[in]* **direction** direction of ray + | *[in]* **v0** first vertex of triangle + | *[in]* **v1** second vertex of triangle + | *[in]* **v2** third vertex of triangle + | *[in, out]* **d** float pointer to save distance to intersection + | *[out]* **intersection** whether there is intersection diff --git a/include/cglm/call.h b/include/cglm/call.h index 87ecea5..b51b731 100644 --- a/include/cglm/call.h +++ b/include/cglm/call.h @@ -31,6 +31,7 @@ extern "C" { #include "call/ease.h" #include "call/curve.h" #include "call/bezier.h" +#include "call/ray.h" #ifdef __cplusplus } diff --git a/include/cglm/call/ray.h b/include/cglm/call/ray.h new file mode 100644 index 0000000..0bfefe0 --- /dev/null +++ b/include/cglm/call/ray.h @@ -0,0 +1,22 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglmc_ray_h +#define cglmc_ray_h +#ifdef __cplusplus +extern "C" { +#endif +#include "../cglm.h" + +CGLM_EXPORT +bool +glmc_ray_triangle(vec3 origin, vec3 direction, vec3 v0, vec3 v1, vec3 v2, float *d); + +#ifdef __cplusplus +} +#endif +#endif /* cglmc_ray_h */ diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index cbd2952..afc7f99 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -30,5 +30,6 @@ #include "ease.h" #include "curve.h" #include "bezier.h" +#include "ray.h" #endif /* cglm_h */ diff --git a/include/cglm/ray.h b/include/cglm/ray.h new file mode 100644 index 0000000..c2433cb --- /dev/null +++ b/include/cglm/ray.h @@ -0,0 +1,66 @@ +/* + * 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_line_triangle_intersect(vec3 origin, vec3 direction, vec3 v0, vec3 v1, vec3 v2, float *d); +*/ + +#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 + * @param[out] intersection whether there is intersection + */ + +CGLM_INLINE +bool +glm_ray_triangle(vec3 origin, vec3 direction, vec3 v0, vec3 v1, vec3 v2, float *d) { + const float epsilon = 0.000001; + vec3 edge1, edge2, p, t, q; + float det, inv_det, u, v; + + 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 0; + inv_det = 1.0 / det; + + glm_vec3_sub(origin, v0, t); + + u = inv_det * glm_vec3_dot(t, p); + + if (u < 0.0 || u > 1.0) + return 0; + + glm_vec3_cross(t, edge1, q); + + v = inv_det * glm_vec3_dot(direction, q); + + if (v < 0.0 || u + v > 1.0) + return 0; + + *d = inv_det * glm_vec3_dot(edge2, q); + return *d > epsilon; +} + +#endif diff --git a/src/ray.c b/src/ray.c new file mode 100644 index 0000000..4ce0c58 --- /dev/null +++ b/src/ray.c @@ -0,0 +1,8 @@ +#include "../include/cglm/cglm.h" +#include "../include/cglm/call.h" + +CGLM_EXPORT +bool +glmc_ray_triangle(vec3 origin, vec3 direction, vec3 v0, vec3 v1, vec3 v2, float *d) { + return glm_ray_triangle(origin, direction, v0, v1, v2, d); +} diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj index e1a0e4d..a95f21e 100644 --- a/win/cglm.vcxproj +++ b/win/cglm.vcxproj @@ -34,6 +34,7 @@ + @@ -61,6 +62,7 @@ + @@ -80,6 +82,7 @@ + diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters index a2f1432..fe23bd6 100644 --- a/win/cglm.vcxproj.filters +++ b/win/cglm.vcxproj.filters @@ -92,6 +92,9 @@ src + + src + @@ -124,6 +127,9 @@ include\cglm\call + + include\cglm\call + include\cglm\simd\avx @@ -241,6 +247,9 @@ include\cglm + + include\cglm + include\cglm\simd