From 0729fd40a4da4da44a37f82c5d6289f261ea237c Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sun, 31 Mar 2019 18:50:52 +0300 Subject: [PATCH 01/14] implement vec2 --- CREDITS | 4 + include/cglm/call/vec2.h | 13 + include/cglm/cglm.h | 1 + include/cglm/common.h | 1 + include/cglm/vec2-ext.h | 189 +++++++++++++++ include/cglm/vec2.h | 499 +++++++++++++++++++++++++++++++++++++++ test/src/test_common.c | 6 + test/src/test_common.h | 3 + test/src/test_main.c | 5 +- test/src/test_tests.h | 4 + test/src/test_vec2.c | 13 + win/cglm.vcxproj | 1 + win/cglm.vcxproj.filters | 5 +- 13 files changed, 742 insertions(+), 2 deletions(-) create mode 100644 include/cglm/call/vec2.h create mode 100644 include/cglm/vec2-ext.h create mode 100644 include/cglm/vec2.h create mode 100644 test/src/test_vec2.c diff --git a/CREDITS b/CREDITS index 7272ddc..a159edf 100644 --- a/CREDITS +++ b/CREDITS @@ -61,3 +61,7 @@ https://forums.khronos.org/showthread.php/10264-Animations-in-1-4-1-release-note https://forums.khronos.org/showthread.php/10644-Animation-Bezier-interpolation https://forums.khronos.org/showthread.php/10387-2D-Tangents-in-Bezier-Splines?p=34164&viewfull=1#post34164 https://forums.khronos.org/showthread.php/10651-Animation-TCB-Spline-Interpolation-in-COLLADA?highlight=bezier + +12. vec2 cross product +http://allenchou.net/2013/07/cross-product-of-2d-vectors/ + diff --git a/include/cglm/call/vec2.h b/include/cglm/call/vec2.h new file mode 100644 index 0000000..acf7f41 --- /dev/null +++ b/include/cglm/call/vec2.h @@ -0,0 +1,13 @@ +// +// vec2.h +// glm +// +// Created by Recep Aslantas on 3/31/19. +// Copyright © 2019 Recep Aslantas. All rights reserved. +// + +#ifndef vec2_h +#define vec2_h + + +#endif /* vec2_h */ diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index 7c301bf..f4c203f 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -9,6 +9,7 @@ #define cglm_h #include "common.h" +#include "vec2.h" #include "vec3.h" #include "vec4.h" #include "mat4.h" diff --git a/include/cglm/common.h b/include/cglm/common.h index 42d5e67..c7c5eb8 100644 --- a/include/cglm/common.h +++ b/include/cglm/common.h @@ -14,6 +14,7 @@ #include #include #include +#include #if defined(_MSC_VER) # ifdef CGLM_DLL diff --git a/include/cglm/vec2-ext.h b/include/cglm/vec2-ext.h new file mode 100644 index 0000000..0b05aa4 --- /dev/null +++ b/include/cglm/vec2-ext.h @@ -0,0 +1,189 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +/* + Functions: + CGLM_INLINE void glm_vec2_broadcast(float val, vec2 d); + CGLM_INLINE bool glm_vec2_eq(vec2 v, float val); + CGLM_INLINE bool glm_vec2_eq_eps(vec2 v, float val); + CGLM_INLINE bool glm_vec2_eq_all(vec2 v); + CGLM_INLINE bool glm_vec2_eqv(vec2 a, vec2 b); + CGLM_INLINE bool glm_vec2_eqv_eps(vec2 a, vec2 b); + CGLM_INLINE float glm_vec2_max(vec2 v); + CGLM_INLINE float glm_vec2_min(vec2 v); + CGLM_INLINE bool glm_vec2_isnan(vec2 v); + CGLM_INLINE bool glm_vec2_isinf(vec2 v); + CGLM_INLINE bool glm_vec2_isvalid(vec2 v); + CGLM_INLINE void glm_vec2_sign(vec2 v, vec2 dest); + CGLM_INLINE void glm_vec2_sqrt(vec2 v, vec2 dest); + */ + +#ifndef cglm_vec2_ext_h +#define cglm_vec2_ext_h + +#include "common.h" +#include "util.h" + +/*! + * @brief fill a vector with specified value + * + * @param[in] val value + * @param[out] d dest + */ +CGLM_INLINE +void +glm_vec2_broadcast(float val, vec2 d) { + d[0] = d[1] = val; +} + +/*! + * @brief check if vector is equal to value (without epsilon) + * + * @param[in] v vector + * @param[in] val value + */ +CGLM_INLINE +bool +glm_vec2_eq(vec2 v, float val) { + return v[0] == val && v[0] == v[1]; +} + +/*! + * @brief check if vector is equal to value (with epsilon) + * + * @param[in] v vector + * @param[in] val value + */ +CGLM_INLINE +bool +glm_vec2_eq_eps(vec2 v, float val) { + return fabsf(v[0] - val) <= FLT_EPSILON + && fabsf(v[1] - val) <= FLT_EPSILON; +} + +/*! + * @brief check if vectors members are equal (without epsilon) + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glm_vec2_eq_all(vec2 v) { + return v[0] == v[1]; +} + +/*! + * @brief check if vector is equal to another (without epsilon) + * + * @param[in] a vector + * @param[in] b vector + */ +CGLM_INLINE +bool +glm_vec2_eqv(vec2 a, vec2 b) { + return a[0] == b[0] && a[1] == b[1]; +} + +/*! + * @brief check if vector is equal to another (with epsilon) + * + * @param[in] a vector + * @param[in] b vector + */ +CGLM_INLINE +bool +glm_vec2_eqv_eps(vec2 a, vec2 b) { + return fabsf(a[0] - b[0]) <= FLT_EPSILON + && fabsf(a[1] - b[1]) <= FLT_EPSILON; +} + +/*! + * @brief max value of vector + * + * @param[in] v vector + */ +CGLM_INLINE +float +glm_vec2_max(vec2 v) { + return glm_max(v[0], v[1]); +} + +/*! + * @brief min value of vector + * + * @param[in] v vector + */ +CGLM_INLINE +float +glm_vec2_min(vec2 v) { + return glm_min(v[0], v[1]); +} + +/*! + * @brief check if all items are NaN (not a number) + * you should only use this in DEBUG mode or very critical asserts + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glm_vec2_isnan(vec2 v) { + return isnan(v[0]) || isnan(v[1]); +} + +/*! + * @brief check if all items are INFINITY + * you should only use this in DEBUG mode or very critical asserts + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glm_vec2_isinf(vec2 v) { + return isinf(v[0]) || isinf(v[1]); +} + +/*! + * @brief check if all items are valid number + * you should only use this in DEBUG mode or very critical asserts + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glm_vec2_isvalid(vec2 v) { + return !glm_vec2_isnan(v) && !glm_vec2_isinf(v); +} + +/*! + * @brief get sign of 32 bit float as +1, -1, 0 + * + * Important: It returns 0 for zero/NaN input + * + * @param v vector + */ +CGLM_INLINE +void +glm_vec2_sign(vec2 v, vec2 dest) { + dest[0] = glm_signf(v[0]); + dest[1] = glm_signf(v[1]); +} + +/*! + * @brief square root of each vector item + * + * @param[in] v vector + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_sqrt(vec2 v, vec2 dest) { + dest[0] = sqrtf(v[0]); + dest[1] = sqrtf(v[1]); +} + +#endif /* cglm_vec2_ext_h */ diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h new file mode 100644 index 0000000..9bf8749 --- /dev/null +++ b/include/cglm/vec2.h @@ -0,0 +1,499 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +/* + Macros: + GLM_VEC2_ONE_INIT + GLM_VEC2_ZERO_INIT + GLM_VEC2_ONE + GLM_VEC2_ZERO + + Functions: + + */ + +#ifndef cglm_vec2_h +#define cglm_vec2_h + +#include "common.h" +#include "util.h" +#include "vec2-ext.h" + +#define GLM_VEC2_ONE_INIT {1.0f, 1.0f} +#define GLM_VEC2_ZERO_INIT {0.0f, 0.0f} + +#define GLM_VEC2_ONE ((vec2)GLM_VEC2_ONE_INIT) +#define GLM_VEC2_ZERO ((vec2)GLM_VEC2_ZERO_INIT) + +/*! + * @brief init vec2 using another vector + * + * @param[in] v a vector + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2(float * __restrict v, vec2 dest) { + dest[0] = v[0]; + dest[1] = v[1]; +} + +/*! + * @brief copy all members of [a] to [dest] + * + * @param[in] a source + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_copy(vec2 a, vec2 dest) { + dest[0] = a[0]; + dest[1] = a[1]; +} + +/*! + * @brief make vector zero + * + * @param[in, out] v vector + */ +CGLM_INLINE +void +glm_vec2_zero(vec2 v) { + v[0] = v[1] = 0.0f; +} + +/*! + * @brief make vector one + * + * @param[in, out] v vector + */ +CGLM_INLINE +void +glm_vec2_one(vec2 v) { + v[0] = v[1] = 1.0f; +} + +/*! + * @brief vec2 dot product + * + * @param[in] a vector1 + * @param[in] b vector2 + * + * @return dot product + */ +CGLM_INLINE +float +glm_vec2_dot(vec2 a, vec2 b) { + return a[0] * b[0] + a[1] * b[1]; +} + +/*! + * @brief vec2 cross product + * + * REF: http://allenchou.net/2013/07/cross-product-of-2d-vectors/ + * + * @param[in] a vector1 + * @param[in] b vector2 + * + * @return Z component of cross product + */ +CGLM_INLINE +float +glm_vec2_cross(vec2 a, vec2 b) { + /* just calculate the z-component */ + return a[0] * b[1] - a[1] * b[0]; +} + +/*! + * @brief norm * norm (magnitude) of vec + * + * we can use this func instead of calling norm * norm, because it would call + * sqrtf fuction twice but with this func we can avoid func call, maybe this is + * not good name for this func + * + * @param[in] v vector + * + * @return norm * norm + */ +CGLM_INLINE +float +glm_vec2_norm2(vec2 v) { + return glm_vec2_dot(v, v); +} + +/*! + * @brief norm (magnitude) of vec2 + * + * @param[in] vec vector + * + * @return norm + */ +CGLM_INLINE +float +glm_vec2_norm(vec2 vec) { + return sqrtf(glm_vec2_norm2(vec)); +} + +/*! + * @brief add a vector to b vector store result in dest + * + * @param[in] a vector1 + * @param[in] b vector2 + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_add(vec2 a, vec2 b, vec2 dest) { + dest[0] = a[0] + b[0]; + dest[1] = a[1] + b[1]; +} + +/*! + * @brief add scalar to v vector store result in dest (d = v + s) + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_adds(vec2 v, float s, vec2 dest) { + dest[0] = v[0] + s; + dest[1] = v[1] + s; +} + +/*! + * @brief subtract b vector from a vector store result in dest + * + * @param[in] a vector1 + * @param[in] b vector2 + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_sub(vec2 a, vec2 b, vec2 dest) { + dest[0] = a[0] - b[0]; + dest[1] = a[1] - b[1]; +} + +/*! + * @brief subtract scalar from v vector store result in dest (d = v - s) + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_subs(vec2 v, float s, vec2 dest) { + dest[0] = v[0] - s; + dest[1] = v[1] - s; +} + +/*! + * @brief multiply two vector (component-wise multiplication) + * + * @param a v1 + * @param b v2 + * @param d v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2]) + */ +CGLM_INLINE +void +glm_vec2_mul(vec2 a, vec2 b, vec2 d) { + d[0] = a[0] * b[0]; + d[1] = a[1] * b[1]; +} + +/*! + * @brief multiply/scale vector with scalar: result = v * s + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_scale(vec2 v, float s, vec2 dest) { + dest[0] = v[0] * s; + dest[1] = v[1] * s; +} + +/*! + * @brief scale as vector specified: result = unit(v) * s + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_scale_as(vec2 v, float s, vec2 dest) { + float norm; + norm = glm_vec2_norm(v); + + if (norm == 0.0f) { + glm_vec2_zero(dest); + return; + } + + glm_vec2_scale(v, s / norm, dest); +} + +/*! + * @brief div vector with another component-wise division: d = a / b + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest result = (a[0]/b[0], a[1]/b[1], a[2]/b[2]) + */ +CGLM_INLINE +void +glm_vec2_div(vec2 a, vec2 b, vec2 dest) { + dest[0] = a[0] / b[0]; + dest[1] = a[1] / b[1]; +} + +/*! + * @brief div vector with scalar: d = v / s + * + * @param[in] v vector + * @param[in] s scalar + * @param[out] dest result = (a[0]/s, a[1]/s, a[2]/s) + */ +CGLM_INLINE +void +glm_vec2_divs(vec2 v, float s, vec2 dest) { + dest[0] = v[0] / s; + dest[1] = v[1] / s; +} + +/*! + * @brief add two vectors and add result to sum + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a + b) + */ +CGLM_INLINE +void +glm_vec2_addadd(vec2 a, vec2 b, vec2 dest) { + dest[0] += a[0] + b[0]; + dest[1] += a[1] + b[1]; +} + +/*! + * @brief sub two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a + b) + */ +CGLM_INLINE +void +glm_vec2_subadd(vec2 a, vec2 b, vec2 dest) { + dest[0] += a[0] - b[0]; + dest[1] += a[1] - b[1]; +} + +/*! + * @brief mul two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += (a * b) + */ +CGLM_INLINE +void +glm_vec2_muladd(vec2 a, vec2 b, vec2 dest) { + dest[0] += a[0] * b[0]; + dest[1] += a[1] * b[1]; +} + +/*! + * @brief mul vector with scalar and add result to sum + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector + * @param[in] s scalar + * @param[out] dest dest += (a * b) + */ +CGLM_INLINE +void +glm_vec2_muladds(vec2 a, float s, vec2 dest) { + dest[0] += a[0] * s; + dest[1] += a[1] * s; +} + +/*! + * @brief add max of two vector to result/dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += max(a, b) + */ +CGLM_INLINE +void +glm_vec2_maxadd(vec2 a, vec2 b, vec2 dest) { + dest[0] += glm_max(a[0], b[0]); + dest[1] += glm_max(a[1], b[1]); +} + +/*! + * @brief add min of two vector to result/dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @param[out] dest dest += min(a, b) + */ +CGLM_INLINE +void +glm_vec2_minadd(vec2 a, vec2 b, vec2 dest) { + dest[0] += glm_min(a[0], b[0]); + dest[1] += glm_min(a[1], b[1]); +} + +/*! + * @brief negate vector components and store result in dest + * + * @param[in] v vector + * @param[out] dest result vector + */ +CGLM_INLINE +void +glm_vec2_negate_to(vec2 v, vec2 dest) { + dest[0] = -v[0]; + dest[1] = -v[1]; +} + +/*! + * @brief negate vector components + * + * @param[in, out] v vector + */ +CGLM_INLINE +void +glm_vec2_negate(vec2 v) { + glm_vec2_negate_to(v, v); +} + +/*! + * @brief normalize vector and store result in same vec + * + * @param[in, out] v vector + */ +CGLM_INLINE +void +glm_vec2_normalize(vec2 v) { + float norm; + + norm = glm_vec2_norm(v); + + if (norm == 0.0f) { + v[0] = v[1] = v[2] = 0.0f; + return; + } + + glm_vec2_scale(v, 1.0f / norm, v); +} + +/*! + * @brief normalize vector to dest + * + * @param[in] vec source + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_normalize_to(vec2 vec, vec2 dest) { + float norm; + + norm = glm_vec2_norm(vec); + + if (norm == 0.0f) { + glm_vec2_zero(dest); + return; + } + + glm_vec2_scale(vec, 1.0f / norm, dest); +} + +/*! + * @brief max values of vectors + * + * @param[in] v1 vector1 + * @param[in] v2 vector2 + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_maxv(vec2 v1, vec2 v2, vec2 dest) { + dest[0] = glm_max(v1[0], v2[0]); + dest[1] = glm_max(v1[1], v2[1]); +} + +/*! + * @brief min values of vectors + * + * @param[in] v1 vector1 + * @param[in] v2 vector2 + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_minv(vec2 v1, vec2 v2, vec2 dest) { + dest[0] = glm_min(v1[0], v2[0]); + dest[1] = glm_min(v1[1], v2[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_vec2_clamp(vec2 v, float minVal, float maxVal) { + v[0] = glm_clamp(v[0], minVal, maxVal); + v[1] = glm_clamp(v[1], minVal, maxVal); +} + +/*! + * @brief linear interpolation between two vector + * + * formula: from + s * (to - from) + * + * @param[in] from from value + * @param[in] to to value + * @param[in] t interpolant (amount) clamped between 0 and 1 + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) { + vec2 s, v; + + /* from + s * (to - from) */ + glm_vec2_broadcast(glm_clamp_zo(t), s); + glm_vec2_sub(to, from, v); + glm_vec2_mul(s, v, v); + glm_vec2_add(from, v, dest); +} + +#endif /* cglm_vec2_h */ diff --git a/test/src/test_common.c b/test/src/test_common.c index d41d3cb..3b78569 100644 --- a/test/src/test_common.c +++ b/test/src/test_common.c @@ -112,6 +112,12 @@ test_assert_eqf(float a, float b) { assert_true(fabsf(a - b) <= 0.000009); /* rounding errors */ } +void +test_assert_vec2_eq(vec2 v1, vec2 v2) { + assert_true(fabsf(v1[0] - v2[0]) <= 0.000009); /* rounding errors */ + assert_true(fabsf(v1[1] - v2[1]) <= 0.000009); +} + void test_assert_vec3_eq(vec3 v1, vec3 v2) { assert_true(fabsf(v1[0] - v2[0]) <= 0.000009); /* rounding errors */ diff --git a/test/src/test_common.h b/test/src/test_common.h index 8a16b0f..09c9891 100644 --- a/test/src/test_common.h +++ b/test/src/test_common.h @@ -40,6 +40,9 @@ test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps); void test_assert_mat3_eq(mat3 m1, mat3 m2); +void +test_assert_vec2_eq(vec2 v1, vec2 v2); + void test_assert_vec3_eq(vec3 v1, vec3 v2); diff --git a/test/src/test_main.c b/test/src/test_main.c index 8ce1673..3bdfebb 100644 --- a/test/src/test_main.c +++ b/test/src/test_main.c @@ -41,7 +41,10 @@ main(int argc, const char * argv[]) { cmocka_unit_test(test_affine), /* bezier */ - cmocka_unit_test(test_bezier) + cmocka_unit_test(test_bezier), + + /* vec2 */ + cmocka_unit_test(test_vec2) }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/test/src/test_tests.h b/test/src/test_tests.h index 618cc9f..cf69346 100644 --- a/test/src/test_tests.h +++ b/test/src/test_tests.h @@ -43,4 +43,8 @@ test_affine(void **state); void test_bezier(void **state); +/* vec2 */ +void +test_vec2(void **state); + #endif /* test_tests_h */ diff --git a/test/src/test_vec2.c b/test/src/test_vec2.c new file mode 100644 index 0000000..26941e2 --- /dev/null +++ b/test/src/test_vec2.c @@ -0,0 +1,13 @@ +/* + * 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_vec2(void **state) { + +} diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj index 90e58a6..54cbfcf 100644 --- a/win/cglm.vcxproj +++ b/win/cglm.vcxproj @@ -88,6 +88,7 @@ + diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters index dd66ee1..0b57eea 100644 --- a/win/cglm.vcxproj.filters +++ b/win/cglm.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -257,5 +257,8 @@ include\cglm\call + + include\cglm + \ No newline at end of file From 047ed259ae798547f8821214adfdf21be96baeb0 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Tue, 4 Jun 2019 19:03:31 +0300 Subject: [PATCH 02/14] vec2: distance implementation --- include/cglm/call/vec2.h | 27 +++++++++++++++++---------- include/cglm/vec2.h | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/include/cglm/call/vec2.h b/include/cglm/call/vec2.h index acf7f41..de59437 100644 --- a/include/cglm/call/vec2.h +++ b/include/cglm/call/vec2.h @@ -1,13 +1,20 @@ -// -// vec2.h -// glm -// -// Created by Recep Aslantas on 3/31/19. -// Copyright © 2019 Recep Aslantas. All rights reserved. -// +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ -#ifndef vec2_h -#define vec2_h +#ifndef cglmc_vec2_h +#define cglmc_vec2_h +#ifdef __cplusplus +extern "C" { +#endif + +#include "../cglm.h" -#endif /* vec2_h */ +#ifdef __cplusplus +} +#endif +#endif /* cglmc_vec2_h */ diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h index 9bf8749..06817e4 100644 --- a/include/cglm/vec2.h +++ b/include/cglm/vec2.h @@ -432,6 +432,32 @@ glm_vec2_normalize_to(vec2 vec, vec2 dest) { glm_vec2_scale(vec, 1.0f / norm, dest); } +/** + * @brief squared distance between two vectors + * + * @param[in] a vector1 + * @param[in] b vector2 + * @return returns squared distance (distance * distance) + */ +CGLM_INLINE +float +glm_vec2_distance2(vec2 a, vec2 b) { + return glm_pow2(b[0] - a[0]) + glm_pow2(b[1] - a[1]); +} + +/** + * @brief distance between two vectors + * + * @param[in] a vector1 + * @param[in] b vector2 + * @return returns distance + */ +CGLM_INLINE +float +glm_vec2_distance(vec2 a, vec2 b) { + return sqrtf(glm_vec2_distance2(a, b)); +} + /*! * @brief max values of vectors * From ad823d96819a2549f854ab7538ac253a3ab4d0a4 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Wed, 19 Jun 2019 23:35:38 +0300 Subject: [PATCH 03/14] mat2: implement some mat2 func * also implement as SSE --- include/cglm/cglm.h | 1 + include/cglm/io.h | 30 +++++++ include/cglm/mat2.h | 163 ++++++++++++++++++++++++++++++++++ include/cglm/simd/sse2/mat2.h | 45 ++++++++++ include/cglm/types.h | 2 + 5 files changed, 241 insertions(+) create mode 100644 include/cglm/mat2.h create mode 100644 include/cglm/simd/sse2/mat2.h diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index f4c203f..cbd2952 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -14,6 +14,7 @@ #include "vec4.h" #include "mat4.h" #include "mat3.h" +#include "mat2.h" #include "affine.h" #include "cam.h" #include "frustum.h" diff --git a/include/cglm/io.h b/include/cglm/io.h index ac0bfeb..cdcb4fb 100644 --- a/include/cglm/io.h +++ b/include/cglm/io.h @@ -83,6 +83,36 @@ glm_mat3_print(mat3 matrix, #undef n } +CGLM_INLINE +void +glm_mat2_print(mat2 matrix, + FILE * __restrict ostream) { + int i; + int j; + +#define m 2 +#define n 2 + + fprintf(ostream, "Matrix (float%dx%d):\n", m, n); + + for (i = 0; i < m; i++) { + fprintf(ostream, "\t|"); + for (j = 0; j < n; j++) { + fprintf(ostream, "%0.4f", matrix[j][i]);; + + if (j != n - 1) + fprintf(ostream, "\t"); + } + + fprintf(ostream, "|\n"); + } + + fprintf(ostream, "\n"); + +#undef m +#undef n +} + CGLM_INLINE void glm_vec4_print(vec4 vec, diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h new file mode 100644 index 0000000..11001f4 --- /dev/null +++ b/include/cglm/mat2.h @@ -0,0 +1,163 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +/* + + */ + +#ifndef cglm_mat2_h +#define cglm_mat2_h + +#include "common.h" +#include "vec2.h" + +#ifdef CGLM_SSE_FP +# include "simd/sse2/mat2.h" +#endif + +#define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}} +#define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}} + + +/* for C only */ +#define GLM_MAT2_IDENTITY ((mat3)GLM_MAT2_IDENTITY_INIT) +#define GLM_MAT2_ZERO ((mat3)GLM_MAT2_ZERO_INIT) + +/*! + * @brief copy all members of [mat] to [dest] + * + * @param[in] mat source + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_mat2_copy(mat2 mat, mat2 dest) { + dest[0][0] = mat[0][0]; + dest[0][1] = mat[0][1]; + dest[1][0] = mat[1][0]; + dest[1][1] = mat[1][1]; +} + +/*! + * @brief make given matrix identity. It is identical with below, + * but it is more easy to do that with this func especially for members + * e.g. glm_mat2_identity(aStruct->aMatrix); + * + * @code + * glm_mat2_copy(GLM_MAT2_IDENTITY, mat); // C only + * + * // or + * mat2 mat = GLM_MAT2_IDENTITY_INIT; + * @endcode + * + * @param[in, out] mat destination + */ +CGLM_INLINE +void +glm_mat2_identity(mat2 mat) { + CGLM_ALIGN_MAT mat2 t = GLM_MAT2_IDENTITY_INIT; + glm_mat2_copy(t, mat); +} + +/*! + * @brief make given matrix array's each element identity matrix + * + * @param[in, out] mat matrix array (must be aligned (16/32) + * if alignment is not disabled) + * + * @param[in] count count of matrices + */ +CGLM_INLINE +void +glm_mat2_identity_array(mat2 * __restrict mat, size_t count) { + CGLM_ALIGN_MAT mat2 t = GLM_MAT2_IDENTITY_INIT; + size_t i; + + for (i = 0; i < count; i++) { + glm_mat2_copy(t, mat[i]); + } +} + +/*! + * @brief make given matrix zero. + * + * @param[in, out] mat matrix + */ +CGLM_INLINE +void +glm_mat2_zero(mat2 mat) { + CGLM_ALIGN_MAT mat2 t = GLM_MAT2_ZERO_INIT; + glm_mat2_copy(t, mat); +} + +/*! + * @brief multiply m1 and m2 to dest + * + * m1, m2 and dest matrices can be same matrix, it is possible to write this: + * + * @code + * mat3 m = GLM_MAT3_IDENTITY_INIT; + * glm_mat3_mul(m, m, m); + * @endcode + * + * @param[in] m1 left matrix + * @param[in] m2 right matrix + * @param[out] dest destination matrix + */ +CGLM_INLINE +void +glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) { +#if defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat2_mul_sse2(m1, m2, dest); +#else + float a00 = m1[0][0], a01 = m1[0][1], + a10 = m1[1][0], a11 = m1[1][1], + b00 = m2[0][0], b01 = m2[0][1], + b10 = m2[1][0], b11 = m2[1][1]; + + dest[0][0] = a00 * b00 + a10 * b01; + dest[0][1] = a01 * b00 + a11 * b01; + dest[1][0] = a00 * b10 + a10 * b11; + dest[1][1] = a01 * b10 + a11 * b11; +#endif +} + +/*! + * @brief transpose mat3 and store in dest + * + * source matrix will not be transposed unless dest is m + * + * @param[in] m matrix + * @param[out] dest result + */ +CGLM_INLINE +void +glm_mat2_transpose_to(mat2 m, mat2 dest) { +#if defined( __SSE__ ) || defined( __SSE2__ ) + glm_mat2_transp_sse2(m, dest); +#else + dest[0][0] = m[0][0]; + dest[0][1] = m[1][0]; + dest[1][0] = m[0][1]; + dest[1][1] = m[1][1]; +#endif +} + +/*! + * @brief tranpose mat3 and store result in same matrix + * + * @param[in, out] m source and dest + */ +CGLM_INLINE +void +glm_mat2_transpose(mat2 m) { + float tmp; + tmp = m[0][1]; + m[0][1] = m[1][0]; + m[1][0] = tmp; +} +#endif /* cglm_mat2_h */ diff --git a/include/cglm/simd/sse2/mat2.h b/include/cglm/simd/sse2/mat2.h new file mode 100644 index 0000000..b3b4d97 --- /dev/null +++ b/include/cglm/simd/sse2/mat2.h @@ -0,0 +1,45 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_mat2_sse_h +#define cglm_mat2_sse_h +#if defined( __SSE__ ) || defined( __SSE2__ ) + +#include "../../common.h" +#include "../intrin.h" + +CGLM_INLINE +void +glm_mat2_mul_sse2(mat2 m1, mat2 m2, mat2 dest) { + __m128 x0, x1, x2; + + x1 = glmm_load(m1[0]); /* d c b a */ + x2 = glmm_load(m2[0]); /* h g f e */ + + /* + dest[0][0] = a * e + c * f; + dest[0][1] = b * e + d * f; + dest[1][0] = a * g + c * h; + dest[1][1] = b * g + d * h; + */ + x0 = _mm_mul_ps(_mm_movelh_ps(x1, x1), glmm_shuff1(x2, 2, 2, 0, 0)); + x1 = _mm_mul_ps(_mm_movehl_ps(x1, x1), glmm_shuff1(x2, 3, 3, 1, 1)); + x1 = _mm_add_ps(x0, x1); + + glmm_store(dest[0], x1); +} + +CGLM_INLINE +void +glm_mat2_transp_sse2(mat2 m, mat2 dest) { + /* d c b a */ + /* d b c a */ + glmm_store(dest[0], glmm_shuff1(glmm_load(m[0]), 3, 1, 2, 0)); +} + +#endif +#endif /* cglm_mat2_sse_h */ diff --git a/include/cglm/types.h b/include/cglm/types.h index 1190b73..13a315d 100644 --- a/include/cglm/types.h +++ b/include/cglm/types.h @@ -38,6 +38,8 @@ typedef int ivec3[3]; typedef CGLM_ALIGN_IF(16) float vec4[4]; typedef vec4 versor; typedef vec3 mat3[3]; +// typedef vec4 mat2; +typedef CGLM_ALIGN_IF(16) vec2 mat2[2]; #ifdef __AVX__ typedef CGLM_ALIGN_IF(32) vec4 mat4[4]; From 2827fbfa796f5ca7efdf82a3133c06b60fc688f0 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 20 Jun 2019 22:51:51 +0300 Subject: [PATCH 04/14] mat2, vec2: add missing functions --- include/cglm/io.h | 22 ++++++ include/cglm/mat2.h | 162 ++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 172 insertions(+), 12 deletions(-) diff --git a/include/cglm/io.h b/include/cglm/io.h index cdcb4fb..c714400 100644 --- a/include/cglm/io.h +++ b/include/cglm/io.h @@ -179,6 +179,28 @@ glm_ivec3_print(ivec3 vec, #undef m } +CGLM_INLINE +void +glm_vec2_print(vec2 vec, + FILE * __restrict ostream) { + int i; + +#define m 2 + + fprintf(ostream, "Vector (float%d):\n\t|", m); + + for (i = 0; i < m; i++) { + fprintf(ostream, "%0.4f", vec[i]); + + if (i != m - 1) + fprintf(ostream, "\t"); + } + + fprintf(ostream, "|\n\n"); + +#undef m +} + CGLM_INLINE void glm_versor_print(versor vec, diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h index 11001f4..539c844 100644 --- a/include/cglm/mat2.h +++ b/include/cglm/mat2.h @@ -22,10 +22,9 @@ #define GLM_MAT2_IDENTITY_INIT {{1.0f, 0.0f}, {0.0f, 1.0f}} #define GLM_MAT2_ZERO_INIT {{0.0f, 0.0f}, {0.0f, 0.0f}} - /* for C only */ -#define GLM_MAT2_IDENTITY ((mat3)GLM_MAT2_IDENTITY_INIT) -#define GLM_MAT2_ZERO ((mat3)GLM_MAT2_ZERO_INIT) +#define GLM_MAT2_IDENTITY ((mat2)GLM_MAT2_IDENTITY_INIT) +#define GLM_MAT2_ZERO ((mat2)GLM_MAT2_ZERO_INIT) /*! * @brief copy all members of [mat] to [dest] @@ -36,10 +35,7 @@ CGLM_INLINE void glm_mat2_copy(mat2 mat, mat2 dest) { - dest[0][0] = mat[0][0]; - dest[0][1] = mat[0][1]; - dest[1][0] = mat[1][0]; - dest[1][1] = mat[1][1]; + glm_vec4_copy(mat[0], dest[0]); } /*! @@ -66,7 +62,7 @@ glm_mat2_identity(mat2 mat) { /*! * @brief make given matrix array's each element identity matrix * - * @param[in, out] mat matrix array (must be aligned (16/32) + * @param[in, out] mat matrix array (must be aligned (16) * if alignment is not disabled) * * @param[in] count count of matrices @@ -100,8 +96,8 @@ glm_mat2_zero(mat2 mat) { * m1, m2 and dest matrices can be same matrix, it is possible to write this: * * @code - * mat3 m = GLM_MAT3_IDENTITY_INIT; - * glm_mat3_mul(m, m, m); + * mat2 m = GLM_MAT2_IDENTITY_INIT; + * glm_mat2_mul(m, m, m); * @endcode * * @param[in] m1 left matrix @@ -127,7 +123,7 @@ glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) { } /*! - * @brief transpose mat3 and store in dest + * @brief transpose mat2 and store in dest * * source matrix will not be transposed unless dest is m * @@ -148,7 +144,7 @@ glm_mat2_transpose_to(mat2 m, mat2 dest) { } /*! - * @brief tranpose mat3 and store result in same matrix + * @brief tranpose mat2 and store result in same matrix * * @param[in, out] m source and dest */ @@ -160,4 +156,146 @@ glm_mat2_transpose(mat2 m) { m[0][1] = m[1][0]; m[1][0] = tmp; } + +/*! + * @brief multiply mat2 with vec2 (column vector) and store in dest vector + * + * @param[in] m mat2 (left) + * @param[in] v vec2 (right, column vector) + * @param[out] dest vec2 (result, column vector) + */ +CGLM_INLINE +void +glm_mat2_mulv(mat2 m, vec2 v, vec2 dest) { + dest[0] = m[0][0] * v[0] + m[1][0] * v[1]; + dest[1] = m[0][1] * v[0] + m[1][1] * v[1]; +} + +/*! + * @brief trace of matrix + * + * sum of the elements on the main diagonal from upper left to the lower right + * + * @param[in] m matrix + */ +CGLM_INLINE +float +glm_mat2_trace(mat2 m) { + return m[0][0] + m[1][1]; +} + +/*! + * @brief scale (multiply with scalar) matrix + * + * multiply matrix with scalar + * + * @param[in, out] m matrix + * @param[in] s scalar + */ +CGLM_INLINE +void +glm_mat2_scale(mat2 m, float s) { + glm_vec4_scale(m[0], s, m[0]); +} + +/*! + * @brief mat2 determinant + * + * @param[in] mat matrix + * + * @return determinant + */ +CGLM_INLINE +float +glm_mat2_det(mat2 mat) { + return mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1]; +} + +/*! + * @brief inverse mat2 and store in dest + * + * @param[in] mat matrix + * @param[out] dest inverse matrix + */ +CGLM_INLINE +void +glm_mat2_inv(mat2 mat, mat2 dest) { + float det; + float a = mat[0][0], b = mat[0][1], + c = mat[1][0], d = mat[1][1]; + + det = 1.0f / (a * d - c * b); + + dest[0][0] = d * det; + dest[0][1] = -b * det; + dest[1][0] = -c * det; + dest[1][1] = a * det; +} + +/*! + * @brief swap two matrix columns + * + * @param[in,out] mat matrix + * @param[in] col1 col1 + * @param[in] col2 col2 + */ +CGLM_INLINE +void +glm_mat2_swap_col(mat2 mat, int col1, int col2) { + float a, b; + + a = mat[col1][0]; + b = mat[col1][1]; + + mat[col1][0] = mat[col2][0]; + mat[col1][1] = mat[col2][1]; + + mat[col2][0] = a; + mat[col2][1] = b; +} + +/*! + * @brief swap two matrix rows + * + * @param[in,out] mat matrix + * @param[in] row1 row1 + * @param[in] row2 row2 + */ +CGLM_INLINE +void +glm_mat2_swap_row(mat2 mat, int row1, int row2) { + float a, b; + + a = mat[0][row1]; + b = mat[1][row1]; + + mat[0][row1] = mat[0][row2]; + mat[1][row1] = mat[1][row2]; + + mat[0][row2] = a; + mat[1][row2] = b; +} + +/*! + * @brief helper for R (row vector) * M (matrix) * C (column vector) + * + * rmc stands for Row * Matrix * Column + * + * the result is scalar because R * M = Matrix1x2 (row vector), + * then Matrix1x2 * Vec2 (column vector) = Matrix1x1 (Scalar) + * + * @param[in] r row vector or matrix1x2 + * @param[in] m matrix2x2 + * @param[in] c column vector or matrix2x1 + * + * @return scalar value e.g. Matrix1x1 + */ +CGLM_INLINE +float +glm_mat2_rmc(vec2 r, mat2 m, vec2 c) { + vec2 tmp; + glm_mat2_mulv(m, c, tmp); + return glm_vec2_dot(r, tmp); +} + #endif /* cglm_mat2_h */ From a4c7c5e1baf15669e138326f58a189d11f305ac8 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Fri, 21 Jun 2019 23:17:08 +0300 Subject: [PATCH 05/14] implement call version for mat2 --- include/cglm/call.h | 4 +- include/cglm/call/mat2.h | 79 ++++++++++++++++++++++++++++++++ include/cglm/mat2.h | 21 +++++++++ src/mat2.c | 99 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 include/cglm/call/mat2.h create mode 100644 src/mat2.c diff --git a/include/cglm/call.h b/include/cglm/call.h index 7cbd501..87ecea5 100644 --- a/include/cglm/call.h +++ b/include/cglm/call.h @@ -12,10 +12,12 @@ extern "C" { #endif #include "cglm.h" +#include "call/vec2.h" #include "call/vec3.h" #include "call/vec4.h" -#include "call/mat4.h" +#include "call/mat2.h" #include "call/mat3.h" +#include "call/mat4.h" #include "call/affine.h" #include "call/cam.h" #include "call/quat.h" diff --git a/include/cglm/call/mat2.h b/include/cglm/call/mat2.h new file mode 100644 index 0000000..91234a3 --- /dev/null +++ b/include/cglm/call/mat2.h @@ -0,0 +1,79 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglmc_mat2_h +#define cglmc_mat2_h +#ifdef __cplusplus +extern "C" { +#endif + +#include "../cglm.h" + +CGLM_EXPORT +void +glmc_mat2_copy(mat2 mat, mat2 dest); + +CGLM_EXPORT +void +glmc_mat2_identity(mat2 mat); + +CGLM_EXPORT +void +glmc_mat2_identity_array(mat2 * __restrict mat, size_t count); + +CGLM_EXPORT +void +glmc_mat2_zero(mat2 mat); + +CGLM_EXPORT +void +glmc_mat2_mul(mat2 m1, mat2 m2, mat2 dest); + +CGLM_EXPORT +void +glmc_mat2_transpose_to(mat2 m, mat2 dest); + +CGLM_EXPORT +void +glmc_mat2_transpose(mat2 m); + +CGLM_EXPORT +void +glmc_mat2_mulv(mat2 m, vec2 v, vec2 dest); + +CGLM_EXPORT +float +glmc_mat2_trace(mat2 m); + +CGLM_EXPORT +void +glmc_mat2_scale(mat2 m, float s); + +CGLM_EXPORT +float +glmc_mat2_det(mat2 mat); + +CGLM_EXPORT +void +glmc_mat2_inv(mat2 mat, mat2 dest); + +CGLM_EXPORT +void +glmc_mat2_swap_col(mat2 mat, int col1, int col2); + +CGLM_EXPORT +void +glmc_mat2_swap_row(mat2 mat, int row1, int row2); + +CGLM_EXPORT +float +glmc_mat2_rmc(vec2 r, mat2 m, vec2 c); + +#ifdef __cplusplus +} +#endif +#endif /* cglmc_mat2_h */ diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h index 539c844..e7a865b 100644 --- a/include/cglm/mat2.h +++ b/include/cglm/mat2.h @@ -6,7 +6,28 @@ */ /* + Macros: + GLM_MAT2_IDENTITY_INIT + GLM_MAT2_ZERO_INIT + GLM_MAT2_IDENTITY + GLM_MAT2_ZERO + Functions: + CGLM_INLINE void glm_mat2_copy(mat2 mat, mat2 dest) + CGLM_INLINE void glm_mat2_identity(mat2 mat) + CGLM_INLINE void glm_mat2_identity_array(mat2 * restrict mat, size_t count) + CGLM_INLINE void glm_mat2_zero(mat2 mat) + CGLM_INLINE void glm_mat2_mul(mat2 m1, mat2 m2, mat2 dest) + CGLM_INLINE void glm_mat2_transpose_to(mat2 m, mat2 dest) + CGLM_INLINE void glm_mat2_transpose(mat2 m) + CGLM_INLINE void glm_mat2_mulv(mat2 m, vec2 v, vec2 dest) + CGLM_INLINE float glm_mat2_trace(mat2 m) + CGLM_INLINE void glm_mat2_scale(mat2 m, float s) + CGLM_INLINE float glm_mat2_det(mat2 mat) + CGLM_INLINE void glm_mat2_inv(mat2 mat, mat2 dest) + CGLM_INLINE void glm_mat2_swap_col(mat2 mat, int col1, int col2) + CGLM_INLINE void glm_mat2_swap_row(mat2 mat, int row1, int row2) + CGLM_INLINE float glm_mat2_rmc(vec2 r, mat2 m, vec2 c) */ #ifndef cglm_mat2_h diff --git a/src/mat2.c b/src/mat2.c new file mode 100644 index 0000000..99a282d --- /dev/null +++ b/src/mat2.c @@ -0,0 +1,99 @@ +/* + * 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 +void +glmc_mat2_copy(mat2 mat, mat2 dest) { + glm_mat2_copy(mat, dest); +} + +CGLM_EXPORT +void +glmc_mat2_identity(mat2 mat) { + glm_mat2_identity(mat); +} + +CGLM_EXPORT +void +glmc_mat2_identity_array(mat2 * __restrict mat, size_t count) { + glm_mat2_identity_array(mat, count); +} + +CGLM_EXPORT +void +glmc_mat2_zero(mat2 mat) { + glm_mat2_zero(mat); +} + +CGLM_EXPORT +void +glmc_mat2_mul(mat2 m1, mat2 m2, mat2 dest) { + glm_mat2_mul(m1, m2, dest); +} + +CGLM_EXPORT +void +glmc_mat2_transpose_to(mat2 m, mat2 dest) { + glm_mat2_transpose_to(m, dest); +} + +CGLM_EXPORT +void +glmc_mat2_transpose(mat2 m) { + glm_mat2_transpose(m); +} + +CGLM_EXPORT +void +glmc_mat2_mulv(mat2 m, vec2 v, vec2 dest) { + glm_mat2_mulv(m, v, dest); +} + +CGLM_EXPORT +float +glmc_mat2_trace(mat2 m) { + return glm_mat2_trace(m); +} + +CGLM_EXPORT +void +glmc_mat2_scale(mat2 m, float s) { + glm_mat2_scale(m, s); +} + +CGLM_EXPORT +float +glmc_mat2_det(mat2 mat) { + return glm_mat2_det(mat); +} + +CGLM_EXPORT +void +glmc_mat2_inv(mat2 mat, mat2 dest) { + glm_mat2_inv(mat, dest); +} + +CGLM_EXPORT +void +glmc_mat2_swap_col(mat2 mat, int col1, int col2) { + glm_mat2_swap_col(mat, col1, col2); +} + +CGLM_EXPORT +void +glmc_mat2_swap_row(mat2 mat, int row1, int row2) { + glm_mat2_swap_row(mat, row1, row2); +} + +CGLM_EXPORT +float +glmc_mat2_rmc(vec2 r, mat2 m, vec2 c) { + return glm_mat2_rmc(r, m, c); +} From cb54a8b8c52050facaa53a3bf6982ec692359f49 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Fri, 30 Aug 2019 22:00:20 +0300 Subject: [PATCH 06/14] vec2: rotate vec2 by angle --- include/cglm/vec2.h | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h index 06817e4..f18cce9 100644 --- a/include/cglm/vec2.h +++ b/include/cglm/vec2.h @@ -13,6 +13,40 @@ GLM_VEC2_ZERO Functions: + CGLM_INLINE void glm_vec2(float * __restrict v, vec2 dest) + CGLM_INLINE void glm_vec2_copy(vec2 a, vec2 dest) + CGLM_INLINE void glm_vec2_zero(vec2 v) + CGLM_INLINE void glm_vec2_one(vec2 v) + CGLM_INLINE float glm_vec2_dot(vec2 a, vec2 b) + CGLM_INLINE float glm_vec2_cross(vec2 a, vec2 b) + CGLM_INLINE float glm_vec2_norm2(vec2 v) + CGLM_INLINE float glm_vec2_norm(vec2 vec) + CGLM_INLINE void glm_vec2_add(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_adds(vec2 v, float s, vec2 dest) + CGLM_INLINE void glm_vec2_sub(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_subs(vec2 v, float s, vec2 dest) + CGLM_INLINE void glm_vec2_mul(vec2 a, vec2 b, vec2 d) + CGLM_INLINE void glm_vec2_scale(vec2 v, float s, vec2 dest) + CGLM_INLINE void glm_vec2_scale_as(vec2 v, float s, vec2 dest) + CGLM_INLINE void glm_vec2_div(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_divs(vec2 v, float s, vec2 dest) + CGLM_INLINE void glm_vec2_addadd(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_subadd(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_muladd(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_muladds(vec2 a, float s, vec2 dest) + CGLM_INLINE void glm_vec2_maxadd(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_minadd(vec2 a, vec2 b, vec2 dest) + CGLM_INLINE void glm_vec2_negate_to(vec2 v, vec2 dest) + CGLM_INLINE void glm_vec2_negate(vec2 v) + CGLM_INLINE void glm_vec2_normalize(vec2 v) + CGLM_INLINE void glm_vec2_normalize_to(vec2 vec, vec2 dest) + CGLM_INLINE void glm_vec2_rotate(vec2 v, float angle, vec2 dest) + CGLM_INLINE float glm_vec2_distance2(vec2 a, vec2 b) + CGLM_INLINE float glm_vec2_distance(vec2 a, vec2 b) + CGLM_INLINE void glm_vec2_maxv(vec2 v1, vec2 v2, vec2 dest) + CGLM_INLINE void glm_vec2_minv(vec2 v1, vec2 v2, vec2 dest) + CGLM_INLINE void glm_vec2_clamp(vec2 v, float minVal, float maxVal) + CGLM_INLINE void glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) */ @@ -432,6 +466,32 @@ glm_vec2_normalize_to(vec2 vec, vec2 dest) { glm_vec2_scale(vec, 1.0f / norm, dest); } +/*! + * @brief rotate vec2 around origin by angle (CCW: counterclockwise) + * + * Formula: + * 𝑥2 = cos(a)𝑥1 − sin(a)𝑦1 + * 𝑦2 = sin(a)𝑥1 + cos(a)𝑦1 + * + * @param[in] v vector to rotate + * @param[in] angle angle by radians + * @param[out] dest destination vector + */ +CGLM_INLINE +void +glm_vec2_rotate(vec2 v, float angle, vec2 dest) { + float c, s, x1, y1; + + c = cosf(angle); + s = sinf(angle); + + x1 = v[0]; + y1 = v[1]; + + dest[0] = c * x1 - s * y1; + dest[1] = s * x1 + c * y1; +} + /** * @brief squared distance between two vectors * From d86f5df776e5117bfc7fedd5ac257682bd418b74 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Fri, 30 Aug 2019 22:56:20 +0300 Subject: [PATCH 07/14] vec: call version for vec2 --- include/cglm/call/vec2.h | 135 +++++++++++++++++++++++++ include/cglm/vec2.h | 50 ++++----- src/vec2.c | 213 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 373 insertions(+), 25 deletions(-) create mode 100644 src/vec2.c diff --git a/include/cglm/call/vec2.h b/include/cglm/call/vec2.h index de59437..d4d3396 100644 --- a/include/cglm/call/vec2.h +++ b/include/cglm/call/vec2.h @@ -13,6 +13,141 @@ extern "C" { #include "../cglm.h" +CGLM_EXPORT +void +glmc_vec2(float * __restrict v, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_copy(vec2 a, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_zero(vec2 v); + +CGLM_EXPORT +void +glmc_vec2_one(vec2 v); + +CGLM_EXPORT +float +glmc_vec2_dot(vec2 a, vec2 b); + +CGLM_EXPORT +float +glmc_vec2_cross(vec2 a, vec2 b); + +CGLM_EXPORT +float +glmc_vec2_norm2(vec2 v); + +CGLM_EXPORT +float +glmc_vec2_norm(vec2 v); + +CGLM_EXPORT +void +glmc_vec2_add(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_adds(vec2 v, float s, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_sub(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_subs(vec2 v, float s, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_mul(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_scale(vec2 v, float s, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_scale_as(vec2 v, float s, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_div(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_divs(vec2 v, float s, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_addadd(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_subadd(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_muladd(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_muladds(vec2 a, float s, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_maxadd(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_minadd(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_negate_to(vec2 v, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_negate(vec2 v); + +CGLM_EXPORT +void +glmc_vec2_normalize(vec2 v); + +CGLM_EXPORT +void +glmc_vec2_normalize_to(vec2 v, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_rotate(vec2 v, float angle, vec2 dest); + +CGLM_EXPORT +float +glmc_vec2_distance2(vec2 a, vec2 b); + +CGLM_EXPORT +float +glmc_vec2_distance(vec2 a, vec2 b); + +CGLM_EXPORT +void +glmc_vec2_maxv(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_minv(vec2 a, vec2 b, vec2 dest); + +CGLM_EXPORT +void +glmc_vec2_clamp(vec2 v, float minval, float maxval); + +CGLM_EXPORT +void +glmc_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest); #ifdef __cplusplus } diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h index f18cce9..3dd4645 100644 --- a/include/cglm/vec2.h +++ b/include/cglm/vec2.h @@ -231,15 +231,15 @@ glm_vec2_subs(vec2 v, float s, vec2 dest) { /*! * @brief multiply two vector (component-wise multiplication) * - * @param a v1 - * @param b v2 - * @param d v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2]) + * @param a v1 + * @param b v2 + * @param dest v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2]) */ CGLM_INLINE void -glm_vec2_mul(vec2 a, vec2 b, vec2 d) { - d[0] = a[0] * b[0]; - d[1] = a[1] * b[1]; +glm_vec2_mul(vec2 a, vec2 b, vec2 dest) { + dest[0] = a[0] * b[0]; + dest[1] = a[1] * b[1]; } /*! @@ -448,22 +448,22 @@ glm_vec2_normalize(vec2 v) { /*! * @brief normalize vector to dest * - * @param[in] vec source + * @param[in] v source * @param[out] dest destination */ CGLM_INLINE void -glm_vec2_normalize_to(vec2 vec, vec2 dest) { +glm_vec2_normalize_to(vec2 v, vec2 dest) { float norm; - norm = glm_vec2_norm(vec); + norm = glm_vec2_norm(v); if (norm == 0.0f) { glm_vec2_zero(dest); return; } - glm_vec2_scale(vec, 1.0f / norm, dest); + glm_vec2_scale(v, 1.0f / norm, dest); } /*! @@ -521,43 +521,43 @@ glm_vec2_distance(vec2 a, vec2 b) { /*! * @brief max values of vectors * - * @param[in] v1 vector1 - * @param[in] v2 vector2 + * @param[in] a vector1 + * @param[in] b vector2 * @param[out] dest destination */ CGLM_INLINE void -glm_vec2_maxv(vec2 v1, vec2 v2, vec2 dest) { - dest[0] = glm_max(v1[0], v2[0]); - dest[1] = glm_max(v1[1], v2[1]); +glm_vec2_maxv(vec2 a, vec2 b, vec2 dest) { + dest[0] = glm_max(a[0], b[0]); + dest[1] = glm_max(a[1], b[1]); } /*! * @brief min values of vectors * - * @param[in] v1 vector1 - * @param[in] v2 vector2 + * @param[in] a vector1 + * @param[in] b vector2 * @param[out] dest destination */ CGLM_INLINE void -glm_vec2_minv(vec2 v1, vec2 v2, vec2 dest) { - dest[0] = glm_min(v1[0], v2[0]); - dest[1] = glm_min(v1[1], v2[1]); +glm_vec2_minv(vec2 a, vec2 b, vec2 dest) { + dest[0] = glm_min(a[0], b[0]); + dest[1] = glm_min(a[1], b[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 + * @param[in] minval minimum value + * @param[in] maxval maximum value */ CGLM_INLINE void -glm_vec2_clamp(vec2 v, float minVal, float maxVal) { - v[0] = glm_clamp(v[0], minVal, maxVal); - v[1] = glm_clamp(v[1], minVal, maxVal); +glm_vec2_clamp(vec2 v, float minval, float maxval) { + v[0] = glm_clamp(v[0], minval, maxval); + v[1] = glm_clamp(v[1], minval, maxval); } /*! diff --git a/src/vec2.c b/src/vec2.c new file mode 100644 index 0000000..67e5a03 --- /dev/null +++ b/src/vec2.c @@ -0,0 +1,213 @@ +/* + * 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 +void +glmc_vec2(float * __restrict v, vec2 dest) { + glm_vec2(v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_copy(vec2 a, vec2 dest) { + glm_vec2_copy(a, dest); +} + +CGLM_EXPORT +void +glmc_vec2_zero(vec2 v) { + glm_vec2_zero(v); +} + +CGLM_EXPORT +void +glmc_vec2_one(vec2 v) { + glm_vec2_one(v); +} + +CGLM_EXPORT +float +glmc_vec2_dot(vec2 a, vec2 b) { + return glm_vec2_dot(a, b); +} + +CGLM_EXPORT +float +glmc_vec2_cross(vec2 a, vec2 b) { + return glm_vec2_cross(a, b); +} + +CGLM_EXPORT +float +glmc_vec2_norm2(vec2 v) { + return glm_vec2_norm2(v); +} + +CGLM_EXPORT +float +glmc_vec2_norm(vec2 v) { + return glm_vec2_norm2(v); +} + +CGLM_EXPORT +void +glmc_vec2_add(vec2 a, vec2 b, vec2 dest) { + glm_vec2_add(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_adds(vec2 v, float s, vec2 dest) { + glm_vec2_adds(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec2_sub(vec2 a, vec2 b, vec2 dest) { + glm_vec2_sub(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_subs(vec2 v, float s, vec2 dest) { + glm_vec2_subs(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec2_mul(vec2 a, vec2 b, vec2 dest) { + glm_vec2_mul(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_scale(vec2 v, float s, vec2 dest) { + glm_vec2_scale(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec2_scale_as(vec2 v, float s, vec2 dest) { + glm_vec2_scale_as(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec2_div(vec2 a, vec2 b, vec2 dest) { + glm_vec2_div(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_divs(vec2 v, float s, vec2 dest) { + glm_vec2_divs(v, s, dest); +} + +CGLM_EXPORT +void +glmc_vec2_addadd(vec2 a, vec2 b, vec2 dest) { + glm_vec2_addadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_subadd(vec2 a, vec2 b, vec2 dest) { + glm_vec2_subadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_muladd(vec2 a, vec2 b, vec2 dest) { + glm_vec2_muladd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_muladds(vec2 a, float s, vec2 dest) { + glm_vec2_muladds(a, s, dest); +} + +CGLM_EXPORT +void +glmc_vec2_maxadd(vec2 a, vec2 b, vec2 dest) { + glm_vec2_maxadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_minadd(vec2 a, vec2 b, vec2 dest) { + glm_vec2_minadd(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_negate_to(vec2 v, vec2 dest) { + glm_vec2_negate_to(v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_negate(vec2 v) { + glm_vec2_negate(v); +} + +CGLM_EXPORT +void +glmc_vec2_normalize(vec2 v) { + glm_vec2_normalize(v); +} + +CGLM_EXPORT +void +glmc_vec2_normalize_to(vec2 v, vec2 dest) { + glm_vec2_normalize_to(v, dest); +} + +CGLM_EXPORT +void +glmc_vec2_rotate(vec2 v, float angle, vec2 dest) { + glm_vec2_rotate(v, angle, dest); +} + +CGLM_EXPORT +float +glmc_vec2_distance2(vec2 a, vec2 b) { + return glm_vec2_distance2(a, b); +} + +CGLM_EXPORT +float +glmc_vec2_distance(vec2 a, vec2 b) { + return glm_vec2_distance(a, b); +} + +CGLM_EXPORT +void +glmc_vec2_maxv(vec2 a, vec2 b, vec2 dest) { + glm_vec2_maxv(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_minv(vec2 a, vec2 b, vec2 dest) { + glm_vec2_minv(a, b, dest); +} + +CGLM_EXPORT +void +glmc_vec2_clamp(vec2 v, float minval, float maxval) { + glm_vec2_clamp(v, minval, maxval); +} + +CGLM_EXPORT +void +glmc_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) { + glm_vec2_lerp(from, to, t, dest); +} From 3640e402da28a9e86d7dfa5a28605b2be1ceb952 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sat, 31 Aug 2019 14:36:57 +0300 Subject: [PATCH 08/14] mat2 struct version --- include/cglm/struct.h | 1 + include/cglm/struct/mat2.h | 259 ++++++++++++++++++++++++++++++++++++ include/cglm/types-struct.h | 25 +++- 3 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 include/cglm/struct/mat2.h diff --git a/include/cglm/struct.h b/include/cglm/struct.h index 66a0e9b..87b47a8 100644 --- a/include/cglm/struct.h +++ b/include/cglm/struct.h @@ -15,6 +15,7 @@ extern "C" { #include "types-struct.h" #include "struct/vec3.h" #include "struct/vec4.h" +#include "struct/mat2.h" #include "struct/mat3.h" #include "struct/mat4.h" #include "struct/affine.h" diff --git a/include/cglm/struct/mat2.h b/include/cglm/struct/mat2.h new file mode 100644 index 0000000..9a4f4df --- /dev/null +++ b/include/cglm/struct/mat2.h @@ -0,0 +1,259 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +/* + Macros: + GLM_MAT2_IDENTITY_INIT + GLM_MAT2_ZERO_INIT + GLM_MAT2_IDENTITY + GLM_MAT2_ZERO + + Functions: + CGLM_INLINE void glms_mat2_identity(mat2 mat) + CGLM_INLINE void glms_mat2_identity_array(mat2 * restrict mat, size_t count) + CGLM_INLINE void glms_mat2_zero(mat2 mat) + CGLM_INLINE void glms_mat2_mul(mat2 m1, mat2 m2, mat2 dest) + CGLM_INLINE void glms_mat2_transpose_to(mat2 m, mat2 dest) + CGLM_INLINE void glms_mat2_transpose(mat2 m) + CGLM_INLINE void glms_mat2_mulv(mat2 m, vec2 v, vec2 dest) + CGLM_INLINE float glms_mat2_trace(mat2 m) + CGLM_INLINE void glms_mat2_scale(mat2 m, float s) + CGLM_INLINE float glms_mat2_det(mat2 mat) + CGLM_INLINE void glms_mat2_inv(mat2 mat, mat2 dest) + CGLM_INLINE void glms_mat2_swap_col(mat2 mat, int col1, int col2) + CGLM_INLINE void glms_mat2_swap_row(mat2 mat, int row1, int row2) + CGLM_INLINE float glms_mat2_rmc(vec2 r, mat2 m, vec2 c) + */ + +#ifndef cglms_mat2_h +#define cglms_mat2_h + +#include "../common.h" +#include "../types-struct.h" +#include "../mat2.h" +#include "vec2.h" + +#define GLMS_MAT2_IDENTITY_INIT {1.0f, 0.0f, 0.0f, 1.0f} +#define GLMS_MAT2_ZERO_INIT {0.0f, 0.0f, 0.0f, 0.0f} + +/* for C only */ +#define GLMS_MAT2_IDENTITY ((mat3s)GLMS_MAT2_IDENTITY_INIT) +#define GLMS_MAT2_ZERO ((mat3s)GLMS_MAT2_ZERO_INIT) + +/*! + * @brief make given matrix identity. It is identical with below, + * but it is more easy to do that with this func especially for members + * e.g. glm_mat2_identity(aStruct->aMatrix); + * + * @code + * glm_mat2_copy(GLM_MAT2_IDENTITY, mat); // C only + * + * // or + * mat2 mat = GLM_MAT2_IDENTITY_INIT; + * @endcode + * + * @returns identity matrix + */ +CGLM_INLINE +mat2s +glms_mat2_identity() { + mat2s r; + glm_mat2_identity(r.raw); + return r; +} + +/*! + * @brief make given matrix array's each element identity matrix + * + * @param[in, out] mat matrix array (must be aligned (16) + * if alignment is not disabled) + * + * @param[in] count count of matrices + */ +CGLM_INLINE +void +glms_mat2_identity_array(mat2s * __restrict mat, size_t count) { + CGLM_ALIGN_MAT mat2s t = GLMS_MAT2_IDENTITY_INIT; + size_t i; + + for (i = 0; i < count; i++) { + glm_mat2_copy(t.raw, mat[i].raw); + } +} + +/*! + * @brief make given matrix zero. + * + * @returns matrix + */ +CGLM_INLINE +mat2s +glms_mat2_zero() { + mat2s r; + glm_mat2_zero(r.raw); + return r; +} + +/*! + * @brief multiply m1 and m2 to dest + * + * m1, m2 and dest matrices can be same matrix, it is possible to write this: + * + * @code + * mat2 m = GLM_MAT2_IDENTITY_INIT; + * glm_mat2_mul(m, m, m); + * @endcode + * + * @param[in] m1 left matrix + * @param[in] m2 right matrix + * + * @returns matrix + */ +CGLM_INLINE +mat2s +glms_mat2_mul(mat2s m1, mat2s m2) { + mat2s r; + glm_mat2_mul(m1.raw, m2.raw, r.raw); + return r; +} + +/*! + * @brief transpose mat2 + * + * @param[in] m matrix to transpose + * + * @returns transposed matrix + */ +CGLM_INLINE +mat2s +glms_mat2_transpose(mat2s m) { + glm_mat2_transpose(m.raw); + return m; +} + +/*! + * @brief multiply mat2 with vec2 (column vector) and store in dest vector + * + * @param[in] m mat2 (left) + * @param[in] v vec2 (right, column vector) + * @returns vec2 (result, column vector) + */ +CGLM_INLINE +vec2s +glms_mat2_mulv(mat2s m, vec2s v) { + vec2s r; + glm_mat2_mulv(m.raw, v.raw, r.raw); + return r; +} + +/*! + * @brief trace of matrix + * + * sum of the elements on the main diagonal from upper left to the lower right + * + * @param[in] m matrix + */ +CGLM_INLINE +float +glms_mat2_trace(mat2s m) { + return glm_mat2_trace(m.raw); +} + +/*! + * @brief scale (multiply with scalar) matrix + * + * multiply matrix with scalar + * + * @param[in, out] m matrix + * @param[in] s scalar + * @returns matrix + */ +CGLM_INLINE +mat2s +glms_mat2_scale(mat2s m, float s) { + glm_mat2_scale(m.raw, s); + return m; +} + +/*! + * @brief mat2 determinant + * + * @param[in] mat matrix + * + * @return determinant + */ +CGLM_INLINE +float +glms_mat2_det(mat2s mat) { + return glm_mat2_det(mat.raw); +} + +/*! + * @brief inverse mat2 and store in dest + * + * @param[in] mat matrix + * @returns matrix + */ +CGLM_INLINE +mat2s +glms_mat2_inv(mat2s mat) { + mat2s r; + glm_mat2_inv(mat.raw, r.raw); + return r; +} + +/*! + * @brief swap two matrix columns + * + * @param[in] mat matrix + * @param[in] col1 col1 + * @param[in] col2 col2 + * @returns matrix + */ +CGLM_INLINE +mat2s +glms_mat2_swap_col(mat2s mat, int col1, int col2) { + glm_mat2_swap_col(mat.raw, col1, col2); + return mat; +} + +/*! + * @brief swap two matrix rows + * + * @param[in] mat matrix + * @param[in] row1 row1 + * @param[in] row2 row2 + * @returns matrix + */ +CGLM_INLINE +mat2s +glms_mat2_swap_row(mat2s mat, int row1, int row2) { + glm_mat2_swap_row(mat.raw, row1, row2); + return mat; +} + +/*! + * @brief helper for R (row vector) * M (matrix) * C (column vector) + * + * rmc stands for Row * Matrix * Column + * + * the result is scalar because R * M = Matrix1x2 (row vector), + * then Matrix1x2 * Vec2 (column vector) = Matrix1x1 (Scalar) + * + * @param[in] r row vector or matrix1x2 + * @param[in] m matrix2x2 + * @param[in] c column vector or matrix2x1 + * + * @return scalar value e.g. Matrix1x1 + */ +CGLM_INLINE +float +glms_mat2_rmc(vec2s r, mat2s m, vec2s c) { + return glm_mat2_rmc(r.raw, m.raw, c.raw); +} + +#endif /* cglms_mat2_h */ diff --git a/include/cglm/types-struct.h b/include/cglm/types-struct.h index 4901f01..f9ff8f5 100644 --- a/include/cglm/types-struct.h +++ b/include/cglm/types-struct.h @@ -10,6 +10,16 @@ #include "types.h" +typedef union vec2s { +#ifndef CGLM_NO_ANONYMOUS_STRUCT + struct { + float x; + float y; + }; +#endif + vec2 raw; +} vec2s; + typedef union vec3s { #ifndef CGLM_NO_ANONYMOUS_STRUCT struct { @@ -61,6 +71,17 @@ typedef union CGLM_ALIGN_IF(16) versors { vec4 raw; } versors; +typedef union mat2s { +#ifndef CGLM_NO_ANONYMOUS_STRUCT + struct { + float m00, m01; + float m10, m11; + }; +#endif + vec2s col[2]; + mat2 raw; +} mat2s; + typedef union mat3s { #ifndef CGLM_NO_ANONYMOUS_STRUCT struct { @@ -70,7 +91,7 @@ typedef union mat3s { }; #endif vec3s col[3]; - mat3 raw; + mat3 raw; } mat3s; typedef union CGLM_ALIGN_MAT mat4s { @@ -83,7 +104,7 @@ typedef union CGLM_ALIGN_MAT mat4s { }; #endif vec4s col[4]; - mat4 raw; + mat4 raw; } mat4s; #endif /* cglm_types_struct_h */ From 43ae3b332a14a0f8cf47a3b66bd9ac5e5e156ed6 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 24 Feb 2020 10:06:19 +0300 Subject: [PATCH 09/14] add tests for vec2 and its call version --- include/cglm/struct/mat2.h | 1 - include/cglm/types-struct.h | 4 +- src/vec2.c | 2 +- test/src/test_tests.h | 50 --- test/src/test_vec2.c | 13 - test/src/test_vec2.h | 596 ++++++++++++++++++++++++++++++++++++ test/src/test_vec3.h | 23 +- test/src/test_vec4.h | 4 +- test/src/tests.c | 2 + test/tests.h | 157 ++++++++++ 10 files changed, 771 insertions(+), 81 deletions(-) delete mode 100644 test/src/test_tests.h delete mode 100644 test/src/test_vec2.c create mode 100644 test/src/test_vec2.h diff --git a/include/cglm/struct/mat2.h b/include/cglm/struct/mat2.h index 9a4f4df..7b2de89 100644 --- a/include/cglm/struct/mat2.h +++ b/include/cglm/struct/mat2.h @@ -35,7 +35,6 @@ #include "../common.h" #include "../types-struct.h" #include "../mat2.h" -#include "vec2.h" #define GLMS_MAT2_IDENTITY_INIT {1.0f, 0.0f, 0.0f, 1.0f} #define GLMS_MAT2_ZERO_INIT {0.0f, 0.0f, 0.0f, 0.0f} diff --git a/include/cglm/types-struct.h b/include/cglm/types-struct.h index aad4876..f211e0a 100644 --- a/include/cglm/types-struct.h +++ b/include/cglm/types-struct.h @@ -113,7 +113,7 @@ typedef union mat2s { } mat2s; typedef union mat3s { - mat3 raw; + mat3 raw; vec3s col[3]; #if CGLM_USE_ANONYMOUS_STRUCT struct { @@ -125,7 +125,7 @@ typedef union mat3s { } mat3s; typedef union CGLM_ALIGN_MAT mat4s { - mat4 raw; + mat4 raw; vec4s col[4]; #if CGLM_USE_ANONYMOUS_STRUCT struct { diff --git a/src/vec2.c b/src/vec2.c index 67e5a03..3048688 100644 --- a/src/vec2.c +++ b/src/vec2.c @@ -53,7 +53,7 @@ glmc_vec2_norm2(vec2 v) { CGLM_EXPORT float glmc_vec2_norm(vec2 v) { - return glm_vec2_norm2(v); + return glm_vec2_norm(v); } CGLM_EXPORT diff --git a/test/src/test_tests.h b/test/src/test_tests.h deleted file mode 100644 index cf69346..0000000 --- a/test/src/test_tests.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c), Recep Aslantas. - * MIT License (MIT), http://opensource.org/licenses/MIT - */ - -#ifndef test_tests_h -#define test_tests_h - -/* mat4 */ -void test_mat4(void **state); - -/* mat3 */ -void test_mat3(void **state); - -/* camera */ -void -test_camera_lookat(void **state); - -void -test_camera_decomp(void **state); - -void -test_project(void **state); - -void -test_clamp(void **state); - -void -test_euler(void **state); - -void -test_quat(void **state); - -void -test_vec4(void **state); - -void -test_vec3(void **state); - -void -test_affine(void **state); - -void -test_bezier(void **state); - -/* vec2 */ -void -test_vec2(void **state); - -#endif /* test_tests_h */ diff --git a/test/src/test_vec2.c b/test/src/test_vec2.c deleted file mode 100644 index 26941e2..0000000 --- a/test/src/test_vec2.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * 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_vec2(void **state) { - -} diff --git a/test/src/test_vec2.h b/test/src/test_vec2.h new file mode 100644 index 0000000..5f04c49 --- /dev/null +++ b/test/src/test_vec2.h @@ -0,0 +1,596 @@ +/* + * 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" + +#ifndef CGLM_TEST_VEC2_ONCE +#define CGLM_TEST_VEC2_ONCE + +/* Macros */ + +TEST_IMPL(MACRO_GLM_VEC2_ONE_INIT) { + vec2 v = GLM_VEC2_ONE_INIT; + + ASSERT(test_eq(v[0], 1.0f)) + ASSERT(test_eq(v[1], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(MACRO_GLM_VEC2_ZERO_INIT) { + vec2 v = GLM_VEC2_ZERO_INIT; + + ASSERT(test_eq(v[0], 0.0f)) + ASSERT(test_eq(v[1], 0.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(MACRO_GLM_VEC2_ONE) { + ASSERT(test_eq(GLM_VEC2_ONE[0], 1.0f)) + ASSERT(test_eq(GLM_VEC2_ONE[1], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(MACRO_GLM_VEC2_ZERO) { + ASSERT(test_eq(GLM_VEC2_ZERO[0], 0.0f)) + ASSERT(test_eq(GLM_VEC2_ZERO[0], 0.0f)) + + TEST_SUCCESS +} + +#endif /* CGLM_TEST_VEC2_ONCE */ + +TEST_IMPL(GLM_PREFIX, vec2) { + vec4 v4 = {10.0f, 9.0f, 8.0f, 7.0f}; + vec3 v3 = {11.0f, 12.0f, 13.0f}; + vec2 v2; + + GLM(vec2)(v4, v2); + ASSERT(test_eq(v2[0], v4[0])) + ASSERT(test_eq(v2[1], v4[1])) + + GLM(vec2)(v3, v2); + ASSERT(test_eq(v2[0], v3[0])) + ASSERT(test_eq(v2[1], v3[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_copy) { + vec2 v1 = {10.0f, 9.0f}; + vec2 v2 = {1.0f, 2.0f}; + + GLM(vec2_copy)(v1, v2); + + ASSERTIFY(test_assert_vec2_eq(v1, v2)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_zero) { + vec2 v1 = {10.0f, 9.0f}; + vec2 v2 = {1.0f, 2.0f}; + + GLM(vec2_zero)(v1); + GLM(vec2_zero)(v2); + + ASSERTIFY(test_assert_vec2_eq(v1, GLM_VEC2_ZERO)) + ASSERTIFY(test_assert_vec2_eq(v2, GLM_VEC2_ZERO)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_one) { + vec2 v1 = {10.0f, 9.0f}; + vec2 v2 = {1.0f, 2.0f}; + + GLM(vec2_one)(v1); + GLM(vec2_one)(v2); + + ASSERTIFY(test_assert_vec2_eq(v1, GLM_VEC2_ONE)) + ASSERTIFY(test_assert_vec2_eq(v2, GLM_VEC2_ONE)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_dot) { + vec2 a = {10.0f, 9.0f}; + vec2 b = {1.0f, 2.0f}; + float dot1, dot2; + + dot1 = GLM(vec2_dot)(a, b); + dot2 = a[0] * b[0] + a[1] * b[1]; + + ASSERT(test_eq(dot1, dot2)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_cross) { + vec2 a = {10.0f, 9.0f}; + vec2 b = {1.0f, 2.0f}; + float cprod; + + cprod = a[0] * b[1] - a[1] * b[0]; + + ASSERT(test_eq(glm_vec2_cross(a, b), cprod)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_norm2) { + vec2 a = {10.0f, 9.0f}; + float n1, n2; + + n1 = GLM(vec2_norm2)(a); + n2 = a[0] * a[0] + a[1] * a[1]; + + ASSERT(test_eq(n1, n2)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_norm) { + vec2 a = {10.0f, 9.0f}; + float n1, n2; + + n1 = GLM(vec2_norm)(a); + n2 = sqrtf(a[0] * a[0] + a[1] * a[1]); + + ASSERT(test_eq(n1, n2)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_add) { + vec2 a = {-10.0f, 9.0f}; + vec2 b = {12.0f, 19.0f}; + vec2 c, d; + + c[0] = a[0] + b[0]; + c[1] = a[1] + b[1]; + + GLM(vec2_add)(a, b, d); + + ASSERTIFY(test_assert_vec2_eq(c, d)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_adds) { + vec4 a = {-10.0f, 9.0f}; + vec4 c, d; + float s = 7.0f; + + c[0] = a[0] + s; + c[1] = a[1] + s; + + GLM(vec2_adds)(a, s, d); + + ASSERTIFY(test_assert_vec2_eq(c, d)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_sub) { + vec2 a = {-10.0f, 9.0f}; + vec2 b = {12.0f, 19.0f}; + vec2 c, d; + + c[0] = a[0] - b[0]; + c[1] = a[1] - b[1]; + + GLM(vec2_sub)(a, b, d); + + ASSERTIFY(test_assert_vec2_eq(c, d)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_subs) { + vec2 a = {-10.0f, 9.0f}; + vec2 c, d; + float s = 7.0f; + + c[0] = a[0] - s; + c[1] = a[1] - s; + + GLM(vec2_subs)(a, s, d); + + ASSERTIFY(test_assert_vec2_eq(c, d)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_mul) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3; + + GLM(vec2_mul)(v1, v2, v3); + + ASSERT(test_eq(v1[0] * v2[0], v3[0])) + ASSERT(test_eq(v1[1] * v2[1], v3[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_scale) { + vec2 v1 = {2.0f, -3.0f}, v2; + float s = 7.0f; + + GLM(vec2_scale)(v1, s, v2); + + ASSERT(test_eq(v1[0] * s, v2[0])) + ASSERT(test_eq(v1[1] * s, v2[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_scale_as) { + vec2 v1 = {2.0f, -3.0f}, v2; + float s = 7.0f; + float norm; + + GLM(vec2_scale_as)(v1, s, v2); + + norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]); + if (norm == 0.0f) { + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + + TEST_SUCCESS + } + + norm = s / norm; + + ASSERT(test_eq(v1[0] * norm, v2[0])) + ASSERT(test_eq(v1[1] * norm, v2[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_div) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3; + + GLM(vec2_div)(v1, v2, v3); + + ASSERT(test_eq(v1[0] / v2[0], v3[0])) + ASSERT(test_eq(v1[1] / v2[1], v3[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_divs) { + vec2 v1 = {2.0f, -3.0f}, v2; + float s = 7.0f; + + GLM(vec2_divs)(v1, s, v2); + + ASSERT(test_eq(v1[0] / s, v2[0])) + ASSERT(test_eq(v1[1] / s, v2[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_addadd) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3 = {1.0f, 2.0f}, + v4 = {1.0f, 2.0f}; + + GLM(vec2_addadd)(v1, v2, v4); + + ASSERT(test_eq(v3[0] + v1[0] + v2[0], v4[0])) + ASSERT(test_eq(v3[1] + v1[1] + v2[1], v4[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_subadd) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3 = {1.0f, 2.0f}, + v4 = {1.0f, 2.0f}; + + GLM(vec2_subadd)(v1, v2, v4); + + ASSERT(test_eq(v3[0] + v1[0] - v2[0], v4[0])) + ASSERT(test_eq(v3[1] + v1[1] - v2[1], v4[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_muladd) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3 = {1.0f, 2.0f}, + v4 = {1.0f, 2.0f}; + + GLM(vec2_muladd)(v1, v2, v4); + + ASSERT(test_eq(v3[0] + v1[0] * v2[0], v4[0])) + ASSERT(test_eq(v3[1] + v1[1] * v2[1], v4[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_muladds) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {1.0f, 2.0f}, + v3 = {1.0f, 2.0f}; + float s = 9.0f; + + GLM(vec2_muladds)(v1, s, v3); + + ASSERT(test_eq(v2[0] + v1[0] * s, v3[0])) + ASSERT(test_eq(v2[1] + v1[1] * s, v3[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_maxadd) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3 = {1.0f, 2.0f}, + v4 = {1.0f, 2.0f}; + + GLM(vec2_maxadd)(v1, v2, v4); + + ASSERT(test_eq(v3[0] + glm_max(v1[0], v2[0]), v4[0])) + ASSERT(test_eq(v3[1] + glm_max(v1[1], v2[1]), v4[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_minadd) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3 = {1.0f, 2.0f}, + v4 = {1.0f, 2.0f}; + + GLM(vec2_minadd)(v1, v2, v4); + + ASSERT(test_eq(v3[0] + glm_min(v1[0], v2[0]), v4[0])) + ASSERT(test_eq(v3[1] + glm_min(v1[1], v2[1]), v4[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_negate_to) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3, v4; + + GLM(vec2_negate_to)(v1, v3); + GLM(vec2_negate_to)(v2, v4); + + ASSERT(test_eq(-v1[0], v3[0])) + ASSERT(test_eq(-v1[1], v3[1])) + + ASSERT(test_eq(-v2[0], v4[0])) + ASSERT(test_eq(-v2[1], v4[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_negate) { + vec2 v1 = {2.0f, -3.0f}, + v2 = {-3.0f, 4.0f}, + v3 = {2.0f, -3.0f}, + v4 = {-3.0f, 4.0f}; + + GLM(vec2_negate)(v1); + GLM(vec2_negate)(v2); + + ASSERT(test_eq(-v1[0], v3[0])) + ASSERT(test_eq(-v1[1], v3[1])) + + ASSERT(test_eq(-v2[0], v4[0])) + ASSERT(test_eq(-v2[1], v4[1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_normalize) { + vec2 v1 = {2.0f, -3.0f}, v2 = {2.0f, -3.0f}; + float s = 1.0f; + float norm; + + GLM(vec2_normalize)(v2); + + norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]); + if (norm == 0.0f) { + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + + TEST_SUCCESS + } + + norm = s / norm; + + ASSERT(test_eq(v1[0] * norm, v2[0])) + ASSERT(test_eq(v1[1] * norm, v2[1])) + + glm_vec2_zero(v1); + GLM(vec2_normalize)(v1); + ASSERTIFY(test_assert_vec2_eq(v1, GLM_VEC2_ZERO)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_normalize_to) { + vec2 v1 = {2.0f, -3.0f}, v2; + float s = 1.0f; + float norm; + + GLM(vec2_normalize_to)(v1, v2); + + norm = sqrtf(v1[0] * v1[0] + v1[1] * v1[1]); + if (norm == 0.0f) { + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + + TEST_SUCCESS + } + + norm = s / norm; + + ASSERT(test_eq(v1[0] * norm, v2[0])) + ASSERT(test_eq(v1[1] * norm, v2[1])) + + glm_vec2_zero(v1); + GLM(vec2_normalize_to)(v1, v2); + ASSERTIFY(test_assert_vec2_eq(v2, GLM_VEC2_ZERO)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_rotate) { + vec2 v1 = {1.0f, 0.0f}; + + GLM(vec2_rotate)(v1, GLM_PI_2f, v1); + + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], 1.0f)) + + GLM(vec2_rotate)(v1, GLM_PI_2f, v1); + + ASSERT(test_eq(v1[0], -1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + + GLM(vec2_rotate)(v1, GLM_PI_2f, v1); + + ASSERT(test_eq(v1[0], 0.0f)) + ASSERT(test_eq(v1[1], -1.0f)) + + GLM(vec2_rotate)(v1, GLM_PI_2f, v1); + + ASSERT(test_eq(v1[0], 1.0f)) + ASSERT(test_eq(v1[1], 0.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_distance2) { + vec2 v1 = {30.0f, 0.0f}, + v2 = {0.0f, 0.0f}, + v3 = {3.0f, 10.0f}, + v4 = {0.46f, 4.0f}; + float d; + + d = GLM(vec2_distance2)(v1, v2); + ASSERT(test_eq(d, 30.0f * 30.0f)) + + d = GLM(vec2_distance2)(v3, v4); + ASSERT(test_eq(powf(v3[0] - v4[0], 2.0f) + + powf(v3[1] - v4[1], 2.0f), d)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_distance) { + vec2 v1 = {30.0f, 0.0f}, + v2 = {0.0f, 0.0f}, + v3 = {3.0f, 10.0f}, + v4 = {0.46f, 4.0f}; + float d; + + d = GLM(vec2_distance)(v1, v2); + ASSERT(test_eq(d, 30.0f)) + + d = GLM(vec2_distance)(v3, v4); + ASSERT(test_eq(sqrtf(powf(v3[0] - v4[0], 2.0f) + + powf(v3[1] - v4[1], 2.0f)), d)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_maxv) { + vec2 v1, v2, v3; + vec2 v5 = {-1.456f, -1.456f}; + vec2 v6 = {11.0f, 11.0f}; + vec2 v7 = {78.0f, -78.0f}; + + GLM(vec2_maxv)(v5, v6, v1); + GLM(vec2_maxv)(v5, v7, v2); + GLM(vec2_maxv)(v6, v7, v3); + + ASSERT(test_eq(v1[0], 11.0f)) + ASSERT(test_eq(v1[1], 11.0f)) + + ASSERT(test_eq(v2[0], 78.0f)) + ASSERT(test_eq(v2[1], -1.456f)) + + ASSERT(test_eq(v3[0], 78.0f)) + ASSERT(test_eq(v3[1], 11.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_minv) { + vec2 v1, v2, v3; + vec2 v5 = {-1.456f, -1.456f}; + vec2 v6 = {11.0f, 11.0f}; + vec2 v7 = {78.0f, -78.0f}; + + GLM(vec2_minv)(v5, v6, v1); + GLM(vec2_minv)(v5, v7, v2); + GLM(vec2_minv)(v6, v7, v3); + + ASSERT(test_eq(v1[0], -1.456f)) + ASSERT(test_eq(v1[1], -1.456f)) + + ASSERT(test_eq(v2[0], -1.456f)) + ASSERT(test_eq(v2[1], -78.0f)) + + ASSERT(test_eq(v3[0], 11.0f)) + ASSERT(test_eq(v3[1], -78.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_clamp) { + vec2 v1 = {-1.456f, -11.456f}; + vec2 v2 = {0.110f, 111.0f}; + vec2 v3 = {78.0f, 32.0f}; + + GLM(vec2_clamp)(v1, -1.03f, 30.0f); + GLM(vec2_clamp)(v2, 0.11f, 111.0f); + GLM(vec2_clamp)(v3, -88.0f, 70.0f); + + ASSERT(test_eq(v1[0], -1.03f)) + ASSERT(test_eq(v1[1], -1.03f)) + + ASSERT(test_eq(v2[0], 0.11f)) + ASSERT(test_eq(v2[1], 111.0f)) + + ASSERT(test_eq(v3[0], 70.0f)) + ASSERT(test_eq(v3[1], 32.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, vec2_lerp) { + vec2 v1 = {-100.0f, -200.0f}; + vec2 v2 = {100.0f, 200.0f}; + vec2 v3; + + GLM(vec2_lerp)(v1, v2, 0.5f, v3); + ASSERT(test_eq(v3[0], 0.0f)) + ASSERT(test_eq(v3[1], 0.0f)) + + GLM(vec2_lerp)(v1, v2, 0.75f, v3); + ASSERT(test_eq(v3[0], 50.0f)) + ASSERT(test_eq(v3[1], 100.0f)) + + TEST_SUCCESS +} diff --git a/test/src/test_vec3.h b/test/src/test_vec3.h index 0b6dc4d..4fa1d25 100644 --- a/test/src/test_vec3.h +++ b/test/src/test_vec3.h @@ -233,7 +233,7 @@ TEST_IMPL(GLM_PREFIX, vec3_zero) { GLM(vec3_zero)(v2); ASSERTIFY(test_assert_vec3_eq(v1, GLM_VEC3_ZERO)) - ASSERTIFY(test_assert_vec3_eq(v1, GLM_VEC3_ZERO)) + ASSERTIFY(test_assert_vec3_eq(v2, GLM_VEC3_ZERO)) TEST_SUCCESS } @@ -335,9 +335,9 @@ TEST_IMPL(GLM_PREFIX, vec3_norm_inf) { } TEST_IMPL(GLM_PREFIX, vec3_add) { - vec4 a = {-10.0f, 9.0f, -8.0f}; - vec4 b = {12.0f, 19.0f, -18.0f}; - vec4 c, d; + vec3 a = {-10.0f, 9.0f, -8.0f}; + vec3 b = {12.0f, 19.0f, -18.0f}; + vec3 c, d; c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; @@ -351,8 +351,8 @@ TEST_IMPL(GLM_PREFIX, vec3_add) { } TEST_IMPL(GLM_PREFIX, vec3_adds) { - vec4 a = {-10.0f, 9.0f, -8.0f}; - vec4 c, d; + vec3 a = {-10.0f, 9.0f, -8.0f}; + vec3 c, d; float s = 7.0f; c[0] = a[0] + s; @@ -367,9 +367,9 @@ TEST_IMPL(GLM_PREFIX, vec3_adds) { } TEST_IMPL(GLM_PREFIX, vec3_sub) { - vec4 a = {-10.0f, 9.0f, -8.0f}; - vec4 b = {12.0f, 19.0f, -18.0f}; - vec4 c, d; + vec3 a = {-10.0f, 9.0f, -8.0f}; + vec3 b = {12.0f, 19.0f, -18.0f}; + vec3 c, d; c[0] = a[0] - b[0]; c[1] = a[1] - b[1]; @@ -383,8 +383,8 @@ TEST_IMPL(GLM_PREFIX, vec3_sub) { } TEST_IMPL(GLM_PREFIX, vec3_subs) { - vec4 a = {-10.0f, 9.0f, -8.0f}; - vec4 c, d; + vec3 a = {-10.0f, 9.0f, -8.0f}; + vec3 c, d; float s = 7.0f; c[0] = a[0] - s; @@ -928,7 +928,6 @@ TEST_IMPL(GLM_PREFIX, vec3_rotate_m4) { TEST_SUCCESS } - TEST_IMPL(GLM_PREFIX, vec3_rotate_m3) { vec3 v1 = {1.0f, 0.0f, 0.0f}, v2 = {1.0f, 1.0f, 1.0f}; mat4 x0, y0, z0; diff --git a/test/src/test_vec4.h b/test/src/test_vec4.h index 5e20c63..abb882f 100644 --- a/test/src/test_vec4.h +++ b/test/src/test_vec4.h @@ -217,7 +217,7 @@ TEST_IMPL(GLM_PREFIX, vec4_zero) { GLM(vec4_zero)(v2); ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ZERO)) - ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ZERO)) + ASSERTIFY(test_assert_vec4_eq(v2, GLM_VEC4_ZERO)) TEST_SUCCESS } @@ -230,7 +230,7 @@ TEST_IMPL(GLM_PREFIX, vec4_one) { GLM(vec4_one)(v2); ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ONE)) - ASSERTIFY(test_assert_vec4_eq(v1, GLM_VEC4_ONE)) + ASSERTIFY(test_assert_vec4_eq(v2, GLM_VEC4_ONE)) TEST_SUCCESS } diff --git a/test/src/tests.c b/test/src/tests.c index ee7c488..90b8dee 100644 --- a/test/src/tests.c +++ b/test/src/tests.c @@ -12,6 +12,7 @@ #define GLM_PREFIX glm_ #define GLM(X) (glm_ ## X) +#include "test_vec2.h" #include "test_vec3.h" #include "test_vec4.h" #include "test_mat3.h" @@ -31,6 +32,7 @@ #define GLM_PREFIX glmc_ #define GLM(X) (glmc_ ## X) +#include "test_vec2.h" #include "test_vec3.h" #include "test_vec4.h" #include "test_mat3.h" diff --git a/test/tests.h b/test/tests.h index e4933e9..e026ed0 100644 --- a/test/tests.h +++ b/test/tests.h @@ -261,6 +261,85 @@ TEST_DECLARE(glmc_quat_rotate_atm) /* bezier */ TEST_DECLARE(bezier) + +/* Macros */ + +TEST_DECLARE(MACRO_GLM_VEC2_ONE_INIT) +TEST_DECLARE(MACRO_GLM_VEC2_ZERO_INIT) +TEST_DECLARE(MACRO_GLM_VEC2_ONE) +TEST_DECLARE(MACRO_GLM_VEC2_ZERO) + +TEST_DECLARE(glm_vec2) +TEST_DECLARE(glm_vec2_copy) +TEST_DECLARE(glm_vec2_zero) +TEST_DECLARE(glm_vec2_one) +TEST_DECLARE(glm_vec2_dot) +TEST_DECLARE(glm_vec2_cross) +TEST_DECLARE(glm_vec2_norm2) +TEST_DECLARE(glm_vec2_norm) +TEST_DECLARE(glm_vec2_add) +TEST_DECLARE(glm_vec2_adds) +TEST_DECLARE(glm_vec2_sub) +TEST_DECLARE(glm_vec2_subs) +TEST_DECLARE(glm_vec2_mul) +TEST_DECLARE(glm_vec2_scale) +TEST_DECLARE(glm_vec2_scale_as) +TEST_DECLARE(glm_vec2_div) +TEST_DECLARE(glm_vec2_divs) +TEST_DECLARE(glm_vec2_addadd) +TEST_DECLARE(glm_vec2_subadd) +TEST_DECLARE(glm_vec2_muladd) +TEST_DECLARE(glm_vec2_muladds) +TEST_DECLARE(glm_vec2_maxadd) +TEST_DECLARE(glm_vec2_minadd) +TEST_DECLARE(glm_vec2_negate_to) +TEST_DECLARE(glm_vec2_negate) +TEST_DECLARE(glm_vec2_normalize) +TEST_DECLARE(glm_vec2_normalize_to) +TEST_DECLARE(glm_vec2_rotate) +TEST_DECLARE(glm_vec2_distance2) +TEST_DECLARE(glm_vec2_distance) +TEST_DECLARE(glm_vec2_maxv) +TEST_DECLARE(glm_vec2_minv) +TEST_DECLARE(glm_vec2_clamp) +TEST_DECLARE(glm_vec2_lerp) + + +TEST_DECLARE(glmc_vec2) +TEST_DECLARE(glmc_vec2_copy) +TEST_DECLARE(glmc_vec2_zero) +TEST_DECLARE(glmc_vec2_one) +TEST_DECLARE(glmc_vec2_dot) +TEST_DECLARE(glmc_vec2_cross) +TEST_DECLARE(glmc_vec2_norm2) +TEST_DECLARE(glmc_vec2_norm) +TEST_DECLARE(glmc_vec2_add) +TEST_DECLARE(glmc_vec2_adds) +TEST_DECLARE(glmc_vec2_sub) +TEST_DECLARE(glmc_vec2_subs) +TEST_DECLARE(glmc_vec2_mul) +TEST_DECLARE(glmc_vec2_scale) +TEST_DECLARE(glmc_vec2_scale_as) +TEST_DECLARE(glmc_vec2_div) +TEST_DECLARE(glmc_vec2_divs) +TEST_DECLARE(glmc_vec2_addadd) +TEST_DECLARE(glmc_vec2_subadd) +TEST_DECLARE(glmc_vec2_muladd) +TEST_DECLARE(glmc_vec2_muladds) +TEST_DECLARE(glmc_vec2_maxadd) +TEST_DECLARE(glmc_vec2_minadd) +TEST_DECLARE(glmc_vec2_negate_to) +TEST_DECLARE(glmc_vec2_negate) +TEST_DECLARE(glmc_vec2_normalize) +TEST_DECLARE(glmc_vec2_normalize_to) +TEST_DECLARE(glmc_vec2_rotate) +TEST_DECLARE(glmc_vec2_distance2) +TEST_DECLARE(glmc_vec2_distance) +TEST_DECLARE(glmc_vec2_maxv) +TEST_DECLARE(glmc_vec2_minv) +TEST_DECLARE(glmc_vec2_clamp) +TEST_DECLARE(glmc_vec2_lerp) + /* vec3 */ TEST_DECLARE(MACRO_GLM_VEC3_ONE_INIT) TEST_DECLARE(MACRO_GLM_VEC3_ZERO_INIT) @@ -834,6 +913,84 @@ TEST_LIST { /* bezier */ TEST_ENTRY(bezier) + /* Macros */ + + TEST_ENTRY(MACRO_GLM_VEC2_ONE_INIT) + TEST_ENTRY(MACRO_GLM_VEC2_ZERO_INIT) + TEST_ENTRY(MACRO_GLM_VEC2_ONE) + TEST_ENTRY(MACRO_GLM_VEC2_ZERO) + + TEST_ENTRY(glm_vec2) + TEST_ENTRY(glm_vec2_copy) + TEST_ENTRY(glm_vec2_zero) + TEST_ENTRY(glm_vec2_one) + TEST_ENTRY(glm_vec2_dot) + TEST_ENTRY(glm_vec2_cross) + TEST_ENTRY(glm_vec2_norm2) + TEST_ENTRY(glm_vec2_norm) + TEST_ENTRY(glm_vec2_add) + TEST_ENTRY(glm_vec2_adds) + TEST_ENTRY(glm_vec2_sub) + TEST_ENTRY(glm_vec2_subs) + TEST_ENTRY(glm_vec2_mul) + TEST_ENTRY(glm_vec2_scale) + TEST_ENTRY(glm_vec2_scale_as) + TEST_ENTRY(glm_vec2_div) + TEST_ENTRY(glm_vec2_divs) + TEST_ENTRY(glm_vec2_addadd) + TEST_ENTRY(glm_vec2_subadd) + TEST_ENTRY(glm_vec2_muladd) + TEST_ENTRY(glm_vec2_muladds) + TEST_ENTRY(glm_vec2_maxadd) + TEST_ENTRY(glm_vec2_minadd) + TEST_ENTRY(glm_vec2_negate_to) + TEST_ENTRY(glm_vec2_negate) + TEST_ENTRY(glm_vec2_normalize) + TEST_ENTRY(glm_vec2_normalize_to) + TEST_ENTRY(glm_vec2_rotate) + TEST_ENTRY(glm_vec2_distance2) + TEST_ENTRY(glm_vec2_distance) + TEST_ENTRY(glm_vec2_maxv) + TEST_ENTRY(glm_vec2_minv) + TEST_ENTRY(glm_vec2_clamp) + TEST_ENTRY(glm_vec2_lerp) + + + TEST_ENTRY(glmc_vec2) + TEST_ENTRY(glmc_vec2_copy) + TEST_ENTRY(glmc_vec2_zero) + TEST_ENTRY(glmc_vec2_one) + TEST_ENTRY(glmc_vec2_dot) + TEST_ENTRY(glmc_vec2_cross) + TEST_ENTRY(glmc_vec2_norm2) + TEST_ENTRY(glmc_vec2_norm) + TEST_ENTRY(glmc_vec2_add) + TEST_ENTRY(glmc_vec2_adds) + TEST_ENTRY(glmc_vec2_sub) + TEST_ENTRY(glmc_vec2_subs) + TEST_ENTRY(glmc_vec2_mul) + TEST_ENTRY(glmc_vec2_scale) + TEST_ENTRY(glmc_vec2_scale_as) + TEST_ENTRY(glmc_vec2_div) + TEST_ENTRY(glmc_vec2_divs) + TEST_ENTRY(glmc_vec2_addadd) + TEST_ENTRY(glmc_vec2_subadd) + TEST_ENTRY(glmc_vec2_muladd) + TEST_ENTRY(glmc_vec2_muladds) + TEST_ENTRY(glmc_vec2_maxadd) + TEST_ENTRY(glmc_vec2_minadd) + TEST_ENTRY(glmc_vec2_negate_to) + TEST_ENTRY(glmc_vec2_negate) + TEST_ENTRY(glmc_vec2_normalize) + TEST_ENTRY(glmc_vec2_normalize_to) + TEST_ENTRY(glmc_vec2_rotate) + TEST_ENTRY(glmc_vec2_distance2) + TEST_ENTRY(glmc_vec2_distance) + TEST_ENTRY(glmc_vec2_maxv) + TEST_ENTRY(glmc_vec2_minv) + TEST_ENTRY(glmc_vec2_clamp) + TEST_ENTRY(glmc_vec2_lerp) + /* vec3 */ /* Macros */ From ad9370537c64c461e080608a3b88c39199bc4fe4 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 24 Feb 2020 22:14:26 +0300 Subject: [PATCH 10/14] add tests for mat2 and its call version --- include/cglm/mat2.h | 2 +- test/src/test_common.c | 89 ++++++++++--- test/src/test_common.h | 15 +++ test/src/test_mat2.h | 286 +++++++++++++++++++++++++++++++++++++++++ test/src/tests.c | 2 + test/tests.h | 74 ++++++++++- 6 files changed, 450 insertions(+), 18 deletions(-) create mode 100644 test/src/test_mat2.h diff --git a/include/cglm/mat2.h b/include/cglm/mat2.h index e7a865b..69d27d3 100644 --- a/include/cglm/mat2.h +++ b/include/cglm/mat2.h @@ -245,7 +245,7 @@ glm_mat2_inv(mat2 mat, mat2 dest) { float a = mat[0][0], b = mat[0][1], c = mat[1][0], d = mat[1][1]; - det = 1.0f / (a * d - c * b); + det = 1.0f / (a * d - b * c); dest[0][0] = d * det; dest[0][1] = -b * det; diff --git a/test/src/test_common.c b/test/src/test_common.c index 6459aa8..c352c89 100644 --- a/test/src/test_common.c +++ b/test/src/test_common.c @@ -31,6 +31,14 @@ test_rand_mat3(mat3 dest) { glm_mat4_pick3(m4, dest); } +void +test_rand_mat2(mat2 dest) { + dest[0][0] = drand48(); + dest[0][1] = drand48(); + dest[1][0] = drand48(); + dest[1][1] = drand48(); +} + void test_rand_vec3(vec3 dest) { dest[0] = drand48(); @@ -73,12 +81,11 @@ test_rand_quat(versor q) { test_status_t test_assert_mat4_eq(mat4 m1, mat4 m2) { - int i, j, k; + int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - for (k = 0; k < 4; k++) - ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009) + ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009) } } @@ -87,12 +94,11 @@ test_assert_mat4_eq(mat4 m1, mat4 m2) { test_status_t test_assert_mat4_eqt(mat4 m1, mat4 m2) { - int i, j, k; + int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - for (k = 0; k < 4; k++) - ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009) + ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009) } } @@ -101,12 +107,67 @@ test_assert_mat4_eqt(mat4 m1, mat4 m2) { test_status_t test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps) { - int i, j, k; + int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - for (k = 0; k < 4; k++) - ASSERT(fabsf(m1[i][j] - m2[i][j]) <= eps); + ASSERT(fabsf(m1[i][j] - m2[i][j]) <= eps); + } + } + + TEST_SUCCESS +} + +test_status_t +test_assert_mat2_eqt(mat2 m1, mat2 m2) { + int i, j; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009); + } + } + + TEST_SUCCESS +} + +test_status_t +test_assert_mat2_eq(mat2 m1, mat2 m2) { + int i, j; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009); + } + } + + TEST_SUCCESS +} + +test_status_t +test_assert_mat2_eq_identity(mat2 m2) { + int i, j; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + if (i == j) { + ASSERT(test_eq(m2[i][j], 1.0f)) + } else { + ASSERT(test_eq(m2[i][j], 0.0f)) + } + } + } + + TEST_SUCCESS +} + +test_status_t +test_assert_mat2_eq_zero(mat2 m2) { + int i, j; + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + ASSERT(test_eq(m2[i][j], 0.0f)) } } @@ -115,12 +176,11 @@ test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps) { test_status_t test_assert_mat3_eq(mat3 m1, mat3 m2) { - int i, j, k; + int i, j; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { - for (k = 0; k < 3; k++) - ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009); + ASSERT(fabsf(m1[i][j] - m2[i][j]) <= 0.0000009); } } @@ -129,12 +189,11 @@ test_assert_mat3_eq(mat3 m1, mat3 m2) { test_status_t test_assert_mat3_eqt(mat3 m1, mat3 m2) { - int i, j, k; + int i, j; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { - for (k = 0; k < 3; k++) - ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009); + ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009); } } diff --git a/test/src/test_common.h b/test/src/test_common.h index 6dcb878..86801b6 100644 --- a/test/src/test_common.h +++ b/test/src/test_common.h @@ -16,6 +16,9 @@ test_rand_mat4(mat4 dest); void test_rand_mat3(mat3 dest); +void +test_rand_mat2(mat2 dest); + test_status_t test_assert_eqf(float a, float b); @@ -34,6 +37,18 @@ test_assert_mat4_eq_identity(mat4 m4); test_status_t test_assert_mat4_eq_zero(mat4 m4); +test_status_t +test_assert_mat2_eqt(mat2 m1, mat2 m2); + +test_status_t +test_assert_mat2_eq(mat2 m1, mat2 m2); + +test_status_t +test_assert_mat2_eq_identity(mat2 m2); + +test_status_t +test_assert_mat2_eq_zero(mat2 m2); + test_status_t test_assert_mat3_eq(mat3 m1, mat3 m2); diff --git a/test/src/test_mat2.h b/test/src/test_mat2.h new file mode 100644 index 0000000..9141caf --- /dev/null +++ b/test/src/test_mat2.h @@ -0,0 +1,286 @@ +/* + * 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" + +#define A_MATRIX2x2 {{1,2},{5,6}} + +#ifndef CGLM_TEST_MAT2_ONCE +#define CGLM_TEST_MAT2_ONCE + +TEST_IMPL(MACRO_GLM_MAT2_IDENTITY_INIT) { + mat2 m = GLM_MAT2_IDENTITY_INIT; + + ASSERT(test_eq(m[0][0], 1.0f)) + ASSERT(test_eq(m[0][1], 0.0f)) + ASSERT(test_eq(m[1][0], 0.0f)) + ASSERT(test_eq(m[1][1], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(MACRO_GLM_MAT2_ZERO_INIT) { + mat2 m = GLM_MAT2_ZERO_INIT; + + ASSERT(test_eq(m[0][0], 0.0f)) + ASSERT(test_eq(m[0][1], 0.0f)) + ASSERT(test_eq(m[1][0], 0.0f)) + ASSERT(test_eq(m[1][1], 0.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(MACRO_GLM_MAT2_IDENTITY) { + ASSERT(test_eq(GLM_MAT2_IDENTITY[0][0], 1.0f)) + ASSERT(test_eq(GLM_MAT2_IDENTITY[0][1], 0.0f)) + ASSERT(test_eq(GLM_MAT2_IDENTITY[1][0], 0.0f)) + ASSERT(test_eq(GLM_MAT2_IDENTITY[1][1], 1.0f)) + + TEST_SUCCESS +} + +TEST_IMPL(MACRO_GLM_MAT2_ZERO) { + ASSERT(test_eq(GLM_MAT2_ZERO[0][0], 0.0f)) + ASSERT(test_eq(GLM_MAT2_ZERO[0][1], 0.0f)) + ASSERT(test_eq(GLM_MAT2_ZERO[1][0], 0.0f)) + ASSERT(test_eq(GLM_MAT2_ZERO[1][1], 0.0f)) + + TEST_SUCCESS +} + +#endif /* CGLM_TEST_MAT2_ONCE */ + +TEST_IMPL(GLM_PREFIX, mat2_copy) { + mat2 m1 = A_MATRIX2x2; + mat2 m2 = GLM_MAT2_IDENTITY_INIT; + + GLM(mat2_copy)(m1, m2); + + test_assert_mat2_eq(m1, m2); + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_identity) { + mat2 m1 = GLM_MAT2_IDENTITY_INIT; + mat2 m2 = GLM_MAT2_IDENTITY_INIT; + mat2 m3; + + GLM(mat2_identity)(m3); + + ASSERTIFY(test_assert_mat2_eq_identity(m1)) + ASSERTIFY(test_assert_mat2_eq_identity(m2)) + ASSERTIFY(test_assert_mat2_eq_identity(m3)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_identity_array) { + int i, count; + mat2 matrices[4] = { + A_MATRIX2x2, + A_MATRIX2x2, + A_MATRIX2x2, + A_MATRIX2x2 + }; + + count = 4; + + GLM(mat2_identity_array)(matrices, count); + + for (i = 0; i < count; i++) { + ASSERTIFY(test_assert_mat2_eq_identity(matrices[i])) + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_zero) { + mat2 m1 = GLM_MAT2_ZERO_INIT; + mat2 m2 = GLM_MAT2_ZERO_INIT; + mat2 m3; + + GLM(mat2_zero)(m3); + + ASSERTIFY(test_assert_mat2_eq_zero(m1)) + ASSERTIFY(test_assert_mat2_eq_zero(m2)) + ASSERTIFY(test_assert_mat2_eq_zero(m3)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_mul) { + mat2 m1 = GLM_MAT2_IDENTITY_INIT; + mat2 m2 = GLM_MAT2_IDENTITY_INIT; + mat2 m3; + mat2 m4 = GLM_MAT2_ZERO_INIT; + int i, j, k; + + /* test random matrices */ + /* random matrices */ + test_rand_mat2(m1); + test_rand_mat2(m2); + + GLM(mat2_mul)(m1, m2, m3); + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) + /* column-major */ + m4[i][j] += m1[k][j] * m2[i][k]; + } + } + + ASSERTIFY(test_assert_mat2_eq(m3, m4)) + + /* test pre compiled */ + GLM(mat2_mul)(m1, m2, m3); + ASSERTIFY(test_assert_mat2_eq(m3, m4)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_transpose_to) { + mat2 mat = A_MATRIX2x2; + mat2 m1; + + GLM(mat2_transpose_to)(mat, m1); + + ASSERTIFY(test_assert_mat2_eqt(mat, m1)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_transpose) { + mat2 mat = A_MATRIX2x2; + mat2 m1; + + GLM(mat2_copy)(mat, m1); + GLM(mat2_transpose)(m1); + + ASSERTIFY(test_assert_mat2_eqt(mat, m1)) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_mulv) { + vec2 res; + mat2 mat = A_MATRIX2x2; + vec2 v = {11.0f, 21.0f}; + int i; + + GLM(mat2_mulv)(mat, v, res); + + for (i = 0; i < 2; i++) { + ASSERT(test_eq(res[i], v[0] * mat[0][i] + v[1] * mat[1][i])) + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_trace) { + mat2 mat = A_MATRIX2x2; + float trace; + + trace = GLM(mat2_trace)(mat); + + ASSERT(test_eq(trace, mat[0][0] + mat[1][1])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_scale) { + mat2 m1 = A_MATRIX2x2; + mat2 m2 = A_MATRIX2x2; + int i, j, scale; + + scale = rand() % 100; + + GLM(mat2_scale)(m1, (float)scale); + + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + ASSERT(test_eq(m1[i][j], m2[i][j] * scale)) + } + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_det) { + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_inv) { + mat2 m1 = GLM_MAT2_IDENTITY_INIT; + mat2 m2 = GLM_MAT2_IDENTITY_INIT; + mat2 m3; + int i; + + m1[0][0] = 41.0f; + m1[0][1] = 0.0f; + m1[1][0] = 0.0f; + m1[1][1] = 70.0f; + + for (i = 0; i < 10000; i++) { + /* test inverse precise */ + GLM(mat2_inv)(m1, m2); + GLM(mat2_inv)(m2, m3); + + ASSERTIFY(test_assert_mat2_eq(m1, m3)) + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_swap_col) { + mat2 m1 = A_MATRIX2x2; + mat2 m2 = A_MATRIX2x2; + + GLM(mat2_swap_col)(m1, 0, 1); + + ASSERTIFY(test_assert_vec2_eq(m1[0], m2[1])) + ASSERTIFY(test_assert_vec2_eq(m1[1], m2[0])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_swap_row) { + mat2 m1 = A_MATRIX2x2; + mat2 m2 = A_MATRIX2x2; + + GLM(mat2_swap_row)(m1, 0, 1); + + ASSERT(test_eq(m1[0][0], m2[0][1])) + ASSERT(test_eq(m1[0][1], m2[0][0])) + + ASSERT(test_eq(m1[1][0], m2[1][1])) + ASSERT(test_eq(m1[1][1], m2[1][0])) + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, mat2_rmc) { + mat2 mat = A_MATRIX2x2; + vec2 v = {11.0f, 12.0f}; + vec2 v1; + float r1, r2; + int i; + + r1 = GLM(mat2_rmc)(v, mat, v); + + for (i = 0; i < 2; i++) { + v1[i] = v[0] * mat[i][0] + v[1] * mat[i][1]; + } + + r2 = v[0] * v1[0] + v[1] * v1[1]; + + ASSERT(test_eq(r1, r2)) + + TEST_SUCCESS +} + +#undef A_MATRIX2x2 diff --git a/test/src/tests.c b/test/src/tests.c index 90b8dee..669b33c 100644 --- a/test/src/tests.c +++ b/test/src/tests.c @@ -15,6 +15,7 @@ #include "test_vec2.h" #include "test_vec3.h" #include "test_vec4.h" +#include "test_mat2.h" #include "test_mat3.h" #include "test_mat4.h" #include "test_quat.h" @@ -35,6 +36,7 @@ #include "test_vec2.h" #include "test_vec3.h" #include "test_vec4.h" +#include "test_mat2.h" #include "test_mat3.h" #include "test_mat4.h" #include "test_quat.h" diff --git a/test/tests.h b/test/tests.h index e026ed0..4c9a552 100644 --- a/test/tests.h +++ b/test/tests.h @@ -159,6 +159,42 @@ TEST_DECLARE(glmc_mat3_swap_col) TEST_DECLARE(glmc_mat3_swap_row) TEST_DECLARE(glmc_mat3_rmc) +TEST_DECLARE(MACRO_GLM_MAT2_IDENTITY_INIT) +TEST_DECLARE(MACRO_GLM_MAT2_ZERO_INIT) +TEST_DECLARE(MACRO_GLM_MAT2_IDENTITY) +TEST_DECLARE(MACRO_GLM_MAT2_ZERO) +TEST_DECLARE(glm_mat2_copy) +TEST_DECLARE(glm_mat2_identity) +TEST_DECLARE(glm_mat2_identity_array) +TEST_DECLARE(glm_mat2_zero) +TEST_DECLARE(glm_mat2_mul) +TEST_DECLARE(glm_mat2_transpose_to) +TEST_DECLARE(glm_mat2_transpose) +TEST_DECLARE(glm_mat2_mulv) +TEST_DECLARE(glm_mat2_trace) +TEST_DECLARE(glm_mat2_scale) +TEST_DECLARE(glm_mat2_det) +TEST_DECLARE(glm_mat2_inv) +TEST_DECLARE(glm_mat2_swap_col) +TEST_DECLARE(glm_mat2_swap_row) +TEST_DECLARE(glm_mat2_rmc) + +TEST_DECLARE(glmc_mat2_copy) +TEST_DECLARE(glmc_mat2_identity) +TEST_DECLARE(glmc_mat2_identity_array) +TEST_DECLARE(glmc_mat2_zero) +TEST_DECLARE(glmc_mat2_mul) +TEST_DECLARE(glmc_mat2_transpose_to) +TEST_DECLARE(glmc_mat2_transpose) +TEST_DECLARE(glmc_mat2_mulv) +TEST_DECLARE(glmc_mat2_trace) +TEST_DECLARE(glmc_mat2_scale) +TEST_DECLARE(glmc_mat2_det) +TEST_DECLARE(glmc_mat2_inv) +TEST_DECLARE(glmc_mat2_swap_col) +TEST_DECLARE(glmc_mat2_swap_row) +TEST_DECLARE(glmc_mat2_rmc) + /* camera */ TEST_DECLARE(camera_lookat) TEST_DECLARE(camera_decomp) @@ -775,7 +811,6 @@ TEST_LIST { TEST_ENTRY(glmc_mat4_swap_row) TEST_ENTRY(glmc_mat4_rmc) - /* mat3 */ TEST_ENTRY(glm_mat3_copy) TEST_ENTRY(glm_mat3_identity) @@ -811,6 +846,42 @@ TEST_LIST { TEST_ENTRY(glmc_mat3_swap_row) TEST_ENTRY(glmc_mat3_rmc) + TEST_ENTRY(MACRO_GLM_MAT2_IDENTITY_INIT) + TEST_ENTRY(MACRO_GLM_MAT2_ZERO_INIT) + TEST_ENTRY(MACRO_GLM_MAT2_IDENTITY) + TEST_ENTRY(MACRO_GLM_MAT2_ZERO) + TEST_ENTRY(glm_mat2_copy) + TEST_ENTRY(glm_mat2_identity) + TEST_ENTRY(glm_mat2_identity_array) + TEST_ENTRY(glm_mat2_zero) + TEST_ENTRY(glm_mat2_mul) + TEST_ENTRY(glm_mat2_transpose_to) + TEST_ENTRY(glm_mat2_transpose) + TEST_ENTRY(glm_mat2_mulv) + TEST_ENTRY(glm_mat2_trace) + TEST_ENTRY(glm_mat2_scale) + TEST_ENTRY(glm_mat2_det) + TEST_ENTRY(glm_mat2_inv) + TEST_ENTRY(glm_mat2_swap_col) + TEST_ENTRY(glm_mat2_swap_row) + TEST_ENTRY(glm_mat2_rmc) + + TEST_ENTRY(glmc_mat2_copy) + TEST_ENTRY(glmc_mat2_identity) + TEST_ENTRY(glmc_mat2_identity_array) + TEST_ENTRY(glmc_mat2_zero) + TEST_ENTRY(glmc_mat2_mul) + TEST_ENTRY(glmc_mat2_transpose_to) + TEST_ENTRY(glmc_mat2_transpose) + TEST_ENTRY(glmc_mat2_mulv) + TEST_ENTRY(glmc_mat2_trace) + TEST_ENTRY(glmc_mat2_scale) + TEST_ENTRY(glmc_mat2_det) + TEST_ENTRY(glmc_mat2_inv) + TEST_ENTRY(glmc_mat2_swap_col) + TEST_ENTRY(glmc_mat2_swap_row) + TEST_ENTRY(glmc_mat2_rmc) + /* camera */ TEST_ENTRY(camera_lookat) TEST_ENTRY(camera_decomp) @@ -955,7 +1026,6 @@ TEST_LIST { TEST_ENTRY(glm_vec2_clamp) TEST_ENTRY(glm_vec2_lerp) - TEST_ENTRY(glmc_vec2) TEST_ENTRY(glmc_vec2_copy) TEST_ENTRY(glmc_vec2_zero) From 701a95583aba506d607fd7241c270cc2c227f24d Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 24 Feb 2020 22:21:43 +0300 Subject: [PATCH 11/14] vec2: fix memory access error[s] --- include/cglm/vec2.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h index 3dd4645..9ad4cdc 100644 --- a/include/cglm/vec2.h +++ b/include/cglm/vec2.h @@ -233,7 +233,7 @@ glm_vec2_subs(vec2 v, float s, vec2 dest) { * * @param a v1 * @param b v2 - * @param dest v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2]) + * @param dest v3 = (a[0] * b[0], a[1] * b[1]) */ CGLM_INLINE void @@ -282,7 +282,7 @@ glm_vec2_scale_as(vec2 v, float s, vec2 dest) { * * @param[in] a vector 1 * @param[in] b vector 2 - * @param[out] dest result = (a[0]/b[0], a[1]/b[1], a[2]/b[2]) + * @param[out] dest result = (a[0]/b[0], a[1]/b[1]) */ CGLM_INLINE void @@ -296,7 +296,7 @@ glm_vec2_div(vec2 a, vec2 b, vec2 dest) { * * @param[in] v vector * @param[in] s scalar - * @param[out] dest result = (a[0]/s, a[1]/s, a[2]/s) + * @param[out] dest result = (a[0]/s, a[1]/s) */ CGLM_INLINE void @@ -438,7 +438,7 @@ glm_vec2_normalize(vec2 v) { norm = glm_vec2_norm(v); if (norm == 0.0f) { - v[0] = v[1] = v[2] = 0.0f; + v[0] = v[1] = 0.0f; return; } From ab20ebc28cf65f7098936c8b49d953190d6604c9 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 24 Feb 2020 22:22:27 +0300 Subject: [PATCH 12/14] build: add vec2 and mat2 files --- Makefile.am | 7 +++++++ win/cglm-test.vcxproj | 5 +++++ win/cglm-test.vcxproj.filters | 15 +++++++++++++++ win/cglm.vcxproj | 8 ++++++++ win/cglm.vcxproj.filters | 26 +++++++++++++++++++++++++- 5 files changed, 60 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index f755b65..8d4246e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,7 +42,10 @@ cglm_HEADERS = include/cglm/version.h \ include/cglm/io.h \ include/cglm/mat4.h \ include/cglm/mat3.h \ + include/cglm/mat2.h \ include/cglm/affine.h \ + include/cglm/vec2.h \ + include/cglm/vec2-ext.h \ include/cglm/vec3.h \ include/cglm/vec3-ext.h \ include/cglm/vec4.h \ @@ -65,6 +68,8 @@ cglm_HEADERS = include/cglm/version.h \ cglm_calldir=$(includedir)/cglm/call cglm_call_HEADERS = include/cglm/call/mat4.h \ include/cglm/call/mat3.h \ + include/cglm/call/mat2.h \ + include/cglm/call/vec2.h \ include/cglm/call/vec3.h \ include/cglm/call/vec4.h \ include/cglm/call/affine.h \ @@ -125,8 +130,10 @@ libcglm_la_SOURCES=\ src/io.c \ src/quat.c \ src/cam.c \ + src/vec2.c \ src/vec3.c \ src/vec4.c \ + src/mat2.c \ src/mat3.c \ src/mat4.c \ src/plane.c \ diff --git a/win/cglm-test.vcxproj b/win/cglm-test.vcxproj index f7ccc91..1c0916d 100644 --- a/win/cglm-test.vcxproj +++ b/win/cglm-test.vcxproj @@ -30,11 +30,16 @@ + + + + + diff --git a/win/cglm-test.vcxproj.filters b/win/cglm-test.vcxproj.filters index 66691ff..c81dc11 100644 --- a/win/cglm-test.vcxproj.filters +++ b/win/cglm-test.vcxproj.filters @@ -64,5 +64,20 @@ src + + src + + + src + + + src + + + src + + + src + \ No newline at end of file diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj index dcb9a76..9b7a84b 100644 --- a/win/cglm.vcxproj +++ b/win/cglm.vcxproj @@ -28,18 +28,21 @@ + + + @@ -52,12 +55,14 @@ + + @@ -69,6 +74,7 @@ + @@ -94,6 +100,7 @@ + @@ -107,6 +114,7 @@ + diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters index 917f837..cf5beb2 100644 --- a/win/cglm.vcxproj.filters +++ b/win/cglm.vcxproj.filters @@ -86,6 +86,12 @@ src + + src + + + src + @@ -254,7 +260,7 @@ include\cglm\call - include\cglm + include\cglm include\cglm\struct @@ -316,5 +322,23 @@ include\cglm + + include\cglm\call + + + include\cglm\call + + + include\cglm\struct + + + include\cglm + + + include\cglm + + + include\cglm + \ No newline at end of file From 638b9f6dbe083450c633b4c1e276505c1ccb6b54 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 24 Feb 2020 23:11:03 +0300 Subject: [PATCH 13/14] =?UTF-8?q?fix=20'function=20declaration=20isn?= =?UTF-8?q?=E2=80=99t=20a=20prototype'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/cglm/struct/mat2.h | 4 ++-- test/src/test_common.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/cglm/struct/mat2.h b/include/cglm/struct/mat2.h index 7b2de89..c73f13c 100644 --- a/include/cglm/struct/mat2.h +++ b/include/cglm/struct/mat2.h @@ -59,7 +59,7 @@ */ CGLM_INLINE mat2s -glms_mat2_identity() { +glms_mat2_identity(void) { mat2s r; glm_mat2_identity(r.raw); return r; @@ -91,7 +91,7 @@ glms_mat2_identity_array(mat2s * __restrict mat, size_t count) { */ CGLM_INLINE mat2s -glms_mat2_zero() { +glms_mat2_zero(void) { mat2s r; glm_mat2_zero(r.raw); return r; diff --git a/test/src/test_common.c b/test/src/test_common.c index c352c89..46b6e63 100644 --- a/test/src/test_common.c +++ b/test/src/test_common.c @@ -47,7 +47,7 @@ test_rand_vec3(vec3 dest) { } vec3s -test_rand_vec3s() { +test_rand_vec3s(void) { vec3s r; test_rand_vec3(r.raw); return r; @@ -62,7 +62,7 @@ test_rand_vec4(vec4 dest) { } vec4s -test_rand_vec4s() { +test_rand_vec4s(void) { vec4s r; test_rand_vec4(r.raw); return r; From eb0d47cfa17b7259d77cfc7955c02345bb55af3b Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Tue, 25 Feb 2020 14:34:11 +0300 Subject: [PATCH 14/14] vec2: add struct version for vec2 and vec2-ext --- Makefile.am | 2 + include/cglm/struct.h | 1 + include/cglm/struct/vec2-ext.h | 198 ++++++++++++ include/cglm/struct/vec2.h | 561 +++++++++++++++++++++++++++++++++ include/cglm/vec2-ext.h | 8 +- include/cglm/vec2.h | 2 +- test/src/test_affine.h | 6 +- win/cglm.vcxproj | 2 + win/cglm.vcxproj.filters | 6 + 9 files changed, 778 insertions(+), 8 deletions(-) create mode 100644 include/cglm/struct/vec2-ext.h create mode 100644 include/cglm/struct/vec2.h diff --git a/Makefile.am b/Makefile.am index 8d4246e..371dd29 100644 --- a/Makefile.am +++ b/Makefile.am @@ -107,6 +107,8 @@ cglm_simd_neon_HEADERS = include/cglm/simd/neon/mat4.h cglm_structdir=$(includedir)/cglm/struct cglm_struct_HEADERS = include/cglm/struct/mat4.h \ include/cglm/struct/mat3.h \ + include/cglm/struct/vec2.h \ + include/cglm/struct/vec2-ext.h \ include/cglm/struct/vec3.h \ include/cglm/struct/vec3-ext.h \ include/cglm/struct/vec4.h \ diff --git a/include/cglm/struct.h b/include/cglm/struct.h index 87b47a8..654a1d4 100644 --- a/include/cglm/struct.h +++ b/include/cglm/struct.h @@ -13,6 +13,7 @@ extern "C" { #include "cglm.h" #include "types-struct.h" +#include "struct/vec2.h" #include "struct/vec3.h" #include "struct/vec4.h" #include "struct/mat2.h" diff --git a/include/cglm/struct/vec2-ext.h b/include/cglm/struct/vec2-ext.h new file mode 100644 index 0000000..d77debe --- /dev/null +++ b/include/cglm/struct/vec2-ext.h @@ -0,0 +1,198 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +/*! + * @brief SIMD like functions + */ + +/* + Functions: + CGLM_INLINE vec2s glms_vec2_fill(float val) + CGLM_INLINE bool glms_vec2_eq(vec2s v, float val) + CGLM_INLINE bool glms_vec2_eq_eps(vec2s v, float val) + CGLM_INLINE bool glms_vec2_eq_all(vec2s v) + CGLM_INLINE bool glms_vec2_eqv(vec2s a, vec2s b) + CGLM_INLINE bool glms_vec2_eqv_eps(vec2s a, vec2s b) + CGLM_INLINE float glms_vec2_max(vec2s v) + CGLM_INLINE float glms_vec2_min(vec2s v) + CGLM_INLINE bool glms_vec2_isnan(vec2s v) + CGLM_INLINE bool glms_vec2_isinf(vec2s v) + CGLM_INLINE bool glms_vec2_isvalid(vec2s v) + CGLM_INLINE vec2s glms_vec2_sign(vec2s v) + CGLM_INLINE vec2s glms_vec2_sqrt(vec2s v) + */ + +#ifndef cglms_vec2s_ext_h +#define cglms_vec2s_ext_h + +#include "../common.h" +#include "../types-struct.h" +#include "../util.h" +#include "../vec2-ext.h" + +/*! + * @brief fill a vector with specified value + * + * @param[in] val value + * @returns dest + */ +CGLM_INLINE +vec2s +glms_vec2_fill(float val) { + vec2s r; + glm_vec2_fill(r.raw, val); + return r; +} + +/*! + * @brief check if vector is equal to value (without epsilon) + * + * @param[in] v vector + * @param[in] val value + */ +CGLM_INLINE +bool +glms_vec2_eq(vec2s v, float val) { + return glm_vec2_eq(v.raw, val); +} + +/*! + * @brief check if vector is equal to value (with epsilon) + * + * @param[in] v vector + * @param[in] val value + */ +CGLM_INLINE +bool +glms_vec2_eq_eps(vec2s v, float val) { + return glm_vec2_eq_eps(v.raw, val); +} + +/*! + * @brief check if vectors members are equal (without epsilon) + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glms_vec2_eq_all(vec2s v) { + return glm_vec2_eq_all(v.raw); +} + +/*! + * @brief check if vector is equal to another (without epsilon) + * + * @param[in] a vector + * @param[in] b vector + */ +CGLM_INLINE +bool +glms_vec2_eqv(vec2s a, vec2s b) { + return glm_vec2_eqv(a.raw, b.raw); +} + +/*! + * @brief check if vector is equal to another (with epsilon) + * + * @param[in] a vector + * @param[in] b vector + */ +CGLM_INLINE +bool +glms_vec2_eqv_eps(vec2s a, vec2s b) { + return glm_vec2_eqv_eps(a.raw, b.raw); +} + +/*! + * @brief max value of vector + * + * @param[in] v vector + */ +CGLM_INLINE +float +glms_vec2_max(vec2s v) { + return glm_vec2_max(v.raw); +} + +/*! + * @brief min value of vector + * + * @param[in] v vector + */ +CGLM_INLINE +float +glms_vec2_min(vec2s v) { + return glm_vec2_min(v.raw); +} + +/*! + * @brief check if all items are NaN (not a number) + * you should only use this in DEBUG mode or very critical asserts + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glms_vec2_isnan(vec2s v) { + return glm_vec2_isnan(v.raw); +} + +/*! + * @brief check if all items are INFINITY + * you should only use this in DEBUG mode or very critical asserts + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glms_vec2_isinf(vec2s v) { + return glm_vec2_isinf(v.raw); +} + +/*! + * @brief check if all items are valid number + * you should only use this in DEBUG mode or very critical asserts + * + * @param[in] v vector + */ +CGLM_INLINE +bool +glms_vec2_isvalid(vec2s v) { + return glm_vec2_isvalid(v.raw); +} + +/*! + * @brief get sign of 32 bit float as +1, -1, 0 + * + * Important: It returns 0 for zero/NaN input + * + * @param v vector + * @returns sign vector + */ +CGLM_INLINE +vec2s +glms_vec2_sign(vec2s v) { + vec2s r; + glm_vec2_sign(v.raw, r.raw); + return r; +} + +/*! + * @brief square root of each vector item + * + * @param[in] v vector + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_sqrt(vec2s v) { + vec2s r; + glm_vec2_sqrt(v.raw, r.raw); + return r; +} + +#endif /* cglms_vec2s_ext_h */ diff --git a/include/cglm/struct/vec2.h b/include/cglm/struct/vec2.h new file mode 100644 index 0000000..e6ea945 --- /dev/null +++ b/include/cglm/struct/vec2.h @@ -0,0 +1,561 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +/* + Macros: + GLMS_VEC2_ONE_INIT + GLMS_VEC2_ZERO_INIT + GLMS_VEC2_ONE + GLMS_VEC2_ZERO + + Functions: + CGLM_INLINE vec2s glms_vec2(vec3s v3) + CGLM_INLINE void glms_vec2_pack(vec2s dst[], vec2 src[], size_t len) + CGLM_INLINE void glms_vec2_unpack(vec2 dst[], vec2s src[], size_t len) + CGLM_INLINE vec2s glms_vec2_zero(void) + CGLM_INLINE vec2s glms_vec2_one(void) + CGLM_INLINE float glms_vec2_dot(vec2s a, vec2s b) + CGLM_INLINE float glms_vec2_cross(vec2s a, vec2s b) + CGLM_INLINE float glms_vec2_norm2(vec2s v) + CGLM_INLINE float glms_vec2_norm(vec2s v) + CGLM_INLINE vec2s glms_vec2_add(vec2s a, vec2s b) + CGLM_INLINE vec2s glms_vec2_adds(vec2s a, float s) + CGLM_INLINE vec2s glms_vec2_sub(vec2s a, vec2s b) + CGLM_INLINE vec2s glms_vec2_subs(vec2s a, float s) + CGLM_INLINE vec2s glms_vec2_mul(vec2s a, vec2s b) + CGLM_INLINE vec2s glms_vec2_scale(vec2s v, float s) + CGLM_INLINE vec2s glms_vec2_scale_as(vec2s v, float s) + CGLM_INLINE vec2s glms_vec2_div(vec2s a, vec2s b) + CGLM_INLINE vec2s glms_vec2_divs(vec2s a, float s) + CGLM_INLINE vec2s glms_vec2_addadd(vec2s a, vec2s b, vec2s dest) + CGLM_INLINE vec2s glms_vec2_subadd(vec2s a, vec2s b, vec2s dest) + CGLM_INLINE vec2s glms_vec2_muladd(vec2s a, vec2s b, vec2s dest) + CGLM_INLINE vec2s glms_vec2_muladds(vec2s a, float s, vec2s dest) + CGLM_INLINE vec2s glms_vec2_maxadd(vec2s a, vec2s b, vec2s dest) + CGLM_INLINE vec2s glms_vec2_minadd(vec2s a, vec2s b, vec2s dest) + CGLM_INLINE vec2s glms_vec2_negate(vec2s v) + CGLM_INLINE vec2s glms_vec2_normalize(vec2s v) + CGLM_INLINE vec2s glms_vec2_rotate(vec2s v, float angle, vec2s axis) + CGLM_INLINE float glms_vec2_distance(vec2s a, vec2s b) + CGLM_INLINE float glms_vec2_distance2(vec2s a, vec2s b) + CGLM_INLINE vec2s glms_vec2_maxv(vec2s a, vec2s b) + CGLM_INLINE vec2s glms_vec2_minv(vec2s a, vec2s b) + CGLM_INLINE vec2s glms_vec2_clamp(vec2s v, float minVal, float maxVal) + CGLM_INLINE vec2s glms_vec2_lerp(vec2s from, vec2s to, float t) + */ + +#ifndef cglms_vec2s_h +#define cglms_vec2s_h + +#include "../common.h" +#include "../types-struct.h" +#include "../util.h" +#include "../vec2.h" +#include "vec2-ext.h" + +#define GLMS_VEC2_ONE_INIT {GLM_VEC2_ONE_INIT} +#define GLMS_VEC2_ZERO_INIT {GLM_VEC2_ZERO_INIT} + +#define GLMS_VEC2_ONE ((vec2s)GLMS_VEC2_ONE_INIT) +#define GLMS_VEC2_ZERO ((vec2s)GLMS_VEC2_ZERO_INIT) + +/*! + * @brief init vec2 using vec2 + * + * @param[in] v4 vector3 + * @returns destination + */ +CGLM_INLINE +vec2s +glms_vec2(vec3s v3) { + vec2s r; + glm_vec2(v3.raw, r.raw); + return r; +} + +/*! + * @brief pack an array of vec2 into an array of vec2s + * + * @param[out] dst array of vec2 + * @param[in] src array of vec2s + * @param[in] len number of elements + */ +CGLM_INLINE +void +glms_vec2_pack(vec2s dst[], vec2 src[], size_t len) { + size_t i; + + for (i = 0; i < len; i++) { + glm_vec2_copy(src[i], dst[i].raw); + } +} + +/*! + * @brief unpack an array of vec2s into an array of vec2 + * + * @param[out] dst array of vec2s + * @param[in] src array of vec2 + * @param[in] len number of elements + */ +CGLM_INLINE +void +glms_vec2_unpack(vec2 dst[], vec2s src[], size_t len) { + size_t i; + + for (i = 0; i < len; i++) { + glm_vec2_copy(src[i].raw, dst[i]); + } +} + +/*! + * @brief make vector zero + * + * @returns zero vector + */ +CGLM_INLINE +vec2s +glms_vec2_zero(void) { + vec2s r; + glm_vec2_zero(r.raw); + return r; +} + +/*! + * @brief make vector one + * + * @returns one vector + */ +CGLM_INLINE +vec2s +glms_vec2_one(void) { + vec2s r; + glm_vec2_one(r.raw); + return r; +} + +/*! + * @brief vec2 dot product + * + * @param[in] a vector1 + * @param[in] b vector2 + * + * @return dot product + */ +CGLM_INLINE +float +glms_vec2_dot(vec2s a, vec2s b) { + return glm_vec2_dot(a.raw, b.raw); +} + +/*! + * @brief vec2 cross product + * + * REF: http://allenchou.net/2013/07/cross-product-of-2d-vectors/ + * + * @param[in] a vector1 + * @param[in] b vector2 + * + * @return Z component of cross product + */ +CGLM_INLINE +float +glms_vec2_cross(vec2s a, vec2s b) { + return glm_vec2_cross(a.raw, b.raw); +} + +/*! + * @brief norm * norm (magnitude) of vec + * + * we can use this func instead of calling norm * norm, because it would call + * sqrtf fuction twice but with this func we can avoid func call, maybe this is + * not good name for this func + * + * @param[in] v vector + * + * @return norm * norm + */ +CGLM_INLINE +float +glms_vec2_norm2(vec2s v) { + return glm_vec2_norm2(v.raw); +} + +/*! + * @brief norm (magnitude) of vec2 + * + * @param[in] v vector + * + * @return norm + */ +CGLM_INLINE +float +glms_vec2_norm(vec2s v) { + return glm_vec2_norm(v.raw); +} + +/*! + * @brief add a vector to b vector store result in dest + * + * @param[in] a vector1 + * @param[in] b vector2 + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_add(vec2s a, vec2s b) { + vec2s r; + glm_vec2_add(a.raw, b.raw, r.raw); + return r; +} + +/*! + * @brief add scalar to v vector store result in dest (d = v + s) + * + * @param[in] a vector + * @param[in] s scalar + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_adds(vec2s a, float s) { + vec2s r; + glm_vec2_adds(a.raw, s, r.raw); + return r; +} + +/*! + * @brief subtract b vector from a vector store result in dest + * + * @param[in] a vector1 + * @param[in] b vector2 + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_sub(vec2s a, vec2s b) { + vec2s r; + glm_vec2_sub(a.raw, b.raw, r.raw); + return r; +} + +/*! + * @brief subtract scalar from v vector store result in dest (d = v - s) + * + * @param[in] a vector + * @param[in] s scalar + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_subs(vec2s a, float s) { + vec2s r; + glm_vec2_subs(a.raw, s, r.raw); + return r; +} + +/*! + * @brief multiply two vector (component-wise multiplication) + * + * @param a vector1 + * @param b vector2 + * @returns v3 = (a[0] * b[0], a[1] * b[1], a[2] * b[2]) + */ +CGLM_INLINE +vec2s +glms_vec2_mul(vec2s a, vec2s b) { + vec2s r; + glm_vec2_mul(a.raw, b.raw, r.raw); + return r; +} + +/*! + * @brief multiply/scale vec2 vector with scalar: result = v * s + * + * @param[in] v vector + * @param[in] s scalar + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_scale(vec2s v, float s) { + vec2s r; + glm_vec2_scale(v.raw, s, r.raw); + return r; +} + +/*! + * @brief make vec2 vector scale as specified: result = unit(v) * s + * + * @param[in] v vector + * @param[in] s scalar + * @returns destination vector + */ +CGLM_INLINE +vec2s +glms_vec2_scale_as(vec2s v, float s) { + vec2s r; + glm_vec2_scale_as(v.raw, s, r.raw); + return r; +} + +/*! + * @brief div vector with another component-wise division: d = a / b + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @returns result = (a[0]/b[0], a[1]/b[1], a[2]/b[2]) + */ +CGLM_INLINE +vec2s +glms_vec2_div(vec2s a, vec2s b) { + vec2s r; + glm_vec2_div(a.raw, b.raw, r.raw); + return r; +} + +/*! + * @brief div vector with scalar: d = v / s + * + * @param[in] a vector + * @param[in] s scalar + * @returns result = (a[0]/s, a[1]/s, a[2]/s) + */ +CGLM_INLINE +vec2s +glms_vec2_divs(vec2s a, float s) { + vec2s r; + glm_vec2_divs(a.raw, s, r.raw); + return r; +} + +/*! + * @brief add two vectors and add result to sum + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @returns dest += (a + b) + */ +CGLM_INLINE +vec2s +glms_vec2_addadd(vec2s a, vec2s b, vec2s dest) { + glm_vec2_addadd(a.raw, b.raw, dest.raw); + return dest; +} + +/*! + * @brief sub two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @returns dest += (a + b) + */ +CGLM_INLINE +vec2s +glms_vec2_subadd(vec2s a, vec2s b, vec2s dest) { + glm_vec2_subadd(a.raw, b.raw, dest.raw); + return dest; +} + +/*! + * @brief mul two vectors and add result to dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @returns dest += (a * b) + */ +CGLM_INLINE +vec2s +glms_vec2_muladd(vec2s a, vec2s b, vec2s dest) { + glm_vec2_muladd(a.raw, b.raw, dest.raw); + return dest; +} + +/*! + * @brief mul vector with scalar and add result to sum + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector + * @param[in] s scalar + * @returns dest += (a * b) + */ +CGLM_INLINE +vec2s +glms_vec2_muladds(vec2s a, float s, vec2s dest) { + glm_vec2_muladds(a.raw, s, dest.raw); + return dest; +} + +/*! + * @brief add max of two vector to result/dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @returns dest += max(a, b) + */ +CGLM_INLINE +vec2s +glms_vec2_maxadd(vec2s a, vec2s b, vec2s dest) { + glm_vec2_maxadd(a.raw, b.raw, dest.raw); + return dest; +} + +/*! + * @brief add min of two vector to result/dest + * + * it applies += operator so dest must be initialized + * + * @param[in] a vector 1 + * @param[in] b vector 2 + * @returns dest += min(a, b) + */ +CGLM_INLINE +vec2s +glms_vec2_minadd(vec2s a, vec2s b, vec2s dest) { + glm_vec2_minadd(a.raw, b.raw, dest.raw); + return dest; +} + +/*! + * @brief negate vector components + * + * @param[in] v vector + * @returns negated vector + */ +CGLM_INLINE +vec2s +glms_vec2_negate(vec2s v) { + glm_vec2_negate(v.raw); + return v; +} + +/*! + * @brief normalize vec2 and store result in same vec + * + * @param[in] v vector + * @returns normalized vector + */ +CGLM_INLINE +vec2s +glms_vec2_normalize(vec2s v) { + glm_vec2_normalize(v.raw); + return v; +} + +/*! + * @brief rotate vec2 around axis by angle using Rodrigues' rotation formula + * + * @param[in] v vector + * @param[in] axis axis vector (must be unit vector) + * @param[in] angle angle by radians + * @returns rotated vector + */ +CGLM_INLINE +vec2s +glms_vec2_rotate(vec2s v, float angle, vec2s axis) { + glm_vec2_rotate(v.raw, angle, axis.raw); + return v; +} + +/** + * @brief distance between two vectors + * + * @param[in] a vector1 + * @param[in] b vector2 + * @return distance + */ +CGLM_INLINE +float +glms_vec2_distance(vec2s a, vec2s b) { + return glm_vec2_distance(a.raw, b.raw); +} + +/** + * @brief squared distance between two vectors + * + * @param[in] a vector1 + * @param[in] b vector2 + * @return squared distance (distance * distance) + */ +CGLM_INLINE +float +glms_vec2_distance2(vec2s a, vec2s b) { + return glm_vec2_distance2(a.raw, b.raw); +} + +/*! + * @brief max values of vectors + * + * @param[in] a vector1 + * @param[in] b vector2 + * @returns destination + */ +CGLM_INLINE +vec2s +glms_vec2_maxv(vec2s a, vec2s b) { + vec2s r; + glm_vec2_maxv(a.raw, b.raw, r.raw); + return r; +} + +/*! + * @brief min values of vectors + * + * @param[in] a vector1 + * @param[in] b vector2 + * @returns destination + */ +CGLM_INLINE +vec2s +glms_vec2_minv(vec2s a, vec2s b) { + vec2s r; + glm_vec2_minv(a.raw, b.raw, r.raw); + return r; +} + +/*! + * @brief clamp vector's individual members between min and max values + * + * @param[in] v vector + * @param[in] minVal minimum value + * @param[in] maxVal maximum value + * @returns clamped vector + */ +CGLM_INLINE +vec2s +glms_vec2_clamp(vec2s v, float minVal, float maxVal) { + glm_vec2_clamp(v.raw, minVal, maxVal); + return v; +} + +/*! + * @brief linear interpolation between two vectors + * + * formula: from + s * (to - from) + * + * @param[in] from from value + * @param[in] to to value + * @param[in] t interpolant (amount) + * @returns destination + */ +CGLM_INLINE +vec2s +glms_vec2_lerp(vec2s from, vec2s to, float t) { + vec2s r; + glm_vec2_lerp(from.raw, to.raw, t, r.raw); + return r; +} + +#endif /* cglms_vec2s_h */ diff --git a/include/cglm/vec2-ext.h b/include/cglm/vec2-ext.h index 0b05aa4..da5ba65 100644 --- a/include/cglm/vec2-ext.h +++ b/include/cglm/vec2-ext.h @@ -7,7 +7,7 @@ /* Functions: - CGLM_INLINE void glm_vec2_broadcast(float val, vec2 d); + CGLM_INLINE void glm_vec2_fill(vec2 v, float val) CGLM_INLINE bool glm_vec2_eq(vec2 v, float val); CGLM_INLINE bool glm_vec2_eq_eps(vec2 v, float val); CGLM_INLINE bool glm_vec2_eq_all(vec2 v); @@ -31,13 +31,13 @@ /*! * @brief fill a vector with specified value * + * @param[out] v dest * @param[in] val value - * @param[out] d dest */ CGLM_INLINE void -glm_vec2_broadcast(float val, vec2 d) { - d[0] = d[1] = val; +glm_vec2_fill(vec2 v, float val) { + v[0] = v[1] = val; } /*! diff --git a/include/cglm/vec2.h b/include/cglm/vec2.h index 9ad4cdc..73ecea9 100644 --- a/include/cglm/vec2.h +++ b/include/cglm/vec2.h @@ -576,7 +576,7 @@ glm_vec2_lerp(vec2 from, vec2 to, float t, vec2 dest) { vec2 s, v; /* from + s * (to - from) */ - glm_vec2_broadcast(glm_clamp_zo(t), s); + glm_vec2_fill(s, glm_clamp_zo(t)); glm_vec2_sub(to, from, v); glm_vec2_mul(s, v, v); glm_vec2_add(from, v, dest); diff --git a/test/src/test_affine.h b/test/src/test_affine.h index 0487716..2199a43 100644 --- a/test/src/test_affine.h +++ b/test/src/test_affine.h @@ -571,7 +571,7 @@ TEST_IMPL(GLM_PREFIX, decompose_rs) { glm_mat4_mul(m2, r, m2); glm_scale(m2, s1); - ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001)); + ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001f)); TEST_SUCCESS } @@ -607,7 +607,7 @@ TEST_IMPL(GLM_PREFIX, decompose) { glm_mat4_mul(m2, r, m2); glm_scale(m2, s); - ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001)); + ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001f)); glm_mat4_identity(m1); glm_translate(m1, (vec3){56.0f, 13.0f, 90.0f}); @@ -628,7 +628,7 @@ TEST_IMPL(GLM_PREFIX, decompose) { glm_translate(m2, t); glm_mat4_mul(m2, r, m2); glm_scale(m2, s); - ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001)); + ASSERTIFY(test_assert_mat4_eq2(m1, m2, 0.00001f)); TEST_SUCCESS } diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj index 9b7a84b..4f0c332 100644 --- a/win/cglm.vcxproj +++ b/win/cglm.vcxproj @@ -107,6 +107,8 @@ + + diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters index cf5beb2..42f116b 100644 --- a/win/cglm.vcxproj.filters +++ b/win/cglm.vcxproj.filters @@ -340,5 +340,11 @@ include\cglm + + include\cglm\struct + + + include\cglm\struct + \ No newline at end of file