diff options
Diffstat (limited to 'src/3rdparty/assimp/include/assimp/matrix4x4.inl')
-rw-r--r-- | src/3rdparty/assimp/include/assimp/matrix4x4.inl | 248 |
1 files changed, 194 insertions, 54 deletions
diff --git a/src/3rdparty/assimp/include/assimp/matrix4x4.inl b/src/3rdparty/assimp/include/assimp/matrix4x4.inl index 9ce794f0a..b15d50a09 100644 --- a/src/3rdparty/assimp/include/assimp/matrix4x4.inl +++ b/src/3rdparty/assimp/include/assimp/matrix4x4.inl @@ -3,7 +3,8 @@ Open Asset Import Library (assimp) --------------------------------------------------------------------------- -Copyright (c) 2006-2016, assimp team +Copyright (c) 2006-2017, assimp team + All rights reserved. @@ -42,8 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file matrix4x4.inl * @brief Inline implementation of the 4x4 matrix operators */ -#ifndef AI_MATRIX4x4_INL_INC -#define AI_MATRIX4x4_INL_INC +#pragma once +#ifndef AI_MATRIX4X4_INL_INC +#define AI_MATRIX4X4_INL_INC #ifdef __cplusplus @@ -156,6 +158,54 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t // ---------------------------------------------------------------------------------------- template <typename TReal> +inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const +{ + aiMatrix4x4t<TReal> temp( + a1 * aFloat, + a2 * aFloat, + a3 * aFloat, + a4 * aFloat, + b1 * aFloat, + b2 * aFloat, + b3 * aFloat, + b4 * aFloat, + c1 * aFloat, + c2 * aFloat, + c3 * aFloat, + c4 * aFloat, + d1 * aFloat, + d2 * aFloat, + d3 * aFloat, + d4 * aFloat); + return temp; +} + +// ---------------------------------------------------------------------------------------- +template <typename TReal> +inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const +{ + aiMatrix4x4t<TReal> temp( + m.a1 + a1, + m.a2 + a2, + m.a3 + a3, + m.a4 + a4, + m.b1 + b1, + m.b2 + b2, + m.b3 + b3, + m.b4 + b4, + m.c1 + c1, + m.c2 + c2, + m.c3 + c3, + m.c4 + c4, + m.d1 + d1, + m.d2 + d2, + m.d3 + d3, + m.d4 + d4); + return temp; +} + +// ---------------------------------------------------------------------------------------- +template <typename TReal> inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const { aiMatrix4x4t<TReal> temp( *this); @@ -242,9 +292,19 @@ inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) { if (p_iIndex > 3) { return NULL; } - - // XXX this is UB. Has been for years. The fact that it works now does not make it better. - return &this->a1 + p_iIndex * 4; + switch ( p_iIndex ) { + case 0: + return &a1; + case 1: + return &b1; + case 2: + return &c1; + case 3: + return &d1; + default: + break; + } + return &a1; } // ---------------------------------------------------------------------------------------- @@ -254,8 +314,19 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const return NULL; } - // XXX same - return &this->a1 + p_iIndex * 4; + switch ( p_iIndex ) { + case 0: + return &a1; + case 1: + return &b1; + case 2: + return &c1; + case 3: + return &d1; + default: + break; + } + return &a1; } // ---------------------------------------------------------------------------------------- @@ -298,57 +369,126 @@ inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil } // ---------------------------------------------------------------------------------------- -template <typename TReal> -inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation, - aiVector3t<TReal>& position) const -{ - const aiMatrix4x4t<TReal>& _this = *this; - // extract translation - position.x = _this[0][3]; - position.y = _this[1][3]; - position.z = _this[2][3]; +#define ASSIMP_MATRIX4_4_DECOMPOSE_PART \ + const aiMatrix4x4t<TReal>& _this = *this;/* Create alias for conveniance. */ \ + \ + /* extract translation */ \ + pPosition.x = _this[0][3]; \ + pPosition.y = _this[1][3]; \ + pPosition.z = _this[2][3]; \ + \ + /* extract the columns of the matrix. */ \ + aiVector3t<TReal> vCols[3] = { \ + aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]), \ + aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]), \ + aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2]) \ + }; \ + \ + /* extract the scaling factors */ \ + pScaling.x = vCols[0].Length(); \ + pScaling.y = vCols[1].Length(); \ + pScaling.z = vCols[2].Length(); \ + \ + /* and the sign of the scaling */ \ + if (Determinant() < 0) pScaling = -pScaling; \ + \ + /* and remove all scaling from the matrix */ \ + if(pScaling.x) vCols[0] /= pScaling.x; \ + if(pScaling.y) vCols[1] /= pScaling.y; \ + if(pScaling.z) vCols[2] /= pScaling.z; \ + \ + do {} while(false) + - // extract the rows of the matrix - aiVector3t<TReal> vRows[3] = { - aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]), - aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]), - aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2]) - }; - - // extract the scaling factors - scaling.x = vRows[0].Length(); - scaling.y = vRows[1].Length(); - scaling.z = vRows[2].Length(); - - // and the sign of the scaling - if (Determinant() < 0) { - scaling.x = -scaling.x; - scaling.y = -scaling.y; - scaling.z = -scaling.z; - } - // and remove all scaling from the matrix - if(scaling.x) - { - vRows[0] /= scaling.x; - } - if(scaling.y) - { - vRows[1] /= scaling.y; - } - if(scaling.z) - { - vRows[2] /= scaling.z; - } + +template <typename TReal> +inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation, + aiVector3t<TReal>& pPosition) const +{ + ASSIMP_MATRIX4_4_DECOMPOSE_PART; // build a 3x3 rotation matrix - aiMatrix3x3t<TReal> m(vRows[0].x,vRows[1].x,vRows[2].x, - vRows[0].y,vRows[1].y,vRows[2].y, - vRows[0].z,vRows[1].z,vRows[2].z); + aiMatrix3x3t<TReal> m(vCols[0].x,vCols[1].x,vCols[2].x, + vCols[0].y,vCols[1].y,vCols[2].y, + vCols[0].z,vCols[1].z,vCols[2].z); // and generate the rotation quaternion from it - rotation = aiQuaterniont<TReal>(m); + pRotation = aiQuaterniont<TReal>(m); +} + +template <typename TReal> +inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const +{ + 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 | + + A = cos(angle_x), B = sin(angle_x); + C = cos(angle_y), D = sin(angle_y); + E = cos(angle_z), F = sin(angle_z); + */ + + // 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. + + 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 + + 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 + pRotation.z = std::atan2(tan_y, tan_x); + } + else + {// oY is fixed. + 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 + + pRotation.z = std::atan2(tan_y, tan_x); + } +} + +#undef ASSIMP_MATRIX4_4_DECOMPOSE_PART + +template <typename TReal> +inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, + aiVector3t<TReal>& pPosition) const +{ +aiQuaterniont<TReal> pRotation; + + Decompose(pScaling, pRotation, pPosition); + pRotation.Normalize(); + + TReal angle_cos = pRotation.w; + TReal angle_sin = std::sqrt(1.0f - angle_cos * angle_cos); + + pRotationAngle = std::acos(angle_cos) * 2; + + // Use a small epsilon to solve floating-point inaccuracies + const TReal epsilon = 10e-3f; + + if(std::fabs(angle_sin) < epsilon) angle_sin = 1; + + pRotationAxis.x = pRotation.x / angle_sin; + pRotationAxis.y = pRotation.y / angle_sin; + pRotationAxis.z = pRotation.z / angle_sin; } // ---------------------------------------------------------------------------------------- @@ -522,7 +662,7 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal * "from" into another vector called "to". * Input : from[3], to[3] which both must be *normalized* non-zero vectors * Output: mtx[3][3] -- a 3x3 matrix in colum-major form - * Authors: Tomas M�ller, John Hughes + * Authors: Tomas Möller, John Hughes * "Efficiently Building a Matrix to Rotate One Vector to Another" * Journal of Graphics Tools, 4(4):1-4, 1999 */ @@ -538,4 +678,4 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<T } #endif // __cplusplus -#endif // AI_MATRIX4x4_INL_INC +#endif // AI_MATRIX4X4_INL_INC |