diff --git a/docs/source/api.rst b/docs/source/api.rst
index e88b426..c7f74a5 100644
--- a/docs/source/api.rst
+++ b/docs/source/api.rst
@@ -46,3 +46,4 @@ Follow the :doc:`build` documentation for this
io
call
sphere
+ curve
diff --git a/docs/source/curve.rst b/docs/source/curve.rst
new file mode 100644
index 0000000..26c9b75
--- /dev/null
+++ b/docs/source/curve.rst
@@ -0,0 +1,41 @@
+.. default-domain:: C
+
+Curve
+================================================================================
+
+Header: cglm/curve.h
+
+Common helpers for common curves. For specific curve see its header/doc
+e.g bezier
+
+Table of contents (click to go):
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Functions:
+
+1. :c:func:`glm_smc`
+
+Functions documentation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. c:function:: float glm_smc(float s, mat4 m, vec4 c)
+
+ | helper function to calculate **S** * **M** * **C** multiplication for curves
+
+ | this function does not encourage you to use SMC, instead it is a helper if you use SMC.
+
+ | if you want to specify S as vector then use more generic glm_mat4_rmc() func.
+
+ | Example usage:
+
+ .. code-block:: c
+
+ Bs = glm_smc(s, GLM_BEZIER_MAT, (vec4){p0, c0, c1, p1})
+
+ Parameters:
+ | *[in]* **s** parameter between 0 and 1 (this will be [s3, s2, s, 1])
+ | *[in]* **m** basis matrix
+ | *[out]* **c** position/control vector
+
+ Returns:
+ scalar value e.g. Bs
diff --git a/include/cglm/call.h b/include/cglm/call.h
index b7fa6e1..7c1c8d7 100644
--- a/include/cglm/call.h
+++ b/include/cglm/call.h
@@ -27,6 +27,7 @@ extern "C" {
#include "call/project.h"
#include "call/sphere.h"
#include "call/ease.h"
+#include "call/curve.h"
#ifdef __cplusplus
}
diff --git a/include/cglm/call/curve.h b/include/cglm/call/curve.h
new file mode 100644
index 0000000..061fdb9
--- /dev/null
+++ b/include/cglm/call/curve.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#ifndef cglmc_curve_h
+#define cglmc_curve_h
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "../cglm.h"
+
+CGLM_EXPORT
+float
+glmc_smc(float s, mat4 m, vec4 c);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* cglmc_curve_h */
diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h
index 8b37162..d79a88e 100644
--- a/include/cglm/cglm.h
+++ b/include/cglm/cglm.h
@@ -26,5 +26,6 @@
#include "project.h"
#include "sphere.h"
#include "ease.h"
+#include "curve.h"
#endif /* cglm_h */
diff --git a/include/cglm/curve.h b/include/cglm/curve.h
new file mode 100644
index 0000000..5033be5
--- /dev/null
+++ b/include/cglm/curve.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#ifndef cglm_curve_h
+#define cglm_curve_h
+
+#include "common.h"
+#include "vec4.h"
+#include "mat4.h"
+
+/*!
+ * @brief helper function to calculate S*M*C multiplication for curves
+ *
+ * This function does not encourage you to use SMC,
+ * instead it is a helper if you use SMC.
+ *
+ * if you want to specify S as vector then use more generic glm_mat4_rmc() func.
+ *
+ * Example usage:
+ * B(s) = glm_smc(s, GLM_BEZIER_MAT, (vec4){p0, c0, c1, p1})
+ *
+ * @param[in] s parameter between 0 and 1 (this will be [s3, s2, s, 1])
+ * @param[in] m basis matrix
+ * @param[in] c position/control vector
+ *
+ * @return B(s)
+ */
+CGLM_INLINE
+float
+glm_smc(float s, mat4 m, vec4 c) {
+ vec4 vs;
+ glm_vec4_cubic(s, vs);
+ return glm_mat4_rmc(vs, m, c);
+}
+
+#endif /* cglm_curve_h */
diff --git a/makefile.am b/makefile.am
index 63fa285..d6498c6 100644
--- a/makefile.am
+++ b/makefile.am
@@ -57,7 +57,8 @@ cglm_HEADERS = include/cglm/version.h \
include/cglm/color.h \
include/cglm/project.h \
include/cglm/sphere.h \
- include/cglm/ease.h
+ include/cglm/ease.h \
+ include/cglm/curve.h
cglm_calldir=$(includedir)/cglm/call
cglm_call_HEADERS = include/cglm/call/mat4.h \
@@ -74,7 +75,8 @@ cglm_call_HEADERS = include/cglm/call/mat4.h \
include/cglm/call/box.h \
include/cglm/call/project.h \
include/cglm/call/sphere.h \
- include/cglm/call/ease.h
+ include/cglm/call/ease.h \
+ include/cglm/call/curve.h
cglm_simddir=$(includedir)/cglm/simd
cglm_simd_HEADERS = include/cglm/simd/intrin.h \
@@ -109,7 +111,8 @@ libcglm_la_SOURCES=\
src/box.c \
src/project.c \
src/sphere.c \
- src/ease.c
+ src/ease.c \
+ src/curve.c
test_tests_SOURCES=\
test/src/test_common.c \
diff --git a/src/curve.c b/src/curve.c
new file mode 100644
index 0000000..74d4702
--- /dev/null
+++ b/src/curve.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c), Recep Aslantas.
+ *
+ * MIT License (MIT), http://opensource.org/licenses/MIT
+ * Full license can be found in the LICENSE file
+ */
+
+#include "../include/cglm/cglm.h"
+#include "../include/cglm/call.h"
+
+CGLM_EXPORT
+float
+glmc_smc(float s, mat4 m, vec4 c) {
+ return glm_smc(s, m, c);
+}
diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj
index 97d9d08..82293f0 100644
--- a/win/cglm.vcxproj
+++ b/win/cglm.vcxproj
@@ -22,6 +22,7 @@
+
@@ -44,6 +45,7 @@
+
@@ -60,6 +62,7 @@
+
diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters
index a668242..7f9735b 100644
--- a/win/cglm.vcxproj.filters
+++ b/win/cglm.vcxproj.filters
@@ -84,6 +84,9 @@
src
+
+ src
+
@@ -239,5 +242,11 @@
include\cglm\simd
+
+ include\cglm\call
+
+
+ include\cglm
+
\ No newline at end of file