Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/assimp/matrix4x4.inl is written in an unsupported language. File is not indexed.

0001 /*
0002 ---------------------------------------------------------------------------
0003 Open Asset Import Library (assimp)
0004 ---------------------------------------------------------------------------
0005 
0006 Copyright (c) 2006-2024, assimp team
0007 
0008 All rights reserved.
0009 
0010 Redistribution and use of this software in source and binary forms,
0011 with or without modification, are permitted provided that the following
0012 conditions are met:
0013 
0014 * Redistributions of source code must retain the above
0015   copyright notice, this list of conditions and the
0016   following disclaimer.
0017 
0018 * Redistributions in binary form must reproduce the above
0019   copyright notice, this list of conditions and the
0020   following disclaimer in the documentation and/or other
0021   materials provided with the distribution.
0022 
0023 * Neither the name of the assimp team, nor the names of its
0024   contributors may be used to endorse or promote products
0025   derived from this software without specific prior
0026   written permission of the assimp team.
0027 
0028 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0029 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0030 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0031 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0032 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0033 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0034 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0035 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0036 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0038 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0039 ---------------------------------------------------------------------------
0040 */
0041 
0042 /** @file matrix4x4.inl
0043  *  @brief Inline implementation of the 4x4 matrix operators
0044  */
0045 #pragma once
0046 #ifndef AI_MATRIX4X4_INL_INC
0047 #define AI_MATRIX4X4_INL_INC
0048 
0049 #ifdef __cplusplus
0050 
0051 #include "matrix4x4.h"
0052 #include "matrix3x3.h"
0053 #include "quaternion.h"
0054 #include "MathFunctions.h"
0055 
0056 #include <algorithm>
0057 #include <limits>
0058 #include <cmath>
0059 
0060 // ----------------------------------------------------------------------------------------
0061 template <typename TReal>
0062 aiMatrix4x4t<TReal>::aiMatrix4x4t() AI_NO_EXCEPT :
0063         a1(1.0f), a2(), a3(), a4(),
0064         b1(), b2(1.0f), b3(), b4(),
0065         c1(), c2(), c3(1.0f), c4(),
0066         d1(), d2(), d3(), d4(1.0f) {
0067     // empty
0068 }
0069 
0070 // ----------------------------------------------------------------------------------------
0071 template <typename TReal>
0072 aiMatrix4x4t<TReal>::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
0073               TReal _b1, TReal _b2, TReal _b3, TReal _b4,
0074               TReal _c1, TReal _c2, TReal _c3, TReal _c4,
0075               TReal _d1, TReal _d2, TReal _d3, TReal _d4) :
0076         a1(_a1), a2(_a2), a3(_a3), a4(_a4),
0077         b1(_b1), b2(_b2), b3(_b3), b4(_b4),
0078         c1(_c1), c2(_c2), c3(_c3), c4(_c4),
0079         d1(_d1), d2(_d2), d3(_d3), d4(_d4) {
0080     // empty
0081 }
0082 
0083 // ------------------------------------------------------------------------------------------------
0084 template <typename TReal>
0085 template <typename TOther>
0086 aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const {
0087     return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
0088         static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
0089         static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
0090         static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4));
0091 }
0092 
0093 
0094 // ----------------------------------------------------------------------------------------
0095 template <typename TReal>
0096 AI_FORCE_INLINE
0097 aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m) {
0098     a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
0099     b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
0100     c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
0101     d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0);
0102 }
0103 
0104 // ----------------------------------------------------------------------------------------
0105 template <typename TReal>
0106 AI_FORCE_INLINE
0107 aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position) {
0108     // build a 3x3 rotation matrix
0109     aiMatrix3x3t<TReal> m = rotation.GetMatrix();
0110 
0111     a1 = m.a1 * scaling.x;
0112     a2 = m.a2 * scaling.x;
0113     a3 = m.a3 * scaling.x;
0114     a4 = position.x;
0115 
0116     b1 = m.b1 * scaling.y;
0117     b2 = m.b2 * scaling.y;
0118     b3 = m.b3 * scaling.y;
0119     b4 = position.y;
0120 
0121     c1 = m.c1 * scaling.z;
0122     c2 = m.c2 * scaling.z;
0123     c3 = m.c3 * scaling.z;
0124     c4= position.z;
0125 
0126     d1 = static_cast<TReal>(0.0);
0127     d2 = static_cast<TReal>(0.0);
0128     d3 = static_cast<TReal>(0.0);
0129     d4 = static_cast<TReal>(1.0);
0130 }
0131 
0132 // ----------------------------------------------------------------------------------------
0133 template <typename TReal>
0134 AI_FORCE_INLINE
0135 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m) {
0136     *this = aiMatrix4x4t<TReal>(
0137         m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
0138         m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
0139         m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4,
0140         m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4,
0141         m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4,
0142         m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4,
0143         m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4,
0144         m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4,
0145         m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4,
0146         m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4,
0147         m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4,
0148         m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4,
0149         m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4,
0150         m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4,
0151         m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4,
0152         m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4);
0153     return *this;
0154 }
0155 
0156 // ----------------------------------------------------------------------------------------
0157 template <typename TReal>
0158 AI_FORCE_INLINE aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const {
0159     aiMatrix4x4t<TReal> temp(
0160         a1 * aFloat,
0161         a2 * aFloat,
0162         a3 * aFloat,
0163         a4 * aFloat,
0164         b1 * aFloat,
0165         b2 * aFloat,
0166         b3 * aFloat,
0167         b4 * aFloat,
0168         c1 * aFloat,
0169         c2 * aFloat,
0170         c3 * aFloat,
0171         c4 * aFloat,
0172         d1 * aFloat,
0173         d2 * aFloat,
0174         d3 * aFloat,
0175         d4 * aFloat);
0176     return temp;
0177 }
0178 
0179 // ----------------------------------------------------------------------------------------
0180 template <typename TReal>
0181 AI_FORCE_INLINE
0182 aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const {
0183     aiMatrix4x4t<TReal> temp(
0184         m.a1 + a1,
0185         m.a2 + a2,
0186         m.a3 + a3,
0187         m.a4 + a4,
0188         m.b1 + b1,
0189         m.b2 + b2,
0190         m.b3 + b3,
0191         m.b4 + b4,
0192         m.c1 + c1,
0193         m.c2 + c2,
0194         m.c3 + c3,
0195         m.c4 + c4,
0196         m.d1 + d1,
0197         m.d2 + d2,
0198         m.d3 + d3,
0199         m.d4 + d4);
0200     return temp;
0201 }
0202 
0203 // ----------------------------------------------------------------------------------------
0204 template <typename TReal>
0205 AI_FORCE_INLINE
0206 aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const {
0207     aiMatrix4x4t<TReal> temp( *this);
0208     temp *= m;
0209     return temp;
0210 }
0211 
0212 // ----------------------------------------------------------------------------------------
0213 template <typename TReal>
0214 AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose() {
0215     // (TReal&) don't remove, GCC complains cause of packed fields
0216     std::swap( (TReal&)b1, (TReal&)a2);
0217     std::swap( (TReal&)c1, (TReal&)a3);
0218     std::swap( (TReal&)c2, (TReal&)b3);
0219     std::swap( (TReal&)d1, (TReal&)a4);
0220     std::swap( (TReal&)d2, (TReal&)b4);
0221     std::swap( (TReal&)d3, (TReal&)c4);
0222     return *this;
0223 }
0224 
0225 // ----------------------------------------------------------------------------------------
0226 template <typename TReal>
0227 AI_FORCE_INLINE
0228 TReal aiMatrix4x4t<TReal>::Determinant() const {
0229     return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4
0230         + a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4
0231         - a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3
0232         + a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2
0233         + a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2
0234         - a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1;
0235 }
0236 
0237 // ----------------------------------------------------------------------------------------
0238 template <typename TReal>
0239 AI_FORCE_INLINE
0240 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() {
0241     // Compute the reciprocal determinant
0242     const TReal det = Determinant();
0243     if(det == static_cast<TReal>(0.0))
0244     {
0245         // Matrix is not invertible. Setting all elements to nan is not really
0246         // correct in a mathematical sense but it is easy to debug for the
0247         // programmer.
0248         const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
0249         *this = aiMatrix4x4t<TReal>(
0250             nan,nan,nan,nan,
0251             nan,nan,nan,nan,
0252             nan,nan,nan,nan,
0253             nan,nan,nan,nan);
0254 
0255         return *this;
0256     }
0257 
0258     const TReal invdet = static_cast<TReal>(1.0) / det;
0259 
0260     aiMatrix4x4t<TReal> res;
0261     res.a1 = invdet  * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2));
0262     res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2));
0263     res.a3 = invdet  * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2));
0264     res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2));
0265     res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1));
0266     res.b2 = invdet  * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1));
0267     res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1));
0268     res.b4 = invdet  * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1));
0269     res.c1 = invdet  * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1));
0270     res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1));
0271     res.c3 = invdet  * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1));
0272     res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1));
0273     res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1));
0274     res.d2 = invdet  * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1));
0275     res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1));
0276     res.d4 = invdet  * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1));
0277     *this = res;
0278 
0279     return *this;
0280 }
0281 
0282 // ----------------------------------------------------------------------------------------
0283 template <typename TReal>
0284 AI_FORCE_INLINE
0285 TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
0286     if (p_iIndex > 3) {
0287         return nullptr;
0288     }
0289     switch ( p_iIndex ) {
0290         case 0:
0291             return &a1;
0292         case 1:
0293             return &b1;
0294         case 2:
0295             return &c1;
0296         case 3:
0297             return &d1;
0298         default:
0299             break;
0300     }
0301     return &a1;
0302 }
0303 
0304 // ----------------------------------------------------------------------------------------
0305 template <typename TReal>
0306 AI_FORCE_INLINE
0307 const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
0308     if (p_iIndex > 3) {
0309         return nullptr;
0310     }
0311 
0312     switch ( p_iIndex ) {
0313         case 0:
0314             return &a1;
0315         case 1:
0316             return &b1;
0317         case 2:
0318             return &c1;
0319         case 3:
0320             return &d1;
0321         default:
0322             break;
0323     }
0324     return &a1;
0325 }
0326 
0327 // ----------------------------------------------------------------------------------------
0328 template <typename TReal>
0329 AI_FORCE_INLINE
0330 bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const {
0331     return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
0332             b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
0333             c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
0334             d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4);
0335 }
0336 
0337 // ----------------------------------------------------------------------------------------
0338 template <typename TReal>
0339 AI_FORCE_INLINE
0340 bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const {
0341     return !(*this == m);
0342 }
0343 
0344 // ---------------------------------------------------------------------------
0345 template<typename TReal>
0346 AI_FORCE_INLINE
0347 bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
0348     return
0349         std::abs(a1 - m.a1) <= epsilon &&
0350         std::abs(a2 - m.a2) <= epsilon &&
0351         std::abs(a3 - m.a3) <= epsilon &&
0352         std::abs(a4 - m.a4) <= epsilon &&
0353         std::abs(b1 - m.b1) <= epsilon &&
0354         std::abs(b2 - m.b2) <= epsilon &&
0355         std::abs(b3 - m.b3) <= epsilon &&
0356         std::abs(b4 - m.b4) <= epsilon &&
0357         std::abs(c1 - m.c1) <= epsilon &&
0358         std::abs(c2 - m.c2) <= epsilon &&
0359         std::abs(c3 - m.c3) <= epsilon &&
0360         std::abs(c4 - m.c4) <= epsilon &&
0361         std::abs(d1 - m.d1) <= epsilon &&
0362         std::abs(d2 - m.d2) <= epsilon &&
0363         std::abs(d3 - m.d3) <= epsilon &&
0364         std::abs(d4 - m.d4) <= epsilon;
0365 }
0366 
0367 // ----------------------------------------------------------------------------------------
0368 
0369 #define ASSIMP_MATRIX4_4_DECOMPOSE_PART         \
0370         const aiMatrix4x4t<TReal>& _this = *this;/* Create alias for conveniance. */ \
0371         \
0372         /* extract translation */ \
0373         pPosition.x = _this[0][3]; \
0374         pPosition.y = _this[1][3]; \
0375         pPosition.z = _this[2][3]; \
0376         \
0377         /* extract the columns of the matrix. */ \
0378         aiVector3t<TReal> vCols[3] = { \
0379                 aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]), \
0380                 aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]), \
0381                 aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2]) \
0382         }; \
0383         \
0384         /* extract the scaling factors */ \
0385         pScaling.x = vCols[0].Length(); \
0386         pScaling.y = vCols[1].Length(); \
0387         pScaling.z = vCols[2].Length(); \
0388         \
0389         /* and the sign of the scaling */ \
0390         if (Determinant() < 0) pScaling = -pScaling; \
0391         \
0392         /* and remove all scaling from the matrix */ \
0393         if(pScaling.x) vCols[0] /= pScaling.x; \
0394         if(pScaling.y) vCols[1] /= pScaling.y; \
0395         if(pScaling.z) vCols[2] /= pScaling.z; \
0396         \
0397         do {} while(false)
0398 
0399 template <typename TReal>
0400 AI_FORCE_INLINE
0401 void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
0402         aiVector3t<TReal>& pPosition) const {
0403         ASSIMP_MATRIX4_4_DECOMPOSE_PART;
0404 
0405     // build a 3x3 rotation matrix
0406     aiMatrix3x3t<TReal> m(vCols[0].x,vCols[1].x,vCols[2].x,
0407         vCols[0].y,vCols[1].y,vCols[2].y,
0408         vCols[0].z,vCols[1].z,vCols[2].z);
0409 
0410     // and generate the rotation quaternion from it
0411     pRotation = aiQuaterniont<TReal>(m);
0412 }
0413 
0414 template <typename TReal>
0415 AI_FORCE_INLINE
0416 void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const {
0417         ASSIMP_MATRIX4_4_DECOMPOSE_PART;
0418 
0419     /*
0420     assuming a right-handed coordinate system
0421     and post-multiplication of column vectors,
0422     the rotation matrix for an euler XYZ rotation is M = Rz * Ry * Rx.
0423     combining gives:
0424 
0425         |  CE  BDE-AF  ADE+BF  0  |
0426     M = |  CF  BDF+AE  ADF-BE  0  |
0427         |  -D    CB      AC    0  |
0428         |   0     0       0    1  |
0429 
0430     where
0431         A = cos(angle_x), B = sin(angle_x);
0432         C = cos(angle_y), D = sin(angle_y);
0433         E = cos(angle_z), F = sin(angle_z);
0434         */
0435 
0436         // Use a small epsilon to solve floating-point inaccuracies
0437     const TReal epsilon = Assimp::Math::getEpsilon<TReal>();
0438 
0439         pRotation.y  = std::asin(-vCols[0].z);// D. Angle around oY.
0440 
0441         TReal C = std::cos(pRotation.y);
0442 
0443         if(std::fabs(C) > epsilon)
0444         {
0445                 // Finding angle around oX.
0446                 TReal tan_x = vCols[2].z / C;// A
0447                 TReal tan_y = vCols[1].z / C;// B
0448 
0449                 pRotation.x = std::atan2(tan_y, tan_x);
0450                 // Finding angle around oZ.
0451                 tan_x = vCols[0].x / C;// E
0452                 tan_y = vCols[0].y / C;// F
0453                 pRotation.z = std::atan2(tan_y, tan_x);
0454         }
0455         else
0456         {// oY is fixed.
0457                 pRotation.x = 0;// Set angle around oX to 0. => A == 1, B == 0, C == 0, D == 1.
0458 
0459                 // And finding angle around oZ.
0460                 TReal tan_x =  vCols[1].y;// BDF+AE => E
0461                 TReal tan_y = -vCols[1].x;// BDE-AF => F
0462 
0463                 pRotation.z = std::atan2(tan_y, tan_x);
0464         }
0465 }
0466 
0467 #undef ASSIMP_MATRIX4_4_DECOMPOSE_PART
0468 
0469 template <typename TReal>
0470 AI_FORCE_INLINE
0471 void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
0472                                                                                         aiVector3t<TReal>& pPosition) const {
0473     aiQuaterniont<TReal> pRotation;
0474 
0475         Decompose(pScaling, pRotation, pPosition);
0476         pRotation.Normalize();
0477 
0478         TReal angle_cos = pRotation.w;
0479         TReal angle_sin = std::sqrt(1.0f - angle_cos * angle_cos);
0480 
0481         pRotationAngle = std::acos(angle_cos) * 2;
0482 
0483         // Use a small epsilon to solve floating-point inaccuracies
0484     const TReal epsilon = 10e-3f;
0485 
0486         if(std::fabs(angle_sin) < epsilon) angle_sin = 1;
0487 
0488         pRotationAxis.x = pRotation.x / angle_sin;
0489         pRotationAxis.y = pRotation.y / angle_sin;
0490         pRotationAxis.z = pRotation.z / angle_sin;
0491 }
0492 
0493 // ----------------------------------------------------------------------------------------
0494 template <typename TReal>
0495 AI_FORCE_INLINE
0496 void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
0497         aiVector3t<TReal>& position) const {
0498     const aiMatrix4x4t<TReal>& _this = *this;
0499 
0500     // extract translation
0501     position.x = _this[0][3];
0502     position.y = _this[1][3];
0503     position.z = _this[2][3];
0504 
0505     // extract rotation
0506     rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this);
0507 }
0508 
0509 // ----------------------------------------------------------------------------------------
0510 template <typename TReal>
0511 AI_FORCE_INLINE
0512 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb) {
0513     return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
0514 }
0515 
0516 // ----------------------------------------------------------------------------------------
0517 template <typename TReal>
0518 AI_FORCE_INLINE
0519 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) {
0520     aiMatrix4x4t<TReal>& _this = *this;
0521 
0522     TReal cx = std::cos(x);
0523     TReal sx = std::sin(x);
0524     TReal cy = std::cos(y);
0525     TReal sy = std::sin(y);
0526     TReal cz = std::cos(z);
0527     TReal sz = std::sin(z);
0528 
0529     // mz*my*mx
0530     _this.a1 = cz * cy;
0531     _this.a2 = cz * sy * sx - sz * cx;
0532     _this.a3 = sz * sx + cz * sy * cx;
0533 
0534     _this.b1 = sz * cy;
0535     _this.b2 = cz * cx + sz * sy * sx;
0536     _this.b3 = sz * sy * cx - cz * sx;
0537 
0538     _this.c1 = -sy;
0539     _this.c2 = cy * sx;
0540     _this.c3 = cy * cx;
0541 
0542     return *this;
0543 }
0544 
0545 // ----------------------------------------------------------------------------------------
0546 template <typename TReal>
0547 AI_FORCE_INLINE
0548 bool aiMatrix4x4t<TReal>::IsIdentity(const TReal epsilon) const {
0549     return (a2 <= epsilon && a2 >= -epsilon &&
0550             a3 <= epsilon && a3 >= -epsilon &&
0551             a4 <= epsilon && a4 >= -epsilon &&
0552             b1 <= epsilon && b1 >= -epsilon &&
0553             b3 <= epsilon && b3 >= -epsilon &&
0554             b4 <= epsilon && b4 >= -epsilon &&
0555             c1 <= epsilon && c1 >= -epsilon &&
0556             c2 <= epsilon && c2 >= -epsilon &&
0557             c4 <= epsilon && c4 >= -epsilon &&
0558             d1 <= epsilon && d1 >= -epsilon &&
0559             d2 <= epsilon && d2 >= -epsilon &&
0560             d3 <= epsilon && d3 >= -epsilon &&
0561             a1 <= 1.f+epsilon && a1 >= 1.f-epsilon &&
0562             b2 <= 1.f+epsilon && b2 >= 1.f-epsilon &&
0563             c3 <= 1.f+epsilon && c3 >= 1.f-epsilon &&
0564             d4 <= 1.f+epsilon && d4 >= 1.f-epsilon);
0565 }
0566 
0567 // ----------------------------------------------------------------------------------------
0568 template <typename TReal>
0569 AI_FORCE_INLINE
0570 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) {
0571     /*
0572          |  1  0       0       0 |
0573      M = |  0  cos(A) -sin(A)  0 |
0574          |  0  sin(A)  cos(A)  0 |
0575          |  0  0       0       1 |  */
0576     out = aiMatrix4x4t<TReal>();
0577     out.b2 = out.c3 = std::cos(a);
0578     out.b3 = -(out.c2 = std::sin(a));
0579     return out;
0580 }
0581 
0582 // ----------------------------------------------------------------------------------------
0583 template <typename TReal>
0584 AI_FORCE_INLINE
0585 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) {
0586     /*
0587          |  cos(A)  0   sin(A)  0 |
0588      M = |  0       1   0       0 |
0589          | -sin(A)  0   cos(A)  0 |
0590          |  0       0   0       1 |
0591         */
0592     out = aiMatrix4x4t<TReal>();
0593     out.a1 = out.c3 = std::cos(a);
0594     out.c1 = -(out.a3 = std::sin(a));
0595     return out;
0596 }
0597 
0598 // ----------------------------------------------------------------------------------------
0599 template <typename TReal>
0600 AI_FORCE_INLINE
0601 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out) {
0602     /*
0603          |  cos(A)  -sin(A)   0   0 |
0604      M = |  sin(A)   cos(A)   0   0 |
0605          |  0        0        1   0 |
0606          |  0        0        0   1 |   */
0607     out = aiMatrix4x4t<TReal>();
0608     out.a1 = out.b2 = std::cos(a);
0609     out.a2 = -(out.b1 = std::sin(a));
0610     return out;
0611 }
0612 
0613 // ----------------------------------------------------------------------------------------
0614 // Returns a rotation matrix for a rotation around an arbitrary axis.
0615 template <typename TReal>
0616 AI_FORCE_INLINE
0617 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out) {
0618     TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
0619     TReal x = axis.x, y = axis.y, z = axis.z;
0620 
0621     // Many thanks to MathWorld and Wikipedia
0622     out.a1 = t*x*x + c;   out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
0623     out.b1 = t*x*y + s*z; out.b2 = t*y*y + c;   out.b3 = t*y*z - s*x;
0624     out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
0625     out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
0626     out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
0627     out.d4 = static_cast<TReal>(1.0);
0628 
0629     return out;
0630 }
0631 
0632 // ----------------------------------------------------------------------------------------
0633 template <typename TReal>
0634 AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
0635     out = aiMatrix4x4t<TReal>();
0636     out.a4 = v.x;
0637     out.b4 = v.y;
0638     out.c4 = v.z;
0639     return out;
0640 }
0641 
0642 // ----------------------------------------------------------------------------------------
0643 template <typename TReal>
0644 AI_FORCE_INLINE
0645 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
0646     out = aiMatrix4x4t<TReal>();
0647     out.a1 = v.x;
0648     out.b2 = v.y;
0649     out.c3 = v.z;
0650     return out;
0651 }
0652 
0653 // ----------------------------------------------------------------------------------------
0654 /** A function for creating a rotation matrix that rotates a vector called
0655  * "from" into another vector called "to".
0656  * Input : from[3], to[3] which both must be *normalized* non-zero vectors
0657  * Output: mtx[3][3] -- a 3x3 matrix in column-major form
0658  * Authors: Tomas Möller, John Hughes
0659  *          "Efficiently Building a Matrix to Rotate One Vector to Another"
0660  *          Journal of Graphics Tools, 4(4):1-4, 1999
0661  */
0662 // ----------------------------------------------------------------------------------------
0663 template <typename TReal>
0664 AI_FORCE_INLINE
0665 aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
0666         const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx) {
0667     aiMatrix3x3t<TReal> m3;
0668     aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
0669     mtx = aiMatrix4x4t<TReal>(m3);
0670     return mtx;
0671 }
0672 
0673 #endif // __cplusplus
0674 #endif // AI_MATRIX4X4_INL_INC