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