diff --git a/include/cglm/vec3-ext.h b/include/cglm/vec3-ext.h index 8a9226f..e119900 100644 --- a/include/cglm/vec3-ext.h +++ b/include/cglm/vec3-ext.h @@ -26,6 +26,7 @@ #define cglm_vec3_ext_h #include "common.h" +#include "util.h" #include #include #include @@ -196,4 +197,19 @@ glm_vec_isvalid(vec3 v) { return !glm_vec_isnan(v) && !glm_vec_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_vec_sign(vec3 v, vec3 dest) { + dest[0] = glm_signf(v[0]); + dest[1] = glm_signf(v[1]); + dest[2] = glm_signf(v[2]); +} + #endif /* cglm_vec3_ext_h */ diff --git a/include/cglm/vec4-ext.h b/include/cglm/vec4-ext.h index 2859588..f6cbe04 100644 --- a/include/cglm/vec4-ext.h +++ b/include/cglm/vec4-ext.h @@ -210,5 +210,33 @@ glm_vec4_isvalid(vec4 v) { return !glm_vec4_isnan(v) && !glm_vec4_isinf(v); } -#endif /* cglm_vec4_ext_h */ +/*! + * @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_vec4_sign(vec4 v, vec4 dest) { +#if defined( __SSE2__ ) || defined( __SSE2__ ) + __m128 x0, x1, x2, x3, x4; + x0 = _mm_load_ps(v); + x1 = _mm_set_ps(0.0f, 0.0f, 1.0f, -1.0f); + x2 = _mm_shuffle1_ps1(x1, 2); + + x3 = _mm_and_ps(_mm_cmpgt_ps(x0, x2), _mm_shuffle1_ps1(x1, 1)); + x4 = _mm_and_ps(_mm_cmplt_ps(x0, x2), _mm_shuffle1_ps1(x1, 0)); + + _mm_store_ps(dest, _mm_or_ps(x3, x4)); +#else + dest[0] = glm_signf(v[0]); + dest[1] = glm_signf(v[1]); + dest[2] = glm_signf(v[2]); + dest[3] = glm_signf(v[3]); +#endif +} + +#endif /* cglm_vec4_ext_h */