00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00040 Matrix4 ()
00041 {
00042 }
00043
00044
00045
00046
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
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
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
00566
00567
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
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)
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
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)
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
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)
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
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)
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
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