Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #ifndef Matrix4_INCLUDE_ONCE 00033 #define Matrix4_INCLUDE_ONCE 00034 00035 #include <vlCore/Vector4.hpp> 00036 #include <vlCore/Matrix3.hpp> 00037 00038 namespace vl 00039 { 00040 //----------------------------------------------------------------------------- 00041 // Matrix4 00042 //----------------------------------------------------------------------------- 00047 template<typename T_Scalar> 00048 class Matrix4 00049 { 00050 public: 00051 typedef T_Scalar scalar_type; 00052 //----------------------------------------------------------------------------- 00053 template<typename T> 00054 explicit Matrix4(const Matrix4<T>& m) 00055 { 00056 e(0,0) = (T_Scalar)m.e(0,0); e(1,0) = (T_Scalar)m.e(1,0); e(2,0) = (T_Scalar)m.e(2,0); e(3,0) = (T_Scalar)m.e(3,0); 00057 e(0,1) = (T_Scalar)m.e(0,1); e(1,1) = (T_Scalar)m.e(1,1); e(2,1) = (T_Scalar)m.e(2,1); e(3,1) = (T_Scalar)m.e(3,1); 00058 e(0,2) = (T_Scalar)m.e(0,2); e(1,2) = (T_Scalar)m.e(1,2); e(2,2) = (T_Scalar)m.e(2,2); e(3,2) = (T_Scalar)m.e(3,2); 00059 e(0,3) = (T_Scalar)m.e(0,3); e(1,3) = (T_Scalar)m.e(1,3); e(2,3) = (T_Scalar)m.e(2,3); e(3,3) = (T_Scalar)m.e(3,3); 00060 } 00061 //----------------------------------------------------------------------------- 00062 Matrix4() 00063 { 00064 setIdentity(); 00065 } 00066 //----------------------------------------------------------------------------- 00067 explicit Matrix4(T_Scalar n) 00068 { 00069 setIdentity(); 00070 e(0,0) = e(1,1) = e(2,2) = e(3,3) = n; 00071 } 00072 //----------------------------------------------------------------------------- 00073 explicit Matrix4(T_Scalar* val) 00074 { 00075 fillPtr(val); 00076 } 00077 //----------------------------------------------------------------------------- 00078 explicit Matrix4( T_Scalar e00, T_Scalar e01, T_Scalar e02, T_Scalar e03, 00079 T_Scalar e10, T_Scalar e11, T_Scalar e12, T_Scalar e13, 00080 T_Scalar e20, T_Scalar e21, T_Scalar e22, T_Scalar e23, 00081 T_Scalar e30, T_Scalar e31, T_Scalar e32, T_Scalar e33) 00082 { 00083 e(0,0) = e00; e(0,1) = e01; e(0,2) = e02; e(0,3) = e03; 00084 e(1,0) = e10; e(1,1) = e11; e(1,2) = e12; e(1,3) = e13; 00085 e(2,0) = e20; e(2,1) = e21; e(2,2) = e22; e(2,3) = e23; 00086 e(3,0) = e30; e(3,1) = e31; e(3,2) = e32; e(3,3) = e33; 00087 } 00088 //----------------------------------------------------------------------------- 00089 Matrix4& fill(T_Scalar val) 00090 { 00091 e(0,0) = e(1,0) = e(2,0) = e(3,0) = 00092 e(0,1) = e(1,1) = e(2,1) = e(3,1) = 00093 e(0,2) = e(1,2) = e(2,2) = e(3,2) = 00094 e(0,3) = e(1,3) = e(2,3) = e(3,3) = val; 00095 return *this; 00096 } 00097 //----------------------------------------------------------------------------- 00098 Matrix4& fillPtr(T_Scalar* val) 00099 { 00100 memcpy(ptr(), val, sizeof(T_Scalar)*16); 00101 return *this; 00102 } 00103 //----------------------------------------------------------------------------- 00104 T_Scalar diff(const Matrix4& other) const 00105 { 00106 T_Scalar err = 0; 00107 for(int i=0; i<4; ++i) 00108 for(int j=0; j<4; ++j) 00109 if (e(j,i) > other.e(j,i)) // avoid fabs/abs 00110 err += e(j,i) - other.e(j,i); 00111 else 00112 err += other.e(j,i) - e(j,i); 00113 return err; 00114 } 00115 //----------------------------------------------------------------------------- 00116 Vector3<T_Scalar> getX() const 00117 { 00118 return Vector3<T_Scalar>(mVec[0].x(), mVec[0].y(), mVec[0].z()); 00119 } 00120 //----------------------------------------------------------------------------- 00121 Vector3<T_Scalar> getY() const 00122 { 00123 return Vector3<T_Scalar>(mVec[1].x(), mVec[1].y(), mVec[1].z()); 00124 } 00125 //----------------------------------------------------------------------------- 00126 Vector3<T_Scalar> getZ() const 00127 { 00128 return Vector3<T_Scalar>(mVec[2].x(), mVec[2].y(), mVec[2].z()); 00129 } 00130 //----------------------------------------------------------------------------- 00131 Vector3<T_Scalar> getT() const 00132 { 00133 return Vector3<T_Scalar>(mVec[3].x(), mVec[3].y(), mVec[3].z()); 00134 } 00135 //----------------------------------------------------------------------------- 00136 Matrix4& setX(const Vector3<T_Scalar>& v) 00137 { 00138 mVec[0].x() = v.x(); 00139 mVec[0].y() = v.y(); 00140 mVec[0].z() = v.z(); 00141 return *this; 00142 } 00143 //----------------------------------------------------------------------------- 00144 Matrix4& setY(const Vector3<T_Scalar>& v) 00145 { 00146 mVec[1].x() = v.x(); 00147 mVec[1].y() = v.y(); 00148 mVec[1].z() = v.z(); 00149 return *this; 00150 } 00151 //----------------------------------------------------------------------------- 00152 Matrix4& setZ(const Vector3<T_Scalar>& v) 00153 { 00154 mVec[2].x() = v.x(); 00155 mVec[2].y() = v.y(); 00156 mVec[2].z() = v.z(); 00157 return *this; 00158 } 00159 //----------------------------------------------------------------------------- 00160 Matrix4& setT(const Vector3<T_Scalar>& v) 00161 { 00162 mVec[3].x() = v.x(); 00163 mVec[3].y() = v.y(); 00164 mVec[3].z() = v.z(); 00165 return *this; 00166 } 00167 //----------------------------------------------------------------------------- 00168 bool operator==(const Matrix4& m) const 00169 { 00170 return memcmp(m.mVec, mVec, sizeof(T_Scalar)*4*4) == 0; 00171 } 00172 //----------------------------------------------------------------------------- 00173 bool operator!=(const Matrix4& m) const 00174 { 00175 return !operator==(m); 00176 } 00177 //----------------------------------------------------------------------------- 00178 Matrix4& operator=(const Matrix4& m) 00179 { 00180 memcpy(mVec, m.mVec, sizeof(T_Scalar)*16); 00181 return *this; 00182 } 00183 //----------------------------------------------------------------------------- 00184 Matrix4 operator+(const Matrix4& m) const 00185 { 00186 Matrix4 t; 00187 for(int i=0; i<4; ++i) 00188 for(int j=0; j<4; ++j) 00189 t.e(j,i) = e(j,i) + m.e(j,i); 00190 00191 return t; 00192 } 00193 //----------------------------------------------------------------------------- 00194 Matrix4& operator+=(const Matrix4& m) 00195 { 00196 for(int i=0; i<4; ++i) 00197 for(int j=0; j<4; ++j) 00198 e(j,i) += m.e(i,j); 00199 return *this; 00200 } 00201 //----------------------------------------------------------------------------- 00202 Matrix4 operator-(const Matrix4& m) const 00203 { 00204 Matrix4 t; 00205 for(int i=0; i<4; ++i) 00206 for(int j=0; j<4; ++j) 00207 t.e(j,i) = e(j,i) - m.e(j,i); 00208 00209 return t; 00210 } 00211 //----------------------------------------------------------------------------- 00212 Matrix4& operator-=(const Matrix4& m) 00213 { 00214 for(int i=0; i<4; ++i) 00215 for(int j=0; j<4; ++j) 00216 e(j,i) -= m.e(i,j); 00217 return *this; 00218 } 00219 //----------------------------------------------------------------------------- 00220 Matrix4& operator*=(const Matrix4& m) 00221 { 00222 return postMultiply(m); 00223 } 00224 //----------------------------------------------------------------------------- 00225 Matrix4 operator-() const 00226 { 00227 Matrix4 t; 00228 for(int i=0; i<4; ++i) 00229 for(int j=0; j<4; ++j) 00230 t.e(j,i) = -e(j,i); 00231 return t; 00232 } 00233 //----------------------------------------------------------------------------- 00234 Matrix4 operator+(T_Scalar d) const 00235 { 00236 Matrix4 t; 00237 for(int i=0; i<4; ++i) 00238 for(int j=0; j<4; ++j) 00239 t.e(j,i) = e(j,i) + d; 00240 return t; 00241 } 00242 //----------------------------------------------------------------------------- 00243 Matrix4& operator+=(T_Scalar d) 00244 { 00245 for(int i=0; i<4; ++i) 00246 for(int j=0; j<4; ++j) 00247 e(j,i) += d; 00248 return *this; 00249 } 00250 //----------------------------------------------------------------------------- 00251 Matrix4 operator-(T_Scalar d) const 00252 { 00253 Matrix4 t; 00254 for(int i=0; i<4; ++i) 00255 for(int j=0; j<4; ++j) 00256 t.e(j,i) = e(j,i) - d; 00257 return t; 00258 } 00259 //----------------------------------------------------------------------------- 00260 Matrix4& operator-=(T_Scalar d) 00261 { 00262 for(int i=0; i<4; ++i) 00263 for(int j=0; j<4; ++j) 00264 e(j,i) -= d; 00265 return *this; 00266 } 00267 //----------------------------------------------------------------------------- 00268 Matrix4 operator*(T_Scalar d) const 00269 { 00270 Matrix4 t; 00271 for(int i=0; i<4; ++i) 00272 for(int j=0; j<4; ++j) 00273 t.e(j,i) = e(j,i) * d; 00274 return t; 00275 } 00276 //----------------------------------------------------------------------------- 00277 Matrix4& operator*=(T_Scalar d) 00278 { 00279 for(int i=0; i<4; ++i) 00280 for(int j=0; j<4; ++j) 00281 e(j,i) *= d; 00282 return *this; 00283 } 00284 //----------------------------------------------------------------------------- 00285 Matrix4 operator/(T_Scalar d) const 00286 { 00287 d = (T_Scalar)1 / d; 00288 Matrix4 t; 00289 for(int i=0; i<4; ++i) 00290 for(int j=0; j<4; ++j) 00291 t.e(j,i) = e(j,i) * d; 00292 return t; 00293 } 00294 //----------------------------------------------------------------------------- 00295 Matrix4& operator/=(T_Scalar d) 00296 { 00297 d = (T_Scalar)1 / d; 00298 for(int i=0; i<4; ++i) 00299 for(int j=0; j<4; ++j) 00300 e(j,i) *= d; 00301 return *this; 00302 } 00303 //----------------------------------------------------------------------------- 00304 bool isIdentity() const 00305 { 00306 Matrix4 i; 00307 return memcmp(ptr(), i.ptr(), sizeof(T_Scalar)*16) == 0; 00308 } 00309 //----------------------------------------------------------------------------- 00310 Matrix4 as3x3() const 00311 { 00312 Matrix4 t = *this; 00313 t[0][3] = 0; 00314 t[1][3] = 0; 00315 t[2][3] = 0; 00316 t[3][3] = 1; 00317 t[3][0] = 0; 00318 t[3][1] = 0; 00319 t[3][2] = 0; 00320 return t; 00321 } 00322 //----------------------------------------------------------------------------- 00323 Matrix3<T_Scalar> get3x3() const 00324 { 00325 Matrix3<T_Scalar> t; 00326 t.e(0,0) = e(0,0); t.e(1,0) = e(1,0); t.e(2,0) = e(2,0); 00327 t.e(0,1) = e(0,1); t.e(1,1) = e(1,1); t.e(2,1) = e(2,1); 00328 t.e(0,2) = e(0,2); t.e(1,2) = e(1,2); t.e(2,2) = e(2,2); 00329 return t; 00330 } 00331 //----------------------------------------------------------------------------- 00333 void set3x3(const Matrix3<T_Scalar>& m) 00334 { 00335 e(0,0) = m.e(0,0); e(1,0) = m.e(1,0); e(2,0) = m.e(2,0); 00336 e(0,1) = m.e(0,1); e(1,1) = m.e(1,1); e(2,1) = m.e(2,1); 00337 e(0,2) = m.e(0,2); e(1,2) = m.e(1,2); e(2,2) = m.e(2,2); 00338 } 00339 //----------------------------------------------------------------------------- 00340 T_Scalar* ptr() 00341 { 00342 return &e(0,0); 00343 } 00344 //----------------------------------------------------------------------------- 00345 const T_Scalar* ptr() const 00346 { 00347 return &e(0,0); 00348 } 00349 //----------------------------------------------------------------------------- 00350 Matrix4& transpose() 00351 { 00352 T_Scalar tmp; 00353 for(int i=0; i<4; ++i) 00354 for(int j=i; j<4; ++j) 00355 { 00356 tmp = e(j,i); 00357 e(j,i) = e(i,j); 00358 e(i,j) = tmp; 00359 } 00360 return *this; 00361 } 00362 //----------------------------------------------------------------------------- 00363 Matrix4 getTransposed() const 00364 { 00365 Matrix4 m; 00366 for(int i=0; i<4; ++i) 00367 for(int j=0; j<4; ++j) 00368 m.e(j,i) = e(i,j); 00369 return m; 00370 } 00371 //----------------------------------------------------------------------------- 00372 Matrix4& getTransposed(Matrix4& dest) const 00373 { 00374 for(int i=0; i<4; ++i) 00375 for(int j=0; j<4; ++j) 00376 dest.e(j,i) = e(i,j); 00377 return dest; 00378 } 00379 //----------------------------------------------------------------------------- 00380 bool isNull() const 00381 { 00382 for(int i=0; i<4; ++i) 00383 for(int j=0; j<4; ++j) 00384 if(e(i,j) != 0) 00385 return false; 00386 return true; 00387 } 00388 //----------------------------------------------------------------------------- 00389 Matrix4& setNull() 00390 { 00391 fill(0); 00392 return *this; 00393 } 00394 //----------------------------------------------------------------------------- 00395 static Matrix4& getNull(Matrix4& out) 00396 { 00397 out.fill(0); 00398 return out; 00399 } 00400 //----------------------------------------------------------------------------- 00401 static Matrix4 getNull() 00402 { 00403 return Matrix4().fill(0); 00404 } 00405 //----------------------------------------------------------------------------- 00406 Matrix4& setIdentity() 00407 { 00408 static const T_Scalar I4d[] = 00409 { 00410 (T_Scalar)1, (T_Scalar)0, (T_Scalar)0, (T_Scalar)0, 00411 (T_Scalar)0, (T_Scalar)1, (T_Scalar)0, (T_Scalar)0, 00412 (T_Scalar)0, (T_Scalar)0, (T_Scalar)1, (T_Scalar)0, 00413 (T_Scalar)0, (T_Scalar)0, (T_Scalar)0, (T_Scalar)1 00414 }; 00415 memcpy(mVec, I4d, sizeof(T_Scalar)*16); 00416 return *this; 00417 } 00418 //----------------------------------------------------------------------------- 00419 static Matrix4 getIdentity() 00420 { 00421 return Matrix4(); 00422 } 00423 //----------------------------------------------------------------------------- 00424 static Matrix4& getIdentity(Matrix4& out) 00425 { 00426 out.setIdentity(); 00427 return out; 00428 } 00429 //----------------------------------------------------------------------------- 00430 T_Scalar getInverse(Matrix4& dest) const; 00431 //----------------------------------------------------------------------------- 00432 Matrix4 getInverse(T_Scalar *determinant=NULL) const 00433 { 00434 Matrix4 tmp; 00435 T_Scalar det = getInverse(tmp); 00436 if (determinant) 00437 *determinant = det; 00438 return tmp; 00439 } 00440 //----------------------------------------------------------------------------- 00441 Matrix4& invert(T_Scalar *determinant=NULL) 00442 { 00443 T_Scalar det = getInverse(*this); 00444 if (determinant) 00445 *determinant = det; 00446 return *this; 00447 } 00448 //----------------------------------------------------------------------------- 00449 static Matrix4 getPerspective(T_Scalar fovy, T_Scalar aspect_ratio, T_Scalar znear, T_Scalar zfar); 00450 //----------------------------------------------------------------------------- 00451 static Matrix4 getFrustum(T_Scalar pleft, T_Scalar pright, T_Scalar pbottom, T_Scalar ptop, T_Scalar pnear, T_Scalar pfar); 00452 //----------------------------------------------------------------------------- 00453 static Matrix4 getOrtho(T_Scalar pleft, T_Scalar pright, T_Scalar pbottom, T_Scalar ptop, T_Scalar pnear, T_Scalar pfar); 00454 //----------------------------------------------------------------------------- 00455 static Matrix4 getOrtho2D(T_Scalar pleft, T_Scalar pright, T_Scalar pbottom, T_Scalar ptop); 00456 //----------------------------------------------------------------------------- 00457 static Matrix4 getLookAtModeling(const Vector3<T_Scalar>& eye, const Vector3<T_Scalar>& at, const Vector3<T_Scalar>& up); 00458 //----------------------------------------------------------------------------- 00459 static Matrix4 getLookAt(const Vector3<T_Scalar>& eye, const Vector3<T_Scalar>& at, const Vector3<T_Scalar>& up); 00460 //----------------------------------------------------------------------------- 00461 void getAsLookAtModeling(Vector3<T_Scalar>& eye, Vector3<T_Scalar>& at, Vector3<T_Scalar>& up, Vector3<T_Scalar>& right) const; 00462 //----------------------------------------------------------------------------- 00463 void getAsLookAt(Vector3<T_Scalar>& eye, Vector3<T_Scalar>& at, Vector3<T_Scalar>& up, Vector3<T_Scalar>& right) const; 00464 //----------------------------------------------------------------------------- 00465 void getYXRotationAngles(T_Scalar& degrees_y, T_Scalar& degrees_x) const; 00466 //----------------------------------------------------------------------------- 00467 static Matrix4& getRotation(Matrix4& out, T_Scalar degrees, T_Scalar x, T_Scalar y, T_Scalar z); 00468 //----------------------------------------------------------------------------- 00469 static Matrix4 getRotation(T_Scalar degrees, T_Scalar x, T_Scalar y, T_Scalar z) 00470 { 00471 Matrix4 m; 00472 return getRotation(m, degrees, x, y, z); 00473 } 00474 //----------------------------------------------------------------------------- 00475 static Matrix4 getRotation(T_Scalar degrees, const Vector3<T_Scalar>& v) 00476 { 00477 return getRotation(degrees, v.x(), v.y(), v.z()); 00478 } 00479 //----------------------------------------------------------------------------- 00480 static Matrix4 getRotation(T_Scalar degrees1, const Vector3<T_Scalar>& v1, T_Scalar degrees2, const Vector3<T_Scalar>& v2) 00481 { 00482 return getRotation(degrees1, v1.x(), v1.y(), v1.z()) * getRotation(degrees2, v2.x(), v2.y(), v2.z()); 00483 } 00484 //----------------------------------------------------------------------------- 00485 static Matrix4 getRotation(T_Scalar degrees1, const Vector3<T_Scalar>& v1, T_Scalar degrees2, const Vector3<T_Scalar>& v2, T_Scalar degrees3, const Vector3<T_Scalar>& v3) 00486 { 00487 return getRotation(degrees1, v1.x(), v1.y(), v1.z()) * getRotation(degrees2, v2.x(), v2.y(), v2.z()) * getRotation(degrees3, v3.x(), v3.y(), v3.z()); 00488 } 00489 //----------------------------------------------------------------------------- 00490 Matrix4& rotate(T_Scalar degrees, const Vector3<T_Scalar>& v) 00491 { 00492 return rotate(degrees, v.x(), v.y(), v.z()); 00493 } 00494 //----------------------------------------------------------------------------- 00495 Matrix4& rotate(T_Scalar degrees, T_Scalar x, T_Scalar y, T_Scalar z) 00496 { 00497 return preMultiply(getRotation(degrees, x, y, z)); 00498 } 00499 //----------------------------------------------------------------------------- 00500 Matrix4& rotate(T_Scalar degrees1, const Vector3<T_Scalar>& v1, T_Scalar degrees2, const Vector3<T_Scalar>& v2) 00501 { 00502 return preMultiply(getRotation(degrees1, v1, degrees2, v2)); 00503 } 00504 //----------------------------------------------------------------------------- 00505 Matrix4& rotate(T_Scalar degrees1, const Vector3<T_Scalar>& v1, T_Scalar degrees2, const Vector3<T_Scalar>& v2, T_Scalar degrees3, const Vector3<T_Scalar>& v3) 00506 { 00507 return preMultiply(getRotation(degrees1, v1, degrees2, v2, degrees3, v3)); 00508 } 00509 //----------------------------------------------------------------------------- 00510 static Matrix4 getRotationXYZ(T_Scalar degX, T_Scalar degY, T_Scalar degZ) 00511 { 00512 return getRotation(degX, 1,0,0) * getRotation(degY, 0,1,0) * getRotation(degZ, 0,0,1); 00513 } 00514 //----------------------------------------------------------------------------- 00515 Matrix4& rotateXYZ(T_Scalar degX, T_Scalar degY, T_Scalar degZ) 00516 { 00517 return preMultiply(getRotationXYZ(degX, degY, degZ)); 00518 } 00519 //----------------------------------------------------------------------------- 00520 static Matrix4 getRotationZYX(T_Scalar degZ, T_Scalar degY, T_Scalar degX) 00521 { 00522 return getRotation(degZ, 0,0,1) * getRotation(degY, 0,1,0) * getRotation(degX, 1,0,0); 00523 } 00524 //----------------------------------------------------------------------------- 00525 Matrix4& rotateZYX(T_Scalar degZ, T_Scalar degY, T_Scalar degX) 00526 { 00527 return preMultiply(getRotationZYX(degZ, degY, degX)); 00528 } 00529 //----------------------------------------------------------------------------- 00530 static Matrix4& getRotation(Matrix4& out, const Vector3<T_Scalar>& from, const Vector3<T_Scalar>& to); 00531 //----------------------------------------------------------------------------- 00532 static Matrix4 getRotation(const Vector3<T_Scalar>& from, const Vector3<T_Scalar>& to) 00533 { 00534 Matrix4 m; 00535 return getRotation(m, from, to); 00536 } 00537 //----------------------------------------------------------------------------- 00538 Matrix4& rotate(const Vector4<T_Scalar>& from, const Vector4<T_Scalar>& to) 00539 { 00540 return preMultiply(getRotation(from, to)); 00541 } 00542 //----------------------------------------------------------------------------- 00543 Matrix4& rotate(const Vector3<T_Scalar>& from, const Vector3<T_Scalar>& to) 00544 { 00545 return preMultiply(getRotation(from, to)); 00546 } 00547 //----------------------------------------------------------------------------- 00548 static Matrix4& getTranslation(Matrix4&out, const Vector3<T_Scalar>& v) 00549 { 00550 return getTranslation(out, v.x(), v.y(), v.z()); 00551 } 00552 //----------------------------------------------------------------------------- 00553 static Matrix4 getTranslation(const Vector3<T_Scalar>& v) 00554 { 00555 Matrix4 m; 00556 return getTranslation(m, v.x(), v.y(), v.z()); 00557 } 00558 //----------------------------------------------------------------------------- 00559 static Matrix4 getTranslation(T_Scalar x, T_Scalar y, T_Scalar z) 00560 { 00561 Matrix4 m; 00562 return getTranslation(m, x, y, z); 00563 } 00564 //----------------------------------------------------------------------------- 00565 static Matrix4& getTranslation(Matrix4& out, T_Scalar x, T_Scalar y, T_Scalar z) 00566 { 00567 out.setIdentity(); 00568 out.e(0,3) = x; 00569 out.e(1,3) = y; 00570 out.e(2,3) = z; 00571 return out; 00572 } 00573 //----------------------------------------------------------------------------- 00574 Matrix4& translate(T_Scalar x, T_Scalar y, T_Scalar z) 00575 { 00576 return preMultiply(getTranslation(x,y,z)); 00577 } 00578 //----------------------------------------------------------------------------- 00579 Matrix4& translate(const Vector3<T_Scalar>& v) 00580 { 00581 return preMultiply(getTranslation(v)); 00582 } 00583 //----------------------------------------------------------------------------- 00584 static Matrix4& getScaling(Matrix4& out, const Vector3<T_Scalar>& v) 00585 { 00586 return getScaling(out, v.x(), v.y(), v.z()); 00587 } 00588 //----------------------------------------------------------------------------- 00589 static Matrix4 getScaling(const Vector3<T_Scalar>& v) 00590 { 00591 Matrix4 m; 00592 return getScaling(m, v.x(), v.y(), v.z()); 00593 } 00594 //----------------------------------------------------------------------------- 00595 static Matrix4 getScaling(T_Scalar x, T_Scalar y, T_Scalar z) 00596 { 00597 Matrix4 m; 00598 return getScaling(m, x, y, z); 00599 } 00600 //----------------------------------------------------------------------------- 00601 static Matrix4& getScaling(Matrix4& out, T_Scalar x, T_Scalar y, T_Scalar z) 00602 { 00603 out.setIdentity(); 00604 out.e(0,0) = x; 00605 out.e(1,1) = y; 00606 out.e(2,2) = z; 00607 return out; 00608 } 00609 //----------------------------------------------------------------------------- 00610 Matrix4& scale(T_Scalar x, T_Scalar y, T_Scalar z) 00611 { 00612 return preMultiply(getScaling(x,y,z)); 00613 } 00614 //----------------------------------------------------------------------------- 00615 Matrix4& scale(const Vector3<T_Scalar> v) 00616 { 00617 return preMultiply(getScaling(v.x(), v.y(), v.z())); 00618 } 00619 //----------------------------------------------------------------------------- 00620 static Matrix4& multiply(Matrix4& out, const Matrix4& p, const Matrix4& q) 00621 { 00622 VL_CHECK(out.ptr() != p.ptr() && out.ptr() != q.ptr()); 00623 00624 out.e(0,0) = q.e(0,0)*p.e(0,0) + q.e(1,0)*p.e(0,1) + q.e(2,0)*p.e(0,2) + q.e(3,0)*p.e(0,3); 00625 out.e(0,1) = q.e(0,1)*p.e(0,0) + q.e(1,1)*p.e(0,1) + q.e(2,1)*p.e(0,2) + q.e(3,1)*p.e(0,3); 00626 out.e(0,2) = q.e(0,2)*p.e(0,0) + q.e(1,2)*p.e(0,1) + q.e(2,2)*p.e(0,2) + q.e(3,2)*p.e(0,3); 00627 out.e(0,3) = q.e(0,3)*p.e(0,0) + q.e(1,3)*p.e(0,1) + q.e(2,3)*p.e(0,2) + q.e(3,3)*p.e(0,3); 00628 00629 out.e(1,0) = q.e(0,0)*p.e(1,0) + q.e(1,0)*p.e(1,1) + q.e(2,0)*p.e(1,2) + q.e(3,0)*p.e(1,3); 00630 out.e(1,1) = q.e(0,1)*p.e(1,0) + q.e(1,1)*p.e(1,1) + q.e(2,1)*p.e(1,2) + q.e(3,1)*p.e(1,3); 00631 out.e(1,2) = q.e(0,2)*p.e(1,0) + q.e(1,2)*p.e(1,1) + q.e(2,2)*p.e(1,2) + q.e(3,2)*p.e(1,3); 00632 out.e(1,3) = q.e(0,3)*p.e(1,0) + q.e(1,3)*p.e(1,1) + q.e(2,3)*p.e(1,2) + q.e(3,3)*p.e(1,3); 00633 00634 out.e(2,0) = q.e(0,0)*p.e(2,0) + q.e(1,0)*p.e(2,1) + q.e(2,0)*p.e(2,2) + q.e(3,0)*p.e(2,3); 00635 out.e(2,1) = q.e(0,1)*p.e(2,0) + q.e(1,1)*p.e(2,1) + q.e(2,1)*p.e(2,2) + q.e(3,1)*p.e(2,3); 00636 out.e(2,2) = q.e(0,2)*p.e(2,0) + q.e(1,2)*p.e(2,1) + q.e(2,2)*p.e(2,2) + q.e(3,2)*p.e(2,3); 00637 out.e(2,3) = q.e(0,3)*p.e(2,0) + q.e(1,3)*p.e(2,1) + q.e(2,3)*p.e(2,2) + q.e(3,3)*p.e(2,3); 00638 00639 out.e(3,0) = q.e(0,0)*p.e(3,0) + q.e(1,0)*p.e(3,1) + q.e(2,0)*p.e(3,2) + q.e(3,0)*p.e(3,3); 00640 out.e(3,1) = q.e(0,1)*p.e(3,0) + q.e(1,1)*p.e(3,1) + q.e(2,1)*p.e(3,2) + q.e(3,1)*p.e(3,3); 00641 out.e(3,2) = q.e(0,2)*p.e(3,0) + q.e(1,2)*p.e(3,1) + q.e(2,2)*p.e(3,2) + q.e(3,2)*p.e(3,3); 00642 out.e(3,3) = q.e(0,3)*p.e(3,0) + q.e(1,3)*p.e(3,1) + q.e(2,3)*p.e(3,2) + q.e(3,3)*p.e(3,3); 00643 00644 return out; 00645 } 00646 //----------------------------------------------------------------------------- 00647 Matrix4& postMultiply(const Matrix4& m) 00648 { 00649 Matrix4<T_Scalar> t; 00650 return *this = multiply(t, *this, m); 00651 } 00652 //----------------------------------------------------------------------------- 00653 Matrix4& preMultiply(const Matrix4& m) 00654 { 00655 Matrix4<T_Scalar> t; 00656 return *this = multiply(t, m, *this); 00657 } 00658 //----------------------------------------------------------------------------- 00659 00660 const T_Scalar& e(int i, int j) const { return mVec[j][i]; } 00661 T_Scalar& e(int i, int j) { return mVec[j][i]; } 00662 00663 private: 00664 const Vector4<T_Scalar>& operator[](unsigned int i) const { VL_CHECK(i<4); return mVec[i]; } 00665 Vector4<T_Scalar>& operator[](unsigned int i) { VL_CHECK(i<4); return mVec[i]; } 00666 00667 protected: 00668 Vector4<T_Scalar> mVec[4]; 00669 }; 00670 //----------------------------------------------------------------------------- 00671 // OPERATORS 00672 //----------------------------------------------------------------------------- 00673 template<typename T_Scalar> 00674 inline Matrix4<T_Scalar> operator*(const Matrix4<T_Scalar>& p, const Matrix4<T_Scalar>& q) 00675 { 00676 Matrix4<T_Scalar> t; 00677 Matrix4<T_Scalar>::multiply(t, p, q); 00678 return t; 00679 } 00680 //----------------------------------------------------------------------------- 00681 template<typename T_Scalar> 00682 inline Matrix4<T_Scalar> operator+(T_Scalar d, const Matrix4<T_Scalar>& m) 00683 { 00684 return m + d; 00685 } 00686 //----------------------------------------------------------------------------- 00687 template<typename T_Scalar> 00688 inline Matrix4<T_Scalar> operator*(T_Scalar d, const Matrix4<T_Scalar>& m) 00689 { 00690 return m * d; 00691 } 00692 //----------------------------------------------------------------------------- 00694 template<typename T_Scalar> 00695 inline Vector4<T_Scalar> operator*(const Matrix4<T_Scalar>& m, const Vector4<T_Scalar>& v) 00696 { 00697 return Vector4<T_Scalar>( 00698 v.x()*m.e(0,0) + v.y()*m.e(0,1) + v.z()*m.e(0,2) + v.w()*m.e(0,3), 00699 v.x()*m.e(1,0) + v.y()*m.e(1,1) + v.z()*m.e(1,2) + v.w()*m.e(1,3), 00700 v.x()*m.e(2,0) + v.y()*m.e(2,1) + v.z()*m.e(2,2) + v.w()*m.e(2,3), 00701 v.x()*m.e(3,0) + v.y()*m.e(3,1) + v.z()*m.e(3,2) + v.w()*m.e(3,3) 00702 ); 00703 } 00704 //----------------------------------------------------------------------------- 00707 template<typename T_Scalar> 00708 inline Vector3<T_Scalar> operator*(const Matrix4<T_Scalar>& m, const Vector3<T_Scalar>& v) 00709 { 00710 return Vector3<T_Scalar>( 00711 v.x()*m.e(0,0) + v.y()*m.e(0,1) + v.z()*m.e(0,2) + /*1**/m.e(0,3), 00712 v.x()*m.e(1,0) + v.y()*m.e(1,1) + v.z()*m.e(1,2) + /*1**/m.e(1,3), 00713 v.x()*m.e(2,0) + v.y()*m.e(2,1) + v.z()*m.e(2,2) + /*1**/m.e(2,3) 00714 ); 00715 } 00716 //----------------------------------------------------------------------------- 00719 template<typename T_Scalar> 00720 inline Vector2<T_Scalar> operator*(const Matrix4<T_Scalar>& m, const Vector2<T_Scalar>& v) 00721 { 00722 return Vector2<T_Scalar>( 00723 v.x()*m.e(0,0) + v.y()*m.e(0,1) + /*0*m.e(0,2) +*/ /*1**/m.e(0,3), 00724 v.x()*m.e(1,0) + v.y()*m.e(1,1) + /*0*m.e(1,2) +*/ /*1**/m.e(1,3) 00725 ); 00726 } 00727 //----------------------------------------------------------------------------- 00729 template<typename T_Scalar> 00730 inline Vector4<T_Scalar> operator*(const Vector4<T_Scalar>& v, const Matrix4<T_Scalar>& m) 00731 { 00732 return Vector4<T_Scalar>( 00733 v.x()*m.e(0,0) + v.y()*m.e(1,0) + v.z()*m.e(2,0) + v.w()*m.e(3,0), 00734 v.x()*m.e(0,1) + v.y()*m.e(1,1) + v.z()*m.e(2,1) + v.w()*m.e(3,1), 00735 v.x()*m.e(0,2) + v.y()*m.e(1,2) + v.z()*m.e(2,2) + v.w()*m.e(3,2), 00736 v.x()*m.e(0,3) + v.y()*m.e(1,3) + v.z()*m.e(2,3) + v.w()*m.e(3,3) 00737 ); 00738 } 00739 //----------------------------------------------------------------------------- 00742 template<typename T_Scalar> 00743 inline Vector3<T_Scalar> operator*(const Vector3<T_Scalar>& v, const Matrix4<T_Scalar>& m) 00744 { 00745 return Vector3<T_Scalar>( 00746 v.x()*m.e(0,0) + v.y()*m.e(1,0) + v.z()*m.e(2,0) + /*1**/m.e(3,0), 00747 v.x()*m.e(0,1) + v.y()*m.e(1,1) + v.z()*m.e(2,1) + /*1**/m.e(3,1), 00748 v.x()*m.e(0,2) + v.y()*m.e(1,2) + v.z()*m.e(2,2) + /*1**/m.e(3,2) 00749 ); 00750 } 00751 //----------------------------------------------------------------------------- 00754 template<typename T_Scalar> 00755 inline Vector2<T_Scalar> operator*(const Vector2<T_Scalar>& v, const Matrix4<T_Scalar>& m) 00756 { 00757 return Vector2<T_Scalar>( 00758 v.x()*m.e(0,0) + v.y()*m.e(1,0) + /*0*m.e(2,0) +*/ /*1**/m.e(3,0), 00759 v.x()*m.e(0,1) + v.y()*m.e(1,1) + /*0*m.e(2,1) +*/ /*1**/m.e(3,1) 00760 ); 00761 } 00762 //----------------------------------------------------------------------------- 00763 template<typename T_Scalar> 00764 Matrix4<T_Scalar> Matrix4<T_Scalar>::getLookAtModeling(const Vector3<T_Scalar>& eye, const Vector3<T_Scalar>& at, const Vector3<T_Scalar>& up) 00765 { 00766 Vector3<T_Scalar> zaxis = (eye-at).normalize(); 00767 Vector3<T_Scalar> xaxis = cross(up, zaxis).normalize(); 00768 Vector3<T_Scalar> yaxis = cross(zaxis, xaxis); 00769 00770 // look at modeling 00771 T_Scalar la_modeling[] = 00772 { 00773 xaxis.x() , xaxis.y() , xaxis.z() , 0, 00774 yaxis.x() , yaxis.y() , yaxis.z() , 0, 00775 zaxis.x() , zaxis.y() , zaxis.z() , 0, 00776 eye.x() , eye.y() , eye.z() , 1 00777 }; 00778 00779 return Matrix4<T_Scalar>(la_modeling); 00780 } 00781 //----------------------------------------------------------------------------- 00782 template<typename T_Scalar> 00783 Matrix4<T_Scalar> Matrix4<T_Scalar>::getLookAt(const Vector3<T_Scalar>& eye, const Vector3<T_Scalar>& at, const Vector3<T_Scalar>& up) 00784 { 00785 Vector3<T_Scalar> zaxis = (eye-at).normalize(); 00786 Vector3<T_Scalar> xaxis = cross(up, zaxis).normalize(); 00787 Vector3<T_Scalar> yaxis = cross(zaxis, xaxis); 00788 00789 // look at view 00790 T_Scalar la_view[] = 00791 { 00792 xaxis.x() , yaxis.x() , zaxis.x() , 0, 00793 xaxis.y() , yaxis.y() , zaxis.y() , 0, 00794 xaxis.z() , yaxis.z() , zaxis.z() , 0, 00795 -dot(xaxis,eye), -dot(yaxis,eye), -dot(zaxis,eye), 1 00796 }; 00797 00798 return Matrix4<T_Scalar>(la_view); 00799 } 00800 //----------------------------------------------------------------------------- 00801 template<typename T_Scalar> 00802 void Matrix4<T_Scalar>::getAsLookAtModeling(Vector3<T_Scalar>& eye, Vector3<T_Scalar>& at, Vector3<T_Scalar>& up, Vector3<T_Scalar>& right) const 00803 { 00804 eye = getT(); 00805 00806 at = -getZ(); 00807 // look.normalize(); 00808 00809 up = getY(); 00810 // up.normalize(); 00811 00812 right = getX(); 00813 // right.normalize(); 00814 } 00815 //----------------------------------------------------------------------------- 00816 template<typename T_Scalar> 00817 void Matrix4<T_Scalar>::getAsLookAt(Vector3<T_Scalar>& eye, Vector3<T_Scalar>& at, Vector3<T_Scalar>& up, Vector3<T_Scalar>& right) const 00818 { 00819 Matrix4<T_Scalar> m = *this; 00820 m.invert(); 00821 m.getAsLookAtModeling(eye, at, up, right); 00822 } 00823 //----------------------------------------------------------------------------- 00824 template<typename T_Scalar> 00825 Matrix4<T_Scalar> Matrix4<T_Scalar>::getPerspective(T_Scalar fovy, T_Scalar aspect_ratio, T_Scalar znear, T_Scalar zfar) 00826 { 00827 Matrix4<T_Scalar> m; 00828 00829 T_Scalar rads = (fovy / ((T_Scalar)2)) * (T_Scalar)dDEG_TO_RAD; 00830 T_Scalar dz = zfar - znear; 00831 T_Scalar sa = sin(rads); 00832 if ((dz == 0) || (sa == 0) || (aspect_ratio == 0)) 00833 return m * 0; 00834 T_Scalar ctan = cos(rads) / sa; 00835 00836 m.e(0,0) = (T_Scalar)(ctan / aspect_ratio); 00837 m.e(1,1) = (T_Scalar)(ctan); 00838 m.e(2,2) = (T_Scalar)(-(zfar + znear) / dz); 00839 m.e(3,2) = -((T_Scalar)1); 00840 m.e(2,3) = (T_Scalar)(-((T_Scalar)2) * znear * zfar / dz); 00841 m.e(3,3) = 0; 00842 00843 return m; 00844 } 00845 //----------------------------------------------------------------------------- 00846 template<typename T_Scalar> 00847 Matrix4<T_Scalar> Matrix4<T_Scalar>::getFrustum(T_Scalar left, T_Scalar right, T_Scalar bottom, T_Scalar top, T_Scalar pnear, T_Scalar pfar) 00848 { 00849 Matrix4<T_Scalar> m; 00850 00851 if (pnear <= 0 || pfar <= 0 || pnear == pfar || left == right || top == bottom) 00852 return m * 0; 00853 00854 T_Scalar x = (((T_Scalar)2)*pnear) / (right-left); 00855 T_Scalar y = (((T_Scalar)2)*pnear) / (top-bottom); 00856 T_Scalar a = (right+left) / (right-left); 00857 T_Scalar b = (top+bottom) / (top-bottom); 00858 T_Scalar c = -(pfar+pnear) / (pfar-pnear); 00859 T_Scalar d = -(((T_Scalar)2)*pfar*pnear) / (pfar-pnear); 00860 00861 m.e(0,0) = x; m.e(0,1) = 0; m.e(0,2) = a; m.e(0,3) = 0; 00862 m.e(1,0) = 0; m.e(1,1) = y; m.e(1,2) = b; m.e(1,3) = 0; 00863 m.e(2,0) = 0; m.e(2,1) = 0; m.e(2,2) = c; m.e(2,3) = d; 00864 m.e(3,0) = 0; m.e(3,1) = 0; m.e(3,2) = -((T_Scalar)1); m.e(3,3) = 0; 00865 00866 return m; 00867 } 00868 //----------------------------------------------------------------------------- 00869 template<typename T_Scalar> 00870 Matrix4<T_Scalar> Matrix4<T_Scalar>::getOrtho(T_Scalar left, T_Scalar right, T_Scalar bottom, T_Scalar top, T_Scalar pnear, T_Scalar pfar) 00871 { 00872 Matrix4<T_Scalar> m; 00873 00874 m.e(0,0) = ((T_Scalar)2) / (right-left); 00875 m.e(0,1) = 0; 00876 m.e(0,2) = 0; 00877 m.e(0,3) = -(right+left) / (right-left); 00878 00879 m.e(1,0) = 0; 00880 m.e(1,1) = ((T_Scalar)2) / (top-bottom); 00881 m.e(1,2) = 0; 00882 m.e(1,3) = -(top+bottom) / (top-bottom); 00883 00884 m.e(2,0) = 0; 00885 m.e(2,1) = 0; 00886 m.e(2,2) = -((T_Scalar)2) / (pfar-pnear); 00887 m.e(2,3) = -(pfar+pnear) / (pfar-pnear); 00888 00889 m.e(3,0) = 0; 00890 m.e(3,1) = 0; 00891 m.e(3,2) = 0; 00892 m.e(3,3) = ((T_Scalar)1); 00893 00894 return m; 00895 } 00896 //----------------------------------------------------------------------------- 00897 template<typename T_Scalar> 00898 Matrix4<T_Scalar> Matrix4<T_Scalar>::getOrtho2D(T_Scalar left, T_Scalar right, T_Scalar bottom, T_Scalar top) 00899 { 00900 return getOrtho(left, right, bottom, top, -1, +1); 00901 } 00902 //----------------------------------------------------------------------------- 00903 template<typename T_Scalar> 00904 Matrix4<T_Scalar>& Matrix4<T_Scalar>::getRotation(Matrix4<T_Scalar>& out, T_Scalar degrees, T_Scalar x, T_Scalar y, T_Scalar z) 00905 { 00906 out.setIdentity(); 00907 00908 if (degrees == 0 || (x == 0 && y ==0 && z == 0)) 00909 return out; 00910 00911 degrees = T_Scalar(degrees * dDEG_TO_RAD); 00912 00913 T_Scalar xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c; 00914 00915 s = (T_Scalar) sin(degrees); 00916 c = (T_Scalar) cos(degrees); 00917 00918 // simple cases 00919 if (x == 0) 00920 { 00921 if (y == 0) 00922 { 00923 if (z != 0) 00924 { 00925 // rotate only around z-axis 00926 out.e(0,0) = (T_Scalar)c; 00927 out.e(1,1) = (T_Scalar)c; 00928 if (z < 0) 00929 { 00930 out.e(1,0) = -(T_Scalar)s; 00931 out.e(0,1) = (T_Scalar)s; 00932 } 00933 else 00934 { 00935 out.e(1,0) = (T_Scalar)s; 00936 out.e(0,1) = -(T_Scalar)s; 00937 } 00938 return out; 00939 } 00940 } 00941 else if (z == 0) 00942 { 00943 // rotate only around y-axis 00944 out.e(0,0) = (T_Scalar)c; 00945 out.e(2,2) = (T_Scalar)c; 00946 if (y < 0) 00947 { 00948 out.e(2,0) = (T_Scalar)s; 00949 out.e(0,2) = -(T_Scalar)s; 00950 } 00951 else 00952 { 00953 out.e(2,0) = -(T_Scalar)s; 00954 out.e(0,2) = (T_Scalar)s; 00955 } 00956 return out; 00957 } 00958 } 00959 else if (y == 0) 00960 { 00961 if (z == 0) 00962 { 00963 // rotate only around x-axis 00964 out.e(1,1) = (T_Scalar)c; 00965 out.e(2,2) = (T_Scalar)c; 00966 if (x < 0) 00967 { 00968 out.e(2,1) = -(T_Scalar)s; 00969 out.e(1,2) = (T_Scalar)s; 00970 } 00971 else 00972 { 00973 out.e(2,1) = (T_Scalar)s; 00974 out.e(1,2) = -(T_Scalar)s; 00975 } 00976 return out; 00977 } 00978 } 00979 00980 // Beginning of general axisa to matrix conversion 00981 T_Scalar dot = x*x + y*y + z*z; 00982 00983 if (dot > (T_Scalar)((T_Scalar)1.0001) || dot < (T_Scalar)0.99999) 00984 { 00985 T_Scalar mag = (T_Scalar) sqrt(dot); 00986 x /= mag; 00987 y /= mag; 00988 z /= mag; 00989 } 00990 00991 xx = x *x; 00992 yy = y * y; 00993 zz = z * z; 00994 xy = x * y; 00995 yz = y * z; 00996 zx = z * x; 00997 xs = x * s; 00998 ys = y * s; 00999 zs = z * s; 01000 one_c = ((T_Scalar)1) - c; 01001 01002 out.e(0,0) = (T_Scalar)((one_c * xx) + c); out.e(1,0) = (T_Scalar)((one_c * xy) + zs); out.e(2,0) = (T_Scalar)((one_c * zx) - ys); 01003 out.e(0,1) = (T_Scalar)((one_c * xy) - zs); out.e(1,1) = (T_Scalar)((one_c * yy) + c); out.e(2,1) = (T_Scalar)((one_c * yz) + xs); 01004 out.e(0,2) = (T_Scalar)((one_c * zx) + ys); out.e(1,2) = (T_Scalar)((one_c * yz) - xs); out.e(2,2) = (T_Scalar)((one_c * zz) + c); 01005 return out; 01006 } 01007 //----------------------------------------------------------------------------- 01008 template<typename T_Scalar> 01009 T_Scalar Matrix4<T_Scalar>::getInverse(Matrix4<T_Scalar>& dest) const 01010 { 01011 const T_Scalar* in = ptr(); 01012 T_Scalar* out = dest.ptr(); 01013 01014 // | 0 | 4 | 8 | 12 | 01015 // | 1 | 5 | 9 | 13 | 01016 // | 2 | 6 | 10 | 14 | 01017 // | 3 | 7 | 11 | 15 | 01018 01019 // | a | b | c | d | 01020 // | e | f | g | h | 01021 // | i | l | m | n | 01022 // | o | p | q | r | 01023 01024 const T_Scalar a = in[0]; const T_Scalar b = in[4]; const T_Scalar c = in[ 8]; const T_Scalar d = in[12]; 01025 const T_Scalar e = in[1]; const T_Scalar f = in[5]; const T_Scalar g = in[ 9]; const T_Scalar h = in[13]; 01026 const T_Scalar i = in[2]; const T_Scalar l = in[6]; const T_Scalar m = in[10]; const T_Scalar n = in[14]; 01027 const T_Scalar o = in[3]; const T_Scalar p = in[7]; const T_Scalar q = in[11]; const T_Scalar r = in[15]; 01028 01029 // 3x3 determinant: 01030 // 01031 // [ a b c ] 01032 // [ d e f ] = aei - ahf + dhc - dbi + gbf - gec = (aei + dhc + gbf) - (ahf + dbi + gec) 01033 // [ g h i ] 01034 01035 const T_Scalar mr = m*r; 01036 const T_Scalar gn = g*n; 01037 const T_Scalar el = e*l; 01038 const T_Scalar ip = i*p; 01039 const T_Scalar mo = m*o; 01040 const T_Scalar hl = h*l; 01041 const T_Scalar mp = m*p; 01042 const T_Scalar nq = n*q; 01043 const T_Scalar gl = g*l; 01044 const T_Scalar no = n*o; 01045 const T_Scalar gi = g*i; 01046 const T_Scalar np = n*p; 01047 const T_Scalar fi = f*i; 01048 const T_Scalar rc = r*c; 01049 const T_Scalar be = b*e; 01050 const T_Scalar af = a*f; 01051 const T_Scalar de = d*e; 01052 const T_Scalar df = d*f; 01053 const T_Scalar ch = c*h; 01054 const T_Scalar qh = q*h; 01055 01056 // | f | g | h | 01057 // | l | m | n | 01058 // | p | q | r | 01059 T_Scalar Ca = +(( f*mr + gn*p + hl*q ) - ( h*mp + nq*f + r*gl )); 01060 01061 // | e | g | h | 01062 // | i | m | n | 01063 // | o | q | r | 01064 T_Scalar Cb = -(( e*mr + gn*o + i*qh ) - ( h*mo + gi*r + nq*e )); 01065 01066 // | e | f | h | 01067 // | i | l | n | 01068 // | o | p | r | 01069 T_Scalar Cc = +(( el*r + ip*h + f*no ) - ( hl*o + np*e + fi*r )); 01070 01071 // | e | f | g | 01072 // | i | l | m | 01073 // | o | p | q | 01074 T_Scalar Cd = -(( el*q + f*mo + g*ip ) - ( gl*o + mp*e + q*fi )); 01075 01076 T_Scalar det = a*Ca + b*Cb + c*Cc + d*Cd; 01077 01078 // singular matrix 01079 if (det == 0) 01080 return det; 01081 01082 // | b | c | d | 01083 // | l | m | n | 01084 // | p | q | r | 01085 T_Scalar Ce = -(( b*mr + c*np + d*l*q ) - ( d*mp + nq*b + rc*l )); 01086 01087 // | a | c | d | 01088 // | i | m | n | 01089 // | o | q | r | 01090 T_Scalar Cf = +(( a*mr + c*no + d*i*q ) - ( d*mo + nq*a + rc*i )); 01091 01092 // | a | b | d | 01093 // | i | l | n | 01094 // | o | p | r | 01095 T_Scalar Cg = -(( a*l*r + b*no + d*ip ) - ( d*l*o + np*a + r*b*i )); 01096 01097 // | a | b | c | 01098 // | i | l | m | 01099 // | o | p | q | 01100 T_Scalar Ch = +(( a*l*q + b*mo + c*ip ) - ( c*l*o + mp*a + q*b*i )); 01101 01102 01103 // | b | c | d | 01104 // | f | g | h | 01105 // | p | q | r | 01106 T_Scalar Ci = +(( b*g*r + ch*p + df*q ) - ( d*g*p + q*h*b + rc*f )); 01107 01108 // | a | c | d | 01109 // | e | g | h | 01110 // | o | q | r | 01111 T_Scalar Cl = -(( a*g*r + ch*o + de*q ) - ( d*g*o + qh*a + rc*e )); 01112 01113 // | a | b | d | 01114 // | e | f | h | 01115 // | o | p | r | 01116 T_Scalar Cm = +(( af*r + b*h*o + de*p ) - ( df*o + h*p*a + r*be )); 01117 01118 // | a | b | c | 01119 // | e | f | g | 01120 // | o | p | q | 01121 T_Scalar Cn = -(( af*q + b*g*o + c*e*p ) - ( c*f*o + g*p*a + q*be )); 01122 01123 01124 // | b | c | d | 01125 // | f | g | h | 01126 // | l | m | n | 01127 T_Scalar Co = -(( b*gn + c*hl + df*m ) - ( d*gl + h*m*b + n*c*f )); 01128 01129 // | a | c | d | 01130 // | e | g | h | 01131 // | i | m | n | 01132 T_Scalar Cp = +(( a*gn + ch*i + de*m ) - ( d*gi + h*m*a + n*c*e )); 01133 01134 // | a | b | d | 01135 // | e | f | h | 01136 // | i | l | n | 01137 T_Scalar Cq = -(( af*n + b*h*i + d*el ) - ( d*fi + hl*a + n*be )); 01138 01139 // | a | b | c | 01140 // | e | f | g | 01141 // | i | l | m | 01142 T_Scalar Cr = +(( af*m + b*gi + c*el ) - ( c*fi + gl*a + m*be )); 01143 01144 #if 0 01145 T_Scalar det2 = e*Ce + f*Cf + g*Cg + h*Ch; 01146 T_Scalar det3 = i*Ci + l*Cl + m*Cm + n*Cn; 01147 T_Scalar det4 = o*Co + p*Cp + q*Cq + r*Cr; 01148 VL_CHECK( fabs(det - det1) < 0.0001 ); 01149 VL_CHECK( fabs(det - det3) < 0.0001 ); 01150 VL_CHECK( fabs(det - det4) < 0.0001 ); 01151 #endif 01152 01153 T_Scalar inv_det = 1 / det; 01154 01155 out[0] = inv_det * Ca; 01156 out[1] = inv_det * Cb; 01157 out[2] = inv_det * Cc; 01158 out[3] = inv_det * Cd; 01159 out[4] = inv_det * Ce; 01160 out[5] = inv_det * Cf; 01161 out[6] = inv_det * Cg; 01162 out[7] = inv_det * Ch; 01163 out[8] = inv_det * Ci; 01164 out[9] = inv_det * Cl; 01165 out[10] = inv_det * Cm; 01166 out[11] = inv_det * Cn; 01167 out[12] = inv_det * Co; 01168 out[13] = inv_det * Cp; 01169 out[14] = inv_det * Cq; 01170 out[15] = inv_det * Cr; 01171 01172 return det; 01173 } 01174 //----------------------------------------------------------------------------- 01175 template<typename T_Scalar> 01176 Matrix4<T_Scalar>& Matrix4<T_Scalar>::getRotation(Matrix4<T_Scalar>& out, const Vector3<T_Scalar>& from, const Vector3<T_Scalar>& to) 01177 { 01178 Vector3<T_Scalar> a,b; 01179 a = from; 01180 b = to; 01181 a.normalize(); 01182 b.normalize(); 01183 T_Scalar cosa = dot(a,b); 01184 cosa = clamp(cosa,-((T_Scalar)1),+((T_Scalar)1)); 01185 Vector3<T_Scalar> axis,n2; 01186 axis = cross(a,b); 01187 axis.normalize(); 01188 T_Scalar alpha = acos(cosa); 01189 return getRotation(out, alpha*(T_Scalar)dRAD_TO_DEG, axis.x(), axis.y(), axis.z()); 01190 } 01191 //----------------------------------------------------------------------------- 01198 template<typename T_Scalar> 01199 void Matrix4<T_Scalar>::getYXRotationAngles(T_Scalar& degrees_y, T_Scalar& degrees_x) const 01200 { 01201 Vector3<T_Scalar> vx = getX(); 01202 Vector3<T_Scalar> vy = getY(); 01203 Vector3<T_Scalar> vz = getZ(); 01204 01205 vx.normalize(); 01206 vy.normalize(); 01207 vz.normalize(); 01208 01209 T_Scalar kx = dot(vy,Vector3<T_Scalar>(0,1,0)); 01210 kx = clamp(kx,-((T_Scalar)1),+((T_Scalar)1)); 01211 degrees_x = acos(kx) * (T_Scalar)dRAD_TO_DEG; 01212 if(dot(vz, Vector3<T_Scalar>(0,1,0)) > 0) 01213 degrees_x = -degrees_x; 01214 01215 T_Scalar ky = dot(vx, Vector3<T_Scalar>(1,0,0)); 01216 ky = clamp(ky,-((T_Scalar)1),+((T_Scalar)1)); 01217 degrees_y = acos(ky) * (T_Scalar)dRAD_TO_DEG; 01218 if(dot(vz, Vector3<T_Scalar>(1,0,0)) < 0) 01219 degrees_y = -degrees_y; 01220 if (fabs(degrees_x) > (T_Scalar)90) 01221 degrees_y = -degrees_y; 01222 } 01223 01224 //----------------------------------------------------------------------------- 01225 01227 typedef Matrix4<double> dmat4; 01229 typedef Matrix4<float> fmat4; 01231 typedef Matrix4<int> imat4; 01233 typedef Matrix4<unsigned int> umat4; 01234 01235 #if VL_PIPELINE_PRECISION == 2 01236 01237 typedef dmat4 mat4; 01238 #else 01239 01240 typedef fmat4 mat4; 01241 #endif 01242 } 01243 01244 #endif