Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/assimp/matrix3x3.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 matrix3x3.inl
0043  *  @brief Inline implementation of the 3x3 matrix operators
0044  */
0045 #pragma once
0046 #ifndef AI_MATRIX3X3_INL_INC
0047 #define AI_MATRIX3X3_INL_INC
0048 
0049 #ifdef __GNUC__
0050 #   pragma GCC system_header
0051 #endif
0052 
0053 #ifdef __cplusplus
0054 #include <assimp/matrix3x3.h>
0055 #include <assimp/matrix4x4.h>
0056 
0057 #include <algorithm>
0058 #include <cmath>
0059 #include <limits>
0060 
0061 // ------------------------------------------------------------------------------------------------
0062 // Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
0063 template <typename TReal>
0064 AI_FORCE_INLINE
0065 aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix) {
0066     a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
0067     b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
0068     c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3;
0069 }
0070 
0071 // ------------------------------------------------------------------------------------------------
0072 template <typename TReal>
0073 AI_FORCE_INLINE
0074 aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m) {
0075     *this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
0076         m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
0077         m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
0078         m.a1 * b1 + m.b1 * b2 + m.c1 * b3,
0079         m.a2 * b1 + m.b2 * b2 + m.c2 * b3,
0080         m.a3 * b1 + m.b3 * b2 + m.c3 * b3,
0081         m.a1 * c1 + m.b1 * c2 + m.c1 * c3,
0082         m.a2 * c1 + m.b2 * c2 + m.c2 * c3,
0083         m.a3 * c1 + m.b3 * c2 + m.c3 * c3);
0084     return *this;
0085 }
0086 
0087 // ------------------------------------------------------------------------------------------------
0088 template <typename TReal>
0089 template <typename TOther>
0090 aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const {
0091     return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
0092         static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
0093         static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
0094 }
0095 
0096 // ------------------------------------------------------------------------------------------------
0097 template <typename TReal>
0098 AI_FORCE_INLINE
0099 aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const {
0100     aiMatrix3x3t<TReal> temp( *this);
0101     temp *= m;
0102     return temp;
0103 }
0104 
0105 // ------------------------------------------------------------------------------------------------
0106 template <typename TReal>
0107 AI_FORCE_INLINE
0108 TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
0109     switch ( p_iIndex ) {
0110         case 0:
0111             return &a1;
0112         case 1:
0113             return &b1;
0114         case 2:
0115             return &c1;
0116         default:
0117             break;
0118     }
0119     return &a1;
0120 }
0121 
0122 // ------------------------------------------------------------------------------------------------
0123 template <typename TReal>
0124 AI_FORCE_INLINE
0125 const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
0126     switch ( p_iIndex ) {
0127         case 0:
0128             return &a1;
0129         case 1:
0130             return &b1;
0131         case 2:
0132             return &c1;
0133         default:
0134             break;
0135     }
0136     return &a1;
0137 }
0138 
0139 // ------------------------------------------------------------------------------------------------
0140 template <typename TReal>
0141 AI_FORCE_INLINE
0142 bool aiMatrix3x3t<TReal>::operator== (const aiMatrix3x3t<TReal>& m) const {
0143     return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
0144            b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
0145            c1 == m.c1 && c2 == m.c2 && c3 == m.c3;
0146 }
0147 
0148 // ------------------------------------------------------------------------------------------------
0149 template <typename TReal>
0150 AI_FORCE_INLINE
0151 bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix3x3t<TReal>& m) const {
0152     return !(*this == m);
0153 }
0154 
0155 // ---------------------------------------------------------------------------
0156 template<typename TReal>
0157 AI_FORCE_INLINE
0158 bool aiMatrix3x3t<TReal>::Equal(const aiMatrix3x3t<TReal>& m, TReal epsilon) const {
0159     return
0160         std::abs(a1 - m.a1) <= epsilon &&
0161         std::abs(a2 - m.a2) <= epsilon &&
0162         std::abs(a3 - m.a3) <= epsilon &&
0163         std::abs(b1 - m.b1) <= epsilon &&
0164         std::abs(b2 - m.b2) <= epsilon &&
0165         std::abs(b3 - m.b3) <= epsilon &&
0166         std::abs(c1 - m.c1) <= epsilon &&
0167         std::abs(c2 - m.c2) <= epsilon &&
0168         std::abs(c3 - m.c3) <= epsilon;
0169 }
0170 
0171 // ------------------------------------------------------------------------------------------------
0172 template <typename TReal>
0173 AI_FORCE_INLINE
0174 aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose() {
0175     // (TReal&) don't remove, GCC complains cause of packed fields
0176     std::swap( (TReal&)a2, (TReal&)b1);
0177     std::swap( (TReal&)a3, (TReal&)c1);
0178     std::swap( (TReal&)b3, (TReal&)c2);
0179     return *this;
0180 }
0181 
0182 // ----------------------------------------------------------------------------------------
0183 template <typename TReal>
0184 AI_FORCE_INLINE
0185 TReal aiMatrix3x3t<TReal>::Determinant() const {
0186     return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
0187 }
0188 
0189 // ----------------------------------------------------------------------------------------
0190 template <typename TReal>
0191 AI_FORCE_INLINE
0192 aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() {
0193     // Compute the reciprocal determinant
0194     TReal det = Determinant();
0195     if(det == static_cast<TReal>(0.0))
0196     {
0197         // Matrix not invertible. Setting all elements to nan is not really
0198         // correct in a mathematical sense; but at least qnans are easy to
0199         // spot. XXX we might throw an exception instead, which would
0200         // be even much better to spot :/.
0201         const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
0202         *this = aiMatrix3x3t<TReal>( nan,nan,nan,nan,nan,nan,nan,nan,nan);
0203 
0204         return *this;
0205     }
0206 
0207     TReal invdet = static_cast<TReal>(1.0) / det;
0208 
0209     aiMatrix3x3t<TReal> res;
0210     res.a1 = invdet  * (b2 * c3 - b3 * c2);
0211     res.a2 = -invdet * (a2 * c3 - a3 * c2);
0212     res.a3 = invdet  * (a2 * b3 - a3 * b2);
0213     res.b1 = -invdet * (b1 * c3 - b3 * c1);
0214     res.b2 = invdet  * (a1 * c3 - a3 * c1);
0215     res.b3 = -invdet * (a1 * b3 - a3 * b1);
0216     res.c1 = invdet  * (b1 * c2 - b2 * c1);
0217     res.c2 = -invdet * (a1 * c2 - a2 * c1);
0218     res.c3 = invdet  * (a1 * b2 - a2 * b1);
0219     *this = res;
0220 
0221     return *this;
0222 }
0223 
0224 // ------------------------------------------------------------------------------------------------
0225 template <typename TReal>
0226 AI_FORCE_INLINE
0227 aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out) {
0228     out.a1 = out.b2 = std::cos(a);
0229     out.b1 = std::sin(a);
0230     out.a2 = - out.b1;
0231 
0232     out.a3 = out.b3 = out.c1 = out.c2 = 0.f;
0233     out.c3 = 1.f;
0234 
0235     return out;
0236 }
0237 
0238 // ------------------------------------------------------------------------------------------------
0239 // Returns a rotation matrix for a rotation around an arbitrary axis.
0240 template <typename TReal>
0241 AI_FORCE_INLINE
0242 aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out) {
0243   TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
0244   TReal x = axis.x, y = axis.y, z = axis.z;
0245 
0246   // Many thanks to MathWorld and Wikipedia
0247   out.a1 = t*x*x + c;   out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
0248   out.b1 = t*x*y + s*z; out.b2 = t*y*y + c;   out.b3 = t*y*z - s*x;
0249   out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
0250 
0251   return out;
0252 }
0253 
0254 // ------------------------------------------------------------------------------------------------
0255 template <typename TReal>
0256 AI_FORCE_INLINE
0257 aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out) {
0258     out = aiMatrix3x3t<TReal>();
0259     out.a3 = v.x;
0260     out.b3 = v.y;
0261     return out;
0262 }
0263 
0264 // ----------------------------------------------------------------------------------------
0265 /** A function for creating a rotation matrix that rotates a vector called
0266  * "from" into another vector called "to".
0267  * Input : from[3], to[3] which both must be *normalized* non-zero vectors
0268  * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
0269  * Authors: Tomas Möller, John Hughes
0270  *          "Efficiently Building a Matrix to Rotate One Vector to Another"
0271  *          Journal of Graphics Tools, 4(4):1-4, 1999
0272  */
0273 // ----------------------------------------------------------------------------------------
0274 template <typename TReal>
0275 AI_FORCE_INLINE aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
0276         const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx) {
0277     const TReal e = from * to;
0278     const TReal f = (e < 0)? -e:e;
0279 
0280     if (f > static_cast<TReal>(1.0) - static_cast<TReal>(0.00001))     /* "from" and "to"-vector almost parallel */
0281     {
0282         aiVector3D u,v;     /* temporary storage vectors */
0283         aiVector3D x;       /* vector most nearly orthogonal to "from" */
0284 
0285         x.x = (from.x > 0.0)? from.x : -from.x;
0286         x.y = (from.y > 0.0)? from.y : -from.y;
0287         x.z = (from.z > 0.0)? from.z : -from.z;
0288 
0289         if (x.x < x.y)
0290         {
0291             if (x.x < x.z)
0292             {
0293                 x.x = static_cast<TReal>(1.0);
0294                 x.y = x.z = static_cast<TReal>(0.0);
0295             }
0296             else
0297             {
0298                 x.z = static_cast<TReal>(1.0);
0299                 x.x = x.y = static_cast<TReal>(0.0);
0300             }
0301         }
0302         else
0303         {
0304             if (x.y < x.z)
0305             {
0306                 x.y = static_cast<TReal>(1.0);
0307                 x.x = x.z = static_cast<TReal>(0.0);
0308             }
0309             else
0310             {
0311                 x.z = static_cast<TReal>(1.0);
0312                 x.x = x.y = static_cast<TReal>(0.0);
0313             }
0314         }
0315 
0316         u.x = x.x - from.x; u.y = x.y - from.y; u.z = x.z - from.z;
0317         v.x = x.x - to.x;   v.y = x.y - to.y;   v.z = x.z - to.z;
0318 
0319         const TReal c1_ = static_cast<TReal>(2.0) / (u * u);
0320         const TReal c2_ = static_cast<TReal>(2.0) / (v * v);
0321         const TReal c3_ = c1_ * c2_  * (u * v);
0322 
0323         for (unsigned int i = 0; i < 3; i++)
0324         {
0325             for (unsigned int j = 0; j < 3; j++)
0326             {
0327                 mtx[i][j] =  - c1_ * u[i] * u[j] - c2_ * v[i] * v[j]
0328                     + c3_ * v[i] * u[j];
0329             }
0330             mtx[i][i] += static_cast<TReal>(1.0);
0331         }
0332     }
0333     else  /* the most common case, unless "from"="to", or "from"=-"to" */
0334     {
0335         const aiVector3D v = from ^ to;
0336         /* ... use this hand optimized version (9 mults less) */
0337         const TReal h = static_cast<TReal>(1.0)/(static_cast<TReal>(1.0) + e);      /* optimization by Gottfried Chen */
0338         const TReal hvx = h * v.x;
0339         const TReal hvz = h * v.z;
0340         const TReal hvxy = hvx * v.y;
0341         const TReal hvxz = hvx * v.z;
0342         const TReal hvyz = hvz * v.y;
0343         mtx[0][0] = e + hvx * v.x;
0344         mtx[0][1] = hvxy - v.z;
0345         mtx[0][2] = hvxz + v.y;
0346 
0347         mtx[1][0] = hvxy + v.z;
0348         mtx[1][1] = e + h * v.y * v.y;
0349         mtx[1][2] = hvyz - v.x;
0350 
0351         mtx[2][0] = hvxz - v.y;
0352         mtx[2][1] = hvyz + v.x;
0353         mtx[2][2] = e + hvz * v.z;
0354     }
0355     return mtx;
0356 }
0357 
0358 #endif // __cplusplus
0359 #endif // AI_MATRIX3X3_INL_INC