From a94861dd5d51d01aecc994443dcdbc8e1cf46bdb Mon Sep 17 00:00:00 2001 From: John Choi Date: Thu, 28 Dec 2023 09:21:05 -0600 Subject: [PATCH 1/5] cleaned up documentation for euler to quat functions and also created the lh file. Made a handed struct file so I remember to do that --- include/cglm/handed/euler_to_quat_lh.h | 100 +++++++++++++++++++++++ include/cglm/handed/euler_to_quat_rh.h | 24 +++--- include/cglm/struct/handed/TODO THIS.txt | 0 3 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 include/cglm/handed/euler_to_quat_lh.h create mode 100644 include/cglm/struct/handed/TODO THIS.txt diff --git a/include/cglm/handed/euler_to_quat_lh.h b/include/cglm/handed/euler_to_quat_lh.h new file mode 100644 index 0000000..2b683d7 --- /dev/null +++ b/include/cglm/handed/euler_to_quat_lh.h @@ -0,0 +1,100 @@ +/* + * 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_euler_xyz_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glm_euler_xzy_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glm_euler_yxz_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glm_euler_yzx_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glm_euler_zxy_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glm_euler_zyx_quat_lh(vec3 angles, versor dest); + */ + +#ifndef cglm_euler_to_quat_lh_h +#define cglm_euler_to_quat_lh_h + +#include "../common.h" + + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x y z order in left hand (roll pitch yaw) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +void +glm_euler_xyz_quat_lh(vec3 angles, versor dest) { +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x z y order in left hand (roll yaw pitch) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +void +glm_euler_xzy_quat_lh(vec3 angles, versor dest) { + +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y x z order in left hand (pitch roll yaw) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +void +glm_euler_yxz_quat_lh(vec3 angles, versor dest) { + +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y z x order in left hand (pitch yaw roll) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +void +glm_euler_yzx_quat_lh(vec3 angles, versor dest) { + +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z x y order in left hand (yaw roll pitch) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +void +glm_euler_zxy_quat_lh(vec3 angles, versor dest) { +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z y x order in left hand (yaw pitch roll) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +void +glm_euler_zyx_quat_lh(vec3 angles, versor dest) { + +} + +#endif /*cglm_euler_to_quat_lh_h*/ \ No newline at end of file diff --git a/include/cglm/handed/euler_to_quat_rh.h b/include/cglm/handed/euler_to_quat_rh.h index b65108c..9782ad1 100644 --- a/include/cglm/handed/euler_to_quat_rh.h +++ b/include/cglm/handed/euler_to_quat_rh.h @@ -24,8 +24,8 @@ * @brief creates NEW quaternion using rotation angles and does * rotations in x y z order in right hand (roll pitch yaw) * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -48,8 +48,8 @@ glm_euler_xyz_quat_rh(vec3 angles, versor dest) { * @brief creates NEW quaternion using rotation angles and does * rotations in x z y order in right hand (roll yaw pitch) * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -72,8 +72,8 @@ glm_euler_xzy_quat_rh(vec3 angles, versor dest) { * @brief creates NEW quaternion using rotation angles and does * rotations in y x z order in right hand (pitch roll yaw) * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -95,8 +95,8 @@ glm_euler_yxz_quat_rh(vec3 angles, versor dest) { * @brief creates NEW quaternion using rotation angles and does * rotations in y z x order in right hand (pitch yaw roll) * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -119,8 +119,8 @@ glm_euler_yzx_quat_rh(vec3 angles, versor dest) { * @brief creates NEW quaternion using rotation angles and does * rotations in z x y order in right hand (yaw roll pitch) * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -142,8 +142,8 @@ glm_euler_zxy_quat_rh(vec3 angles, versor dest) { * @brief creates NEW quaternion using rotation angles and does * rotations in z y x order in right hand (yaw pitch roll) * - * @param[out] q quaternion - * @param[in] angle angles x y z (radians) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void diff --git a/include/cglm/struct/handed/TODO THIS.txt b/include/cglm/struct/handed/TODO THIS.txt new file mode 100644 index 0000000..e69de29 From c998d0186aa56945e179fd19336a5004e3ff0657 Mon Sep 17 00:00:00 2001 From: John Choi Date: Thu, 28 Dec 2023 09:52:17 -0600 Subject: [PATCH 2/5] made struct versions of euler to quat. Also fixed up documentation in euler to quat struct. --- include/cglm/euler.h | 24 ++-- include/cglm/struct/euler.h | 24 ++-- include/cglm/struct/handed/TODO THIS.txt | 0 include/cglm/struct/handed/euler_to_quat_lh.h | 115 ++++++++++++++++++ include/cglm/struct/handed/euler_to_quat_rh.h | 115 ++++++++++++++++++ 5 files changed, 254 insertions(+), 24 deletions(-) delete mode 100644 include/cglm/struct/handed/TODO THIS.txt create mode 100644 include/cglm/struct/handed/euler_to_quat_lh.h create mode 100644 include/cglm/struct/handed/euler_to_quat_rh.h diff --git a/include/cglm/euler.h b/include/cglm/euler.h index fb4adc0..358e9bf 100644 --- a/include/cglm/euler.h +++ b/include/cglm/euler.h @@ -460,8 +460,8 @@ 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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -477,8 +477,8 @@ glm_euler_xyz_quat(vec3 angles, versor 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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -494,8 +494,8 @@ glm_euler_xzy_quat(vec3 angles, versor 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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -511,8 +511,8 @@ glm_euler_yxz_quat(vec3 angles, versor 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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -528,8 +528,8 @@ glm_euler_yzx_quat(vec3 angles, versor 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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void @@ -545,8 +545,8 @@ glm_euler_zxy_quat(vec3 angles, versor 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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE void diff --git a/include/cglm/struct/euler.h b/include/cglm/struct/euler.h index 7b75946..3395745 100644 --- a/include/cglm/struct/euler.h +++ b/include/cglm/struct/euler.h @@ -159,8 +159,8 @@ glms_euler_by_order(vec3s angles, glm_euler_seq ord) { * @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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE versors @@ -174,8 +174,8 @@ glms_euler_xyz_quat(vec3s angles) { * @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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE versors @@ -189,8 +189,8 @@ glms_euler_xzy_quat(vec3s angles) { * @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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE versors @@ -204,8 +204,8 @@ glms_euler_yxz_quat(vec3s angles) { * @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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE versors @@ -219,8 +219,8 @@ glms_euler_yzx_quat(vec3s angles) { * @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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE versors @@ -234,8 +234,8 @@ glms_euler_zxy_quat(vec3s angles) { * @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) + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion */ CGLM_INLINE versors diff --git a/include/cglm/struct/handed/TODO THIS.txt b/include/cglm/struct/handed/TODO THIS.txt deleted file mode 100644 index e69de29..0000000 diff --git a/include/cglm/struct/handed/euler_to_quat_lh.h b/include/cglm/struct/handed/euler_to_quat_lh.h new file mode 100644 index 0000000..3964e51 --- /dev/null +++ b/include/cglm/struct/handed/euler_to_quat_lh.h @@ -0,0 +1,115 @@ +/* + * 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 glms_euler_xyz_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_xzy_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_yxz_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_yzx_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_zxy_quat_lh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_zyx_quat_lh(vec3 angles, versor dest); + */ + +#ifndef cglms_euler_to_quat_lh_h +#define cglms_euler_to_quat_lh_h + +#include "../common.h" + + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x y z order in left hand (roll pitch yaw) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_xyz_quat_lh(vec3s angles) { + versors dest; + glm_euler_xyz_quat_lh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x z y order in left hand (roll yaw pitch) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_xzy_quat_lh(vec3s angles) { + versors dest; + glm_euler_xzy_quat_lh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y x z order in left hand (pitch roll yaw) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_yxz_quat_lh(vec3s angles) { + versors dest; + glm_euler_yxz_quat_lh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y z x order in left hand (pitch yaw roll) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_yzx_quat_lh(vec3s angles) { + versors dest; + glm_euler_yzx_quat_lh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z x y order in left hand (yaw roll pitch) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_zxy_quat_lh(vec3s angles) { + versors dest; + glm_euler_zxy_quat_lh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z y x order in left hand (yaw pitch roll) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_zyx_quat_lh(vec3s angles) { + versors dest; + glm_euler_zyx_quat_lh(angles.raw, dest.raw); + return dest; +} + + +#endif /* cglms_euler_to_quat_lh_h */ diff --git a/include/cglm/struct/handed/euler_to_quat_rh.h b/include/cglm/struct/handed/euler_to_quat_rh.h new file mode 100644 index 0000000..6c7f400 --- /dev/null +++ b/include/cglm/struct/handed/euler_to_quat_rh.h @@ -0,0 +1,115 @@ +/* + * 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 glms_euler_xyz_quat_rh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_xzy_quat_rh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_yxz_quat_rh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_yzx_quat_rh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_zxy_quat_rh(vec3 angles, versor dest); + CGLM_INLINE void glms_euler_zyx_quat_rh(vec3 angles, versor dest); + */ + +#ifndef cglms_euler_to_quat_rh_h +#define cglms_euler_to_quat_rh_h + +#include "../common.h" + + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x y z order in right hand (roll pitch yaw) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_xyz_quat_rh(vec3s angles) { + versors dest; + glm_euler_xyz_quat_rh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in x z y order in right hand (roll yaw pitch) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_xzy_quat_rh(vec3s angles) { + versors dest; + glm_euler_xzy_quat_rh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y x z order in right hand (pitch roll yaw) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_yxz_quat_rh(vec3s angles) { + versors dest; + glm_euler_yxz_quat_rh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in y z x order in right hand (pitch yaw roll) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_yzx_quat_rh(vec3s angles) { + versors dest; + glm_euler_yzx_quat_rh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z x y order in right hand (yaw roll pitch) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_zxy_quat_rh(vec3s angles) { + versors dest; + glm_euler_zxy_quat_rh(angles.raw, dest.raw); + return dest; +} + +/*! + * @brief creates NEW quaternion using rotation angles and does + * rotations in z y x order in right hand (yaw pitch roll) + * + * @param[in] angles angles x y z (radians) + * @param[out] dest quaternion + */ +CGLM_INLINE +versors +glms_euler_zyx_quat_rh(vec3s angles) { + versors dest; + glm_euler_zyx_quat_rh(angles.raw, dest.raw); + return dest; +} + + +#endif /* cglms_euler_to_quat_rh_h */ From fa6244c42b21a130e8413c24ab5275f9cb9eacf8 Mon Sep 17 00:00:00 2001 From: John Choi Date: Thu, 28 Dec 2023 10:31:14 -0600 Subject: [PATCH 3/5] added tests for euler_to_quat_lh. Currently they don't have any euler->mat4->quat tests because there is no left handed version of those. But I could try to find a way to change it --- test/src/test_euler_to_quat_lh.h | 521 +++++++++++++++++++++++++++++++ test/tests.h | 46 ++- 2 files changed, 566 insertions(+), 1 deletion(-) create mode 100644 test/src/test_euler_to_quat_lh.h diff --git a/test/src/test_euler_to_quat_lh.h b/test/src/test_euler_to_quat_lh.h new file mode 100644 index 0000000..2269757 --- /dev/null +++ b/test/src/test_euler_to_quat_lh.h @@ -0,0 +1,521 @@ +/* + * 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" +#include "../../include/cglm/handed/euler_to_quat_lh.h" + +TEST_IMPL(GLM_PREFIX, euler_xyz_quat_lh) { + 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}; + + /* random angles for testing */ + vec3 angles; + + /* quaternion representations for rotations */ + versor rot_x, rot_y, rot_z; + + versor expected; + versor result; + versor tmp; + + mat4 expected_mat4; + + /* 100 randomized tests */ + for (int i = 0; i < 100; i++) { + 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + + glm_euler_xyz_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + 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[0] = x; + angles[1] = y; + angles[2] = z; + + /* 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + + /* use my function to get the quaternion */ + glm_euler_xyz_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_xzy_quat_lh) { + 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}; + + /* random angles for testing */ + vec3 angles; + + /* quaternion representations for rotations */ + versor rot_x, rot_y, rot_z; + + versor expected; + versor result; + versor tmp; + + /* 100 randomized tests */ + for (int i = 0; i < 100; i++) { + 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + + glm_euler_xzy_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + 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[0] = x; + angles[1] = y; + angles[2] = z; + + /* 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + + /* use my function to get the quaternion */ + glm_euler_xzy_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_yxz_quat_lh) { + 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}; + + /* random angles for testing */ + vec3 angles; + + /* quaternion representations for rotations */ + versor rot_x, rot_y, rot_z; + + versor expected; + versor result; + versor tmp; + + /* 100 randomized tests */ + for (int i = 0; i < 100; i++) { + 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + + glm_euler_yxz_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + ASSERTIFY(test_assert_quat_eq(result, expected)) + + /* verify that it acts the same as glm_euler_by_order */ + glm_euler_by_order(angles, GLM_EULER_YXZ, expected_mat4); + glm_mat4_quat(expected_mat4, expected); + + ASSERTIFY(test_assert_quat_eq_abs(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[0] = x; + angles[1] = y; + angles[2] = z; + + /* 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + + /* use my function to get the quaternion */ + glm_euler_yxz_quat_lh(angles, result); + + /* 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)) + + /* verify that it acts the same as glm_euler_by_order */ + glm_euler_by_order(angles, GLM_EULER_YXZ, expected_mat4); + glm_mat4_quat(expected_mat4, expected); + + ASSERTIFY(test_assert_quat_eq_abs(result, expected)); + } + } + } + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_yzx_quat_lh) { + 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}; + + /* random angles for testing */ + vec3 angles; + + /* quaternion representations for rotations */ + versor rot_x, rot_y, rot_z; + + versor expected; + versor result; + versor tmp; + + /* 100 randomized tests */ + for (int i = 0; i < 100; i++) { + 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + + glm_euler_yzx_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + ASSERTIFY(test_assert_quat_eq(result, expected)) + + /* verify that it acts the same as glm_euler_by_order */ + glm_euler_by_order(angles, GLM_EULER_YZX, expected_mat4); + glm_mat4_quat(expected_mat4, expected); + + ASSERTIFY(test_assert_quat_eq_abs(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[0] = x; + angles[1] = y; + angles[2] = z; + + /* 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + + /* use my function to get the quaternion */ + glm_euler_yzx_quat_lh(angles, result); + + /* 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)) + + /* verify that it acts the same as glm_euler_by_order */ + glm_euler_by_order(angles, GLM_EULER_YZX, expected_mat4); + glm_mat4_quat(expected_mat4, expected); + + ASSERTIFY(test_assert_quat_eq_abs(result, expected)); + } + } + } + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_zxy_quat_lh) { + 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}; + + /* random angles for testing */ + vec3 angles; + + /* quaternion representations for rotations */ + versor rot_x, rot_y, rot_z; + + versor expected; + versor result; + versor tmp; + + /* 100 randomized tests */ + for (int i = 0; i < 100; i++) { + 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + + glm_euler_zxy_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + 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[0] = x; + angles[1] = y; + angles[2] = z; + + /* 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + + /* use my function to get the quaternion */ + glm_euler_zxy_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + TEST_SUCCESS +} + +TEST_IMPL(GLM_PREFIX, euler_zyx_quat_lh) { + 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}; + + /* random angles for testing */ + vec3 angles; + + /* quaternion representations for rotations */ + versor rot_x, rot_y, rot_z; + + versor expected; + versor result; + versor tmp; + + /* 100 randomized tests */ + for (int i = 0; i < 100; i++) { + 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + + glm_euler_zyx_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + 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[0] = x; + angles[1] = y; + angles[2] = z; + + /* 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 */ + glm_quat_identity(expected); + + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_z, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_y, expected); + glm_quat_copy(expected, tmp); + glm_quat_mul(tmp, rot_x, expected); + + /* use my function to get the quaternion */ + glm_euler_zyx_quat_lh(angles, result); + + /* verify if the magnitude of the quaternion stays 1 */ + ASSERT(test_eq(glm_quat_norm(result), 1.0f)) + + /* verify that it acts the same as rotating by 3 axis quaternions */ + ASSERTIFY(test_assert_quat_eq(result, expected)) + } + } + } + TEST_SUCCESS +} + + diff --git a/test/tests.h b/test/tests.h index 37f8abb..a6c0ff0 100644 --- a/test/tests.h +++ b/test/tests.h @@ -363,9 +363,31 @@ TEST_DECLARE(clamp) TEST_DECLARE(glm_euler_xyz_quat_rh) TEST_DECLARE(glm_euler_xzy_quat_rh) TEST_DECLARE(glm_euler_yxz_quat_rh) -TEST_DECLARE(glm_euler_yzx_quat_rh) +TEST_DECLARE(glm_euler_yzx_quat_rh) TEST_DECLARE(glm_euler_zxy_quat_rh) TEST_DECLARE(glm_euler_zyx_quat_rh) + +TEST_DECLARE(glm_euler_xyz_quat_lh) +TEST_DECLARE(glm_euler_xzy_quat_lh) +TEST_DECLARE(glm_euler_yxz_quat_lh) +TEST_DECLARE(glm_euler_yzx_quat_lh) +TEST_DECLARE(glm_euler_zxy_quat_lh) +TEST_DECLARE(glm_euler_zyx_quat_lh) + +TEST_DECLARE(glmc_euler_xyz_quat_rh) +TEST_DECLARE(glmc_euler_xzy_quat_rh) +TEST_DECLARE(glmc_euler_yxz_quat_rh) +TEST_DECLARE(glmc_euler_yzx_quat_rh) +TEST_DECLARE(glmc_euler_zxy_quat_rh) +TEST_DECLARE(glmc_euler_zyx_quat_rh) + +TEST_DECLARE(glmc_euler_xyz_quat_lh) +TEST_DECLARE(glmc_euler_xzy_quat_lh) +TEST_DECLARE(glmc_euler_yxz_quat_lh) +TEST_DECLARE(glmc_euler_yzx_quat_lh) +TEST_DECLARE(glmc_euler_zxy_quat_lh) +TEST_DECLARE(glmc_euler_zyx_quat_lh) + TEST_DECLARE(euler) /* ray */ @@ -1385,6 +1407,28 @@ TEST_LIST { TEST_ENTRY(glm_euler_yzx_quat_rh) TEST_ENTRY(glm_euler_zxy_quat_rh) TEST_ENTRY(glm_euler_zyx_quat_rh) + + TEST_ENTRY(glm_euler_xyz_quat_lh) + TEST_ENTRY(glm_euler_xzy_quat_lh) + TEST_ENTRY(glm_euler_yxz_quat_lh) + TEST_ENTRY(glm_euler_yzx_quat_lh) + TEST_ENTRY(glm_euler_zxy_quat_lh) + TEST_ENTRY(glm_euler_zyx_quat_lh) + + TEST_ENTRY(glmc_euler_xyz_quat_rh) + TEST_ENTRY(glmc_euler_xzy_quat_rh) + TEST_ENTRY(glmc_euler_yxz_quat_rh) + TEST_ENTRY(glmc_euler_yzx_quat_rh) + TEST_ENTRY(glmc_euler_zxy_quat_rh) + TEST_ENTRY(glmc_euler_zyx_quat_rh) + + TEST_ENTRY(glmc_euler_xyz_quat_lh) + TEST_ENTRY(glmc_euler_xzy_quat_lh) + TEST_ENTRY(glmc_euler_yxz_quat_lh) + TEST_ENTRY(glmc_euler_yzx_quat_lh) + TEST_ENTRY(glmc_euler_zxy_quat_lh) + TEST_ENTRY(glmc_euler_zyx_quat_lh) + TEST_ENTRY(euler) /* ray */ From aa20b8ae7fbf6416ee46178c5a78330d710b7198 Mon Sep 17 00:00:00 2001 From: John Choi Date: Thu, 28 Dec 2023 11:01:01 -0600 Subject: [PATCH 4/5] added implementation of euler_to_quat_lh and fixed the tests. Now I gotta decide what to name the macros for controlling lefthand and also make call functions for rh and lh conditionally declared --- include/cglm/handed/euler_to_quat_lh.h | 62 ++++++++++++++++++++++++++ test/src/test_euler_to_quat_lh.h | 26 ----------- test/src/tests.c | 2 + 3 files changed, 64 insertions(+), 26 deletions(-) diff --git a/include/cglm/handed/euler_to_quat_lh.h b/include/cglm/handed/euler_to_quat_lh.h index 2b683d7..67b5e22 100644 --- a/include/cglm/handed/euler_to_quat_lh.h +++ b/include/cglm/handed/euler_to_quat_lh.h @@ -31,6 +31,17 @@ CGLM_INLINE void glm_euler_xyz_quat_lh(vec3 angles, versor dest) { + float xc, yc, zc, + xs, ys, zs; + + xs = sinf(angles[0] * 0.5f); xc = cosf(angles[0] * 0.5f); + ys = sinf(angles[1] * 0.5f); yc = cosf(angles[1] * 0.5f); + zs = -sinf(angles[2] * 0.5f); zc = cosf(angles[2] * 0.5f); + + dest[0] = xc * ys * zs + xs * yc * zc; + dest[1] = xc * ys * zc - xs * yc * zs; + dest[2] = xc * yc * zs + xs * ys * zc; + dest[3] = xc * yc * zc - xs * ys * zs; } /*! @@ -43,7 +54,17 @@ glm_euler_xyz_quat_lh(vec3 angles, versor dest) { CGLM_INLINE void glm_euler_xzy_quat_lh(vec3 angles, versor dest) { + float xc, yc, zc, + xs, ys, zs; + xs = sinf(angles[0] * 0.5f); xc = cosf(angles[0] * 0.5f); + ys = sinf(angles[1] * 0.5f); yc = cosf(angles[1] * 0.5f); + zs = -sinf(angles[2] * 0.5f); zc = cosf(angles[2] * 0.5f); + + dest[0] = -xc * zs * ys + xs * zc * yc; + dest[1] = xc * zc * ys - xs * zs * yc; + dest[2] = xc * zs * yc + xs * zc * ys; + dest[3] = xc * zc * yc + xs * zs * ys; } /*! @@ -56,7 +77,17 @@ glm_euler_xzy_quat_lh(vec3 angles, versor dest) { CGLM_INLINE void glm_euler_yxz_quat_lh(vec3 angles, versor dest) { + float xc, yc, zc, + xs, ys, zs; + xs = sinf(angles[0] * 0.5f); xc = cosf(angles[0] * 0.5f); + ys = sinf(angles[1] * 0.5f); yc = cosf(angles[1] * 0.5f); + zs = -sinf(angles[2] * 0.5f); zc = cosf(angles[2] * 0.5f); + + dest[0] = yc * xs * zc + ys * xc * zs; + dest[1] = -yc * xs * zs + ys * xc * zc; + dest[2] = yc * xc * zs - ys * xs * zc; + dest[3] = yc * xc * zc + ys * xs * zs; } /*! @@ -69,7 +100,17 @@ glm_euler_yxz_quat_lh(vec3 angles, versor dest) { CGLM_INLINE void glm_euler_yzx_quat_lh(vec3 angles, versor dest) { + float xc, yc, zc, + xs, ys, zs; + xs = sinf(angles[0] * 0.5f); xc = cosf(angles[0] * 0.5f); + ys = sinf(angles[1] * 0.5f); yc = cosf(angles[1] * 0.5f); + zs = -sinf(angles[2] * 0.5f); zc = cosf(angles[2] * 0.5f); + + dest[0] = yc * zc * xs + ys * zs * xc; + dest[1] = yc * zs * xs + ys * zc * xc; + dest[2] = yc * zs * xc - ys * zc * xs; + dest[3] = yc * zc * xc - ys * zs * xs; } /*! @@ -82,6 +123,17 @@ glm_euler_yzx_quat_lh(vec3 angles, versor dest) { CGLM_INLINE void glm_euler_zxy_quat_lh(vec3 angles, versor dest) { + float xc, yc, zc, + xs, ys, zs; + + xs = sinf(angles[0] * 0.5f); xc = cosf(angles[0] * 0.5f); + ys = sinf(angles[1] * 0.5f); yc = cosf(angles[1] * 0.5f); + zs = -sinf(angles[2] * 0.5f); zc = cosf(angles[2] * 0.5f); + + dest[0] = zc * xs * yc - zs * xc * ys; + dest[1] = zc * xc * ys + zs * xs * yc; + dest[2] = zc * xs * ys + zs * xc * yc; + dest[3] = zc * xc * yc - zs * xs * ys; } /*! @@ -94,7 +146,17 @@ glm_euler_zxy_quat_lh(vec3 angles, versor dest) { CGLM_INLINE void glm_euler_zyx_quat_lh(vec3 angles, versor dest) { + float xc, yc, zc, + xs, ys, zs; + xs = sinf(angles[0] * 0.5f); xc = cosf(angles[0] * 0.5f); + ys = sinf(angles[1] * 0.5f); yc = cosf(angles[1] * 0.5f); + zs = -sinf(angles[2] * 0.5f); zc = cosf(angles[2] * 0.5f); + + dest[0] = zc * yc * xs - zs * ys * xc; + dest[1] = zc * ys * xc + zs * yc * xs; + dest[2] = -zc * ys * xs + zs * yc * xc; + dest[3] = zc * yc * xc + zs * ys * xs; } #endif /*cglm_euler_to_quat_lh_h*/ \ No newline at end of file diff --git a/test/src/test_euler_to_quat_lh.h b/test/src/test_euler_to_quat_lh.h index 2269757..faec48e 100644 --- a/test/src/test_euler_to_quat_lh.h +++ b/test/src/test_euler_to_quat_lh.h @@ -23,8 +23,6 @@ TEST_IMPL(GLM_PREFIX, euler_xyz_quat_lh) { versor result; versor tmp; - mat4 expected_mat4; - /* 100 randomized tests */ for (int i = 0; i < 100; i++) { test_rand_vec3(angles); @@ -213,12 +211,6 @@ TEST_IMPL(GLM_PREFIX, euler_yxz_quat_lh) { /* verify that it acts the same as rotating by 3 axis quaternions */ ASSERTIFY(test_assert_quat_eq(result, expected)) - - /* verify that it acts the same as glm_euler_by_order */ - glm_euler_by_order(angles, GLM_EULER_YXZ, expected_mat4); - glm_mat4_quat(expected_mat4, expected); - - ASSERTIFY(test_assert_quat_eq_abs(result, expected)); } @@ -252,12 +244,6 @@ TEST_IMPL(GLM_PREFIX, euler_yxz_quat_lh) { ASSERT(test_eq(glm_quat_norm(result), 1.0f)) ASSERTIFY(test_assert_quat_eq(result, expected)) - - /* verify that it acts the same as glm_euler_by_order */ - glm_euler_by_order(angles, GLM_EULER_YXZ, expected_mat4); - glm_mat4_quat(expected_mat4, expected); - - ASSERTIFY(test_assert_quat_eq_abs(result, expected)); } } } @@ -305,12 +291,6 @@ TEST_IMPL(GLM_PREFIX, euler_yzx_quat_lh) { /* verify that it acts the same as rotating by 3 axis quaternions */ ASSERTIFY(test_assert_quat_eq(result, expected)) - - /* verify that it acts the same as glm_euler_by_order */ - glm_euler_by_order(angles, GLM_EULER_YZX, expected_mat4); - glm_mat4_quat(expected_mat4, expected); - - ASSERTIFY(test_assert_quat_eq_abs(result, expected)); } @@ -344,12 +324,6 @@ TEST_IMPL(GLM_PREFIX, euler_yzx_quat_lh) { ASSERT(test_eq(glm_quat_norm(result), 1.0f)) ASSERTIFY(test_assert_quat_eq(result, expected)) - - /* verify that it acts the same as glm_euler_by_order */ - glm_euler_by_order(angles, GLM_EULER_YZX, expected_mat4); - glm_mat4_quat(expected_mat4, expected); - - ASSERTIFY(test_assert_quat_eq_abs(result, expected)); } } } diff --git a/test/src/tests.c b/test/src/tests.c index 274f7e0..4d93294 100644 --- a/test/src/tests.c +++ b/test/src/tests.c @@ -40,6 +40,7 @@ #include "test_cam_rh_no.h" #include "test_cam_rh_zo.h" #include "test_euler_to_quat_rh.h" +#include "test_euler_to_quat_lh.h" #undef GLM #undef GLM_PREFIX @@ -78,6 +79,7 @@ #include "test_cam_rh_no.h" #include "test_cam_rh_zo.h" #include "test_euler_to_quat_rh.h" +#include "test_euler_to_quat_lh.h" #undef GLM #undef GLM_PREFIX From 1ccd9af866d760c05563fb72b19709a944644d6f Mon Sep 17 00:00:00 2001 From: John Choi Date: Sat, 30 Dec 2023 12:06:40 -0600 Subject: [PATCH 5/5] added comment about rh vs lh zsin --- include/cglm/euler.h | 41 +++++++++++++++++++++++++- include/cglm/handed/euler_to_quat_lh.h | 5 ++++ include/cglm/handed/euler_to_quat_rh.h | 5 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/cglm/euler.h b/include/cglm/euler.h index 358e9bf..d069f10 100644 --- a/include/cglm/euler.h +++ b/include/cglm/euler.h @@ -43,7 +43,46 @@ #include "common.h" -#include "handed/euler_to_quat_rh.h" +#ifdef CGLM_FORCE_LEFT_HANDED +# include "handed/euler_to_quat_lh.h" +#else +# include "handed/euler_to_quat_rh.h" +#endif + + +#ifndef CGLM_CLIPSPACE_INCLUDE_ALL +# if CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_ZO +# include "clipspace/ortho_lh_zo.h" +# include "clipspace/persp_lh_zo.h" +# include "clipspace/view_lh_zo.h" +# elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_LH_NO +# include "clipspace/ortho_lh_no.h" +# include "clipspace/persp_lh_no.h" +# include "clipspace/view_lh_no.h" +# elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_ZO +# include "clipspace/ortho_rh_zo.h" +# include "clipspace/persp_rh_zo.h" +# include "clipspace/view_rh_zo.h" +# elif CGLM_CONFIG_CLIP_CONTROL == CGLM_CLIP_CONTROL_RH_NO +# include "clipspace/ortho_rh_no.h" +# include "clipspace/persp_rh_no.h" +# include "clipspace/view_rh_no.h" +# endif +#else +# include "clipspace/ortho_lh_zo.h" +# include "clipspace/persp_lh_zo.h" +# include "clipspace/ortho_lh_no.h" +# include "clipspace/persp_lh_no.h" +# include "clipspace/ortho_rh_zo.h" +# include "clipspace/persp_rh_zo.h" +# include "clipspace/ortho_rh_no.h" +# include "clipspace/persp_rh_no.h" +# include "clipspace/view_lh_zo.h" +# include "clipspace/view_lh_no.h" +# include "clipspace/view_rh_zo.h" +# include "clipspace/view_rh_no.h" +#endif + /*! * if you have axis order like vec3 orderVec = [0, 1, 2] or [0, 2, 1]... diff --git a/include/cglm/handed/euler_to_quat_lh.h b/include/cglm/handed/euler_to_quat_lh.h index 67b5e22..def40c9 100644 --- a/include/cglm/handed/euler_to_quat_lh.h +++ b/include/cglm/handed/euler_to_quat_lh.h @@ -15,6 +15,11 @@ CGLM_INLINE void glm_euler_zyx_quat_lh(vec3 angles, versor dest); */ +/* + Things to note: + The only difference between euler to quat rh vs lh is that the zsin part is negative + */ + #ifndef cglm_euler_to_quat_lh_h #define cglm_euler_to_quat_lh_h diff --git a/include/cglm/handed/euler_to_quat_rh.h b/include/cglm/handed/euler_to_quat_rh.h index 9782ad1..aeb6f81 100644 --- a/include/cglm/handed/euler_to_quat_rh.h +++ b/include/cglm/handed/euler_to_quat_rh.h @@ -15,6 +15,11 @@ CGLM_INLINE void glm_euler_zyx_quat_rh(vec3 angles, versor dest); */ +/* + Things to note: + The only difference between euler to quat rh vs lh is that the zsin part is negative + */ + #ifndef cglm_euler_to_quat_rh_h #define cglm_euler_to_quat_rh_h