From 090f940f502c9ef0e9309e5f015629334a0120d8 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Sat, 20 Jan 2018 18:38:26 +0300 Subject: [PATCH 1/3] swizzle support --- include/cglm/common.h | 3 +++ include/cglm/vec3.h | 27 +++++++++++++++++++++++++++ include/cglm/vec4.h | 29 +++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/include/cglm/common.h b/include/cglm/common.h index f0eb965..84a09b6 100644 --- a/include/cglm/common.h +++ b/include/cglm/common.h @@ -54,6 +54,9 @@ #define glm__memzero(type, dest, size) glm__memset(type, dest, size, 0) +#define GLM_SHUFFLE4(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w)) +#define GLM_SHUFFLE3(z, y, x) (((z) << 4) | ((y) << 2) | (x)) + #include "types.h" #include "simd/intrin.h" diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index ebcedcf..e5559e1 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -44,6 +44,7 @@ CGLM_INLINE void glm_vec_maxv(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_minv(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_ortho(vec3 v, vec3 dest); + CGLM_INLINE void glm_vec_swizzle(vec3 v, int mask, vec3 dest); Convenient: CGLM_INLINE void glm_cross(vec3 a, vec3 b, vec3 d); @@ -69,6 +70,11 @@ #define GLM_ZUP (vec3){0.0f, 0.0f, 1.0f} #define GLM_XUP (vec3){1.0f, 0.0f, 0.0f} +#define GLM_XXX GLM_SHUFFLE3(0, 0, 0) +#define GLM_YYY GLM_SHUFFLE3(1, 1, 1) +#define GLM_ZZZ GLM_SHUFFLE3(2, 2, 2) +#define GLM_ZYX GLM_SHUFFLE3(0, 1, 2) + /*! * @brief init vec3 using vec4 * @@ -528,4 +534,25 @@ glm_normalize_to(vec3 v, vec3 dest) { glm_vec_normalize_to(v, dest); } +/*! + * @brief swizzle vector components + * + * you can use existin masks e.g. GLM_XXX, GLM_ZYX + * + * @param[in] v source + * @param[in] mask mask + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec_swizzle(vec3 v, int mask, vec3 dest) { + vec3 t; + + t[0] = v[(mask & (3 << 0))]; + t[1] = v[(mask & (3 << 2)) >> 2]; + t[2] = v[(mask & (3 << 4)) >> 4]; + + glm_vec_copy(t, dest); +} + #endif /* cglm_vec3_h */ diff --git a/include/cglm/vec4.h b/include/cglm/vec4.h index e76bfac..a92758a 100644 --- a/include/cglm/vec4.h +++ b/include/cglm/vec4.h @@ -38,6 +38,7 @@ CGLM_INLINE float glm_vec4_distance(vec4 v1, vec4 v2); CGLM_INLINE void glm_vec4_maxv(vec4 v1, vec4 v2, vec4 dest); CGLM_INLINE void glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest); + CGLM_INLINE void glm_vec4_swizzle(vec4 v, int mask, vec4 dest); */ #ifndef cglm_vec4_h @@ -57,6 +58,12 @@ #define GLM_VEC4_ONE (vec4)GLM_VEC4_ONE_INIT #define GLM_VEC4_BLACK (vec4)GLM_VEC4_BLACK_INIT +#define GLM_XXXX GLM_SHUFFLE4(0, 0, 0, 0) +#define GLM_YYYY GLM_SHUFFLE4(1, 1, 1, 1) +#define GLM_ZZZZ GLM_SHUFFLE4(2, 2, 2, 2) +#define GLM_WWWW GLM_SHUFFLE4(3, 3, 3, 3) +#define GLM_WZYX GLM_SHUFFLE4(0, 1, 2, 3) + /*! * @brief init vec4 using vec3 * @@ -369,4 +376,26 @@ glm_vec4_minv(vec4 v1, vec4 v2, vec4 dest) { dest[3] = glm_min(v1[3], v2[3]); } +/*! + * @brief swizzle vector components + * + * you can use existin masks e.g. GLM_XXXX, GLM_WZYX + * + * @param[in] v source + * @param[in] mask mask + * @param[out] dest destination + */ +CGLM_INLINE +void +glm_vec4_swizzle(vec4 v, int mask, vec4 dest) { + vec4 t; + + t[0] = v[(mask & (3 << 0))]; + t[1] = v[(mask & (3 << 2)) >> 2]; + t[2] = v[(mask & (3 << 4)) >> 4]; + t[3] = v[(mask & (3 << 6)) >> 6]; + + glm_vec4_copy(t, dest); +} + #endif /* cglm_vec4_h */ From 1fdd459733002bcdb52eb9f2c01e3b0f84e0d059 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 6 Jun 2019 13:12:17 +0300 Subject: [PATCH 2/3] add tests for vector swizzling, rename vec to vec3 --- include/cglm/vec3.h | 6 +++--- test/src/test_vec3.c | 26 ++++++++++++++++++++++++++ test/src/test_vec4.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 3 deletions(-) diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index ea8d9a1..323618a 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -61,7 +61,7 @@ CGLM_INLINE void glm_vec3_ortho(vec3 v, vec3 dest); CGLM_INLINE void glm_vec3_clamp(vec3 v, float minVal, float maxVal); CGLM_INLINE void glm_vec3_lerp(vec3 from, vec3 to, float t, vec3 dest); - CGLM_INLINE void glm_vec_swizzle(vec3 v, int mask, vec3 dest); + CGLM_INLINE void glm_vec3_swizzle(vec3 v, int mask, vec3 dest); Convenient: CGLM_INLINE void glm_cross(vec3 a, vec3 b, vec3 d); @@ -862,14 +862,14 @@ glm_normalize_to(vec3 v, vec3 dest) { */ CGLM_INLINE void -glm_vec_swizzle(vec3 v, int mask, vec3 dest) { +glm_vec3_swizzle(vec3 v, int mask, vec3 dest) { vec3 t; t[0] = v[(mask & (3 << 0))]; t[1] = v[(mask & (3 << 2)) >> 2]; t[2] = v[(mask & (3 << 4)) >> 4]; - glm_vec_copy(t, dest); + glm_vec3_copy(t, dest); } #endif /* cglm_vec3_h */ diff --git a/test/src/test_vec3.c b/test/src/test_vec3.c index 4f1f2d1..19af4aa 100644 --- a/test/src/test_vec3.c +++ b/test/src/test_vec3.c @@ -84,4 +84,30 @@ test_vec3(void **state) { vs3 = glms_vec3_add(vs1, vs2); vs4 = glms_vec3_maxv(vs1, vs3); test_assert_vec3s_eq(vs3, vs4); + + /* swizzle */ + + /* ZYX */ + v1[0] = 1; + v1[1] = 2; + v1[2] = 3; + glm_vec3_swizzle(v1, GLM_ZYX, v1); + test_assert_vec3_eq(v1, (vec3){3, 2, 1}); + + glm_vec3_swizzle(v1, GLM_XXX, v1); + test_assert_vec3_eq(v1, (vec3){3, 3, 3}); + + v1[0] = 1; + v1[1] = 2; + v1[2] = 3; + + glm_vec3_swizzle(v1, GLM_YYY, v1); + test_assert_vec3_eq(v1, (vec3){2, 2, 2}); + + v1[0] = 1; + v1[1] = 2; + v1[2] = 3; + + glm_vec3_swizzle(v1, GLM_ZZZ, v1); + test_assert_vec3_eq(v1, (vec3){3, 3, 3}); } diff --git a/test/src/test_vec4.c b/test/src/test_vec4.c index 02137b0..2e9d12e 100644 --- a/test/src/test_vec4.c +++ b/test/src/test_vec4.c @@ -183,6 +183,44 @@ test_vec4(void **state) { assert_true(v3[2] >= 0.0999 && v3[2] <= 0.80001); assert_true(v3[3] >= 0.0999 && v3[3] <= 0.80001); + /* swizzle */ + + /* ZYX */ + v1[0] = 1; + v1[1] = 2; + v1[2] = 3; + v1[3] = 4; + + glm_vec4_swizzle(v1, GLM_WZYX, v1); + test_assert_vec4_eq(v1, (vec4){4, 3, 2, 1}); + + glm_vec4_swizzle(v1, GLM_XXXX, v1); + test_assert_vec4_eq(v1, (vec4){4, 4, 4, 4}); + + v1[0] = 1; + v1[1] = 2; + v1[2] = 3; + v1[3] = 4; + + glm_vec4_swizzle(v1, GLM_YYYY, v1); + test_assert_vec4_eq(v1, (vec4){2, 2, 2, 2}); + + v1[0] = 1; + v1[1] = 2; + v1[2] = 3; + v1[3] = 4; + + glm_vec4_swizzle(v1, GLM_ZZZZ, v1); + test_assert_vec4_eq(v1, (vec4){3, 3, 3, 3}); + + v1[0] = 1; + v1[1] = 2; + v1[2] = 3; + v1[3] = 4; + + glm_vec4_swizzle(v1, GLM_WWWW, v1); + test_assert_vec4_eq(v1, (vec4){4, 4, 4, 4}); + /* structs */ vs1 = test_rand_vec4s(); vs2 = test_rand_vec4s(); From 2025b357576a242f9e184aece49e5b866cd52bb8 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 6 Jun 2019 13:18:31 +0300 Subject: [PATCH 3/3] struct: struct vesion of swizzle funcs --- include/cglm/struct/vec3.h | 18 ++++++++++++++++++ include/cglm/struct/vec4.h | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/cglm/struct/vec3.h b/include/cglm/struct/vec3.h index fbe716d..4e8d677 100644 --- a/include/cglm/struct/vec3.h +++ b/include/cglm/struct/vec3.h @@ -58,6 +58,7 @@ CGLM_INLINE vec3s glms_vec3_ortho(vec3s v); CGLM_INLINE vec3s glms_vec3_clamp(vec3s v, float minVal, float maxVal); CGLM_INLINE vec3s glms_vec3_lerp(vec3s from, vec3s to, float t); + CGLM_INLINE vec3s glms_vec3_swizzle(vec3s v, int mask); Convenient: CGLM_INLINE vec3s glms_cross(vec3s a, vec3s b); @@ -747,4 +748,21 @@ glms_normalize(vec3s v) { return v; } +/*! + * @brief swizzle vector components + * + * you can use existin masks e.g. GLM_XXX, GLM_ZYX + * + * @param[in] v source + * @param[in] mask mask + * @returns swizzled vector + */ +CGLM_INLINE +vec3s +glms_vec3_swizzle(vec3s v, int mask) { + vec3s dest; + glm_vec3_swizzle(v.raw, mask, dest.raw); + return dest; +} + #endif /* cglms_vec3s_h */ diff --git a/include/cglm/struct/vec4.h b/include/cglm/struct/vec4.h index 4fe75ba..0b403a9 100644 --- a/include/cglm/struct/vec4.h +++ b/include/cglm/struct/vec4.h @@ -48,6 +48,7 @@ CGLM_INLINE vec4s glms_vec4_clamp(vec4s v, float minVal, float maxVal); CGLM_INLINE vec4s glms_vec4_lerp(vec4s from, vec4s to, float t); CGLM_INLINE vec4s glms_vec4_cubic(float s); + CGLM_INLINE vec4s glms_vec4_swizzle(vec4s v, int mask); */ #ifndef cglms_vec4s_h @@ -577,4 +578,21 @@ glms_vec4_cubic(float s) { return r; } +/*! + * @brief swizzle vector components + * + * you can use existin masks e.g. GLM_XXXX, GLM_WZYX + * + * @param[in] v source + * @param[in] mask mask + * @returns swizzled vector + */ +CGLM_INLINE +vec4s +glms_vec4_swizzle(vec4s v, int mask) { + vec4s dest; + glm_vec4_swizzle(v.raw, mask, dest.raw); + return dest; +} + #endif /* cglms_vec4s_h */