1/// @ref gtx_euler_angles 2/// @file glm/gtx/euler_angles.inl 3 4#include "compatibility.hpp" // glm::atan2 5 6namespace glm 7{ 8 template <typename T> 9 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleX 10 ( 11 T const & angleX 12 ) 13 { 14 T cosX = glm::cos(angleX); 15 T sinX = glm::sin(angleX); 16 17 return tmat4x4<T, defaultp>( 18 T(1), T(0), T(0), T(0), 19 T(0), cosX, sinX, T(0), 20 T(0),-sinX, cosX, T(0), 21 T(0), T(0), T(0), T(1)); 22 } 23 24 template <typename T> 25 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleY 26 ( 27 T const & angleY 28 ) 29 { 30 T cosY = glm::cos(angleY); 31 T sinY = glm::sin(angleY); 32 33 return tmat4x4<T, defaultp>( 34 cosY, T(0), -sinY, T(0), 35 T(0), T(1), T(0), T(0), 36 sinY, T(0), cosY, T(0), 37 T(0), T(0), T(0), T(1)); 38 } 39 40 template <typename T> 41 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleZ 42 ( 43 T const & angleZ 44 ) 45 { 46 T cosZ = glm::cos(angleZ); 47 T sinZ = glm::sin(angleZ); 48 49 return tmat4x4<T, defaultp>( 50 cosZ, sinZ, T(0), T(0), 51 -sinZ, cosZ, T(0), T(0), 52 T(0), T(0), T(1), T(0), 53 T(0), T(0), T(0), T(1)); 54 } 55 56 template <typename T> 57 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleXY 58 ( 59 T const & angleX, 60 T const & angleY 61 ) 62 { 63 T cosX = glm::cos(angleX); 64 T sinX = glm::sin(angleX); 65 T cosY = glm::cos(angleY); 66 T sinY = glm::sin(angleY); 67 68 return tmat4x4<T, defaultp>( 69 cosY, -sinX * -sinY, cosX * -sinY, T(0), 70 T(0), cosX, sinX, T(0), 71 sinY, -sinX * cosY, cosX * cosY, T(0), 72 T(0), T(0), T(0), T(1)); 73 } 74 75 template <typename T> 76 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleYX 77 ( 78 T const & angleY, 79 T const & angleX 80 ) 81 { 82 T cosX = glm::cos(angleX); 83 T sinX = glm::sin(angleX); 84 T cosY = glm::cos(angleY); 85 T sinY = glm::sin(angleY); 86 87 return tmat4x4<T, defaultp>( 88 cosY, 0, -sinY, T(0), 89 sinY * sinX, cosX, cosY * sinX, T(0), 90 sinY * cosX, -sinX, cosY * cosX, T(0), 91 T(0), T(0), T(0), T(1)); 92 } 93 94 template <typename T> 95 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleXZ 96 ( 97 T const & angleX, 98 T const & angleZ 99 ) 100 { 101 return eulerAngleX(angleX) * eulerAngleZ(angleZ); 102 } 103 104 template <typename T> 105 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleZX 106 ( 107 T const & angleZ, 108 T const & angleX 109 ) 110 { 111 return eulerAngleZ(angleZ) * eulerAngleX(angleX); 112 } 113 114 template <typename T> 115 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleYZ 116 ( 117 T const & angleY, 118 T const & angleZ 119 ) 120 { 121 return eulerAngleY(angleY) * eulerAngleZ(angleZ); 122 } 123 124 template <typename T> 125 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleZY 126 ( 127 T const & angleZ, 128 T const & angleY 129 ) 130 { 131 return eulerAngleZ(angleZ) * eulerAngleY(angleY); 132 } 133 134 template <typename T> 135 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleXYZ 136 ( 137 T const & t1, 138 T const & t2, 139 T const & t3 140 ) 141 { 142 T c1 = glm::cos(-t1); 143 T c2 = glm::cos(-t2); 144 T c3 = glm::cos(-t3); 145 T s1 = glm::sin(-t1); 146 T s2 = glm::sin(-t2); 147 T s3 = glm::sin(-t3); 148 149 tmat4x4<T, defaultp> Result; 150 Result[0][0] = c2 * c3; 151 Result[0][1] =-c1 * s3 + s1 * s2 * c3; 152 Result[0][2] = s1 * s3 + c1 * s2 * c3; 153 Result[0][3] = static_cast<T>(0); 154 Result[1][0] = c2 * s3; 155 Result[1][1] = c1 * c3 + s1 * s2 * s3; 156 Result[1][2] =-s1 * c3 + c1 * s2 * s3; 157 Result[1][3] = static_cast<T>(0); 158 Result[2][0] =-s2; 159 Result[2][1] = s1 * c2; 160 Result[2][2] = c1 * c2; 161 Result[2][3] = static_cast<T>(0); 162 Result[3][0] = static_cast<T>(0); 163 Result[3][1] = static_cast<T>(0); 164 Result[3][2] = static_cast<T>(0); 165 Result[3][3] = static_cast<T>(1); 166 return Result; 167 } 168 169 template <typename T> 170 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> eulerAngleYXZ 171 ( 172 T const & yaw, 173 T const & pitch, 174 T const & roll 175 ) 176 { 177 T tmp_ch = glm::cos(yaw); 178 T tmp_sh = glm::sin(yaw); 179 T tmp_cp = glm::cos(pitch); 180 T tmp_sp = glm::sin(pitch); 181 T tmp_cb = glm::cos(roll); 182 T tmp_sb = glm::sin(roll); 183 184 tmat4x4<T, defaultp> Result; 185 Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb; 186 Result[0][1] = tmp_sb * tmp_cp; 187 Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb; 188 Result[0][3] = static_cast<T>(0); 189 Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb; 190 Result[1][1] = tmp_cb * tmp_cp; 191 Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb; 192 Result[1][3] = static_cast<T>(0); 193 Result[2][0] = tmp_sh * tmp_cp; 194 Result[2][1] = -tmp_sp; 195 Result[2][2] = tmp_ch * tmp_cp; 196 Result[2][3] = static_cast<T>(0); 197 Result[3][0] = static_cast<T>(0); 198 Result[3][1] = static_cast<T>(0); 199 Result[3][2] = static_cast<T>(0); 200 Result[3][3] = static_cast<T>(1); 201 return Result; 202 } 203 204 template <typename T> 205 GLM_FUNC_QUALIFIER tmat4x4<T, defaultp> yawPitchRoll 206 ( 207 T const & yaw, 208 T const & pitch, 209 T const & roll 210 ) 211 { 212 T tmp_ch = glm::cos(yaw); 213 T tmp_sh = glm::sin(yaw); 214 T tmp_cp = glm::cos(pitch); 215 T tmp_sp = glm::sin(pitch); 216 T tmp_cb = glm::cos(roll); 217 T tmp_sb = glm::sin(roll); 218 219 tmat4x4<T, defaultp> Result; 220 Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb; 221 Result[0][1] = tmp_sb * tmp_cp; 222 Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb; 223 Result[0][3] = static_cast<T>(0); 224 Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb; 225 Result[1][1] = tmp_cb * tmp_cp; 226 Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb; 227 Result[1][3] = static_cast<T>(0); 228 Result[2][0] = tmp_sh * tmp_cp; 229 Result[2][1] = -tmp_sp; 230 Result[2][2] = tmp_ch * tmp_cp; 231 Result[2][3] = static_cast<T>(0); 232 Result[3][0] = static_cast<T>(0); 233 Result[3][1] = static_cast<T>(0); 234 Result[3][2] = static_cast<T>(0); 235 Result[3][3] = static_cast<T>(1); 236 return Result; 237 } 238 239 template <typename T> 240 GLM_FUNC_QUALIFIER tmat2x2<T, defaultp> orientate2 241 ( 242 T const & angle 243 ) 244 { 245 T c = glm::cos(angle); 246 T s = glm::sin(angle); 247 248 tmat2x2<T, defaultp> Result; 249 Result[0][0] = c; 250 Result[0][1] = s; 251 Result[1][0] = -s; 252 Result[1][1] = c; 253 return Result; 254 } 255 256 template <typename T> 257 GLM_FUNC_QUALIFIER tmat3x3<T, defaultp> orientate3 258 ( 259 T const & angle 260 ) 261 { 262 T c = glm::cos(angle); 263 T s = glm::sin(angle); 264 265 tmat3x3<T, defaultp> Result; 266 Result[0][0] = c; 267 Result[0][1] = s; 268 Result[0][2] = 0.0f; 269 Result[1][0] = -s; 270 Result[1][1] = c; 271 Result[1][2] = 0.0f; 272 Result[2][0] = 0.0f; 273 Result[2][1] = 0.0f; 274 Result[2][2] = 1.0f; 275 return Result; 276 } 277 278 template <typename T, precision P> 279 GLM_FUNC_QUALIFIER tmat3x3<T, P> orientate3 280 ( 281 tvec3<T, P> const & angles 282 ) 283 { 284 return tmat3x3<T, P>(yawPitchRoll(angles.z, angles.x, angles.y)); 285 } 286 287 template <typename T, precision P> 288 GLM_FUNC_QUALIFIER tmat4x4<T, P> orientate4 289 ( 290 tvec3<T, P> const & angles 291 ) 292 { 293 return yawPitchRoll(angles.z, angles.x, angles.y); 294 } 295 296 template <typename T> 297 GLM_FUNC_DECL void extractEulerAngleXYZ(tmat4x4<T, defaultp> const & M, 298 T & t1, 299 T & t2, 300 T & t3) 301 { 302 float T1 = glm::atan2<T, defaultp>(M[2][1], M[2][2]); 303 float C2 = glm::sqrt(M[0][0]*M[0][0] + M[1][0]*M[1][0]); 304 float T2 = glm::atan2<T, defaultp>(-M[2][0], C2); 305 float S1 = glm::sin(T1); 306 float C1 = glm::cos(T1); 307 float T3 = glm::atan2<T, defaultp>(S1*M[0][2] - C1*M[0][1], C1*M[1][1] - S1*M[1][2 ]); 308 t1 = -T1; 309 t2 = -T2; 310 t3 = -T3; 311 } 312}//namespace glm 313