matrix.h

Go to the documentation of this file.
00001 
00006 /*
00007  Copyright (C) 2001-2006, William Joseph.
00008  All Rights Reserved.
00009 
00010  This file is part of GtkRadiant.
00011 
00012  GtkRadiant is free software; you can redistribute it and/or modify
00013  it under the terms of the GNU General Public License as published by
00014  the Free Software Foundation; either version 2 of the License, or
00015  (at your option) any later version.
00016 
00017  GtkRadiant is distributed in the hope that it will be useful,
00018  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  GNU General Public License for more details.
00021 
00022  You should have received a copy of the GNU General Public License
00023  along with GtkRadiant; if not, write to the Free Software
00024  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00025  */
00026 
00027 #if !defined(INCLUDED_MATH_MATRIX_H)
00028 #define INCLUDED_MATH_MATRIX_H
00029 
00030 #include "math/Vector3.h"
00031 #include "math/Vector4.h"
00032 
00034 class Matrix4
00035 {
00036         float m_elements[16];
00037     public:
00038 
00039         // Default constructor
00040         Matrix4 ()
00041         {
00042         }
00043 
00044         /* NAMED CONSTRUCTORS FOR SPECIFIC MATRICES */
00045 
00046         /* Get a new identity matrix */
00047 
00048         static Matrix4 getIdentity ()
00049         {
00050             return Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
00051         }
00052 
00059         static Matrix4 getTranslation (const Vector3& translation)
00060         {
00061             return Matrix4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, translation.x(), translation.y(), translation.z(), 1);
00062         }
00063 
00064         // Custom constructor
00065 
00066         Matrix4 (float xx_, float xy_, float xz_, float xw_, float yx_, float yy_, float yz_, float yw_, float zx_,
00067                 float zy_, float zz_, float zw_, float tx_, float ty_, float tz_, float tw_)
00068         {
00069             xx() = xx_;
00070             xy() = xy_;
00071             xz() = xz_;
00072             xw() = xw_;
00073             yx() = yx_;
00074             yy() = yy_;
00075             yz() = yz_;
00076             yw() = yw_;
00077             zx() = zx_;
00078             zy() = zy_;
00079             zz() = zz_;
00080             zw() = zw_;
00081             tx() = tx_;
00082             ty() = ty_;
00083             tz() = tz_;
00084             tw() = tw_;
00085         }
00086 
00087         float& xx ()
00088         {
00089             return m_elements[0];
00090         }
00091         const float& xx () const
00092         {
00093             return m_elements[0];
00094         }
00095         float& xy ()
00096         {
00097             return m_elements[1];
00098         }
00099         const float& xy () const
00100         {
00101             return m_elements[1];
00102         }
00103         float& xz ()
00104         {
00105             return m_elements[2];
00106         }
00107         const float& xz () const
00108         {
00109             return m_elements[2];
00110         }
00111         float& xw ()
00112         {
00113             return m_elements[3];
00114         }
00115         const float& xw () const
00116         {
00117             return m_elements[3];
00118         }
00119         float& yx ()
00120         {
00121             return m_elements[4];
00122         }
00123         const float& yx () const
00124         {
00125             return m_elements[4];
00126         }
00127         float& yy ()
00128         {
00129             return m_elements[5];
00130         }
00131         const float& yy () const
00132         {
00133             return m_elements[5];
00134         }
00135         float& yz ()
00136         {
00137             return m_elements[6];
00138         }
00139         const float& yz () const
00140         {
00141             return m_elements[6];
00142         }
00143         float& yw ()
00144         {
00145             return m_elements[7];
00146         }
00147         const float& yw () const
00148         {
00149             return m_elements[7];
00150         }
00151         float& zx ()
00152         {
00153             return m_elements[8];
00154         }
00155         const float& zx () const
00156         {
00157             return m_elements[8];
00158         }
00159         float& zy ()
00160         {
00161             return m_elements[9];
00162         }
00163         const float& zy () const
00164         {
00165             return m_elements[9];
00166         }
00167         float& zz ()
00168         {
00169             return m_elements[10];
00170         }
00171         const float& zz () const
00172         {
00173             return m_elements[10];
00174         }
00175         float& zw ()
00176         {
00177             return m_elements[11];
00178         }
00179         const float& zw () const
00180         {
00181             return m_elements[11];
00182         }
00183         float& tx ()
00184         {
00185             return m_elements[12];
00186         }
00187         const float& tx () const
00188         {
00189             return m_elements[12];
00190         }
00191         float& ty ()
00192         {
00193             return m_elements[13];
00194         }
00195         const float& ty () const
00196         {
00197             return m_elements[13];
00198         }
00199         float& tz ()
00200         {
00201             return m_elements[14];
00202         }
00203         const float& tz () const
00204         {
00205             return m_elements[14];
00206         }
00207         float& tw ()
00208         {
00209             return m_elements[15];
00210         }
00211         const float& tw () const
00212         {
00213             return m_elements[15];
00214         }
00215 
00216         Vector4& x ()
00217         {
00218             return reinterpret_cast<Vector4&> (xx());
00219         }
00220         const Vector4& x () const
00221         {
00222             return reinterpret_cast<const Vector4&> (xx());
00223         }
00224         Vector4& y ()
00225         {
00226             return reinterpret_cast<Vector4&> (yx());
00227         }
00228         const Vector4& y () const
00229         {
00230             return reinterpret_cast<const Vector4&> (yx());
00231         }
00232         Vector4& z ()
00233         {
00234             return reinterpret_cast<Vector4&> (zx());
00235         }
00236         const Vector4& z () const
00237         {
00238             return reinterpret_cast<const Vector4&> (zx());
00239         }
00240         Vector4& t ()
00241         {
00242             return reinterpret_cast<Vector4&> (tx());
00243         }
00244         const Vector4& t () const
00245         {
00246             return reinterpret_cast<const Vector4&> (tx());
00247         }
00248 
00249         const float& index (std::size_t i) const
00250         {
00251             return m_elements[i];
00252         }
00253         float& index (std::size_t i)
00254         {
00255             return m_elements[i];
00256         }
00257         const float& index (std::size_t r, std::size_t c) const
00258         {
00259             return m_elements[(r << 2) + c];
00260         }
00261         float& index (std::size_t r, std::size_t c)
00262         {
00263             return m_elements[(r << 2) + c];
00264         }
00265 
00269         operator float* ()
00270         {
00271             return m_elements;
00272         }
00273 
00276         operator const float* () const
00277         {
00278             return m_elements;
00279         }
00280 
00287         Vector4 transform (const Vector4& vector4) const
00288         {
00289             return Vector4(m_elements[0] * vector4[0] + m_elements[4] * vector4[1] + m_elements[8] * vector4[2]
00290                     + m_elements[12] * vector4[3], m_elements[1] * vector4[0] + m_elements[5] * vector4[1]
00291                     + m_elements[9] * vector4[2] + m_elements[13] * vector4[3], m_elements[2] * vector4[0]
00292                     + m_elements[6] * vector4[1] + m_elements[10] * vector4[2] + m_elements[14] * vector4[3],
00293                     m_elements[3] * vector4[0] + m_elements[7] * vector4[1] + m_elements[11] * vector4[2]
00294                             + m_elements[15] * vector4[3]);
00295         }
00296 
00307         Vector4 transform (const Vector3& vector3) const
00308         {
00309             return transform(Vector4(vector3, 1));
00310         }
00311 
00312 };
00313 
00315 const Matrix4 g_matrix4_identity(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
00316 
00318 inline bool operator== (const Matrix4& self, const Matrix4& other)
00319 {
00320     return self.xx() == other.xx() && self.xy() == other.xy() && self.xz() == other.xz() && self.xw() == other.xw()
00321             && self.yx() == other.yx() && self.yy() == other.yy() && self.yz() == other.yz() && self.yw() == other.yw()
00322             && self.zx() == other.zx() && self.zy() == other.zy() && self.zz() == other.zz() && self.zw() == other.zw()
00323             && self.tx() == other.tx() && self.ty() == other.ty() && self.tz() == other.tz() && self.tw() == other.tw();
00324 }
00325 
00327 inline bool matrix4_equal (const Matrix4& self, const Matrix4& other)
00328 {
00329     return self == other;
00330 }
00331 
00333 inline bool matrix4_equal_epsilon (const Matrix4& self, const Matrix4& other, float epsilon)
00334 {
00335     return float_equal_epsilon(self.xx(), other.xx(), epsilon) && float_equal_epsilon(self.xy(), other.xy(), epsilon)
00336             && float_equal_epsilon(self.xz(), other.xz(), epsilon) && float_equal_epsilon(self.xw(), other.xw(),
00337             epsilon) && float_equal_epsilon(self.yx(), other.yx(), epsilon) && float_equal_epsilon(self.yy(),
00338             other.yy(), epsilon) && float_equal_epsilon(self.yz(), other.yz(), epsilon) && float_equal_epsilon(
00339             self.yw(), other.yw(), epsilon) && float_equal_epsilon(self.zx(), other.zx(), epsilon)
00340             && float_equal_epsilon(self.zy(), other.zy(), epsilon) && float_equal_epsilon(self.zz(), other.zz(),
00341             epsilon) && float_equal_epsilon(self.zw(), other.zw(), epsilon) && float_equal_epsilon(self.tx(),
00342             other.tx(), epsilon) && float_equal_epsilon(self.ty(), other.ty(), epsilon) && float_equal_epsilon(
00343             self.tz(), other.tz(), epsilon) && float_equal_epsilon(self.tw(), other.tw(), epsilon);
00344 }
00345 
00348 inline bool matrix4_affine_equal (const Matrix4& self, const Matrix4& other)
00349 {
00350     return self[0] == other[0] && self[1] == other[1] && self[2] == other[2] && self[4] == other[4] && self[5]
00351             == other[5] && self[6] == other[6] && self[8] == other[8] && self[9] == other[9] && self[10] == other[10]
00352             && self[12] == other[12] && self[13] == other[13] && self[14] == other[14];
00353 }
00354 
00355 enum Matrix4Handedness
00356 {
00357     MATRIX4_RIGHTHANDED = 0, MATRIX4_LEFTHANDED = 1,
00358 };
00359 
00361 inline Matrix4Handedness matrix4_handedness (const Matrix4& self)
00362 {
00363     return (self.x().getVector3().crossProduct(self.y().getVector3()).dot(self.z().getVector3()) < 0.0) ? MATRIX4_LEFTHANDED
00364             : MATRIX4_RIGHTHANDED;
00365 }
00366 
00368 inline Matrix4 matrix4_multiplied_by_matrix4 (const Matrix4& self, const Matrix4& other)
00369 {
00370     return Matrix4(other[0] * self[0] + other[1] * self[4] + other[2] * self[8] + other[3] * self[12], other[0]
00371             * self[1] + other[1] * self[5] + other[2] * self[9] + other[3] * self[13], other[0] * self[2] + other[1]
00372             * self[6] + other[2] * self[10] + other[3] * self[14], other[0] * self[3] + other[1] * self[7] + other[2]
00373             * self[11] + other[3] * self[15], other[4] * self[0] + other[5] * self[4] + other[6] * self[8] + other[7]
00374             * self[12], other[4] * self[1] + other[5] * self[5] + other[6] * self[9] + other[7] * self[13], other[4]
00375             * self[2] + other[5] * self[6] + other[6] * self[10] + other[7] * self[14], other[4] * self[3] + other[5]
00376             * self[7] + other[6] * self[11] + other[7] * self[15], other[8] * self[0] + other[9] * self[4] + other[10]
00377             * self[8] + other[11] * self[12], other[8] * self[1] + other[9] * self[5] + other[10] * self[9] + other[11]
00378             * self[13], other[8] * self[2] + other[9] * self[6] + other[10] * self[10] + other[11] * self[14], other[8]
00379             * self[3] + other[9] * self[7] + other[10] * self[11] + other[11] * self[15], other[12] * self[0]
00380             + other[13] * self[4] + other[14] * self[8] + other[15] * self[12], other[12] * self[1] + other[13]
00381             * self[5] + other[14] * self[9] + other[15] * self[13], other[12] * self[2] + other[13] * self[6]
00382             + other[14] * self[10] + other[15] * self[14], other[12] * self[3] + other[13] * self[7] + other[14]
00383             * self[11] + other[15] * self[15]);
00384 }
00385 
00387 inline void matrix4_multiply_by_matrix4 (Matrix4& self, const Matrix4& other)
00388 {
00389     self = matrix4_multiplied_by_matrix4(self, other);
00390 }
00391 
00393 inline Matrix4 matrix4_premultiplied_by_matrix4 (const Matrix4& self, const Matrix4& other)
00394 {
00395 #if 1
00396     return matrix4_multiplied_by_matrix4(other, self);
00397 #else
00398     return Matrix4(
00399             self[0] * other[0] + self[1] * other[4] + self[2] * other[8] + self[3] * other[12],
00400             self[0] * other[1] + self[1] * other[5] + self[2] * other[9] + self[3] * other[13],
00401             self[0] * other[2] + self[1] * other[6] + self[2] * other[10]+ self[3] * other[14],
00402             self[0] * other[3] + self[1] * other[7] + self[2] * other[11]+ self[3] * other[15],
00403             self[4] * other[0] + self[5] * other[4] + self[6] * other[8] + self[7] * other[12],
00404             self[4] * other[1] + self[5] * other[5] + self[6] * other[9] + self[7] * other[13],
00405             self[4] * other[2] + self[5] * other[6] + self[6] * other[10]+ self[7] * other[14],
00406             self[4] * other[3] + self[5] * other[7] + self[6] * other[11]+ self[7] * other[15],
00407             self[8] * other[0] + self[9] * other[4] + self[10]* other[8] + self[11]* other[12],
00408             self[8] * other[1] + self[9] * other[5] + self[10]* other[9] + self[11]* other[13],
00409             self[8] * other[2] + self[9] * other[6] + self[10]* other[10]+ self[11]* other[14],
00410             self[8] * other[3] + self[9] * other[7] + self[10]* other[11]+ self[11]* other[15],
00411             self[12]* other[0] + self[13]* other[4] + self[14]* other[8] + self[15]* other[12],
00412             self[12]* other[1] + self[13]* other[5] + self[14]* other[9] + self[15]* other[13],
00413             self[12]* other[2] + self[13]* other[6] + self[14]* other[10]+ self[15]* other[14],
00414             self[12]* other[3] + self[13]* other[7] + self[14]* other[11]+ self[15]* other[15]
00415     );
00416 #endif
00417 }
00418 
00420 inline void matrix4_premultiply_by_matrix4 (Matrix4& self, const Matrix4& other)
00421 {
00422     self = matrix4_premultiplied_by_matrix4(self, other);
00423 }
00424 
00426 inline bool matrix4_is_affine (const Matrix4& transform)
00427 {
00428     return transform[3] == 0 && transform[7] == 0 && transform[11] == 0 && transform[15] == 1;
00429 }
00430 
00433 inline Matrix4 matrix4_affine_multiplied_by_matrix4 (const Matrix4& self, const Matrix4& other)
00434 {
00435     return Matrix4(other[0] * self[0] + other[1] * self[4] + other[2] * self[8], other[0] * self[1] + other[1]
00436             * self[5] + other[2] * self[9], other[0] * self[2] + other[1] * self[6] + other[2] * self[10], 0, other[4]
00437             * self[0] + other[5] * self[4] + other[6] * self[8], other[4] * self[1] + other[5] * self[5] + other[6]
00438             * self[9], other[4] * self[2] + other[5] * self[6] + other[6] * self[10], 0, other[8] * self[0] + other[9]
00439             * self[4] + other[10] * self[8], other[8] * self[1] + other[9] * self[5] + other[10] * self[9], other[8]
00440             * self[2] + other[9] * self[6] + other[10] * self[10], 0, other[12] * self[0] + other[13] * self[4]
00441             + other[14] * self[8] + self[12], other[12] * self[1] + other[13] * self[5] + other[14] * self[9]
00442             + self[13], other[12] * self[2] + other[13] * self[6] + other[14] * self[10] + self[14], 1);
00443 }
00444 
00447 inline void matrix4_affine_multiply_by_matrix4 (Matrix4& self, const Matrix4& other)
00448 {
00449     self = matrix4_affine_multiplied_by_matrix4(self, other);
00450 }
00451 
00454 inline Matrix4 matrix4_affine_premultiplied_by_matrix4 (const Matrix4& self, const Matrix4& other)
00455 {
00456 #if 1
00457     return matrix4_affine_multiplied_by_matrix4(other, self);
00458 #else
00459     return Matrix4(
00460             self[0] * other[0] + self[1] * other[4] + self[2] * other[8],
00461             self[0] * other[1] + self[1] * other[5] + self[2] * other[9],
00462             self[0] * other[2] + self[1] * other[6] + self[2] * other[10],
00463             0,
00464             self[4] * other[0] + self[5] * other[4] + self[6] * other[8],
00465             self[4] * other[1] + self[5] * other[5] + self[6] * other[9],
00466             self[4] * other[2] + self[5] * other[6] + self[6] * other[10],
00467             0,
00468             self[8] * other[0] + self[9] * other[4] + self[10]* other[8],
00469             self[8] * other[1] + self[9] * other[5] + self[10]* other[9],
00470             self[8] * other[2] + self[9] * other[6] + self[10]* other[10],
00471             0,
00472             self[12]* other[0] + self[13]* other[4] + self[14]* other[8] + other[12],
00473             self[12]* other[1] + self[13]* other[5] + self[14]* other[9] + other[13],
00474             self[12]* other[2] + self[13]* other[6] + self[14]* other[10]+ other[14],
00475             1
00476     )
00477     );
00478 #endif
00479 }
00480 
00483 inline void matrix4_affine_premultiply_by_matrix4 (Matrix4& self, const Matrix4& other)
00484 {
00485     self = matrix4_affine_premultiplied_by_matrix4(self, other);
00486 }
00487 
00489 template<typename Element>
00490 inline BasicVector3<Element> matrix4_transformed_point (const Matrix4& self, const BasicVector3<Element>& point)
00491 {
00492     return BasicVector3<Element> (static_cast<Element> (self[0] * point[0] + self[4] * point[1] + self[8] * point[2]
00493             + self[12]),
00494             static_cast<Element> (self[1] * point[0] + self[5] * point[1] + self[9] * point[2] + self[13]),
00495             static_cast<Element> (self[2] * point[0] + self[6] * point[1] + self[10] * point[2] + self[14]));
00496 }
00497 
00499 template<typename Element>
00500 inline void matrix4_transform_point (const Matrix4& self, BasicVector3<Element>& point)
00501 {
00502     point = matrix4_transformed_point(self, point);
00503 }
00504 
00506 template<typename Element>
00507 inline BasicVector3<Element> matrix4_transformed_direction (const Matrix4& self, const BasicVector3<Element>& direction)
00508 {
00509     return BasicVector3<Element> (static_cast<Element> (self[0] * direction[0] + self[4] * direction[1] + self[8]
00510             * direction[2]), static_cast<Element> (self[1] * direction[0] + self[5] * direction[1] + self[9]
00511             * direction[2]), static_cast<Element> (self[2] * direction[0] + self[6] * direction[1] + self[10]
00512             * direction[2]));
00513 }
00514 
00516 template<typename Element>
00517 inline void matrix4_transform_direction (const Matrix4& self, BasicVector3<Element>& normal)
00518 {
00519     normal = matrix4_transformed_direction(self, normal);
00520 }
00521 
00523 inline Vector4 matrix4_transformed_vector4 (const Matrix4& self, const Vector4& vector4)
00524 {
00525     return Vector4(self[0] * vector4[0] + self[4] * vector4[1] + self[8] * vector4[2] + self[12] * vector4[3], self[1]
00526             * vector4[0] + self[5] * vector4[1] + self[9] * vector4[2] + self[13] * vector4[3], self[2] * vector4[0]
00527             + self[6] * vector4[1] + self[10] * vector4[2] + self[14] * vector4[3], self[3] * vector4[0] + self[7]
00528             * vector4[1] + self[11] * vector4[2] + self[15] * vector4[3]);
00529 }
00530 
00532 inline void matrix4_transform_vector4 (const Matrix4& self, Vector4& vector4)
00533 {
00534     vector4 = matrix4_transformed_vector4(self, vector4);
00535 }
00536 
00538 inline void matrix4_transpose (Matrix4& self)
00539 {
00540     std::swap(self.xy(), self.yx());
00541     std::swap(self.xz(), self.zx());
00542     std::swap(self.xw(), self.tx());
00543     std::swap(self.yz(), self.zy());
00544     std::swap(self.yw(), self.ty());
00545     std::swap(self.zw(), self.tz());
00546 }
00547 
00549 inline Matrix4 matrix4_transposed (const Matrix4& self)
00550 {
00551     return Matrix4(self.xx(), self.yx(), self.zx(), self.tx(), self.xy(), self.yy(), self.zy(), self.ty(), self.xz(),
00552             self.yz(), self.zz(), self.tz(), self.xw(), self.yw(), self.zw(), self.tw());
00553 }
00554 
00557 inline Matrix4 matrix4_affine_inverse (const Matrix4& self)
00558 {
00559     Matrix4 result;
00560 
00561     // determinant of rotation submatrix
00562     double det = self[0] * (self[5] * self[10] - self[9] * self[6]) - self[1]
00563             * (self[4] * self[10] - self[8] * self[6]) + self[2] * (self[4] * self[9] - self[8] * self[5]);
00564 
00565     // throw exception here if (det*det < 1e-25)
00566 
00567     // invert rotation submatrix
00568     det = 1.0 / det;
00569 
00570     result[0] = ((self[5] * self[10] - self[6] * self[9]) * det);
00571     result[1] = (-(self[1] * self[10] - self[2] * self[9]) * det);
00572     result[2] = ((self[1] * self[6] - self[2] * self[5]) * det);
00573     result[3] = 0;
00574     result[4] = (-(self[4] * self[10] - self[6] * self[8]) * det);
00575     result[5] = ((self[0] * self[10] - self[2] * self[8]) * det);
00576     result[6] = (-(self[0] * self[6] - self[2] * self[4]) * det);
00577     result[7] = 0;
00578     result[8] = ((self[4] * self[9] - self[5] * self[8]) * det);
00579     result[9] = (-(self[0] * self[9] - self[1] * self[8]) * det);
00580     result[10] = ((self[0] * self[5] - self[1] * self[4]) * det);
00581     result[11] = 0;
00582 
00583     // multiply translation part by rotation
00584     result[12] = -(self[12] * result[0] + self[13] * result[4] + self[14] * result[8]);
00585     result[13] = -(self[12] * result[1] + self[13] * result[5] + self[14] * result[9]);
00586     result[14] = -(self[12] * result[2] + self[13] * result[6] + self[14] * result[10]);
00587     result[15] = 1;
00588 
00589     return result;
00590 }
00591 
00592 inline void matrix4_affine_invert (Matrix4& self)
00593 {
00594     self = matrix4_affine_inverse(self);
00595 }
00596 
00598 template<int VALUE_>
00599 struct IntegralConstant
00600 {
00601         enum unnamed_
00602         {
00603             VALUE = VALUE_
00604         };
00605 };
00606 
00608 template<typename Row, typename Col>
00609 class Matrix4Index
00610 {
00611     public:
00612         typedef IntegralConstant<Row::VALUE> r;
00613         typedef IntegralConstant<Col::VALUE> c;
00614         typedef IntegralConstant<(r::VALUE * 4) + c::VALUE> i;
00615 };
00616 
00620 template<typename Row, typename Col>
00621 class Matrix4Cofactor
00622 {
00623     public:
00624         typedef typename Matrix4Index<typename Row::x, typename Col::x>::i xx;
00625         typedef typename Matrix4Index<typename Row::x, typename Col::y>::i xy;
00626         typedef typename Matrix4Index<typename Row::x, typename Col::z>::i xz;
00627         typedef typename Matrix4Index<typename Row::y, typename Col::x>::i yx;
00628         typedef typename Matrix4Index<typename Row::y, typename Col::y>::i yy;
00629         typedef typename Matrix4Index<typename Row::y, typename Col::z>::i yz;
00630         typedef typename Matrix4Index<typename Row::z, typename Col::x>::i zx;
00631         typedef typename Matrix4Index<typename Row::z, typename Col::y>::i zy;
00632         typedef typename Matrix4Index<typename Row::z, typename Col::z>::i zz;
00633         static double apply (const Matrix4& self)
00634         {
00635             return self[xx::VALUE] * (self[yy::VALUE] * self[zz::VALUE] - self[zy::VALUE] * self[yz::VALUE])
00636                     - self[xy::VALUE] * (self[yx::VALUE] * self[zz::VALUE] - self[zx::VALUE] * self[yz::VALUE])
00637                     + self[xz::VALUE] * (self[yx::VALUE] * self[zy::VALUE] - self[zx::VALUE] * self[yy::VALUE]);
00638         }
00639 };
00640 
00643 template<int Element>
00644 class Cofactor4
00645 {
00646     public:
00647         typedef IntegralConstant<(Element <= 0) ? 1 : 0> x;
00648         typedef IntegralConstant<(Element <= 1) ? 2 : 1> y;
00649         typedef IntegralConstant<(Element <= 2) ? 3 : 2> z;
00650 };
00651 
00653 inline double matrix4_determinant (const Matrix4& self)
00654 {
00655     return self.xx() * Matrix4Cofactor<Cofactor4<0> , Cofactor4<0> >::apply(self) - self.xy() * Matrix4Cofactor<
00656             Cofactor4<0> , Cofactor4<1> >::apply(self) + self.xz()
00657             * Matrix4Cofactor<Cofactor4<0> , Cofactor4<2> >::apply(self) - self.xw() * Matrix4Cofactor<Cofactor4<0> ,
00658             Cofactor4<3> >::apply(self);
00659 }
00660 
00663 inline Matrix4 matrix4_full_inverse (const Matrix4& self)
00664 {
00665     double determinant = 1.0 / matrix4_determinant(self);
00666 
00667     return Matrix4(static_cast<float> (Matrix4Cofactor<Cofactor4<0> , Cofactor4<0> >::apply(self) * determinant),
00668             static_cast<float> (-Matrix4Cofactor<Cofactor4<1> , Cofactor4<0> >::apply(self) * determinant),
00669             static_cast<float> (Matrix4Cofactor<Cofactor4<2> , Cofactor4<0> >::apply(self) * determinant),
00670             static_cast<float> (-Matrix4Cofactor<Cofactor4<3> , Cofactor4<0> >::apply(self) * determinant),
00671             static_cast<float> (-Matrix4Cofactor<Cofactor4<0> , Cofactor4<1> >::apply(self) * determinant),
00672             static_cast<float> (Matrix4Cofactor<Cofactor4<1> , Cofactor4<1> >::apply(self) * determinant),
00673             static_cast<float> (-Matrix4Cofactor<Cofactor4<2> , Cofactor4<1> >::apply(self) * determinant),
00674             static_cast<float> (Matrix4Cofactor<Cofactor4<3> , Cofactor4<1> >::apply(self) * determinant),
00675             static_cast<float> (Matrix4Cofactor<Cofactor4<0> , Cofactor4<2> >::apply(self) * determinant),
00676             static_cast<float> (-Matrix4Cofactor<Cofactor4<1> , Cofactor4<2> >::apply(self) * determinant),
00677             static_cast<float> (Matrix4Cofactor<Cofactor4<2> , Cofactor4<2> >::apply(self) * determinant),
00678             static_cast<float> (-Matrix4Cofactor<Cofactor4<3> , Cofactor4<2> >::apply(self) * determinant),
00679             static_cast<float> (-Matrix4Cofactor<Cofactor4<0> , Cofactor4<3> >::apply(self) * determinant),
00680             static_cast<float> (Matrix4Cofactor<Cofactor4<1> , Cofactor4<3> >::apply(self) * determinant),
00681             static_cast<float> (-Matrix4Cofactor<Cofactor4<2> , Cofactor4<3> >::apply(self) * determinant),
00682             static_cast<float> (Matrix4Cofactor<Cofactor4<3> , Cofactor4<3> >::apply(self) * determinant));
00683 }
00684 
00686 inline void matrix4_full_invert (Matrix4& self)
00687 {
00688     self = matrix4_full_inverse(self);
00689 }
00690 
00692 inline Vector3 matrix4_get_translation_vec3 (const Matrix4& self)
00693 {
00694     return self.t().getVector3();
00695 }
00696 
00699 inline void matrix4_translate_by_vec3 (Matrix4& self, const Vector3& translation)
00700 {
00701     matrix4_multiply_by_matrix4(self, Matrix4::getTranslation(translation));
00702 }
00703 
00706 inline Matrix4 matrix4_translated_by_vec3 (const Matrix4& self, const Vector3& translation)
00707 {
00708     return matrix4_multiplied_by_matrix4(self, Matrix4::getTranslation(translation));
00709 }
00710 
00711 #include "math/pi.h"
00712 
00715 inline float angle_modulate_degrees_range (float angle)
00716 {
00717     return static_cast<float> (float_mod_range(angle, 360.0));
00718 }
00719 
00721 inline Vector3 euler_radians_to_degrees (const Vector3& euler)
00722 {
00723     return Vector3(static_cast<float> (radians_to_degrees(euler.x())),
00724             static_cast<float> (radians_to_degrees(euler.y())), static_cast<float> (radians_to_degrees(euler.z())));
00725 }
00726 
00728 inline Vector3 euler_degrees_to_radians (const Vector3& euler)
00729 {
00730     return Vector3(static_cast<float> (degrees_to_radians(euler.x())),
00731             static_cast<float> (degrees_to_radians(euler.y())), static_cast<float> (degrees_to_radians(euler.z())));
00732 }
00733 
00735 inline Matrix4 matrix4_rotation_for_sincos_x (float s, float c)
00736 {
00737     return Matrix4(1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1);
00738 }
00739 
00741 inline Matrix4 matrix4_rotation_for_x (double x)
00742 {
00743     return matrix4_rotation_for_sincos_x(static_cast<float> (sin(x)), static_cast<float> (cos(x)));
00744 }
00745 
00747 inline Matrix4 matrix4_rotation_for_x_degrees (float x)
00748 {
00749     return matrix4_rotation_for_x(degrees_to_radians(x));
00750 }
00751 
00753 inline Matrix4 matrix4_rotation_for_sincos_y (float s, float c)
00754 {
00755     return Matrix4(c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1);
00756 }
00757 
00759 inline Matrix4 matrix4_rotation_for_y (double y)
00760 {
00761     return matrix4_rotation_for_sincos_y(static_cast<float> (sin(y)), static_cast<float> (cos(y)));
00762 }
00763 
00765 inline Matrix4 matrix4_rotation_for_y_degrees (float y)
00766 {
00767     return matrix4_rotation_for_y(degrees_to_radians(y));
00768 }
00769 
00771 inline Matrix4 matrix4_rotation_for_sincos_z (float s, float c)
00772 {
00773     return Matrix4(c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
00774 }
00775 
00777 inline Matrix4 matrix4_rotation_for_z (double z)
00778 {
00779     return matrix4_rotation_for_sincos_z(static_cast<float> (sin(z)), static_cast<float> (cos(z)));
00780 }
00781 
00783 inline Matrix4 matrix4_rotation_for_z_degrees (float z)
00784 {
00785     return matrix4_rotation_for_z(degrees_to_radians(z));
00786 }
00787 
00789 
00811 inline Matrix4 matrix4_rotation_for_euler_xyz (const Vector3& euler)
00812 {
00813 #if 1
00814 
00815     double cx = cos(euler[0]);
00816     double sx = sin(euler[0]);
00817     double cy = cos(euler[1]);
00818     double sy = sin(euler[1]);
00819     double cz = cos(euler[2]);
00820     double sz = sin(euler[2]);
00821 
00822     return Matrix4(static_cast<float> (cy * cz), static_cast<float> (cy * sz), static_cast<float> (-sy), 0,
00823             static_cast<float> (sx * sy * cz + cx * -sz), static_cast<float> (sx * sy * sz + cx * cz),
00824             static_cast<float> (sx * cy), 0, static_cast<float> (cx * sy * cz + sx * sz), static_cast<float> (cx * sy
00825                     * sz + -sx * cz), static_cast<float> (cx * cy), 0, 0, 0, 0, 1);
00826 
00827 #else
00828 
00829     return matrix4_premultiply_by_matrix4(
00830             matrix4_premultiply_by_matrix4(
00831                     matrix4_rotation_for_x(euler[0]),
00832                     matrix4_rotation_for_y(euler[1])
00833             ),
00834             matrix4_rotation_for_z(euler[2])
00835     );
00836 
00837 #endif
00838 }
00839 
00841 inline Matrix4 matrix4_rotation_for_euler_xyz_degrees (const Vector3& euler)
00842 {
00843     return matrix4_rotation_for_euler_xyz(euler_degrees_to_radians(euler));
00844 }
00845 
00848 inline void matrix4_rotate_by_euler_xyz_degrees (Matrix4& self, const Vector3& euler)
00849 {
00850     matrix4_multiply_by_matrix4(self, matrix4_rotation_for_euler_xyz_degrees(euler));
00851 }
00852 
00854 inline Matrix4 matrix4_rotation_for_euler_yzx (const Vector3& euler)
00855 {
00856     return matrix4_premultiplied_by_matrix4(matrix4_premultiplied_by_matrix4(matrix4_rotation_for_y(euler[1]),
00857             matrix4_rotation_for_z(euler[2])), matrix4_rotation_for_x(euler[0]));
00858 }
00859 
00861 inline Matrix4 matrix4_rotation_for_euler_yzx_degrees (const Vector3& euler)
00862 {
00863     return matrix4_rotation_for_euler_yzx(euler_degrees_to_radians(euler));
00864 }
00865 
00867 inline Matrix4 matrix4_rotation_for_euler_xzy (const Vector3& euler)
00868 {
00869     return matrix4_premultiplied_by_matrix4(matrix4_premultiplied_by_matrix4(matrix4_rotation_for_x(euler[0]),
00870             matrix4_rotation_for_z(euler[2])), matrix4_rotation_for_y(euler[1]));
00871 }
00872 
00874 inline Matrix4 matrix4_rotation_for_euler_xzy_degrees (const Vector3& euler)
00875 {
00876     return matrix4_rotation_for_euler_xzy(euler_degrees_to_radians(euler));
00877 }
00878 
00880 
00885 inline Matrix4 matrix4_rotation_for_euler_yxz (const Vector3& euler)
00886 {
00887 #if 1
00888 
00889     double cx = cos(euler[0]);
00890     double sx = sin(euler[0]);
00891     double cy = cos(euler[1]);
00892     double sy = sin(euler[1]);
00893     double cz = cos(euler[2]);
00894     double sz = sin(euler[2]);
00895 
00896     return Matrix4(static_cast<float> (cy * cz + sx * sy * -sz), static_cast<float> (cy * sz + sx * sy * cz),
00897             static_cast<float> (-cx * sy), 0, static_cast<float> (cx * -sz), static_cast<float> (cx * cz),
00898             static_cast<float> (sx), 0, static_cast<float> (sy * cz + -sx * cy * -sz), static_cast<float> (sy * sz
00899                     + -sx * cy * cz), static_cast<float> (cx * cy), 0, 0, 0, 0, 1);
00900 
00901 #else
00902 
00903     return matrix4_premultiply_by_matrix4(
00904             matrix4_premultiply_by_matrix4(
00905                     matrix4_rotation_for_y(euler[1]),
00906                     matrix4_rotation_for_x(euler[0])
00907             ),
00908             matrix4_rotation_for_z(euler[2])
00909     );
00910 
00911 #endif
00912 }
00913 
00915 inline Matrix4 matrix4_rotation_for_euler_yxz_degrees (const Vector3& euler)
00916 {
00917     return matrix4_rotation_for_euler_yxz(euler_degrees_to_radians(euler));
00918 }
00919 
00922 inline Matrix4 matrix4_rotated_by_euler_yxz_degrees (const Matrix4& self, const Vector3& euler)
00923 {
00924     return matrix4_multiplied_by_matrix4(self, matrix4_rotation_for_euler_yxz_degrees(euler));
00925 }
00926 
00929 inline void matrix4_rotate_by_euler_yxz_degrees (Matrix4& self, const Vector3& euler)
00930 {
00931     self = matrix4_rotated_by_euler_yxz_degrees(self, euler);
00932 }
00933 
00935 inline Matrix4 matrix4_rotation_for_euler_zxy (const Vector3& euler)
00936 {
00937 #if 1
00938     return matrix4_premultiplied_by_matrix4(matrix4_premultiplied_by_matrix4(matrix4_rotation_for_z(euler[2]),
00939             matrix4_rotation_for_x(euler[0])), matrix4_rotation_for_y(euler[1]));
00940 #else
00941     double cx = cos(euler[0]);
00942     double sx = sin(euler[0]);
00943     double cy = cos(euler[1]);
00944     double sy = sin(euler[1]);
00945     double cz = cos(euler[2]);
00946     double sz = sin(euler[2]);
00947 
00948     return Matrix4(
00949             static_cast<float>(cz * cy + sz * sx * sy),
00950             static_cast<float>(sz * cx),
00951             static_cast<float>(cz * -sy + sz * sx * cy),
00952             0,
00953             static_cast<float>(-sz * cy + cz * sx * sy),
00954             static_cast<float>(cz * cx),
00955             static_cast<float>(-sz * -sy + cz * cx * cy),
00956             0,
00957             static_cast<float>(cx* sy),
00958             static_cast<float>(-sx),
00959             static_cast<float>(cx* cy),
00960             0,
00961             0,
00962             0,
00963             0,
00964             1
00965     );
00966 #endif
00967 }
00968 
00970 inline Matrix4 matrix4_rotation_for_euler_zxy_degrees (const Vector3& euler)
00971 {
00972     return matrix4_rotation_for_euler_zxy(euler_degrees_to_radians(euler));
00973 }
00974 
00977 inline Matrix4 matrix4_rotated_by_euler_zxy_degrees (const Matrix4& self, const Vector3& euler)
00978 {
00979     return matrix4_multiplied_by_matrix4(self, matrix4_rotation_for_euler_zxy_degrees(euler));
00980 }
00981 
00984 inline void matrix4_rotate_by_euler_zxy_degrees (Matrix4& self, const Vector3& euler)
00985 {
00986     self = matrix4_rotated_by_euler_zxy_degrees(self, euler);
00987 }
00988 
00990 inline Matrix4 matrix4_rotation_for_euler_zyx (const Vector3& euler)
00991 {
00992 #if 1
00993 
00994     double cx = cos(euler[0]);
00995     double sx = sin(euler[0]);
00996     double cy = cos(euler[1]);
00997     double sy = sin(euler[1]);
00998     double cz = cos(euler[2]);
00999     double sz = sin(euler[2]);
01000 
01001     return Matrix4(static_cast<float> (cy * cz), static_cast<float> (sx * sy * cz + cx * sz), static_cast<float> (cx
01002             * -sy * cz + sx * sz), 0, static_cast<float> (cy * -sz), static_cast<float> (sx * sy * -sz + cx * cz),
01003             static_cast<float> (cx * -sy * -sz + sx * cz), 0, static_cast<float> (sy), static_cast<float> (-sx * cy),
01004             static_cast<float> (cx * cy), 0, 0, 0, 0, 1);
01005 
01006 #else
01007 
01008     return matrix4_premultiply_by_matrix4(
01009             matrix4_premultiply_by_matrix4(
01010                     matrix4_rotation_for_z(euler[2]),
01011                     matrix4_rotation_for_y(euler[1])
01012             ),
01013             matrix4_rotation_for_x(euler[0])
01014     );
01015 
01016 #endif
01017 }
01018 
01020 inline Matrix4 matrix4_rotation_for_euler_zyx_degrees (const Vector3& euler)
01021 {
01022     return matrix4_rotation_for_euler_zyx(euler_degrees_to_radians(euler));
01023 }
01024 
01027 inline Vector3 matrix4_get_rotation_euler_xyz (const Matrix4& self)
01028 {
01029     double a = asin(-self[2]);
01030     double ca = cos(a);
01031 
01032     if (fabs(ca) > 0.005) // Gimbal lock?
01033     {
01034         return Vector3(static_cast<float> (atan2(self[6] / ca, self[10] / ca)), static_cast<float> (a),
01035                 static_cast<float> (atan2(self[1] / ca, self[0] / ca)));
01036     } else // Gimbal lock has occurred
01037     {
01038         return Vector3(static_cast<float> (atan2(-self[9], self[5])), static_cast<float> (a), 0);
01039     }
01040 }
01041 
01043 inline Vector3 matrix4_get_rotation_euler_xyz_degrees (const Matrix4& self)
01044 {
01045     return euler_radians_to_degrees(matrix4_get_rotation_euler_xyz(self));
01046 }
01047 
01050 inline Vector3 matrix4_get_rotation_euler_yxz (const Matrix4& self)
01051 {
01052     double a = asin(self[6]);
01053     double ca = cos(a);
01054 
01055     if (fabs(ca) > 0.005) // Gimbal lock?
01056     {
01057         return Vector3(static_cast<float> (a), static_cast<float> (atan2(-self[2] / ca, self[10] / ca)),
01058                 static_cast<float> (atan2(-self[4] / ca, self[5] / ca)));
01059     } else // Gimbal lock has occurred
01060     {
01061         return Vector3(static_cast<float> (a), static_cast<float> (atan2(self[8], self[0])), 0);
01062     }
01063 }
01064 
01066 inline Vector3 matrix4_get_rotation_euler_yxz_degrees (const Matrix4& self)
01067 {
01068     return euler_radians_to_degrees(matrix4_get_rotation_euler_yxz(self));
01069 }
01070 
01073 inline Vector3 matrix4_get_rotation_euler_zxy (const Matrix4& self)
01074 {
01075     double a = asin(-self[9]);
01076     double ca = cos(a);
01077 
01078     if (fabs(ca) > 0.005) // Gimbal lock?
01079     {
01080         return Vector3(static_cast<float> (a), static_cast<float> (atan2(self[8] / ca, self[10] / ca)),
01081                 static_cast<float> (atan2(self[1] / ca, self[5] / ca)));
01082     } else // Gimbal lock has occurred
01083     {
01084         return Vector3(static_cast<float> (a), 0, static_cast<float> (atan2(-self[4], self[0])));
01085     }
01086 }
01087 
01089 inline Vector3 matrix4_get_rotation_euler_zxy_degrees (const Matrix4& self)
01090 {
01091     return euler_radians_to_degrees(matrix4_get_rotation_euler_zxy(self));
01092 }
01093 
01096 inline Vector3 matrix4_get_rotation_euler_zyx (const Matrix4& self)
01097 {
01098     double a = asin(self[8]);
01099     double ca = cos(a);
01100 
01101     if (fabs(ca) > 0.005) // Gimbal lock?
01102     {
01103         return Vector3(static_cast<float> (atan2(-self[9] / ca, self[10] / ca)), static_cast<float> (a),
01104                 static_cast<float> (atan2(-self[4] / ca, self[0] / ca)));
01105     } else // Gimbal lock has occurred
01106     {
01107         return Vector3(0, static_cast<float> (a), static_cast<float> (atan2(self[1], self[5])));
01108     }
01109 }
01110 
01112 inline Vector3 matrix4_get_rotation_euler_zyx_degrees (const Matrix4& self)
01113 {
01114     return euler_radians_to_degrees(matrix4_get_rotation_euler_zyx(self));
01115 }
01116 
01118 inline void matrix4_pivoted_rotate_by_euler_xyz_degrees (Matrix4& self, const Vector3& euler, const Vector3& pivotpoint)
01119 {
01120     matrix4_translate_by_vec3(self, pivotpoint);
01121     matrix4_rotate_by_euler_xyz_degrees(self, euler);
01122     matrix4_translate_by_vec3(self, -pivotpoint);
01123 }
01124 
01126 inline Matrix4 matrix4_scale_for_vec3 (const Vector3& scale)
01127 {
01128     return Matrix4(scale[0], 0, 0, 0, 0, scale[1], 0, 0, 0, 0, scale[2], 0, 0, 0, 0, 1);
01129 }
01130 
01133 inline Vector3 matrix4_get_scale_vec3 (const Matrix4& self)
01134 {
01135     return Vector3(static_cast<float> (self.x().getVector3().getLength()),
01136             static_cast<float> (self.y().getVector3().getLength()),
01137             static_cast<float> (self.z().getVector3().getLength()));
01138 }
01139 
01141 inline void matrix4_scale_by_vec3 (Matrix4& self, const Vector3& scale)
01142 {
01143     matrix4_multiply_by_matrix4(self, matrix4_scale_for_vec3(scale));
01144 }
01145 
01147 inline void matrix4_pivoted_scale_by_vec3 (Matrix4& self, const Vector3& scale, const Vector3& pivotpoint)
01148 {
01149     matrix4_translate_by_vec3(self, pivotpoint);
01150     matrix4_scale_by_vec3(self, scale);
01151     matrix4_translate_by_vec3(self, -pivotpoint);
01152 }
01153 
01156 inline void matrix4_transform_by_euler_xyz_degrees (Matrix4& self, const Vector3& translation, const Vector3& euler,
01157         const Vector3& scale)
01158 {
01159     matrix4_translate_by_vec3(self, translation);
01160     matrix4_rotate_by_euler_xyz_degrees(self, euler);
01161     matrix4_scale_by_vec3(self, scale);
01162 }
01163 
01165 inline void matrix4_pivoted_transform_by_euler_xyz_degrees (Matrix4& self, const Vector3& translation,
01166         const Vector3& euler, const Vector3& scale, const Vector3& pivotpoint)
01167 {
01168     matrix4_translate_by_vec3(self, pivotpoint + translation);
01169     matrix4_rotate_by_euler_xyz_degrees(self, euler);
01170     matrix4_scale_by_vec3(self, scale);
01171     matrix4_translate_by_vec3(self, -pivotpoint);
01172 }
01173 
01174 #endif

Generated by  doxygen 1.6.2