diff --git a/include/cglm/call/euler.h b/include/cglm/call/euler.h index 2de68fb..52dd1ef 100644 --- a/include/cglm/call/euler.h +++ b/include/cglm/call/euler.h @@ -49,6 +49,31 @@ CGLM_EXPORT void glmc_euler_by_order(vec3 angles, glm_euler_seq axis, mat4 dest); +CGLM_EXPORT +void +glmc_euler_xyz_quat(versor q, vec3 angles); + +CGLM_EXPORT +void +glmc_euler_xzy_quat(versor q, vec3 angles); + +CGLM_EXPORT +void +glmc_euler_yxz_quat(versor q, vec3 angles); + +CGLM_EXPORT +void +glmc_euler_yzx_quat(versor q, vec3 angles); + +CGLM_EXPORT +void +glmc_euler_zxy_quat(versor q, vec3 angles); + +CGLM_EXPORT +void +glmc_euler_zyx_quat(versor q, vec3 angles); + + #ifdef __cplusplus } #endif diff --git a/include/cglm/call/quat.h b/include/cglm/call/quat.h index f24dc59..1fe5195 100644 --- a/include/cglm/call/quat.h +++ b/include/cglm/call/quat.h @@ -25,30 +25,6 @@ CGLM_EXPORT void glmc_quat_init(versor q, float x, float y, float z, float w); -CGLM_EXPORT -void -glmc_euler_xyz_quat(versor q, vec3 angles); - -CGLM_EXPORT -void -glmc_euler_xzy_quat(versor q, vec3 angles); - -CGLM_EXPORT -void -glmc_euler_yxz_quat(versor q, vec3 angles); - -CGLM_EXPORT -void -glmc_euler_yzx_quat(versor q, vec3 angles); - -CGLM_EXPORT -void -glmc_euler_zxy_quat(versor q, vec3 angles); - -CGLM_EXPORT -void -glmc_euler_zyx_quat(versor q, vec3 angles); - CGLM_EXPORT void glmc_quat(versor q, float angle, float x, float y, float z); diff --git a/include/cglm/euler.h b/include/cglm/euler.h index 9f921f2..9efbaa1 100644 --- a/include/cglm/euler.h +++ b/include/cglm/euler.h @@ -30,6 +30,12 @@ CGLM_INLINE void glm_euler_by_order(vec3 angles, glm_euler_seq ord, mat4 dest); + CGLM_INLINE void glm_euler_xyz_quat(versor q, vec3 angles); + CGLM_INLINE void glm_euler_xzy_quat(versor q, vec3 angles); + CGLM_INLINE void glm_euler_yxz_quat(versor q, vec3 angles); + CGLM_INLINE void glm_euler_yzx_quat(versor q, vec3 angles); + CGLM_INLINE void glm_euler_zxy_quat(versor q, vec3 angles); + CGLM_INLINE void glm_euler_zyx_quat(versor q, vec3 angles); */ #ifndef cglm_euler_h @@ -449,5 +455,167 @@ glm_euler_by_order(vec3 angles, glm_euler_seq ord, mat4 dest) { } +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x y z order (roll pitch yaw) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +void +glm_euler_xyz_quat(versor q, vec3 angles) { + float xs = sinf(angles[0] / 2.0f); + float xc = cosf(angles[0] / 2.0f); + + float ys = sinf(angles[1] / 2.0f); + float yc = cosf(angles[1] / 2.0f); + + float zs = sinf(angles[2] / 2.0f); + float zc = cosf(angles[2] / 2.0f); + + + glm_quat_init(q, + zc * yc * xs - zs * ys * xc, + zc * ys * xc + zs * yc * xs, + -zc * ys * xs + zs * yc * xc, + zc * yc * xc + zs * ys * xs); +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x z y order (roll yaw pitch) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +void +glm_euler_xzy_quat(versor q, vec3 angles) { + float xs = sinf(angles[0] / 2.0f); + float xc = cosf(angles[0] / 2.0f); + + float ys = sinf(angles[1] / 2.0f); + float yc = cosf(angles[1] / 2.0f); + + float zs = sinf(angles[2] / 2.0f); + float zc = cosf(angles[2] / 2.0f); + + glm_quat_init(q, + yc * zc * xs + ys * zs * xc, + yc * zs * xs + ys * zc * xc, + yc * zs * xc - ys * zc * xs, + yc * zc * xc - ys * zs * xs); + +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y x z order (pitch roll yaw) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +void +glm_euler_yxz_quat(versor q, vec3 angles) { + float xs = sinf(angles[0] / 2.0f); + float xc = cosf(angles[0] / 2.0f); + + float ys = sinf(angles[1] / 2.0f); + float yc = cosf(angles[1] / 2.0f); + + float zs = sinf(angles[2] / 2.0f); + float zc = cosf(angles[2] / 2.0f); + + glm_quat_init(q, + zc * xs * yc - zs * xc * ys, + zc * xc * ys + zs * xs * yc, + zc * xs * ys + zs * xc * yc, + zc * xc * yc - zs * xs * ys); +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y z x order (pitch yaw roll) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +void +glm_euler_yzx_quat(versor q, vec3 angles) { + float xs = sinf(angles[0] / 2.0f); + float xc = cosf(angles[0] / 2.0f); + + float ys = sinf(angles[1] / 2.0f); + float yc = cosf(angles[1] / 2.0f); + + float zs = sinf(angles[2] / 2.0f); + float zc = cosf(angles[2] / 2.0f); + + glm_quat_init(q, + -xc * zs * ys + xs * zc * yc, + xc * zc * ys - xs * zs * yc, + xc * zs * yc + xs * zc * ys, + xc * zc * yc + xs * zs * ys); + +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z x y order (yaw roll pitch) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +void +glm_euler_zxy_quat(versor q, vec3 angles) { + float xs = sinf(angles[0] / 2.0f); + float xc = cosf(angles[0] / 2.0f); + + float ys = sinf(angles[1] / 2.0f); + float yc = cosf(angles[1] / 2.0f); + + float zs = sinf(angles[2] / 2.0f); + float zc = cosf(angles[2] / 2.0f); + + glm_quat_init(q, + yc * xs * zc + ys * xc * zs, + -yc * xs * zs + ys * xc * zc, + yc * xc * zs - ys * xs * zc, + yc * xc * zc + ys * xs * zs); + + +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z y x order (yaw pitch roll) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +void +glm_euler_zyx_quat(versor q, vec3 angles) { + float xs = sinf(angles[0] / 2.0f); + float xc = cosf(angles[0] / 2.0f); + + float ys = sinf(angles[1] / 2.0f); + float yc = cosf(angles[1] / 2.0f); + + float zs = sinf(angles[2] / 2.0f); + float zc = cosf(angles[2] / 2.0f); + + glm_quat_init(q, + xc * ys * zs + xs * yc * zc, + xc * ys * zc - xs * yc * zs, + xc * yc * zs + xs * ys * zc, + xc * yc * zc - xs * ys * zs); + +} + #endif /* cglm_euler_h */ diff --git a/include/cglm/quat.h b/include/cglm/quat.h index 02e0b46..ab0c590 100644 --- a/include/cglm/quat.h +++ b/include/cglm/quat.h @@ -13,12 +13,6 @@ Functions: CGLM_INLINE void glm_quat_identity(versor q); CGLM_INLINE void glm_quat_init(versor q, float x, float y, float z, float w); - CGLM_INLINE void glm_euler_xyz_quat(versor q, vec3 angles); - CGLM_INLINE void glm_euler_xzy_quat(versor q, vec3 angles); - CGLM_INLINE void glm_euler_yxz_quat(versor q, vec3 angles); - CGLM_INLINE void glm_euler_yzx_quat(versor q, vec3 angles); - CGLM_INLINE void glm_euler_zxy_quat(versor q, vec3 angles); - CGLM_INLINE void glm_euler_zyx_quat(versor q, vec3 angles); CGLM_INLINE void glm_quat(versor q, float angle, float x, float y, float z); CGLM_INLINE void glm_quatv(versor q, float angle, vec3 axis); CGLM_INLINE void glm_quat_copy(versor q, versor dest); @@ -145,168 +139,6 @@ glm_quat_init(versor q, float x, float y, float z, float w) { q[3] = w; } -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in x y z order (roll pitch yaw) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -void -glm_euler_xyz_quat(versor q, vec3 angles) { - float xs = sinf(angles[0] / 2.0f); - float xc = cosf(angles[0] / 2.0f); - - float ys = sinf(angles[1] / 2.0f); - float yc = cosf(angles[1] / 2.0f); - - float zs = sinf(angles[2] / 2.0f); - float zc = cosf(angles[2] / 2.0f); - - - glm_quat_init(q, - zc * yc * xs - zs * ys * xc, - zc * ys * xc + zs * yc * xs, - -zc * ys * xs + zs * yc * xc, - zc * yc * xc + zs * ys * xs); -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in x z y order (roll yaw pitch) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -void -glm_euler_xzy_quat(versor q, vec3 angles) { - float xs = sinf(angles[0] / 2.0f); - float xc = cosf(angles[0] / 2.0f); - - float ys = sinf(angles[1] / 2.0f); - float yc = cosf(angles[1] / 2.0f); - - float zs = sinf(angles[2] / 2.0f); - float zc = cosf(angles[2] / 2.0f); - - glm_quat_init(q, - yc * zc * xs + ys * zs * xc, - yc * zs * xs + ys * zc * xc, - yc * zs * xc - ys * zc * xs, - yc * zc * xc - ys * zs * xs); - -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in y x z order (pitch roll yaw) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -void -glm_euler_yxz_quat(versor q, vec3 angles) { - float xs = sinf(angles[0] / 2.0f); - float xc = cosf(angles[0] / 2.0f); - - float ys = sinf(angles[1] / 2.0f); - float yc = cosf(angles[1] / 2.0f); - - float zs = sinf(angles[2] / 2.0f); - float zc = cosf(angles[2] / 2.0f); - - glm_quat_init(q, - zc * xs * yc - zs * xc * ys, - zc * xc * ys + zs * xs * yc, - zc * xs * ys + zs * xc * yc, - zc * xc * yc - zs * xs * ys); -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in y z x order (pitch yaw roll) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -void -glm_euler_yzx_quat(versor q, vec3 angles) { - float xs = sinf(angles[0] / 2.0f); - float xc = cosf(angles[0] / 2.0f); - - float ys = sinf(angles[1] / 2.0f); - float yc = cosf(angles[1] / 2.0f); - - float zs = sinf(angles[2] / 2.0f); - float zc = cosf(angles[2] / 2.0f); - - glm_quat_init(q, - -xc * zs * ys + xs * zc * yc, - xc * zc * ys - xs * zs * yc, - xc * zs * yc + xs * zc * ys, - xc * zc * yc + xs * zs * ys); - -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in z x y order (yaw roll pitch) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -void -glm_euler_zxy_quat(versor q, vec3 angles) { - float xs = sinf(angles[0] / 2.0f); - float xc = cosf(angles[0] / 2.0f); - - float ys = sinf(angles[1] / 2.0f); - float yc = cosf(angles[1] / 2.0f); - - float zs = sinf(angles[2] / 2.0f); - float zc = cosf(angles[2] / 2.0f); - - glm_quat_init(q, - yc * xs * zc + ys * xc * zs, - -yc * xs * zs + ys * xc * zc, - yc * xc * zs - ys * xs * zc, - yc * xc * zc + ys * xs * zs); - - -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in z y x order (yaw pitch roll) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -void -glm_euler_zyx_quat(versor q, vec3 angles) { - float xs = sinf(angles[0] / 2.0f); - float xc = cosf(angles[0] / 2.0f); - - float ys = sinf(angles[1] / 2.0f); - float yc = cosf(angles[1] / 2.0f); - - float zs = sinf(angles[2] / 2.0f); - float zc = cosf(angles[2] / 2.0f); - - glm_quat_init(q, - xc * ys * zs + xs * yc * zc, - xc * ys * zc - xs * yc * zs, - xc * yc * zs + xs * ys * zc, - xc * yc * zc - xs * ys * zs); - -} - /*! * @brief creates NEW quaternion with axis vector * diff --git a/include/cglm/struct/euler.h b/include/cglm/struct/euler.h index 6575930..1f73cde 100644 --- a/include/cglm/struct/euler.h +++ b/include/cglm/struct/euler.h @@ -26,6 +26,12 @@ CGLM_INLINE mat4s glms_euler_zxy(vec3s angles) CGLM_INLINE mat4s glms_euler_zyx(vec3s angles) CGLM_INLINE mat4s glms_euler_by_order(vec3s angles, glm_euler_seq ord) + CGLM_INLINE versors glms_euler_xyz_quat(versors q, vec3s angles) + CGLM_INLINE versors glms_euler_xzy_quat(versors q, vec3s angles) + CGLM_INLINE versors glms_euler_yxz_quat(versors q, vec3s angles) + CGLM_INLINE versors glms_euler_yzx_quat(versors q, vec3s angles) + CGLM_INLINE versors glms_euler_zxy_quat(versors q, vec3s angles) + CGLM_INLINE versors glms_euler_zyx_quat(versors q, vec3s angles) */ #ifndef cglms_euler_h @@ -149,4 +155,95 @@ glms_euler_by_order(vec3s angles, glm_euler_seq ord) { return dest; } +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x y z order (roll pitch yaw) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +versors +glms_euler_xyz_quat(versors q, vec3s angles) { + versors dest; + glm_euler_xyz_quat(dest.raw, angles.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x z y order (roll yaw pitch) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +versors +glms_euler_xzy_quat(versors q, vec3s angles) { + versors dest; + glm_euler_xzy_quat(dest.raw, angles.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y x z order (pitch roll yaw) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +versors +glms_euler_yxz_quat(versors q, vec3s angles) { + versors dest; + glm_euler_yxz_quat(dest.raw, angles.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y z x order (pitch yaw roll) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +versors +glms_euler_yzx_quat(versors q, vec3s angles) { + versors dest; + glm_euler_yzx_quat(dest.raw, angles.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z x y order (yaw roll pitch) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +versors +glms_euler_zxy_quat(versors q, vec3s angles) { + versors dest; + glm_euler_zxy_quat(dest.raw, angles.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z y x order (yaw pitch roll) + * + * @param[out] q quaternion + * @param[in] angle angles x y z (radians) + */ +CGLM_INLINE +versors +glms_euler_zyx_quat(versors q, vec3s angles) { + versors dest; + glm_euler_zyx_quat(dest.raw, angles.raw); + return dest; +} + + #endif /* cglms_euler_h */ diff --git a/include/cglm/struct/quat.h b/include/cglm/struct/quat.h index 2384911..a37cdc5 100644 --- a/include/cglm/struct/quat.h +++ b/include/cglm/struct/quat.h @@ -14,12 +14,6 @@ CGLM_INLINE versors glms_quat_identity(void) CGLM_INLINE void glms_quat_identity_array(versor *q, size_t count) CGLM_INLINE versors glms_quat_init(float x, float y, float z, float w) - CGLM_INLINE versors glms_euler_xyz_quat(versors q, vec3s angles) - CGLM_INLINE versors glms_euler_xzy_quat(versors q, vec3s angles) - CGLM_INLINE versors glms_euler_yxz_quat(versors q, vec3s angles) - CGLM_INLINE versors glms_euler_yzx_quat(versors q, vec3s angles) - CGLM_INLINE versors glms_euler_zxy_quat(versors q, vec3s angles) - CGLM_INLINE versors glms_euler_zyx_quat(versors q, vec3s angles) CGLM_INLINE versors glms_quatv(float angle, vec3s axis) CGLM_INLINE versors glms_quat(float angle, float x, float y, float z) CGLM_INLINE versors glms_quat_from_vecs(vec3s a, vec3s b) @@ -126,97 +120,6 @@ glms_quat_(init)(float x, float y, float z, float w) { return dest; } -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in x y z order (roll pitch yaw) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -versors -glms_euler_xyz_quat(versors q, vec3s angles) { - versors dest; - glm_euler_xyz_quat(dest.raw, angles.raw); - return dest; -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in x z y order (roll yaw pitch) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -versors -glms_euler_xzy_quat(versors q, vec3s angles) { - versors dest; - glm_euler_xzy_quat(dest.raw, angles.raw); - return dest; -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in y x z order (pitch roll yaw) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -versors -glms_euler_yxz_quat(versors q, vec3s angles) { - versors dest; - glm_euler_yxz_quat(dest.raw, angles.raw); - return dest; -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in y z x order (pitch yaw roll) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -versors -glms_euler_yzx_quat(versors q, vec3s angles) { - versors dest; - glm_euler_yzx_quat(dest.raw, angles.raw); - return dest; -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in z x y order (yaw roll pitch) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -versors -glms_euler_zxy_quat(versors q, vec3s angles) { - versors dest; - glm_euler_zxy_quat(dest.raw, angles.raw); - return dest; -} - -/*! - * @brief creates NEW quaternion using rotation angles and does - * rotations in z y x order (yaw pitch roll) - * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) - */ -CGLM_INLINE -versors -glms_euler_zyx_quat(versors q, vec3s angles) { - versors dest; - glm_euler_zyx_quat(dest.raw, angles.raw); - return dest; -} - - /*! * @brief creates NEW quaternion with axis vector * diff --git a/src/euler.c b/src/euler.c index a59b1df..53c0bf5 100644 --- a/src/euler.c +++ b/src/euler.c @@ -61,3 +61,40 @@ void glmc_euler_by_order(vec3 angles, glm_euler_seq axis, mat4 dest) { glm_euler_by_order(angles, axis, dest); } + +CGLM_EXPORT +void +glmc_euler_xyz_quat(versor q, vec3 angles) { + glm_euler_xyz_quat(q, angles); +} + +CGLM_EXPORT +void +glmc_euler_xzy_quat(versor q, vec3 angles) { + glm_euler_xzy_quat(q, angles); +} + +CGLM_EXPORT +void +glmc_euler_yxz_quat(versor q, vec3 angles) { + glm_euler_yxz_quat(q, angles); +} + +CGLM_EXPORT +void +glmc_euler_yzx_quat(versor q, vec3 angles) { + glm_euler_yzx_quat(q, angles); +} + +CGLM_EXPORT +void +glmc_euler_zxy_quat(versor q, vec3 angles) { + glm_euler_zxy_quat(q, angles); +} + +CGLM_EXPORT +void +glmc_euler_zyx_quat(versor q, vec3 angles) { + glm_euler_zyx_quat(q, angles); +} + diff --git a/src/quat.c b/src/quat.c index a393789..1796939 100644 --- a/src/quat.c +++ b/src/quat.c @@ -26,42 +26,6 @@ glmc_quat_init(versor q, float x, float y, float z, float w) { glm_quat_init(q, x, y, z, w); } -CGLM_EXPORT -void -glmc_euler_xyz_quat(versor q, vec3 angles) { - glm_euler_xyz_quat(q, angles); -} - -CGLM_EXPORT -void -glmc_euler_xzy_quat(versor q, vec3 angles) { - glm_euler_xzy_quat(q, angles); -} - -CGLM_EXPORT -void -glmc_euler_yxz_quat(versor q, vec3 angles) { - glm_euler_yxz_quat(q, angles); -} - -CGLM_EXPORT -void -glmc_euler_yzx_quat(versor q, vec3 angles) { - glm_euler_yzx_quat(q, angles); -} - -CGLM_EXPORT -void -glmc_euler_zxy_quat(versor q, vec3 angles) { - glm_euler_zxy_quat(q, angles); -} - -CGLM_EXPORT -void -glmc_euler_zyx_quat(versor q, vec3 angles) { - glm_euler_zyx_quat(q, angles); -} - CGLM_EXPORT void glmc_quat(versor q, float angle, float x, float y, float z) { diff --git a/test/src/test_euler.c b/test/src/test_euler.c index b71e0f0..6d8f20e 100644 --- a/test/src/test_euler.c +++ b/test/src/test_euler.c @@ -7,6 +7,545 @@ #include "test_common.h" + +TEST_IMPL(GLM_PREFIX, euler_xyz_quat) { + for (int i = 0; i < 100; i++) { + /*random angles for testing*/ + vec3 angles; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + test_rand_vec3(angles); + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in xyz order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_xyz_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + + + /*Start gimbal lock tests*/ + for (float x = -90.0f; x <= 90.0f; x += 90.0f) { + for (float y = -90.0f; y <= 90.0f; y += 90.0f) { + for (float z = -90.0f; z <= 90.0f; z += 90.0f) { + /* angles that will cause gimbal lock*/ + vec3 angles = {x, y, z}; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in xyz order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_xyz_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_xzy_quat) { + for (int i = 0; i < 100; i++) { + /*random angles for testing*/ + vec3 angles; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + test_rand_vec3(angles); + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in xzy order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_xzy_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + + /*Start gimbal lock tests*/ + for (float x = -90.0f; x <= 90.0f; x += 90.0f) { + for (float y = -90.0f; y <= 90.0f; y += 90.0f) { + for (float z = -90.0f; z <= 90.0f; z += 90.0f) { + /* angles that will cause gimbal lock*/ + vec3 angles = {x, y, z}; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in xyz order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_xzy_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_yxz_quat) { + for (int i = 0; i < 100; i++) { + /*random angles for testing*/ + vec3 angles; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + test_rand_vec3(angles); + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in yxz order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_yxz_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + + /*Start gimbal lock tests*/ + for (float x = -90.0f; x <= 90.0f; x += 90.0f) { + for (float y = -90.0f; y <= 90.0f; y += 90.0f) { + for (float z = -90.0f; z <= 90.0f; z += 90.0f) { + /* angles that will cause gimbal lock*/ + vec3 angles = {x, y, z}; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in yxz order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_yxz_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_yzx_quat) { + for (int i = 0; i < 100; i++) { + /*random angles for testing*/ + vec3 angles; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + test_rand_vec3(angles); + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in yzx order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_yzx_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + + /*Start gimbal lock tests*/ + for (float x = -90.0f; x <= 90.0f; x += 90.0f) { + for (float y = -90.0f; y <= 90.0f; y += 90.0f) { + for (float z = -90.0f; z <= 90.0f; z += 90.0f) { + /* angles that will cause gimbal lock*/ + vec3 angles = {x, y, z}; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in yzx order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_yzx_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_zxy_quat) { + for (int i = 0; i < 100; i++) { + /*random angles for testing*/ + vec3 angles; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + test_rand_vec3(angles); + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in zxy order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + + /*use my function to get the quaternion*/ + glm_euler_zxy_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + + /*Start gimbal lock tests*/ + for (float x = -90.0f; x <= 90.0f; x += 90.0f) { + for (float y = -90.0f; y <= 90.0f; y += 90.0f) { + for (float z = -90.0f; z <= 90.0f; z += 90.0f) { + /* angles that will cause gimbal lock*/ + vec3 angles = {x, y, z}; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in zxy order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + + + /*use my function to get the quaternion*/ + glm_euler_zxy_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_zyx_quat) { + for (int i = 0; i < 100; i++) { + /*random angles for testing*/ + vec3 angles; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + test_rand_vec3(angles); + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in zyx order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + + + /*use my function to get the quaternion*/ + glm_euler_zyx_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + + /*Start gimbal lock tests*/ + for (float x = -90.0f; x <= 90.0f; x += 90.0f) { + for (float y = -90.0f; y <= 90.0f; y += 90.0f) { + for (float z = -90.0f; z <= 90.0f; z += 90.0f) { + + /* angles that will cause gimbal lock*/ + vec3 angles = {x, y, z}; + + /*quaternion representations for rotations*/ + versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; + versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; + + vec3 axis_x = {1.0f, 0.0f, 0.0f}; + vec3 axis_y = {0.0f, 1.0f, 0.0f}; + vec3 axis_z = {0.0f, 0.0f, 1.0f}; + + versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; + versor result; + + /*create the rotation quaternions using the angles and axises*/ + glm_quatv(rot_x, angles[0], axis_x); + glm_quatv(rot_y, angles[1], axis_y); + glm_quatv(rot_z, angles[2], axis_z); + + /*apply the rotations to a unit quaternion in zyx order*/ + versor tmp; + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_z, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_y, tmp, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(rot_x, tmp, expected); + + + /*use my function to get the quaternion*/ + glm_euler_zyx_quat(result, angles); + + /*verify if the magnitude of the quaternion stays 1*/ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + + TEST_SUCCESS +} + TEST_IMPL(euler) { mat4 rot1, rot2; vec3 inAngles, outAngles; @@ -41,5 +580,14 @@ TEST_IMPL(euler) { glmc_euler_xyz(outAngles, rot2); ASSERTIFY(test_assert_mat4_eq(rot1, rot2)) + /* somehow when I try to make tests outside of this thing, + it won't work. So they stay here for now */ + ASSERTIFY(test_GLM_PREFIXeuler_xyz_quat()); + ASSERTIFY(test_GLM_PREFIXeuler_xzy_quat()); + ASSERTIFY(test_GLM_PREFIXeuler_yxz_quat()); + ASSERTIFY(test_GLM_PREFIXeuler_yzx_quat()); + ASSERTIFY(test_GLM_PREFIXeuler_zxy_quat()); + ASSERTIFY(test_GLM_PREFIXeuler_zyx_quat()); + TEST_SUCCESS } diff --git a/test/src/test_quat.h b/test/src/test_quat.h index c167ca1..da831fe 100644 --- a/test/src/test_quat.h +++ b/test/src/test_quat.h @@ -102,544 +102,6 @@ TEST_IMPL(GLM_PREFIX, quat_init) { TEST_SUCCESS } -TEST_IMPL(GLM_PREFIX, euler_xyz_quat) { - for (int i = 0; i < 100; i++) { - /*random angles for testing*/ - vec3 angles; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - test_rand_vec3(angles); - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in xyz order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_xyz_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - - - /*Start gimbal lock tests*/ - for (float x = -90.0f; x <= 90.0f; x += 90.0f) { - for (float y = -90.0f; y <= 90.0f; y += 90.0f) { - for (float z = -90.0f; z <= 90.0f; z += 90.0f) { - /* angles that will cause gimbal lock*/ - vec3 angles = {x, y, z}; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in xyz order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_xyz_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - } - } - TEST_SUCCESS -} - -TEST_IMPL(GLM_PREFIX, euler_xzy_quat) { - for (int i = 0; i < 100; i++) { - /*random angles for testing*/ - vec3 angles; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - test_rand_vec3(angles); - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in xzy order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_xzy_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - - /*Start gimbal lock tests*/ - for (float x = -90.0f; x <= 90.0f; x += 90.0f) { - for (float y = -90.0f; y <= 90.0f; y += 90.0f) { - for (float z = -90.0f; z <= 90.0f; z += 90.0f) { - /* angles that will cause gimbal lock*/ - vec3 angles = {x, y, z}; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in xyz order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_xzy_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - } - } - - TEST_SUCCESS -} - -TEST_IMPL(GLM_PREFIX, euler_yxz_quat) { - for (int i = 0; i < 100; i++) { - /*random angles for testing*/ - vec3 angles; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - test_rand_vec3(angles); - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in yxz order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_yxz_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - - /*Start gimbal lock tests*/ - for (float x = -90.0f; x <= 90.0f; x += 90.0f) { - for (float y = -90.0f; y <= 90.0f; y += 90.0f) { - for (float z = -90.0f; z <= 90.0f; z += 90.0f) { - /* angles that will cause gimbal lock*/ - vec3 angles = {x, y, z}; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in yxz order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_yxz_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - } - } - - TEST_SUCCESS -} - -TEST_IMPL(GLM_PREFIX, euler_yzx_quat) { - for (int i = 0; i < 100; i++) { - /*random angles for testing*/ - vec3 angles; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - test_rand_vec3(angles); - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in yzx order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_yzx_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - - /*Start gimbal lock tests*/ - for (float x = -90.0f; x <= 90.0f; x += 90.0f) { - for (float y = -90.0f; y <= 90.0f; y += 90.0f) { - for (float z = -90.0f; z <= 90.0f; z += 90.0f) { - /* angles that will cause gimbal lock*/ - vec3 angles = {x, y, z}; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in yzx order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_yzx_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - } - } - - TEST_SUCCESS -} - -TEST_IMPL(GLM_PREFIX, euler_zxy_quat) { - for (int i = 0; i < 100; i++) { - /*random angles for testing*/ - vec3 angles; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - test_rand_vec3(angles); - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in zxy order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - - /*use my function to get the quaternion*/ - glm_euler_zxy_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - - /*Start gimbal lock tests*/ - for (float x = -90.0f; x <= 90.0f; x += 90.0f) { - for (float y = -90.0f; y <= 90.0f; y += 90.0f) { - for (float z = -90.0f; z <= 90.0f; z += 90.0f) { - /* angles that will cause gimbal lock*/ - vec3 angles = {x, y, z}; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in zxy order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - - - /*use my function to get the quaternion*/ - glm_euler_zxy_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - } - } - - TEST_SUCCESS -} - -TEST_IMPL(GLM_PREFIX, euler_zyx_quat) { - for (int i = 0; i < 100; i++) { - /*random angles for testing*/ - vec3 angles; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - test_rand_vec3(angles); - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in zyx order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - - - /*use my function to get the quaternion*/ - glm_euler_zyx_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - - /*Start gimbal lock tests*/ - for (float x = -90.0f; x <= 90.0f; x += 90.0f) { - for (float y = -90.0f; y <= 90.0f; y += 90.0f) { - for (float z = -90.0f; z <= 90.0f; z += 90.0f) { - - /* angles that will cause gimbal lock*/ - vec3 angles = {x, y, z}; - - /*quaternion representations for rotations*/ - versor rot_x = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_y = {0.0f, 0.0f, 0.0f, 1.0f}; - versor rot_z = {0.0f, 0.0f, 0.0f, 1.0f}; - - vec3 axis_x = {1.0f, 0.0f, 0.0f}; - vec3 axis_y = {0.0f, 1.0f, 0.0f}; - vec3 axis_z = {0.0f, 0.0f, 1.0f}; - - versor expected = {0.0f, 0.0f, 0.0f, 1.0f}; - versor result; - - /*create the rotation quaternions using the angles and axises*/ - glm_quatv(rot_x, angles[0], axis_x); - glm_quatv(rot_y, angles[1], axis_y); - glm_quatv(rot_z, angles[2], axis_z); - - /*apply the rotations to a unit quaternion in zyx order*/ - versor tmp; - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_z, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_y, tmp, expected); - glm_quat_copy(expected, tmp); - glm_quat_mul(rot_x, tmp, expected); - - - /*use my function to get the quaternion*/ - glm_euler_zyx_quat(result, angles); - - /*verify if the magnitude of the quaternion stays 1*/ - ASSERT(test_eq(glm_quat_norm(result), 1.0f)) - - ASSERTIFY(test_assert_quat_eq(result, expected)) - } - } - } - - TEST_SUCCESS -} - TEST_IMPL(GLM_PREFIX, quatv) { versor q1 = {1.0f, 2.0f, 3.0f, 4.0f}; vec3 v1, v2; diff --git a/test/tests.h b/test/tests.h index 7e3697e..6c3f321 100644 --- a/test/tests.h +++ b/test/tests.h @@ -361,6 +361,12 @@ TEST_DECLARE(clamp) /* euler */ TEST_DECLARE(euler) +TEST_DECLARE(glm_euler_xyz_quat) +TEST_DECLARE(glm_euler_xzy_quat) +TEST_DECLARE(glm_euler_yxz_quat) +TEST_DECLARE(glm_euler_yzx_quat) +TEST_DECLARE(glm_euler_zxy_quat) +TEST_DECLARE(glm_euler_zyx_quat) /* ray */ TEST_DECLARE(glm_ray_triangle) @@ -374,12 +380,6 @@ TEST_DECLARE(glm_quat_identity) TEST_DECLARE(glm_quat_identity_array) TEST_DECLARE(glm_quat_init) TEST_DECLARE(glm_quatv) -TEST_DECLARE(glm_euler_xyz_quat) -TEST_DECLARE(glm_euler_xzy_quat) -TEST_DECLARE(glm_euler_yxz_quat) -TEST_DECLARE(glm_euler_yzx_quat) -TEST_DECLARE(glm_euler_zxy_quat) -TEST_DECLARE(glm_euler_zyx_quat) TEST_DECLARE(glm_quat) TEST_DECLARE(glm_quat_copy) TEST_DECLARE(glm_quat_norm) @@ -1341,9 +1341,10 @@ TEST_LIST { /* utils */ TEST_ENTRY(clamp) - + /* euler */ TEST_ENTRY(euler) + /* ray */ TEST_ENTRY(glm_ray_triangle) @@ -1357,12 +1358,6 @@ TEST_LIST { TEST_ENTRY(glm_quat_identity_array) TEST_ENTRY(glm_quat_init) TEST_ENTRY(glm_quatv) - TEST_ENTRY(glm_euler_xyz_quat) - TEST_ENTRY(glm_euler_xzy_quat) - TEST_ENTRY(glm_euler_yxz_quat) - TEST_ENTRY(glm_euler_yzx_quat) - TEST_ENTRY(glm_euler_zxy_quat) - TEST_ENTRY(glm_euler_zyx_quat) TEST_ENTRY(glm_quat) TEST_ENTRY(glm_quat_copy) TEST_ENTRY(glm_quat_norm)