From 205d13aa93484b83cca2b83e7b592f18a09ba890 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 26 Mar 2018 23:00:38 +0300 Subject: [PATCH] fix euler angles (extrinsic -> intrinsic) because cglm uses intrinsics for these rotations --- include/cglm/euler.h | 442 ++++++++++++++++++++++++------------------- 1 file changed, 243 insertions(+), 199 deletions(-) diff --git a/include/cglm/euler.h b/include/cglm/euler.h index 2289b04..66e0f77 100644 --- a/include/cglm/euler.h +++ b/include/cglm/euler.h @@ -5,6 +5,14 @@ * Full license can be found in the LICENSE file */ +/* + NOTE: + angles must be passed as [X-Angle, Y-Angle, Z-angle] order + For instance you don't pass angles as [Z-Angle, X-Angle, Y-angle] to + glm_euler_zxy funciton, All RELATED functions accept angles same order + which is [X, Y, Z]. + */ + /* Types: enum glm_euler_sq @@ -95,219 +103,255 @@ glm_euler_angles(mat4 m, vec3 dest) { } } + /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ex, Ey, Ez] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] + * @param[out] dest rotation matrix + */ +CGLM_INLINE +void +glm_euler_xyz(vec3 angles, mat4 dest) { + float cx, cy, cz, + sx, sy, sz, czsx, cxcz, sysz; + + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); + + czsx = cz * sx; + cxcz = cx * cz; + sysz = sy * sz; + + dest[0][0] = cy * cz; + dest[0][1] = czsx * sy + cx * sz; + dest[0][2] = -cxcz * sy + sx * sz; + dest[1][0] = -cy * sz; + dest[1][1] = cxcz - sx * sysz; + dest[1][2] = czsx + cx * sysz; + dest[2][0] = sy; + dest[2][1] = -cy * sx; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; +} + +/*! + * @brief build rotation matrix from euler angles + * + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void glm_euler(vec3 angles, mat4 dest) { - float cx, cy, cz, - sx, sy, sz; - - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); - - dest[0][0] = cy * cz; - dest[0][1] = cy * sz; - dest[0][2] =-sy; - dest[1][0] = cz * sx * sy - cx * sz; - dest[1][1] = cx * cz + sx * sy * sz; - dest[1][2] = cy * sx; - dest[2][0] = cx * cz * sy + sx * sz; - dest[2][1] =-cz * sx + cx * sy * sz; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + glm_euler_xyz(angles, dest); } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ez, Ey, Ex] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_zyx(vec3 angles, - mat4 dest) { +glm_euler_xzy(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, sxsy, cysx, cxsy, cxcy; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz; - dest[0][1] = cz * sx * sy + cx * sz; - dest[0][2] =-cx * cz * sy + sx * sz; - dest[1][0] =-cy * sz; - dest[1][1] = cx * cz - sx * sy * sz; - dest[1][2] = cz * sx + cx * sy * sz; - dest[2][0] = sy; - dest[2][1] =-cy * sx; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + sxsy = sx * sy; + cysx = cy * sx; + cxsy = cx * sy; + cxcy = cx * cy; + + dest[0][0] = cy * cz; + dest[0][1] = sxsy + cxcy * sz; + dest[0][2] = -cxsy + cysx * sz; + dest[1][0] = -sz; + dest[1][1] = cx * cz; + dest[1][2] = cz * sx; + dest[2][0] = cz * sy; + dest[2][1] = -cysx + cxsy * sz; + dest[2][2] = cxcy + sxsy * sz; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } + /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ez, Ex, Ey] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_zxy(vec3 angles, - mat4 dest) { +glm_euler_yxz(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, cycz, sysz, czsy, cysz; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz + sx * sy * sz; - dest[0][1] = cx * sz; - dest[0][2] =-cz * sy + cy * sx * sz; - dest[1][0] = cz * sx * sy - cy * sz; - dest[1][1] = cx * cz; - dest[1][2] = cy * cz * sx + sy * sz; - dest[2][0] = cx * sy; - dest[2][1] =-sx; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + cycz = cy * cz; + sysz = sy * sz; + czsy = cz * sy; + cysz = cy * sz; + + dest[0][0] = cycz + sx * sysz; + dest[0][1] = cx * sz; + dest[0][2] = -czsy + cysz * sx; + dest[1][0] = -cysz + czsy * sx; + dest[1][1] = cx * cz; + dest[1][2] = cycz * sx + sysz; + dest[2][0] = cx * sy; + dest[2][1] = -sx; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ex, Ez, Ey] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_xzy(vec3 angles, - mat4 dest) { +glm_euler_yzx(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, sxsy, cxcy, cysx, cxsy; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz; - dest[0][1] = sz; - dest[0][2] =-cz * sy; - dest[1][0] = sx * sy - cx * cy * sz; - dest[1][1] = cx * cz; - dest[1][2] = cy * sx + cx * sy * sz; - dest[2][0] = cx * sy + cy * sx * sz; - dest[2][1] =-cz * sx; - dest[2][2] = cx * cy - sx * sy * sz; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + sxsy = sx * sy; + cxcy = cx * cy; + cysx = cy * sx; + cxsy = cx * sy; + + dest[0][0] = cy * cz; + dest[0][1] = sz; + dest[0][2] = -cz * sy; + dest[1][0] = sxsy - cxcy * sz; + dest[1][1] = cx * cz; + dest[1][2] = cysx + cxsy * sz; + dest[2][0] = cxsy + cysx * sz; + dest[2][1] = -cz * sx; + dest[2][2] = cxcy - sxsy * sz; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ey, Ez, Ex] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_yzx(vec3 angles, - mat4 dest) { +glm_euler_zxy(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, cycz, sxsy, cysz; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz; - dest[0][1] = sx * sy + cx * cy * sz; - dest[0][2] =-cx * sy + cy * sx * sz; - dest[1][0] =-sz; - dest[1][1] = cx * cz; - dest[1][2] = cz * sx; - dest[2][0] = cz * sy; - dest[2][1] =-cy * sx + cx * sy * sz; - dest[2][2] = cx * cy + sx * sy * sz; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + cycz = cy * cz; + sxsy = sx * sy; + cysz = cy * sz; + + dest[0][0] = cycz - sxsy * sz; + dest[0][1] = cz * sxsy + cysz; + dest[0][2] = -cx * sy; + dest[1][0] = -cx * sz; + dest[1][1] = cx * cz; + dest[1][2] = sx; + dest[2][0] = cz * sy + cysz * sx; + dest[2][1] = -cycz * sx + sy * sz; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector [Ey, Ex, Ez] + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[out] dest rotation matrix */ CGLM_INLINE void -glm_euler_yxz(vec3 angles, - mat4 dest) { +glm_euler_zyx(vec3 angles, mat4 dest) { float cx, cy, cz, - sx, sy, sz; + sx, sy, sz, czsx, cxcz, sysz; - sx = sinf(angles[0]); cx = cosf(angles[0]); - sy = sinf(angles[1]); cy = cosf(angles[1]); - sz = sinf(angles[2]); cz = cosf(angles[2]); + sx = sinf(angles[0]); cx = cosf(angles[0]); + sy = sinf(angles[1]); cy = cosf(angles[1]); + sz = sinf(angles[2]); cz = cosf(angles[2]); - dest[0][0] = cy * cz - sx * sy * sz; - dest[0][1] = cz * sx * sy + cy * sz; - dest[0][2] =-cx * sy; - dest[1][0] =-cx * sz; - dest[1][1] = cx * cz; - dest[1][2] = sx; - dest[2][0] = cz * sy + cy * sx * sz; - dest[2][1] =-cy * cz * sx + sy * sz; - dest[2][2] = cx * cy; - dest[0][3] = 0.0f; - dest[1][3] = 0.0f; - dest[2][3] = 0.0f; - dest[3][0] = 0.0f; - dest[3][1] = 0.0f; - dest[3][2] = 0.0f; - dest[3][3] = 1.0f; + czsx = cz * sx; + cxcz = cx * cz; + sysz = sy * sz; + + dest[0][0] = cy * cz; + dest[0][1] = cy * sz; + dest[0][2] = -sy; + dest[1][0] = czsx * sy - cx * sz; + dest[1][1] = cxcz + sx * sysz; + dest[1][2] = cy * sx; + dest[2][0] = cxcz * sy + sx * sz; + dest[2][1] = -czsx + cx * sysz; + dest[2][2] = cx * cy; + dest[0][3] = 0.0f; + dest[1][3] = 0.0f; + dest[2][3] = 0.0f; + dest[3][0] = 0.0f; + dest[3][1] = 0.0f; + dest[3][2] = 0.0f; + dest[3][3] = 1.0f; } /*! * @brief build rotation matrix from euler angles * - * @param[in] angles angles as vector (ord parameter spceifies angles order) + * @param[in] angles angles as vector [Xangle, Yangle, Zangle] * @param[in] ord euler order * @param[out] dest rotation matrix */ @@ -332,71 +376,71 @@ glm_euler_by_order(vec3 angles, glm_euler_sq ord, mat4 dest) { sysz = sy * sz; switch (ord) { - case GLM_EULER_XYZ: - dest[0][0] = cycz; - dest[0][1] = cysz; - dest[0][2] =-sy; - dest[1][0] = czsx * sy - cxsz; - dest[1][1] = cxcz + sx * sysz; - dest[1][2] = cysx; - dest[2][0] = cx * czsy + sx * sz; - dest[2][1] =-czsx + cx * sysz; - dest[2][2] = cxcy; - break; case GLM_EULER_XZY: - dest[0][0] = cycz; - dest[0][1] = sz; - dest[0][2] =-czsy; - dest[1][0] = sx * sy - cx * cysz; - dest[1][1] = cxcz; - dest[1][2] = cysx + cx * sysz; - dest[2][0] = cx * sy + cysx * sz; - dest[2][1] =-czsx; - dest[2][2] = cxcy - sx * sysz; + dest[0][0] = cycz; + dest[0][1] = sx * sy + cx * cysz; + dest[0][2] = -cx * sy + cysx * sz; + dest[1][0] = -sz; + dest[1][1] = cxcz; + dest[1][2] = czsx; + dest[2][0] = czsy; + dest[2][1] = -cysx + cx * sysz; + dest[2][2] = cxcy + sx * sysz; break; - case GLM_EULER_ZXY: - dest[0][0] = cycz + sx * sysz; - dest[0][1] = cxsz; - dest[0][2] =-czsy + cysx * sz; - dest[1][0] = czsx * sy - cysz; - dest[1][1] = cxcz; - dest[1][2] = cycz * sx + sysz; - dest[2][0] = cx * sy; - dest[2][1] =-sx; - dest[2][2] = cxcy; - break; - case GLM_EULER_ZYX: - dest[0][0] = cycz; - dest[0][1] = czsx * sy + cxsz; - dest[0][2] =-cx * czsy + sx * sz; - dest[1][0] =-cysz; - dest[1][1] = cxcz - sx * sysz; - dest[1][2] = czsx + cx * sysz; - dest[2][0] = sy; - dest[2][1] =-cysx; - dest[2][2] = cxcy; + case GLM_EULER_XYZ: + dest[0][0] = cycz; + dest[0][1] = czsx * sy + cxsz; + dest[0][2] = -cx * czsy + sx * sz; + dest[1][0] = -cysz; + dest[1][1] = cxcz - sx * sysz; + dest[1][2] = czsx + cx * sysz; + dest[2][0] = sy; + dest[2][1] = -cysx; + dest[2][2] = cxcy; break; case GLM_EULER_YXZ: - dest[0][0] = cycz - sx * sysz; - dest[0][1] = czsx * sy + cysz; - dest[0][2] =-cx * sy; - dest[1][0] =-cxsz; - dest[1][1] = cxcz; - dest[1][2] = sx; - dest[2][0] = czsy + cysx * sz; - dest[2][1] =-cycz * sx + sysz; - dest[2][2] = cxcy; + dest[0][0] = cycz + sx * sysz; + dest[0][1] = cxsz; + dest[0][2] = -czsy + cysx * sz; + dest[1][0] = czsx * sy - cysz; + dest[1][1] = cxcz; + dest[1][2] = cycz * sx + sysz; + dest[2][0] = cx * sy; + dest[2][1] = -sx; + dest[2][2] = cxcy; break; case GLM_EULER_YZX: - dest[0][0] = cycz; - dest[0][1] = sx * sy + cx * cysz; - dest[0][2] =-cx * sy + cysx * sz; - dest[1][0] =-sz; - dest[1][1] = cxcz; - dest[1][2] = czsx; - dest[2][0] = czsy; - dest[2][1] =-cysx + cx * sysz; - dest[2][2] = cxcy + sx * sysz; + dest[0][0] = cycz; + dest[0][1] = sz; + dest[0][2] = -czsy; + dest[1][0] = sx * sy - cx * cysz; + dest[1][1] = cxcz; + dest[1][2] = cysx + cx * sysz; + dest[2][0] = cx * sy + cysx * sz; + dest[2][1] = -czsx; + dest[2][2] = cxcy - sx * sysz; + break; + case GLM_EULER_ZXY: + dest[0][0] = cycz - sx * sysz; + dest[0][1] = czsx * sy + cysz; + dest[0][2] = -cx * sy; + dest[1][0] = -cxsz; + dest[1][1] = cxcz; + dest[1][2] = sx; + dest[2][0] = czsy + cysx * sz; + dest[2][1] = -cycz * sx + sysz; + dest[2][2] = cxcy; + break; + case GLM_EULER_ZYX: + dest[0][0] = cycz; + dest[0][1] = cysz; + dest[0][2] = -sy; + dest[1][0] = czsx * sy - cxsz; + dest[1][1] = cxcz + sx * sysz; + dest[1][2] = cysx; + dest[2][0] = cx * czsy + sx * sz; + dest[2][1] = -czsx + cx * sysz; + dest[2][2] = cxcy; break; }