From fadde1e26a403c73db2ca9210aabc5766bf15cbe Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 8 Mar 2018 13:04:29 +0300 Subject: [PATCH 01/21] fix libtool version number --- makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/makefile.am b/makefile.am index ff951c8..f6d1471 100644 --- a/makefile.am +++ b/makefile.am @@ -16,7 +16,7 @@ AM_CFLAGS = -Wall \ -pedantic lib_LTLIBRARIES = libcglm.la -libcglm_la_LDFLAGS = -no-undefined -version-info 0:3:5 +libcglm_la_LDFLAGS = -no-undefined -version-info 0:1:0 checkLDFLAGS = -L./.libs \ -L./test/lib/cmocka/build/src \ From 91b2a989e2ca50ccfe75aa70ee05b242cd94311d Mon Sep 17 00:00:00 2001 From: mcsquizzy123 Date: Mon, 19 Mar 2018 18:37:49 -0700 Subject: [PATCH 02/21] typo fixes - heaer and haeder --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 84b321e..e10597f 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ If you want to use inline versions of funcstions then; include main header ```C #include ``` -the haeder will include all headers. Then call func you want e.g. rotate vector by axis: +the header will include all headers. Then call func you want e.g. rotate vector by axis: ```C glm_vec_rotate(v1, glm_rad(45), (vec3){1.0f, 0.0f, 0.0f}); ``` @@ -180,7 +180,7 @@ to call pre-compiled versions include header with `c` postfix, c means call. Pre ```C #include ``` -this header will include all heaers with c postfix. You need to call functions with c posfix: +this header will include all headers with c postfix. You need to call functions with c posfix: ```C glmc_vec_normalize(vec); ``` From 86055097e1e8325abbe7624c5f97b18c1b209220 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 22 Mar 2018 18:10:10 +0300 Subject: [PATCH 03/21] clamp functions --- include/cglm/util.h | 13 +++++++++++++ include/cglm/vec3.h | 15 +++++++++++++++ include/cglm/vec4.h | 16 ++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/include/cglm/util.h b/include/cglm/util.h index 12db1a2..20b4c67 100644 --- a/include/cglm/util.h +++ b/include/cglm/util.h @@ -115,4 +115,17 @@ glm_max(float a, float b) { return b; } +/*! + * @brief clamp a number between min and max + * + * @param[in] val value to clamp + * @param[in] minVal minimum value + * @param[in] maxVal maximum value + */ +CGLM_INLINE +float +glm_clamp(float val, float minVal, float maxVal) { + return glm_min(glm_max(val, minVal), maxVal); +} + #endif /* cglm_util_h */ diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index 26adf7d..82c729a 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -478,6 +478,21 @@ glm_vec_ortho(vec3 v, vec3 dest) { dest[2] = v[0] - v[1]; } +/*! + * @brief clamp vector's individual members between min and max values + * + * @param[in, out] v vector + * @param[in] minVal minimum value + * @param[in] maxVal maximum value + */ +CGLM_INLINE +void +glm_vec_clamp(vec3 v, float minVal, float maxVal) { + v[0] = glm_clamp(v[0], minVal, maxVal); + v[1] = glm_clamp(v[1], minVal, maxVal); + v[2] = glm_clamp(v[2], minVal, maxVal); +} + /*! * @brief vec3 cross product * diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index a656166..0e6659e 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -373,4 +373,20 @@ glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest) { dest[3] = glm_min(v1[3], v2[3]); } +/*! + * @brief clamp vector's individual members between min and max values + * + * @param[in, out] v vector + * @param[in] minVal minimum value + * @param[in] maxVal maximum value + */ +CGLM_INLINE +void +glm_vec4_clamp(vec4 v, float minVal, float maxVal) { + v[0] = glm_clamp(v[0], minVal, maxVal); + v[1] = glm_clamp(v[1], minVal, maxVal); + v[2] = glm_clamp(v[2], minVal, maxVal); + v[3] = glm_clamp(v[3], minVal, maxVal); +} + #endif /* cglm_vec4_h */ From 48b7b30e4261d03d385aa263022bf756908d47ad Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 22 Mar 2018 21:18:08 +0300 Subject: [PATCH 04/21] add call version for clamp --- include/cglm/call/vec3.h | 4 ++++ include/cglm/call/vec4.h | 4 ++++ include/cglm/vec3.h | 1 + include/cglm/vec4.h | 1 + src/vec3.c | 6 ++++++ src/vec4.c | 6 ++++++ 6 files changed, 22 insertions(+) diff --git a/include/cglm/call/vec3.h b/include/cglm/call/vec3.h index a637d7e..461de0b 100644 --- a/include/cglm/call/vec3.h +++ b/include/cglm/call/vec3.h @@ -104,6 +104,10 @@ CGLM_EXPORT void glmc_vec_minv(vec3 v1, vec3 v2, vec3 dest); +CGLM_EXPORT +void +glmc_vec_clamp(vec3 v, float minVal, float maxVal); + #ifdef __cplusplus } #endif diff --git a/include/cglm/call/vec4.h b/include/cglm/call/vec4.h index 084fce2..b63af80 100644 --- a/include/cglm/call/vec4.h +++ b/include/cglm/call/vec4.h @@ -85,6 +85,10 @@ CGLM_EXPORT void glmc_vec4_minv(vec4 v1, vec4 v2, vec4 dest); +CGLM_EXPORT +void +glmc_vec4_clamp(vec4 v, float minVal, float maxVal); + #ifdef __cplusplus } #endif diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index 82c729a..e2108f3 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -46,6 +46,7 @@ CGLM_INLINE void glm_vec_maxv(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_minv(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_ortho(vec3 v, vec3 dest); + CGLM_INLINE void glm_vec_clamp(vec3 v, float minVal, float maxVal); Convenient: CGLM_INLINE void glm_cross(vec3 a, vec3 b, vec3 d); diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index 0e6659e..95bab09 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -40,6 +40,7 @@ CGLM_INLINE float glm_vec4_distance(vec4 v1, vec4 v2); CGLM_INLINE void glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest); CGLM_INLINE void glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest); + CGLM_INLINE void glm_vec4_clamp(vec4 v, float minVal, float maxVal); */ #ifndef cglm_vec4_h diff --git a/src/vec3.c b/src/vec3.c index f377d88..ebc677d 100644 --- a/src/vec3.c +++ b/src/vec3.c @@ -139,3 +139,9 @@ void glmc_vec_minv(vec3 v1, vec3 v2, vec3 dest) { glm_vec_maxv(v1, v2, dest); } + +CGLM_EXPORT +void +glmc_vec_clamp(vec3 v, float minVal, float maxVal) { + glm_vec_clamp(v, minVal, maxVal); +} diff --git a/src/vec4.c b/src/vec4.c index 279652d..f5f6a06 100644 --- a/src/vec4.c +++ b/src/vec4.c @@ -109,3 +109,9 @@ void glmc_vec4_minv(vec4 v1, vec4 v2, vec4 dest) { glm_vec4_maxv(v1, v2, dest); } + +CGLM_EXPORT +void +glmc_vec4_clamp(vec4 v, float minVal, float maxVal) { + glm_vec4_clamp(v, minVal, maxVal); +} From 71b48b530ebd73a33a8f72cb92092db5b6caf9de Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 22 Mar 2018 21:24:26 +0300 Subject: [PATCH 05/21] add documentation for clamp --- docs/source/util.rst | 15 +++++++++++++++ docs/source/vec3.rst | 10 ++++++++++ docs/source/vec4.rst | 10 ++++++++++ 3 files changed, 35 insertions(+) diff --git a/docs/source/util.rst b/docs/source/util.rst index 048be70..43a9d49 100644 --- a/docs/source/util.rst +++ b/docs/source/util.rst @@ -18,6 +18,9 @@ Functions: #. :c:func:`glm_make_rad` #. :c:func:`glm_make_deg` #. :c:func:`glm_pow2` +#. :c:func:`glm_min` +#. :c:func:`glm_max` +#. :c:func:`glm_clamp` Functions documentation ~~~~~~~~~~~~~~~~~~~~~~~ @@ -91,3 +94,15 @@ Functions documentation Returns: maximum value + +.. c:function:: void glm_clamp(float val, float minVal, float maxVal) + + constrain a value to lie between two further values + + Parameters: + | *[in]* **val** input value + | *[in]* **minVal** minimum value + | *[in]* **maxVal** maximum value + + Returns: + clamped value diff --git a/docs/source/vec3.rst b/docs/source/vec3.rst index 2ae95f0..355178d 100644 --- a/docs/source/vec3.rst +++ b/docs/source/vec3.rst @@ -53,6 +53,7 @@ Functions: #. :c:func:`glm_vec_maxv` #. :c:func:`glm_vec_minv` #. :c:func:`glm_vec_ortho` +#. :c:func:`glm_vec_clamp` Functions documentation ~~~~~~~~~~~~~~~~~~~~~~~ @@ -271,3 +272,12 @@ Functions documentation Parameters: | *[in]* **mat** vector | *[out]* **dest** orthogonal/perpendicular vector + +.. c:function:: void glm_vec_clamp(vec3 v, float minVal, float maxVal) + + constrain a value to lie between two further values + + Parameters: + | *[in, out]* **v** vector + | *[in]* **minVal** minimum value + | *[in]* **maxVal** maximum value diff --git a/docs/source/vec4.rst b/docs/source/vec4.rst index 60be7fa..ac1b9c5 100644 --- a/docs/source/vec4.rst +++ b/docs/source/vec4.rst @@ -39,6 +39,7 @@ Functions: #. :c:func:`glm_vec4_distance` #. :c:func:`glm_vec4_maxv` #. :c:func:`glm_vec4_minv` +#. :c:func:`glm_vec4_clamp` Functions documentation ~~~~~~~~~~~~~~~~~~~~~~~ @@ -203,3 +204,12 @@ Functions documentation | *[in]* **v1** vector1 | *[in]* **v2** vector2 | *[out]* **dest** destination + +.. c:function:: void glm_vec4_clamp(vec4 v, float minVal, float maxVal) + + constrain a value to lie between two further values + + Parameters: + | *[in, out]* **v** vector + | *[in]* **minVal** minimum value + | *[in]* **maxVal** maximum value From 21ec45b2af4d664b62477235ec290f3b262764be Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 22 Mar 2018 21:24:41 +0300 Subject: [PATCH 06/21] add tests for clamp --- makefile.am | 3 ++- test/src/test_clamp.c | 30 ++++++++++++++++++++++++++++++ test/src/test_main.c | 5 ++++- test/src/test_tests.h | 3 +++ 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 test/src/test_clamp.c diff --git a/makefile.am b/makefile.am index f6d1471..0767008 100644 --- a/makefile.am +++ b/makefile.am @@ -104,7 +104,8 @@ test_tests_SOURCES=\ test/src/test_common.c \ test/src/test_main.c \ test/src/test_mat4.c \ - test/src/test_cam.c + test/src/test_cam.c \ + test/src/test_clamp.c all-local: sh ./post-build.sh diff --git a/test/src/test_clamp.c b/test/src/test_clamp.c new file mode 100644 index 0000000..ee98958 --- /dev/null +++ b/test/src/test_clamp.c @@ -0,0 +1,30 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "test_common.h" + +void +test_clamp(void **state) { + vec3 v3 = {15.07, 0.4, 17.3}; + vec4 v4 = {5.07, 2.3, 1.3, 1.4}; + + assert_true(glm_clamp(1.6f, 0.0f, 1.0f) == 1.0f); + assert_true(glm_clamp(-1.6f, 0.0f, 1.0f) == 0.0f); + assert_true(glm_clamp(0.6f, 0.0f, 1.0f) == 0.6f); + + glm_vec_clamp(v3, 0.0, 1.0); + glm_vec4_clamp(v4, 1.5, 3.0); + + assert_true(v3[0] == 1.0f); + assert_true(v3[1] == 0.4f); + assert_true(v3[2] == 1.0f); + + assert_true(v4[0] == 3.0f); + assert_true(v4[1] == 2.3f); + assert_true(v4[2] == 1.5f); + assert_true(v4[3] == 1.5f); +} diff --git a/test/src/test_main.c b/test/src/test_main.c index 5d59cfd..4de5184 100644 --- a/test/src/test_main.c +++ b/test/src/test_main.c @@ -14,7 +14,10 @@ main(int argc, const char * argv[]) { /* camera */ cmocka_unit_test(test_camera_lookat), - cmocka_unit_test(test_camera_decomp) + cmocka_unit_test(test_camera_decomp), + + /* vector */ + cmocka_unit_test(test_clamp) }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/test/src/test_tests.h b/test/src/test_tests.h index a4e5adb..fb9771e 100644 --- a/test/src/test_tests.h +++ b/test/src/test_tests.h @@ -16,4 +16,7 @@ test_camera_lookat(void **state); void test_camera_decomp(void **state); +void +test_clamp(void **state); + #endif /* test_tests_h */ From 205d13aa93484b83cca2b83e7b592f18a09ba890 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 26 Mar 2018 23:00:38 +0300 Subject: [PATCH 07/21] fix euler angles (extrinsic -> intrinsic) because cglm uses intrinsics for these rotations --- include/cglm/euler.h | 442 ++++++++++++++++++++++++------------------- 1 file changed, 243 insertions(+), 199 deletions(-) diff --git a/include/cglm/euler.h b/include/cglm/euler.h index 2289b04..66e0f77 100644 --- a/include/cglm/euler.h +++ b/include/cglm/euler.h @@ -5,6 +5,14 @@ * Full license can be found in the LICENSE file */ +/* + NOTE: + angles must be passed as [X-Angle, Y-Angle, Z-angle] order + For instance you don't pass angles as [Z-Angle, X-Angle, Y-angle] to + glm_euler_zxy funciton, All RELATED functions accept angles same order + which is [X, Y, Z]. + */ + /* Types: enum glm_euler_sq @@ -95,219 +103,255 @@ glm_euler_angles(mat4 m, vec3 dest) { } } + /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ex, Ey, Ez] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] + * @param[out] dest rotation matrix + */ +CGLM_INLINE +void +glm_euler_xyz(vec3 angles, mat4 dest) { + float cx, cy, cz, + sx, sy, sz, czsx, cxcz, sysz; + + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); + + czsx = cz * sx; + cxcz = cx * cz; + sysz = sy * sz; + + dest[0][0] = cy * cz; + dest[0][1] = czsx * sy + cx * sz; + dest[0][2] = -cxcz * sy + sx * sz; + dest[1][0] = -cy * sz; + dest[1][1] = cxcz - sx * sysz; + dest[1][2] = czsx + cx * sysz; + dest[2][0] = sy; + dest[2][1] = -cy * sx; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; +} + +/*! + * @brief build rotation matrix from euler angles + * + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void glm_euler(vec3 angles, mat4 dest) { - float cx, cy, cz, - sx, sy, sz; - - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); - - dest[0][0] = cy * cz; - dest[0][1] = cy * sz; - dest[0][2] =-sy; - dest[1][0] = cz * sx * sy - cx * sz; - dest[1][1] = cx * cz + sx * sy * sz; - dest[1][2] = cy * sx; - dest[2][0] = cx * cz * sy + sx * sz; - dest[2][1] =-cz * sx + cx * sy * sz; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + glm_euler_xyz(angles, dest); } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ez, Ey, Ex] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_zyx(vec3 angles, - mat4 dest) { +glm_euler_xzy(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, sxsy, cysx, cxsy, cxcy; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz; - dest[0][1] = cz * sx * sy + cx * sz; - dest[0][2] =-cx * cz * sy + sx * sz; - dest[1][0] =-cy * sz; - dest[1][1] = cx * cz - sx * sy * sz; - dest[1][2] = cz * sx + cx * sy * sz; - dest[2][0] = sy; - dest[2][1] =-cy * sx; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + sxsy = sx * sy; + cysx = cy * sx; + cxsy = cx * sy; + cxcy = cx * cy; + + dest[0][0] = cy * cz; + dest[0][1] = sxsy + cxcy * sz; + dest[0][2] = -cxsy + cysx * sz; + dest[1][0] = -sz; + dest[1][1] = cx * cz; + dest[1][2] = cz * sx; + dest[2][0] = cz * sy; + dest[2][1] = -cysx + cxsy * sz; + dest[2][2] = cxcy + sxsy * sz; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } + /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ez, Ex, Ey] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_zxy(vec3 angles, - mat4 dest) { +glm_euler_yxz(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, cycz, sysz, czsy, cysz; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz + sx * sy * sz; - dest[0][1] = cx * sz; - dest[0][2] =-cz * sy + cy * sx * sz; - dest[1][0] = cz * sx * sy - cy * sz; - dest[1][1] = cx * cz; - dest[1][2] = cy * cz * sx + sy * sz; - dest[2][0] = cx * sy; - dest[2][1] =-sx; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + cycz = cy * cz; + sysz = sy * sz; + czsy = cz * sy; + cysz = cy * sz; + + dest[0][0] = cycz + sx * sysz; + dest[0][1] = cx * sz; + dest[0][2] = -czsy + cysz * sx; + dest[1][0] = -cysz + czsy * sx; + dest[1][1] = cx * cz; + dest[1][2] = cycz * sx + sysz; + dest[2][0] = cx * sy; + dest[2][1] = -sx; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ex, Ez, Ey] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_xzy(vec3 angles, - mat4 dest) { +glm_euler_yzx(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, sxsy, cxcy, cysx, cxsy; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz; - dest[0][1] = sz; - dest[0][2] =-cz * sy; - dest[1][0] = sx * sy - cx * cy * sz; - dest[1][1] = cx * cz; - dest[1][2] = cy * sx + cx * sy * sz; - dest[2][0] = cx * sy + cy * sx * sz; - dest[2][1] =-cz * sx; - dest[2][2] = cx * cy - sx * sy * sz; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + sxsy = sx * sy; + cxcy = cx * cy; + cysx = cy * sx; + cxsy = cx * sy; + + dest[0][0] = cy * cz; + dest[0][1] = sz; + dest[0][2] = -cz * sy; + dest[1][0] = sxsy - cxcy * sz; + dest[1][1] = cx * cz; + dest[1][2] = cysx + cxsy * sz; + dest[2][0] = cxsy + cysx * sz; + dest[2][1] = -cz * sx; + dest[2][2] = cxcy - sxsy * sz; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ey, Ez, Ex] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_yzx(vec3 angles, - mat4 dest) { +glm_euler_zxy(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, cycz, sxsy, cysz; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz; - dest[0][1] = sx * sy + cx * cy * sz; - dest[0][2] =-cx * sy + cy * sx * sz; - dest[1][0] =-sz; - dest[1][1] = cx * cz; - dest[1][2] = cz * sx; - dest[2][0] = cz * sy; - dest[2][1] =-cy * sx + cx * sy * sz; - dest[2][2] = cx * cy + sx * sy * sz; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + cycz = cy * cz; + sxsy = sx * sy; + cysz = cy * sz; + + dest[0][0] = cycz - sxsy * sz; + dest[0][1] = cz * sxsy + cysz; + dest[0][2] = -cx * sy; + dest[1][0] = -cx * sz; + dest[1][1] = cx * cz; + dest[1][2] = sx; + dest[2][0] = cz * sy + cysz * sx; + dest[2][1] = -cycz * sx + sy * sz; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ey, Ex, Ez] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_yxz(vec3 angles, - mat4 dest) { +glm_euler_zyx(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, czsx, cxcz, sysz; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz - sx * sy * sz; - dest[0][1] = cz * sx * sy + cy * sz; - dest[0][2] =-cx * sy; - dest[1][0] =-cx * sz; - dest[1][1] = cx * cz; - dest[1][2] = sx; - dest[2][0] = cz * sy + cy * sx * sz; - dest[2][1] =-cy * cz * sx + sy * sz; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + czsx = cz * sx; + cxcz = cx * cz; + sysz = sy * sz; + + dest[0][0] = cy * cz; + dest[0][1] = cy * sz; + dest[0][2] = -sy; + dest[1][0] = czsx * sy - cx * sz; + dest[1][1] = cxcz + sx * sysz; + dest[1][2] = cy * sx; + dest[2][0] = cxcz * sy + sx * sz; + dest[2][1] = -czsx + cx * sysz; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector (ord parameter spceifies angles order) + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[in] ord euler order * @param[out] dest rotation matrix */ @@ -332,71 +376,71 @@ glm_euler_by_order(vec3 angles, glm_euler_sq ord, mat4 dest) { sysz = sy * sz; switch (ord) { - case GLM_EULER_XYZ: - dest[0][0] = cycz; - dest[0][1] = cysz; - dest[0][2] =-sy; - dest[1][0] = czsx * sy - cxsz; - dest[1][1] = cxcz + sx * sysz; - dest[1][2] = cysx; - dest[2][0] = cx * czsy + sx * sz; - dest[2][1] =-czsx + cx * sysz; - dest[2][2] = cxcy; - break; case GLM_EULER_XZY: - dest[0][0] = cycz; - dest[0][1] = sz; - dest[0][2] =-czsy; - dest[1][0] = sx * sy - cx * cysz; - dest[1][1] = cxcz; - dest[1][2] = cysx + cx * sysz; - dest[2][0] = cx * sy + cysx * sz; - dest[2][1] =-czsx; - dest[2][2] = cxcy - sx * sysz; + dest[0][0] = cycz; + dest[0][1] = sx * sy + cx * cysz; + dest[0][2] = -cx * sy + cysx * sz; + dest[1][0] = -sz; + dest[1][1] = cxcz; + dest[1][2] = czsx; + dest[2][0] = czsy; + dest[2][1] = -cysx + cx * sysz; + dest[2][2] = cxcy + sx * sysz; break; - case GLM_EULER_ZXY: - dest[0][0] = cycz + sx * sysz; - dest[0][1] = cxsz; - dest[0][2] =-czsy + cysx * sz; - dest[1][0] = czsx * sy - cysz; - dest[1][1] = cxcz; - dest[1][2] = cycz * sx + sysz; - dest[2][0] = cx * sy; - dest[2][1] =-sx; - dest[2][2] = cxcy; - break; - case GLM_EULER_ZYX: - dest[0][0] = cycz; - dest[0][1] = czsx * sy + cxsz; - dest[0][2] =-cx * czsy + sx * sz; - dest[1][0] =-cysz; - dest[1][1] = cxcz - sx * sysz; - dest[1][2] = czsx + cx * sysz; - dest[2][0] = sy; - dest[2][1] =-cysx; - dest[2][2] = cxcy; + case GLM_EULER_XYZ: + dest[0][0] = cycz; + dest[0][1] = czsx * sy + cxsz; + dest[0][2] = -cx * czsy + sx * sz; + dest[1][0] = -cysz; + dest[1][1] = cxcz - sx * sysz; + dest[1][2] = czsx + cx * sysz; + dest[2][0] = sy; + dest[2][1] = -cysx; + dest[2][2] = cxcy; break; case GLM_EULER_YXZ: - dest[0][0] = cycz - sx * sysz; - dest[0][1] = czsx * sy + cysz; - dest[0][2] =-cx * sy; - dest[1][0] =-cxsz; - dest[1][1] = cxcz; - dest[1][2] = sx; - dest[2][0] = czsy + cysx * sz; - dest[2][1] =-cycz * sx + sysz; - dest[2][2] = cxcy; + dest[0][0] = cycz + sx * sysz; + dest[0][1] = cxsz; + dest[0][2] = -czsy + cysx * sz; + dest[1][0] = czsx * sy - cysz; + dest[1][1] = cxcz; + dest[1][2] = cycz * sx + sysz; + dest[2][0] = cx * sy; + dest[2][1] = -sx; + dest[2][2] = cxcy; break; case GLM_EULER_YZX: - dest[0][0] = cycz; - dest[0][1] = sx * sy + cx * cysz; - dest[0][2] =-cx * sy + cysx * sz; - dest[1][0] =-sz; - dest[1][1] = cxcz; - dest[1][2] = czsx; - dest[2][0] = czsy; - dest[2][1] =-cysx + cx * sysz; - dest[2][2] = cxcy + sx * sysz; + dest[0][0] = cycz; + dest[0][1] = sz; + dest[0][2] = -czsy; + dest[1][0] = sx * sy - cx * cysz; + dest[1][1] = cxcz; + dest[1][2] = cysx + cx * sysz; + dest[2][0] = cx * sy + cysx * sz; + dest[2][1] = -czsx; + dest[2][2] = cxcy - sx * sysz; + break; + case GLM_EULER_ZXY: + dest[0][0] = cycz - sx * sysz; + dest[0][1] = czsx * sy + cysz; + dest[0][2] = -cx * sy; + dest[1][0] = -cxsz; + dest[1][1] = cxcz; + dest[1][2] = sx; + dest[2][0] = czsy + cysx * sz; + dest[2][1] = -cycz * sx + sysz; + dest[2][2] = cxcy; + break; + case GLM_EULER_ZYX: + dest[0][0] = cycz; + dest[0][1] = cysz; + dest[0][2] = -sy; + dest[1][0] = czsx * sy - cxsz; + dest[1][1] = cxcz + sx * sysz; + dest[1][2] = cysx; + dest[2][0] = cx * czsy + sx * sz; + dest[2][1] = -czsx + cx * sysz; + dest[2][2] = cxcy; break; } From c244b68e73e079dfa387437b683e596ee8db9cad Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Tue, 27 Mar 2018 11:22:05 +0300 Subject: [PATCH 08/21] build: improve build-deps --- build-deps.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build-deps.sh b/build-deps.sh index 23bb9e9..74b1cfa 100644 --- a/build-deps.sh +++ b/build-deps.sh @@ -16,14 +16,18 @@ cd $(dirname "$0") if [ "$(uname)" = "Darwin" ]; then libtoolBin=$(which glibtoolize) libtoolBinDir=$(dirname "${libtoolBin}") - ln -s $libtoolBin "${libtoolBinDir}/libtoolize" + + if [ ! -f "${libtoolBinDir}/libtoolize" ]; then + ln -s $libtoolBin "${libtoolBinDir}/libtoolize" + fi fi # general deps: gcc make autoconf automake libtool cmake # test - cmocka cd ./test/lib/cmocka -mkdir build +rm -rf build +mkdir -p build cd build cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug .. make -j8 From 429821179559511aff831e42677664bd1d71b45a Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Tue, 27 Mar 2018 12:14:12 +0300 Subject: [PATCH 09/21] euler: fix extracting XYZ angles --- include/cglm/call/euler.h | 4 +++ include/cglm/euler.h | 51 ++++++++++++++++++--------------------- src/euler.c | 6 +++++ 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/include/cglm/call/euler.h b/include/cglm/call/euler.h index 8cbea2b..9b85485 100644 --- a/include/cglm/call/euler.h +++ b/include/cglm/call/euler.h @@ -21,6 +21,10 @@ CGLM_EXPORT void glmc_euler(vec3 angles, mat4 dest); +CGLM_EXPORT +void +glmc_euler_xyz(vec3 angles, mat4 dest); + CGLM_EXPORT void glmc_euler_zyx(vec3 angles, mat4 dest); diff --git a/include/cglm/euler.h b/include/cglm/euler.h index 66e0f77..7417bde 100644 --- a/include/cglm/euler.h +++ b/include/cglm/euler.h @@ -69,38 +69,33 @@ glm_euler_order(int ord[3]) { CGLM_INLINE void glm_euler_angles(mat4 m, vec3 dest) { - if (m[0][2] < 1.0f) { - if (m[0][2] > -1.0f) { - vec3 a[2]; - float cy1, cy2; - int path; + float m00, m01, m10, m11, m20, m21, m22; + float thetaX, thetaY, thetaZ; - a[0][1] = asinf(-m[0][2]); - a[1][1] = CGLM_PI - a[0][1]; + m00 = m[0][0]; m10 = m[1][0]; m20 = m[2][0]; + m01 = m[0][1]; m11 = m[1][1]; m21 = m[2][1]; + m22 = m[2][2]; - cy1 = cosf(a[0][1]); - cy2 = cosf(a[1][1]); - - a[0][0] = atan2f(m[1][2] / cy1, m[2][2] / cy1); - a[1][0] = atan2f(m[1][2] / cy2, m[2][2] / cy2); - - a[0][2] = atan2f(m[0][1] / cy1, m[0][0] / cy1); - a[1][2] = atan2f(m[0][1] / cy2, m[0][0] / cy2); - - path = (fabsf(a[0][0]) + fabsf(a[0][1]) + fabsf(a[0][2])) >= - (fabsf(a[1][0]) + fabsf(a[1][1]) + fabsf(a[1][2])); - - glm_vec_copy(a[path], dest); - } else { - dest[0] = atan2f(m[1][0], m[2][0]); - dest[1] = CGLM_PI_2; - dest[2] = 0.0f; + thetaY = 0.0f; + if (m20 < 1.0f) { + if (m20 > -1.0f) { + thetaY = asinf(m20); + thetaX = atan2f(-m21, m22); + thetaZ = atan2f(-m10, m00); + } else { /* m20 == -1 */ + /* Not a unique solution */ + thetaX = -atan2f(m01, m11); + thetaZ = 0.0f; } - } else { - dest[0] = atan2f(-m[1][0], -m[2][0]); - dest[1] =-CGLM_PI_2; - dest[2] = 0.0f; + } else {/* m20 == +1 */ + thetaY = CGLM_PI_2; + thetaX = atan2f(m01, m11); + thetaZ = 0.0f; } + + dest[0] = thetaX; + dest[1] = thetaY; + dest[2] = thetaZ; } diff --git a/src/euler.c b/src/euler.c index 5c945e2..44d6edb 100644 --- a/src/euler.c +++ b/src/euler.c @@ -20,6 +20,12 @@ glmc_euler(vec3 angles, mat4 dest) { glm_euler(angles, dest); } +CGLM_EXPORT +void +glmc_euler_xyz(vec3 angles, mat4 dest) { + glm_euler_xyz(angles, dest); +} + CGLM_EXPORT void glmc_euler_zyx(vec3 angles, mat4 dest) { From d1f3feeb6e2bbbf76a0524e098a6ca913665bd2f Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Tue, 27 Mar 2018 12:14:46 +0300 Subject: [PATCH 10/21] test: add tests for euler XYZ --- makefile.am | 3 ++- test/src/test_common.c | 7 +++++++ test/src/test_common.h | 3 +++ test/src/test_euler.c | 44 ++++++++++++++++++++++++++++++++++++++++++ test/src/test_main.c | 5 ++++- test/src/test_tests.h | 3 +++ 6 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 test/src/test_euler.c diff --git a/makefile.am b/makefile.am index 0767008..a81bdd5 100644 --- a/makefile.am +++ b/makefile.am @@ -105,7 +105,8 @@ test_tests_SOURCES=\ test/src/test_main.c \ test/src/test_mat4.c \ test/src/test_cam.c \ - test/src/test_clamp.c + test/src/test_clamp.c \ + test/src/test_euler.c all-local: sh ./post-build.sh diff --git a/test/src/test_common.c b/test/src/test_common.c index e6f36ab..23f2b50 100644 --- a/test/src/test_common.c +++ b/test/src/test_common.c @@ -50,3 +50,10 @@ test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps) { } } } + +void +test_assert_vec3_eq(vec3 v1, vec3 v2) { + assert_true(fabsf(v1[0] - v2[0]) <= 0.0000009); + assert_true(fabsf(v1[1] - v2[1]) <= 0.0000009); + assert_true(fabsf(v1[2] - v2[2]) <= 0.0000009); +} diff --git a/test/src/test_common.h b/test/src/test_common.h index 5fff3d7..aeea4d6 100644 --- a/test/src/test_common.h +++ b/test/src/test_common.h @@ -31,4 +31,7 @@ test_assert_mat4_eq(mat4 m1, mat4 m2); void test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps); +void +test_assert_vec3_eq(vec3 v1, vec3 v2); + #endif /* test_common_h */ diff --git a/test/src/test_euler.c b/test/src/test_euler.c new file mode 100644 index 0000000..b71c4cb --- /dev/null +++ b/test/src/test_euler.c @@ -0,0 +1,44 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "test_common.h" + +void +test_euler(void **state) { + mat4 rot1, rot2; + vec3 inAngles, outAngles; + + inAngles[0] = glm_rad(-45.0f); /* X angle */ + inAngles[1] = glm_rad(88.0f); /* Y angle */ + inAngles[2] = glm_rad(18.0f); /* Z angle */ + + glm_euler_xyz(inAngles, rot1); + + /* extract angles */ + glmc_euler_angles(rot1, outAngles); + + /* angles must be equal in that range */ + test_assert_vec3_eq(inAngles, outAngles); + + /* matrices must be equal */ + glmc_euler_xyz(outAngles, rot2); + test_assert_mat4_eq(rot1, rot2); + + /* change range */ + inAngles[0] = glm_rad(-145.0f); /* X angle */ + inAngles[1] = glm_rad(818.0f); /* Y angle */ + inAngles[2] = glm_rad(181.0f); /* Z angle */ + + glm_euler_xyz(inAngles, rot1); + glmc_euler_angles(rot1, outAngles); + + /* angles may not be equal but matrices MUST! */ + + /* matrices must be equal */ + glmc_euler_xyz(outAngles, rot2); + test_assert_mat4_eq(rot1, rot2); +} diff --git a/test/src/test_main.c b/test/src/test_main.c index 4de5184..38eb4c2 100644 --- a/test/src/test_main.c +++ b/test/src/test_main.c @@ -17,7 +17,10 @@ main(int argc, const char * argv[]) { cmocka_unit_test(test_camera_decomp), /* vector */ - cmocka_unit_test(test_clamp) + cmocka_unit_test(test_clamp), + + /* euler */ + cmocka_unit_test(test_euler) }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/test/src/test_tests.h b/test/src/test_tests.h index fb9771e..b1288f7 100644 --- a/test/src/test_tests.h +++ b/test/src/test_tests.h @@ -19,4 +19,7 @@ test_camera_decomp(void **state); void test_clamp(void **state); +void +test_euler(void **state); + #endif /* test_tests_h */ From 26110f83d112357d1e900edfbe17f9e0eacd283e Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Tue, 27 Mar 2018 12:35:19 +0300 Subject: [PATCH 11/21] euler: fix thetaY in extracting angles --- include/cglm/euler.h | 5 ++--- test/src/test_main.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/include/cglm/euler.h b/include/cglm/euler.h index 7417bde..5db7e66 100644 --- a/include/cglm/euler.h +++ b/include/cglm/euler.h @@ -76,7 +76,6 @@ glm_euler_angles(mat4 m, vec3 dest) { m01 = m[0][1]; m11 = m[1][1]; m21 = m[2][1]; m22 = m[2][2]; - thetaY = 0.0f; if (m20 < 1.0f) { if (m20 > -1.0f) { thetaY = asinf(m20); @@ -84,10 +83,11 @@ glm_euler_angles(mat4 m, vec3 dest) { thetaZ = atan2f(-m10, m00); } else { /* m20 == -1 */ /* Not a unique solution */ + thetaY = -CGLM_PI_2; thetaX = -atan2f(m01, m11); thetaZ = 0.0f; } - } else {/* m20 == +1 */ + } else { /* m20 == +1 */ thetaY = CGLM_PI_2; thetaX = atan2f(m01, m11); thetaZ = 0.0f; @@ -98,7 +98,6 @@ glm_euler_angles(mat4 m, vec3 dest) { dest[2] = thetaZ; } - /*! * @brief build rotation matrix from euler angles * diff --git a/test/src/test_main.c b/test/src/test_main.c index 38eb4c2..38d2fe4 100644 --- a/test/src/test_main.c +++ b/test/src/test_main.c @@ -20,7 +20,7 @@ main(int argc, const char * argv[]) { cmocka_unit_test(test_clamp), /* euler */ - cmocka_unit_test(test_euler) + cmocka_unit_test(test_euler) }; return cmocka_run_group_tests(tests, NULL, NULL); From 5a7b9caf166a1606965763d0d7ed0213fba414d9 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 29 Mar 2018 00:02:37 +0300 Subject: [PATCH 12/21] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e10597f..6d047e8 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Complete documentation: http://cglm.readthedocs.io - _dup (duplicate) is changed to _copy. For instance `glm_vec_dup -> glm_vec_copy` - OpenGL related functions are dropped to make this lib platform/third-party independent - make sure you have latest version and feel free to report bugs, troubles +- **[bugfix]** euler angles was implemented in reverse order (extrinsic) it was fixed, now they are intrinsic. Make sure that you have the latest version #### Note for C++ developers: If you don't aware about original GLM library yet, you may also want to look at: From ca504f70583d2e890dcc6d4e1d1368ab30898119 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 29 Mar 2018 00:12:16 +0300 Subject: [PATCH 13/21] now working on v0.3.6 --- configure.ac | 2 +- include/cglm/version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 23e8a15..afb694b 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ #***************************************************************************** AC_PREREQ([2.69]) -AC_INIT([cglm], [0.3.5], [info@recp.me]) +AC_INIT([cglm], [0.3.6], [info@recp.me]) AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/include/cglm/version.h b/include/cglm/version.h index a025ccb..c27a26e 100644 --- a/include/cglm/version.h +++ b/include/cglm/version.h @@ -10,6 +10,6 @@ #define CGLM_VERSION_MAJOR 0 #define CGLM_VERSION_MINOR 3 -#define CGLM_VERSION_PATCH 5 +#define CGLM_VERSION_PATCH 6 #endif /* cglm_version_h */ From db4761b4371c4c7175aaba201be78c9df656b49b Mon Sep 17 00:00:00 2001 From: Jess Date: Sun, 1 Apr 2018 18:12:46 +0900 Subject: [PATCH 14/21] Added backers and sponsors on the README --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d047e8..4e7c4ef 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,11 @@ # 🎥 OpenGL Mathematics (glm) for `C` [![Build Status](https://travis-ci.org/recp/cglm.svg?branch=master)](https://travis-ci.org/recp/cglm) -[![Build status](https://ci.appveyor.com/api/projects/status/av7l3gc0yhfex8y4/branch/master?svg=true)](https://ci.appveyor.com/project/recp/cglm/branch/master) + [![Build status](https://ci.appveyor.com/api/projects/status/av7l3gc0yhfex8y4/branch/master?svg=true)](https://ci.appveyor.com/project/recp/cglm/branch/master) [![Documentation Status](https://readthedocs.org/projects/cglm/badge/?version=latest)](http://cglm.readthedocs.io/en/latest/?badge=latest) [![Coverage Status](https://coveralls.io/repos/github/recp/cglm/badge.svg?branch=master)](https://coveralls.io/github/recp/cglm?branch=master) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/6a62b37d5f214f178ebef269dc4a6bf1)](https://www.codacy.com/app/recp/cglm?utm_source=github.com&utm_medium=referral&utm_content=recp/cglm&utm_campaign=Badge_Grade) +[![Backers on Open Collective](https://opencollective.com/cglm/backers/badge.svg)](#backers) +[![Sponsors on Open Collective](https://opencollective.com/cglm/sponsors/badge.svg)](#sponsors) The original glm library is for C++ only (templates, namespaces, classes...), this library targeted to C99 but currently you can use it for C89 safely by language extensions e.g `__restrict` @@ -115,6 +117,36 @@ glm_mul(T, R, modelMat); glm_inv_tr(modelMat); ``` +## Contributors + +This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. + + + +## Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/cglm#backer)] + + + + +## Sponsors + +Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/cglm#sponsor)] + + + + + + + + + + + + + + ## License MIT. check the LICENSE file From 984916d52065c3f4f3e262ed3ed3966892ff182c Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 2 Apr 2018 11:50:53 +0300 Subject: [PATCH 15/21] invalidate axis-aligned boundng box util --- include/cglm/box.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/cglm/box.h b/include/cglm/box.h index d7184c5..c8115a6 100644 --- a/include/cglm/box.h +++ b/include/cglm/box.h @@ -153,4 +153,16 @@ glm_aabb_frustum(vec3 box[2], vec4 planes[6]) { return true; } +/*! + * @brief invalidate AABB min and max values + * + * @param[in, out] box bounding box + */ +CGLM_INLINE +void +glm_aabb_invalidate(vec3 box[2]) { + glm_vec_broadcast(FLT_MAX, box[0]); + glm_vec_broadcast(-FLT_MAX, box[1]); +} + #endif /* cglm_box_h */ From b0991342a65ce15f7e67e667ec2214837b64509a Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 2 Apr 2018 12:08:08 +0300 Subject: [PATCH 16/21] aabb printer function --- include/cglm/io.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/cglm/io.h b/include/cglm/io.h index 2ee8ee8..f38fad7 100644 --- a/include/cglm/io.h +++ b/include/cglm/io.h @@ -171,4 +171,33 @@ glm_versor_print(versor vec, #undef m } +CGLM_INLINE +void +glm_aabb_print(vec3 bbox[2], + const char * __restrict tag, + FILE * __restrict ostream) { + int i, j; + +#define m 3 + + fprintf(ostream, "AABB (%s):\n", tag ? tag: "float"); + + for (i = 0; i < 2; i++) { + fprintf(ostream, "\t|"); + + for (j = 0; j < m; j++) { + fprintf(ostream, "%0.4f", bbox[i][j]); + + if (j != m - 1) + fprintf(ostream, "\t"); + } + + fprintf(ostream, "|\n"); + } + + fprintf(ostream, "\n"); + +#undef m +} + #endif /* cglm_io_h */ From 86efe64b8ee3093f111b706ca17fba3a09e8a419 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 2 Apr 2018 12:35:22 +0300 Subject: [PATCH 17/21] helper for check aabb is valid or not --- include/cglm/box.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/cglm/box.h b/include/cglm/box.h index c8115a6..89ef5a9 100644 --- a/include/cglm/box.h +++ b/include/cglm/box.h @@ -165,4 +165,16 @@ glm_aabb_invalidate(vec3 box[2]) { glm_vec_broadcast(-FLT_MAX, box[1]); } +/*! + * @brief check if AABB is valid or not + * + * @param[in] box bounding box + */ +CGLM_INLINE +bool +glm_aabb_isvalid(vec3 box[2]) { + return glm_vec_max(box[0]) != FLT_MAX + && glm_vec_min(box[1]) != -FLT_MAX; +} + #endif /* cglm_box_h */ From acda316c12f36991f9044ed94ee70c59d23efa7c Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 2 Apr 2018 16:18:50 +0300 Subject: [PATCH 18/21] get sign of float helper as -1, +1 and 0 * add clarification for zero input --- docs/source/util.rst | 17 ++++++++++++++++- include/cglm/util.h | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/source/util.rst b/docs/source/util.rst index 43a9d49..a9f4066 100644 --- a/docs/source/util.rst +++ b/docs/source/util.rst @@ -13,6 +13,7 @@ Table of contents (click to go): Functions: 1. :c:func:`glm_sign` +#. :c:func:`glm_signf` #. :c:func:`glm_rad` #. :c:func:`glm_deg` #. :c:func:`glm_make_rad` @@ -27,7 +28,9 @@ Functions documentation .. c:function:: int glm_sign(int val) - | returns sign of 32 bit integer as +1 or -1 + | returns sign of 32 bit integer as +1, -1, 0 + + | **Important**: It returns 0 for zero input Parameters: | *[in]* **val** an integer @@ -35,6 +38,18 @@ Functions documentation Returns: sign of given number +.. c:function:: float glm_signf(float val) + + | returns sign of 32 bit integer as +1.0, -1.0, 0.0 + + | **Important**: It returns 0.0f for zero input + + Parameters: + | *[in]* **val** a float + + Returns: + sign of given number + .. c:function:: float glm_rad(float deg) | convert degree to radians diff --git a/include/cglm/util.h b/include/cglm/util.h index 20b4c67..2a9ece7 100644 --- a/include/cglm/util.h +++ b/include/cglm/util.h @@ -21,7 +21,9 @@ #include "common.h" /*! - * @brief get sign of 32 bit integer as +1 or -1 + * @brief get sign of 32 bit integer as +1, -1, 0 + * + * Important: It returns 0 for zero input * * @param val integer value */ @@ -31,6 +33,19 @@ glm_sign(int val) { return ((val >> 31) - (-val >> 31)); } +/*! + * @brief get sign of 32 bit float as +1, -1, 0 + * + * Important: It returns 0 for zero/NaN input + * + * @param val float value + */ +CGLM_INLINE +float +glm_signf(float val) { + return (val > 0.0f) - (val < 0.0f); +} + /*! * @brief convert degree to radians * From dbd1e334ea3bfa9c15afe002990605b3656dffe0 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 2 Apr 2018 16:26:14 +0300 Subject: [PATCH 19/21] aabb box size and radius --- include/cglm/box.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/include/cglm/box.h b/include/cglm/box.h index 89ef5a9..7032339 100644 --- a/include/cglm/box.h +++ b/include/cglm/box.h @@ -177,4 +177,26 @@ glm_aabb_isvalid(vec3 box[2]) { && glm_vec_min(box[1]) != -FLT_MAX; } +/*! + * @brief distance between of min and max + * + * @param[in] box bounding box + */ +CGLM_INLINE +float +glm_aabb_size(vec3 box[2]) { + return glm_vec_distance(box[0], box[1]); +} + +/*! + * @brief radius of sphere which surrounds AABB + * + * @param[in] box bounding box + */ +CGLM_INLINE +float +glm_aabb_radius(vec3 box[2]) { + return glm_aabb_size(box) * 0.5f; +} + #endif /* cglm_box_h */ From 74f9865884ef17fc2dd72482a42aa2204ab9d4e3 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 2 Apr 2018 16:36:55 +0300 Subject: [PATCH 20/21] add docs for new aabb functions --- docs/source/box.rst | 40 ++++++++++++++++++++++++++++++++++++++++ docs/source/io.rst | 10 ++++++++++ 2 files changed, 50 insertions(+) diff --git a/docs/source/box.rst b/docs/source/box.rst index 84ba145..e6082e8 100644 --- a/docs/source/box.rst +++ b/docs/source/box.rst @@ -24,6 +24,10 @@ Functions: #. :c:func:`glm_aabb_crop` #. :c:func:`glm_aabb_crop_until` #. :c:func:`glm_aabb_frustum` +#. :c:func:`glm_aabb_invalidate` +#. :c:func:`glm_aabb_isvalid` +#. :c:func:`glm_aabb_size` +#. :c:func:`glm_aabb_radius` Functions documentation ~~~~~~~~~~~~~~~~~~~~~~~ @@ -91,3 +95,39 @@ Functions documentation Parameters: | *[in]* **box** bounding box | *[out]* **planes** frustum planes + +.. c:function:: void glm_aabb_invalidate(vec3 box[2]) + + | invalidate AABB min and max values + + | It fills *max* values with -FLT_MAX and *min* values with +FLT_MAX + + Parameters: + | *[in, out]* **box** bounding box + +.. c:function:: bool check if AABB is valid or not + + | check if AABB intersects with frustum planes + + Parameters: + | *[in]* **box** bounding box + + Returns: + returns true if aabb is valid otherwise false + +.. c:function:: float glm_aabb_size(vec3 box[2]) + + | distance between of min and max + + Parameters: + | *[in]* **box** bounding box + + Returns: + distance between min - max + +.. c:function:: float glm_aabb_radius(vec3 box[2]) + + | radius of sphere which surrounds AABB + + Parameters: + | *[in]* **box** bounding box diff --git a/docs/source/io.rst b/docs/source/io.rst index 9cf8900..34fe696 100644 --- a/docs/source/io.rst +++ b/docs/source/io.rst @@ -39,6 +39,7 @@ Functions: #. :c:func:`glm_vec3_print` #. :c:func:`glm_ivec3_print` #. :c:func:`glm_versor_print` +#. :c:func:`glm_aabb_print` Functions documentation ~~~~~~~~~~~~~~~~~~~~~~~ @@ -90,3 +91,12 @@ Functions documentation Parameters: | *[in]* **vec** quaternion | *[in]* **ostream** FILE to write + +.. c:function:: void glm_aabb_print(versor vec, const char * __restrict tag, FILE * __restrict ostream) + + | print aabb to given stream + + Parameters: + | *[in]* **vec** aabb (axis-aligned bounding box) + | *[in]* **tag** tag to find it more easly in logs + | *[in]* **ostream** FILE to write From c298f4a4d761e8e7fc51715eaca07d8010886d25 Mon Sep 17 00:00:00 2001 From: Matt Reyer Date: Mon, 2 Apr 2018 11:33:58 -0400 Subject: [PATCH 21/21] Fix small typo. --- docs/source/box.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/box.rst b/docs/source/box.rst index e6082e8..6aa4d62 100644 --- a/docs/source/box.rst +++ b/docs/source/box.rst @@ -105,9 +105,9 @@ Functions documentation Parameters: | *[in, out]* **box** bounding box -.. c:function:: bool check if AABB is valid or not +.. c:function:: bool glm_aabb_isvalid(vec3 box[2]) - | check if AABB intersects with frustum planes + | check if AABB is valid or not Parameters: | *[in]* **box** bounding box