diff --git a/include/assimp/matrix4x4.inl b/include/assimp/matrix4x4.inl index 67edd6c14..6f96d5a6b 100644 --- a/include/assimp/matrix4x4.inl +++ b/include/assimp/matrix4x4.inl @@ -424,12 +424,18 @@ inline void aiMatrix4x4t::Decompose(aiVector3t& pScaling, aiVector { ASSIMP_MATRIX4_4_DECOMPOSE_PART; - /* - | CE -CF D 0 | - M = | BDE+AF -BDF+AE -BC 0 | - | -ADE+BF -ADF+BE AC 0 | - | 0 0 0 1 | + /* + assuming a right-handed coordinate system + and post-multiplication of column vectors, + the rotation matrix for an euler XYZ rotation is M = Rz * Ry * Rx. + combining gives: + + | CE BDE-AF ADE+BF 0 | + M = | CF BDF+AE ADF-BE 0 | + | -D CB AC 0 | + | 0 0 0 1 | + where A = cos(angle_x), B = sin(angle_x); C = cos(angle_y), D = sin(angle_y); E = cos(angle_z), F = sin(angle_z); @@ -438,20 +444,20 @@ inline void aiMatrix4x4t::Decompose(aiVector3t& pScaling, aiVector // Use a small epsilon to solve floating-point inaccuracies const TReal epsilon = 10e-3f; - pRotation.y = std::asin(vCols[2].x);// D. Angle around oY. + pRotation.y = std::asin(-vCols[0].z);// D. Angle around oY. TReal C = std::cos(pRotation.y); if(std::fabs(C) > epsilon) { // Finding angle around oX. - TReal tan_x = vCols[2].z / C;// A - TReal tan_y = -vCols[2].y / C;// B + TReal tan_x = vCols[2].z / C;// A + TReal tan_y = vCols[1].z / C;// B pRotation.x = std::atan2(tan_y, tan_x); // Finding angle around oZ. - tan_x = vCols[0].x / C;// E - tan_y = -vCols[1].x / C;// F + tan_x = vCols[0].x / C;// E + tan_y = vCols[0].y / C;// F pRotation.z = std::atan2(tan_y, tan_x); } else @@ -459,8 +465,8 @@ inline void aiMatrix4x4t::Decompose(aiVector3t& pScaling, aiVector pRotation.x = 0;// Set angle around oX to 0. => A == 1, B == 0, C == 0, D == 1. // And finding angle around oZ. - TReal tan_x = vCols[1].y;// -BDF+AE => E - TReal tan_y = vCols[0].y;// BDE+AF => F + TReal tan_x = vCols[1].y;// BDF+AE => E + TReal tan_y = -vCols[1].x;// BDE-AF => F pRotation.z = std::atan2(tan_y, tan_x); }