Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/linmath/lmatrix4_src.I

Go to the documentation of this file.
00001 // Filename: lmatrix4_src.I
00002 // Created by:  drose (15Jan99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 ////////////////////////////////////////////////////////////////////
00020 //     Function: LMatrix4::ident_mat
00021 //       Access: Public, Static
00022 //  Description: Returns an identity matrix.
00023 //
00024 //               This function definition must appear first, since
00025 //               some inline functions below take advantage of it.
00026 ////////////////////////////////////////////////////////////////////
00027 INLINE_LINMATH const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00028 ident_mat() {
00029   return _ident_mat;
00030 }
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: LMatrix4::Default Constructor
00034 //       Access: Public
00035 //  Description:
00036 ////////////////////////////////////////////////////////////////////
00037 INLINE_LINMATH FLOATNAME(LMatrix4)::
00038 FLOATNAME(LMatrix4)() {
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: LMatrix4::Copy Constructor
00043 //       Access: Public
00044 //  Description:
00045 ////////////////////////////////////////////////////////////////////
00046 INLINE_LINMATH FLOATNAME(LMatrix4)::
00047 FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix4) &copy) {
00048   memcpy(_m.data,copy._m.data,sizeof(_m.data));
00049 //  (*this) = copy;
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: LMatrix4::Copy Assignment Operator
00054 //       Access: Public
00055 //  Description:
00056 ////////////////////////////////////////////////////////////////////
00057 INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00058 operator = (const FLOATNAME(LMatrix4) &copy) {
00059   //xxx888
00060   memcpy(_m.data,copy._m.data,sizeof(_m.data));
00061 //  set(copy(0, 0), copy(0, 1), copy(0, 2), copy(0, 3),
00062 //      copy(1, 0), copy(1, 1), copy(1, 2), copy(1, 3),
00063 //      copy(2, 0), copy(2, 1), copy(2, 2), copy(2, 3),
00064 //      copy(3, 0), copy(3, 1), copy(3, 2), copy(3, 3));
00065   return *this;
00066   //xxx000
00067 }
00068 
00069 ////////////////////////////////////////////////////////////////////
00070 //     Function: LMatrix4::Fill Assignment Operator
00071 //       Access: Public
00072 //  Description:
00073 ////////////////////////////////////////////////////////////////////
00074 INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00075 operator = (FLOATTYPE fill_value) {
00076   fill(fill_value);
00077   return *this;
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: LMatrix4::Constructor
00082 //       Access: Public
00083 //  Description:
00084 ////////////////////////////////////////////////////////////////////
00085 INLINE_LINMATH FLOATNAME(LMatrix4)::
00086 FLOATNAME(LMatrix4)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03,
00087                     FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12, FLOATTYPE e13,
00088                     FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22, FLOATTYPE e23,
00089                     FLOATTYPE e30, FLOATTYPE e31, FLOATTYPE e32, FLOATTYPE e33) {
00090 
00091   _m.m._00 = e00;
00092   _m.m._01 = e01;
00093   _m.m._02 = e02;
00094   _m.m._03 = e03;
00095 
00096   _m.m._10 = e10;
00097   _m.m._11 = e11;
00098   _m.m._12 = e12;
00099   _m.m._13 = e13;
00100 
00101   _m.m._20 = e20;
00102   _m.m._21 = e21;
00103   _m.m._22 = e22;
00104   _m.m._23 = e23;
00105 
00106   _m.m._30 = e30;
00107   _m.m._31 = e31;
00108   _m.m._32 = e32;
00109   _m.m._33 = e33;
00110 }
00111 
00112 ////////////////////////////////////////////////////////////////////
00113 //     Function: LMatrix4::Constructor, upper 3x3
00114 //       Access: Public
00115 //  Description:
00116 ////////////////////////////////////////////////////////////////////
00117 INLINE_LINMATH FLOATNAME(LMatrix4)::
00118 FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3) {
00119 
00120   _m.m._00 = upper3._m.m._00;
00121   _m.m._01 = upper3._m.m._01;
00122   _m.m._02 = upper3._m.m._02;
00123   _m.m._03 = 0.0f;
00124 
00125   _m.m._10 = upper3._m.m._10;
00126   _m.m._11 = upper3._m.m._11;
00127   _m.m._12 = upper3._m.m._12;
00128   _m.m._13 = 0.0f;
00129 
00130   _m.m._20 = upper3._m.m._20;
00131   _m.m._21 = upper3._m.m._21;
00132   _m.m._22 = upper3._m.m._22;
00133   _m.m._23 = 0.0f;
00134 
00135   _m.m._30 = 0.0f;
00136   _m.m._31 = 0.0f;
00137   _m.m._32 = 0.0f;
00138   _m.m._33 = 1.0f;
00139 
00140 //  set(upper3(0, 0), upper3(0, 1), upper3(0, 2), 0.0f,
00141 //      upper3(1, 0), upper3(1, 1), upper3(1, 2), 0.0f,
00142 //      upper3(2, 0), upper3(2, 1), upper3(2, 2), 0.0f,
00143 //      0.0f, 0.0f, 0.0f, 1.0f);
00144 }
00145 
00146 ////////////////////////////////////////////////////////////////////
00147 //     Function: LMatrix4::Constructor, upper 3x3 plus translation
00148 //       Access: Public
00149 //  Description:
00150 ////////////////////////////////////////////////////////////////////
00151 INLINE_LINMATH FLOATNAME(LMatrix4)::
00152 FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3,
00153          const FLOATNAME(LVecBase3) &trans) {
00154 
00155   _m.m._00 = upper3._m.m._00;
00156   _m.m._01 = upper3._m.m._01;
00157   _m.m._02 = upper3._m.m._02;
00158   _m.m._03 = 0.0f;
00159 
00160   _m.m._10 = upper3._m.m._10;
00161   _m.m._11 = upper3._m.m._11;
00162   _m.m._12 = upper3._m.m._12;
00163   _m.m._13 = 0.0f;
00164 
00165   _m.m._20 = upper3._m.m._20;
00166   _m.m._21 = upper3._m.m._21;
00167   _m.m._22 = upper3._m.m._22;
00168   _m.m._23 = 0.0f;
00169 
00170   _m.m._30 = trans._v.v._0;
00171   _m.m._31 = trans._v.v._1;
00172   _m.m._32 = trans._v.v._2;
00173   _m.m._33 = 1.0f;
00174 
00175 //  set(upper3(0, 0), upper3(0, 1), upper3(0, 2), 0.0f,
00176 //      upper3(1, 0), upper3(1, 1), upper3(1, 2), 0.0f,
00177 //      upper3(2, 0), upper3(2, 1), upper3(2, 2), 0.0f,
00178 //      trans[0], trans[1], trans[2], 1.0f);
00179 }
00180 
00181 ////////////////////////////////////////////////////////////////////
00182 //     Function: LMatrix4::fill
00183 //       Access: Public
00184 //  Description: Sets each element of the matrix to the indicated
00185 //               fill_value.  This is of questionable value, but is
00186 //               sometimes useful when initializing to zero.
00187 ////////////////////////////////////////////////////////////////////
00188 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00189 fill(FLOATTYPE fill_value) {
00190   set(fill_value, fill_value, fill_value, fill_value,
00191       fill_value, fill_value, fill_value, fill_value,
00192       fill_value, fill_value, fill_value, fill_value,
00193       fill_value, fill_value, fill_value, fill_value);
00194 }
00195 
00196 ////////////////////////////////////////////////////////////////////
00197 //     Function: LMatrix4::set
00198 //       Access: Public
00199 //  Description:
00200 ////////////////////////////////////////////////////////////////////
00201 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00202 set(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03,
00203     FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12, FLOATTYPE e13,
00204     FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22, FLOATTYPE e23,
00205     FLOATTYPE e30, FLOATTYPE e31, FLOATTYPE e32, FLOATTYPE e33) {
00206 
00207   _m.m._00 = e00;
00208   _m.m._01 = e01;
00209   _m.m._02 = e02;
00210   _m.m._03 = e03;
00211 
00212   _m.m._10 = e10;
00213   _m.m._11 = e11;
00214   _m.m._12 = e12;
00215   _m.m._13 = e13;
00216 
00217   _m.m._20 = e20;
00218   _m.m._21 = e21;
00219   _m.m._22 = e22;
00220   _m.m._23 = e23;
00221 
00222   _m.m._30 = e30;
00223   _m.m._31 = e31;
00224   _m.m._32 = e32;
00225   _m.m._33 = e33;
00226 }
00227 
00228 ////////////////////////////////////////////////////////////////////
00229 //     Function: LMatrix4::set_upper_3
00230 //       Access: Public
00231 //  Description: Sets the upper 3x3 submatrix.
00232 ////////////////////////////////////////////////////////////////////
00233 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00234 set_upper_3(const FLOATNAME(LMatrix3) &upper3) {
00235   _m.m._00 = upper3(0, 0);
00236   _m.m._01 = upper3(0, 1);
00237   _m.m._02 = upper3(0, 2);
00238 
00239   _m.m._10 = upper3(1, 0);
00240   _m.m._11 = upper3(1, 1);
00241   _m.m._12 = upper3(1, 2);
00242 
00243   _m.m._20 = upper3(2, 0);
00244   _m.m._21 = upper3(2, 1);
00245   _m.m._22 = upper3(2, 2);
00246 }
00247 
00248 ////////////////////////////////////////////////////////////////////
00249 //     Function: LMatrix4::get_upper_3
00250 //       Access: Public
00251 //  Description: Retrieves the upper 3x3 submatrix.
00252 ////////////////////////////////////////////////////////////////////
00253 INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix4)::
00254 get_upper_3() const {
00255   return FLOATNAME(LMatrix3)
00256     (_m.m._00, _m.m._01, _m.m._02,
00257      _m.m._10, _m.m._11, _m.m._12,
00258      _m.m._20, _m.m._21, _m.m._22);
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: LMatrix4::set_row
00263 //       Access: Public
00264 //  Description: Replaces the indicated row of the matrix.
00265 ////////////////////////////////////////////////////////////////////
00266 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00267 set_row(int row, const FLOATNAME(LVecBase4) &v) {
00268   (*this)(row, 0) = v._v.v._0;
00269   (*this)(row, 1) = v._v.v._1;
00270   (*this)(row, 2) = v._v.v._2;
00271   (*this)(row, 3) = v._v.v._3;
00272 }
00273 
00274 ////////////////////////////////////////////////////////////////////
00275 //     Function: LMatrix4::set_col
00276 //       Access: Public
00277 //  Description: Replaces the indicated column of the matrix.
00278 ////////////////////////////////////////////////////////////////////
00279 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00280 set_col(int col, const FLOATNAME(LVecBase4) &v) {
00281   (*this)(0, col) = v._v.v._0;
00282   (*this)(1, col) = v._v.v._1;
00283   (*this)(2, col) = v._v.v._2;
00284   (*this)(3, col) = v._v.v._3;
00285 }
00286 
00287 ////////////////////////////////////////////////////////////////////
00288 //     Function: LMatrix4::set_row
00289 //       Access: Public
00290 //  Description: Replaces the indicated row of the matrix with the
00291 //               indicated 3-component vector, ignoring the last
00292 //               column.
00293 ////////////////////////////////////////////////////////////////////
00294 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00295 set_row(int row, const FLOATNAME(LVecBase3) &v) {
00296   (*this)(row, 0) = v._v.v._0;
00297   (*this)(row, 1) = v._v.v._1;
00298   (*this)(row, 2) = v._v.v._2;
00299 }
00300 
00301 ////////////////////////////////////////////////////////////////////
00302 //     Function: LMatrix4::set_col
00303 //       Access: Public
00304 //  Description: Replaces the indicated column of the matrix with the
00305 //               indicated 3-component vector, ignoring the last
00306 //               row.
00307 ////////////////////////////////////////////////////////////////////
00308 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00309 set_col(int col, const FLOATNAME(LVecBase3) &v) {
00310   (*this)(0, col) = v._v.v._0;
00311   (*this)(1, col) = v._v.v._1;
00312   (*this)(2, col) = v._v.v._2;
00313 }
00314 
00315 ////////////////////////////////////////////////////////////////////
00316 //     Function: LMatrix4::get_row
00317 //       Access: Public
00318 //  Description: Retrieves the indicated row of the matrix as a
00319 //               4-component vector.
00320 ////////////////////////////////////////////////////////////////////
00321 INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LMatrix4)::
00322 get_row(int row) const {
00323   return FLOATNAME(LVecBase4)((*this)(row, 0),
00324                               (*this)(row, 1),
00325                               (*this)(row, 2),
00326                               (*this)(row, 3));
00327 }
00328 
00329 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00330 get_row(FLOATNAME(LVecBase4) &result_vec,int row) const {
00331   result_vec._v.v._0 = (*this)(row, 0);
00332   result_vec._v.v._1 = (*this)(row, 1);
00333   result_vec._v.v._2 = (*this)(row, 2);
00334   result_vec._v.v._3 = (*this)(row, 3);
00335 }
00336 
00337 ////////////////////////////////////////////////////////////////////
00338 //     Function: LMatrix4::get_col
00339 //       Access: Public
00340 //  Description: Retrieves the indicated column of the matrix as a
00341 //               4-component vector.
00342 ////////////////////////////////////////////////////////////////////
00343 INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LMatrix4)::
00344 get_col(int col) const {
00345   return FLOATNAME(LVecBase4)((*this)(0, col),
00346                               (*this)(1, col),
00347                               (*this)(2, col),
00348                               (*this)(3, col));
00349 }
00350 
00351 ////////////////////////////////////////////////////////////////////
00352 //     Function: LMatrix4::get_row3
00353 //       Access: Public
00354 //  Description: Retrieves the row column of the matrix as a
00355 //               3-component vector, ignoring the last column.
00356 ////////////////////////////////////////////////////////////////////
00357 INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
00358 get_row3(int row) const {
00359   return FLOATNAME(LVecBase3)((*this)(row, 0),
00360                               (*this)(row, 1),
00361                               (*this)(row, 2));
00362 }
00363 
00364 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00365 get_row3(FLOATNAME(LVecBase3) &result_vec,int row) const {
00366   result_vec._v.v._0 = (*this)(row, 0);
00367   result_vec._v.v._1 = (*this)(row, 1);
00368   result_vec._v.v._2 = (*this)(row, 2);
00369 }
00370 
00371 ////////////////////////////////////////////////////////////////////
00372 //     Function: LMatrix4::get_col3
00373 //       Access: Public
00374 //  Description: Retrieves the indicated column of the matrix as a
00375 //               3-component vector, ignoring the last row.
00376 ////////////////////////////////////////////////////////////////////
00377 INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
00378 get_col3(int col) const {
00379   return FLOATNAME(LVecBase3)((*this)(0, col),
00380                               (*this)(1, col),
00381                               (*this)(2, col));
00382 }
00383 
00384 ////////////////////////////////////////////////////////////////////
00385 //     Function: LMatrix4::Indexing operator
00386 //       Access: Public
00387 //  Description:
00388 ////////////////////////////////////////////////////////////////////
00389 INLINE_LINMATH FLOATTYPE &FLOATNAME(LMatrix4)::
00390 operator () (int row, int col) {
00391   nassertr(row >= 0 && row < 4 && col >= 0 && col < 4, _m.data[0]);
00392   return _m.data[row * 4 + col];
00393 }
00394 
00395 ////////////////////////////////////////////////////////////////////
00396 //     Function: LMatrix4::Indexing operator
00397 //       Access: Public
00398 //  Description:
00399 ////////////////////////////////////////////////////////////////////
00400 INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::
00401 operator () (int row, int col) const {
00402   nassertr(row >= 0 && row < 4 && col >= 0 && col < 4, 0.0f);
00403   return _m.data[row * 4 + col];
00404 }
00405 
00406 ////////////////////////////////////////////////////////////////////
00407 //     Function: LMatrix4::is_nan
00408 //       Access: Public
00409 //  Description: Returns true if any component of the matrix is
00410 //               not-a-number, false otherwise.
00411 ////////////////////////////////////////////////////////////////////
00412 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
00413 is_nan() const {
00414   return
00415     cnan(_m.data[0]) || cnan(_m.data[1]) || cnan(_m.data[2]) || cnan(_m.data[3]) ||
00416     cnan(_m.data[4]) || cnan(_m.data[5]) || cnan(_m.data[6]) || cnan(_m.data[7]) ||
00417     cnan(_m.data[8]) || cnan(_m.data[9]) || cnan(_m.data[10]) || cnan(_m.data[11]) ||
00418     cnan(_m.data[12]) || cnan(_m.data[13]) || cnan(_m.data[14]) || cnan(_m.data[15]);
00419 }
00420 
00421 ////////////////////////////////////////////////////////////////////
00422 //     Function: LMatrix4::get_cell
00423 //       Access: Public
00424 //  Description: Returns a particular element of the matrix.
00425 ////////////////////////////////////////////////////////////////////
00426 INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::
00427 get_cell(int row, int col) const {
00428   nassertr(row >= 0 && row < 4 && col >= 0 && col < 4, 0.0f);
00429   return _m.data[row * 4 + col];
00430 }
00431 
00432 ////////////////////////////////////////////////////////////////////
00433 //     Function: LMatrix4::set_cell
00434 //       Access: Public
00435 //  Description: Changes a particular element of the matrix.
00436 ////////////////////////////////////////////////////////////////////
00437 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00438 set_cell(int row, int col, FLOATTYPE value) {
00439   nassertv(row >= 0 && row < 4 && col >= 0 && col < 4);
00440   _m.data[row * 4 + col] = value;
00441 }
00442 
00443 ////////////////////////////////////////////////////////////////////
00444 //     Function: LMatrix4::get_data
00445 //       Access: Public
00446 //  Description: Returns the address of the first of the nine data
00447 //               elements in the matrix.  The remaining elements
00448 //               occupy the next eight positions in row-major order.
00449 ////////////////////////////////////////////////////////////////////
00450 INLINE_LINMATH const FLOATTYPE *FLOATNAME(LMatrix4)::
00451 get_data() const {
00452   return _m.data;
00453 }
00454 
00455 ////////////////////////////////////////////////////////////////////
00456 //     Function: LMatrix4::get_num_components
00457 //       Access: Public
00458 //  Description: Returns the number of elements in the matrix, 16.
00459 ////////////////////////////////////////////////////////////////////
00460 INLINE_LINMATH int FLOATNAME(LMatrix4)::
00461 get_num_components() const {
00462   return 16;
00463 }
00464 
00465 ////////////////////////////////////////////////////////////////////
00466 //     Function: LMatrix4::begin
00467 //       Access: Public
00468 //  Description: Returns an iterator that may be used to traverse the
00469 //               elements of the matrix, STL-style.
00470 ////////////////////////////////////////////////////////////////////
00471 INLINE_LINMATH FLOATNAME(LMatrix4)::iterator FLOATNAME(LMatrix4)::
00472 begin() {
00473   return _m.data;
00474 }
00475 
00476 ////////////////////////////////////////////////////////////////////
00477 //     Function: LMatrix4::end
00478 //       Access: Public
00479 //  Description: Returns an iterator that may be used to traverse the
00480 //               elements of the matrix, STL-style.
00481 ////////////////////////////////////////////////////////////////////
00482 INLINE_LINMATH FLOATNAME(LMatrix4)::iterator FLOATNAME(LMatrix4)::
00483 end() {
00484   return begin() + 16;
00485 }
00486 
00487 ////////////////////////////////////////////////////////////////////
00488 //     Function: LMatrix4::begin
00489 //       Access: Public
00490 //  Description: Returns an iterator that may be used to traverse the
00491 //               elements of the matrix, STL-style.
00492 ////////////////////////////////////////////////////////////////////
00493 INLINE_LINMATH FLOATNAME(LMatrix4)::const_iterator FLOATNAME(LMatrix4)::
00494 begin() const {
00495   return _m.data;
00496 }
00497 
00498 ////////////////////////////////////////////////////////////////////
00499 //     Function: LMatrix4::end
00500 //       Access: Public
00501 //  Description: Returns an iterator that may be used to traverse the
00502 //               elements of the matrix, STL-style.
00503 ////////////////////////////////////////////////////////////////////
00504 INLINE_LINMATH FLOATNAME(LMatrix4)::const_iterator FLOATNAME(LMatrix4)::
00505 end() const {
00506   return begin() + 16;
00507 }
00508 
00509 ////////////////////////////////////////////////////////////////////
00510 //     Function: LMatrix4::Ordering Operator
00511 //       Access: Public
00512 //  Description: This performs a lexicographical comparison.  It's of
00513 //               questionable mathematical meaning, but sometimes has
00514 //               a practical purpose for sorting unique vectors,
00515 //               especially in an STL container.  Also see
00516 //               compare_to().
00517 ////////////////////////////////////////////////////////////////////
00518 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
00519 operator < (const FLOATNAME(LMatrix4) &other) const {
00520   return compare_to(other) < 0;
00521 }
00522 
00523 ////////////////////////////////////////////////////////////////////
00524 //     Function: LMatrix4::Equality Operator
00525 //       Access: Public
00526 //  Description:
00527 ////////////////////////////////////////////////////////////////////
00528 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
00529 operator == (const FLOATNAME(LMatrix4) &other) const {
00530   return compare_to(other) == 0;
00531 }
00532 
00533 ////////////////////////////////////////////////////////////////////
00534 //     Function: LMatrix4::Inequality Operator
00535 //       Access: Public
00536 //  Description:
00537 ////////////////////////////////////////////////////////////////////
00538 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
00539 operator != (const FLOATNAME(LMatrix4) &other) const {
00540   return !operator == (other);
00541 }
00542 
00543 ////////////////////////////////////////////////////////////////////
00544 //     Function: LMatrix4::compare_to
00545 //       Access: Public
00546 //  Description: This flavor of compare_to uses a default threshold
00547 //               value based on the numeric type.
00548 ////////////////////////////////////////////////////////////////////
00549 INLINE_LINMATH int FLOATNAME(LMatrix4)::
00550 compare_to(const FLOATNAME(LMatrix4) &other) const {
00551   return compare_to(other, NEARLY_ZERO(FLOATTYPE));
00552 }
00553 
00554 #define VECTOR4_MATRIX4_PRODUCT(v_res, v, mat)       \
00555 v_res._v.v._0 = v._v.v._0*mat._m.m._00 + v._v.v._1*mat._m.m._10 + v._v.v._2*mat._m.m._20 + v._v.v._3*mat._m.m._30;   \
00556 v_res._v.v._1 = v._v.v._0*mat._m.m._01 + v._v.v._1*mat._m.m._11 + v._v.v._2*mat._m.m._21 + v._v.v._3*mat._m.m._31;   \
00557 v_res._v.v._2 = v._v.v._0*mat._m.m._02 + v._v.v._1*mat._m.m._12 + v._v.v._2*mat._m.m._22 + v._v.v._3*mat._m.m._32;   \
00558 v_res._v.v._3 = v._v.v._0*mat._m.m._03 + v._v.v._1*mat._m.m._13 + v._v.v._2*mat._m.m._23 + v._v.v._3*mat._m.m._33;
00559 
00560 ////////////////////////////////////////////////////////////////////
00561 //     Function: LMatrix4::xform
00562 //       Access: Public
00563 //  Description: 4-component vector or point times matrix.  This is a
00564 //               fully general operation.
00565 ////////////////////////////////////////////////////////////////////
00566 INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LMatrix4)::
00567 xform(const FLOATNAME(LVecBase4) &v) const {
00568     FLOATNAME(LVecBase4) v_res;
00569 
00570         VECTOR4_MATRIX4_PRODUCT(v_res, v,(*this));
00571         return v_res;
00572 
00573 /*  return FLOATNAME(LVecBase4)(v.dot(get_col(0)),
00574                               v.dot(get_col(1)),
00575                               v.dot(get_col(2)),
00576                               v.dot(get_col(3)));
00577 */
00578 }
00579 
00580 ////////////////////////////////////////////////////////////////////
00581 //     Function: LMatrix4::xform_point
00582 //       Access: Public
00583 //  Description: The matrix transforms a 3-component point (including
00584 //               translation component) and returns the result.  This
00585 //               assumes the matrix is an affine transform.
00586 ////////////////////////////////////////////////////////////////////
00587 INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
00588 xform_point(const FLOATNAME(LVecBase3) &v) const {
00589 
00590         FLOATNAME(LVecBase3) v_res;
00591 
00592         // v._v.v._3 == 1.0f for this case
00593 
00594         v_res._v.v._0 = v._v.v._0*_m.m._00 + v._v.v._1*_m.m._10 + v._v.v._2*_m.m._20 + _m.m._30;
00595         v_res._v.v._1 = v._v.v._0*_m.m._01 + v._v.v._1*_m.m._11 + v._v.v._2*_m.m._21 + _m.m._31;
00596         v_res._v.v._2 = v._v.v._0*_m.m._02 + v._v.v._1*_m.m._12 + v._v.v._2*_m.m._22 + _m.m._32;
00597 
00598         return v_res;
00599 
00600 /*
00601   return FLOATNAME(LVecBase3)(v.dot(get_col3(0)) + _m.m._30,
00602                               v.dot(get_col3(1)) + _m.m._31,
00603                               v.dot(get_col3(2)) + _m.m._32);
00604 */
00605 }
00606 
00607 ////////////////////////////////////////////////////////////////////
00608 //     Function: LMatrix4::xform_vec
00609 //       Access: Public
00610 //  Description: The matrix transforms a 3-component vector (without
00611 //               translation component) and returns the result.  This
00612 //               assumes the matrix is an affine transform.
00613 ////////////////////////////////////////////////////////////////////
00614 INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
00615 xform_vec(const FLOATNAME(LVecBase3) &v) const {
00616         FLOATNAME(LVecBase3) v_res;
00617 
00618         // v._v.v._3 == 0.0f for this case
00619 
00620         v_res._v.v._0 = v._v.v._0*_m.m._00 + v._v.v._1*_m.m._10 + v._v.v._2*_m.m._20;
00621         v_res._v.v._1 = v._v.v._0*_m.m._01 + v._v.v._1*_m.m._11 + v._v.v._2*_m.m._21;
00622         v_res._v.v._2 = v._v.v._0*_m.m._02 + v._v.v._1*_m.m._12 + v._v.v._2*_m.m._22;
00623 
00624         return v_res;
00625 /*
00626   return FLOATNAME(LVecBase3)(v.dot(get_col3(0)),
00627                               v.dot(get_col3(1)),
00628                               v.dot(get_col3(2)));
00629 */
00630 }
00631 
00632 ////////////////////////////////////////////////////////////////////
00633 //     Function: LMatrix4::mult_cel
00634 //       Access: Private
00635 //  Description: Returns one cell of the result of a matrix-matrix
00636 //               multiplication operation.
00637 ////////////////////////////////////////////////////////////////////
00638 INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::
00639 mult_cel(const FLOATNAME(LMatrix4) &other, int row, int col) const {
00640   return get_row(row).dot(other.get_col(col));
00641 }
00642 
00643 #define MATRIX4_PRODUCT(res, a, b)                                          \
00644 res._m.m._00 = a._m.m._00*b._m.m._00 + a._m.m._01*b._m.m._10 + a._m.m._02*b._m.m._20 + a._m.m._03*b._m.m._30;   \
00645 res._m.m._01 = a._m.m._00*b._m.m._01 + a._m.m._01*b._m.m._11 + a._m.m._02*b._m.m._21 + a._m.m._03*b._m.m._31;   \
00646 res._m.m._02 = a._m.m._00*b._m.m._02 + a._m.m._01*b._m.m._12 + a._m.m._02*b._m.m._22 + a._m.m._03*b._m.m._32;   \
00647 res._m.m._03 = a._m.m._00*b._m.m._03 + a._m.m._01*b._m.m._13 + a._m.m._02*b._m.m._23 + a._m.m._03*b._m.m._33;   \
00648                                                                    \
00649 res._m.m._10 = a._m.m._10*b._m.m._00 + a._m.m._11*b._m.m._10 + a._m.m._12*b._m.m._20 + a._m.m._13*b._m.m._30;   \
00650 res._m.m._11 = a._m.m._10*b._m.m._01 + a._m.m._11*b._m.m._11 + a._m.m._12*b._m.m._21 + a._m.m._13*b._m.m._31;   \
00651 res._m.m._12 = a._m.m._10*b._m.m._02 + a._m.m._11*b._m.m._12 + a._m.m._12*b._m.m._22 + a._m.m._13*b._m.m._32;   \
00652 res._m.m._13 = a._m.m._10*b._m.m._03 + a._m.m._11*b._m.m._13 + a._m.m._12*b._m.m._23 + a._m.m._13*b._m.m._33;   \
00653                                                                    \
00654 res._m.m._20 = a._m.m._20*b._m.m._00 + a._m.m._21*b._m.m._10 + a._m.m._22*b._m.m._20 + a._m.m._23*b._m.m._30;   \
00655 res._m.m._21 = a._m.m._20*b._m.m._01 + a._m.m._21*b._m.m._11 + a._m.m._22*b._m.m._21 + a._m.m._23*b._m.m._31;   \
00656 res._m.m._22 = a._m.m._20*b._m.m._02 + a._m.m._21*b._m.m._12 + a._m.m._22*b._m.m._22 + a._m.m._23*b._m.m._32;   \
00657 res._m.m._23 = a._m.m._20*b._m.m._03 + a._m.m._21*b._m.m._13 + a._m.m._22*b._m.m._23 + a._m.m._23*b._m.m._33;   \
00658                                                                    \
00659 res._m.m._30 = a._m.m._30*b._m.m._00 + a._m.m._31*b._m.m._10 + a._m.m._32*b._m.m._20 + a._m.m._33*b._m.m._30;   \
00660 res._m.m._31 = a._m.m._30*b._m.m._01 + a._m.m._31*b._m.m._11 + a._m.m._32*b._m.m._21 + a._m.m._33*b._m.m._31;   \
00661 res._m.m._32 = a._m.m._30*b._m.m._02 + a._m.m._31*b._m.m._12 + a._m.m._32*b._m.m._22 + a._m.m._33*b._m.m._32;   \
00662 res._m.m._33 = a._m.m._30*b._m.m._03 + a._m.m._31*b._m.m._13 + a._m.m._32*b._m.m._23 + a._m.m._33*b._m.m._33;
00663 
00664 ////////////////////////////////////////////////////////////////////
00665 //     Function: LMatrix4::matrix * matrix
00666 //       Access: Public
00667 //  Description:
00668 ////////////////////////////////////////////////////////////////////
00669 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
00670 operator * (const FLOATNAME(LMatrix4) &other) const {
00671         FLOATNAME(LMatrix4) t;
00672 
00673         MATRIX4_PRODUCT(t,(*this),other);
00674 /*
00675 typedef union {
00676         struct {
00677            FLOATTYPE  _m.m._11, _m.m._12, _m.m._13, _m.m._14;
00678            FLOATTYPE  _m.m._21, _m.m._22, _m.m._23, _m.m._24;
00679            FLOATTYPE  _m.m._31, _m.m._32, _m.m._33, _m.m._34;
00680            FLOATTYPE  _m.m._41, _m.m._42, _m.m._43, _m.m._44;
00681         };
00682 
00683                 FLOATTYPE m[4][4];
00684     } MYMATRIX4;
00685 
00686         FLOATNAME(LMatrix4) t;
00687 
00688         MYMATRIX4 *result_ptr=(MYMATRIX4 *)t.get_m.data();
00689         MYMATRIX4 *mat1_ptr=(MYMATRIX4 *)this->get_m.data();
00690         MYMATRIX4 *mat2_ptr=(MYMATRIX4 *)other.get_m.data();
00691 
00692         MATRIX4_PRODUCT(result_ptr,mat1_ptr,mat2_ptr);
00693 */
00694 
00695 /*
00696 
00697   t(0, 0) = mult_cel(other, 0, 0);
00698   t(0, 1) = mult_cel(other, 0, 1);
00699   t(0, 2) = mult_cel(other, 0, 2);
00700   t(0, 3) = mult_cel(other, 0, 3);
00701 
00702   t(1, 0) = mult_cel(other, 1, 0);
00703   t(1, 1) = mult_cel(other, 1, 1);
00704   t(1, 2) = mult_cel(other, 1, 2);
00705   t(1, 3) = mult_cel(other, 1, 3);
00706 
00707   t(2, 0) = mult_cel(other, 2, 0);
00708   t(2, 1) = mult_cel(other, 2, 1);
00709   t(2, 2) = mult_cel(other, 2, 2);
00710   t(2, 3) = mult_cel(other, 2, 3);
00711 
00712   t(3, 0) = mult_cel(other, 3, 0);
00713   t(3, 1) = mult_cel(other, 3, 1);
00714   t(3, 2) = mult_cel(other, 3, 2);
00715   t(3, 3) = mult_cel(other, 3, 3);
00716 */
00717   return t;
00718 }
00719 
00720 // this = other1 * other2
00721 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00722 multiply(const FLOATNAME(LMatrix4) &other1, const FLOATNAME(LMatrix4) &other2) {
00723 // faster than operator * since it writes result in place, avoiding extra copying
00724 // this will fail if you try to mat.multiply(mat,other_mat)
00725 
00726   #ifdef _DEBUG
00727      assert((&other1 != this) && (&other2 != this));
00728   #endif
00729 
00730   MATRIX4_PRODUCT((*this),other1,other2);
00731 }
00732 
00733 // this = scale_mat(scale_vector) * other_mat, efficiently
00734 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00735 scale_multiply(const FLOATNAME(LVecBase3) &scale_vector,const FLOATNAME(LMatrix4) &other_mat) {
00736   #ifdef _DEBUG
00737      assert(&other_mat != this);
00738   #endif
00739 
00740    // optimize for 0.0 or 1.0 factors?
00741 
00742   _m.m._00 = other_mat._m.m._00 * scale_vector._v.v._0;
00743   _m.m._01 = other_mat._m.m._01 * scale_vector._v.v._0;
00744   _m.m._02 = other_mat._m.m._02 * scale_vector._v.v._0;
00745   _m.m._03 = other_mat._m.m._03 * scale_vector._v.v._0;
00746 
00747   _m.m._10 = other_mat._m.m._10 * scale_vector._v.v._1;
00748   _m.m._11 = other_mat._m.m._11 * scale_vector._v.v._1;
00749   _m.m._12 = other_mat._m.m._12 * scale_vector._v.v._1;
00750   _m.m._13 = other_mat._m.m._13 * scale_vector._v.v._1;
00751 
00752   _m.m._20 = other_mat._m.m._20 * scale_vector._v.v._2;
00753   _m.m._21 = other_mat._m.m._21 * scale_vector._v.v._2;
00754   _m.m._22 = other_mat._m.m._22 * scale_vector._v.v._2;
00755   _m.m._23 = other_mat._m.m._23 * scale_vector._v.v._2;
00756 }
00757 
00758 ////////////////////////////////////////////////////////////////////
00759 //     Function: LMatrix4::matrix * scalar
00760 //       Access: Public
00761 //  Description:
00762 ////////////////////////////////////////////////////////////////////
00763 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
00764 operator * (FLOATTYPE scalar) const {
00765   FLOATNAME(LMatrix4) t;
00766 
00767   t._m.m._00 = _m.m._00 * scalar;
00768   t._m.m._01 = _m.m._01 * scalar;
00769   t._m.m._02 = _m.m._02 * scalar;
00770   t._m.m._03 = _m.m._03 * scalar;
00771 
00772   t._m.m._10 = _m.m._10 * scalar;
00773   t._m.m._11 = _m.m._11 * scalar;
00774   t._m.m._12 = _m.m._12 * scalar;
00775   t._m.m._13 = _m.m._13 * scalar;
00776 
00777   t._m.m._20 = _m.m._20 * scalar;
00778   t._m.m._21 = _m.m._21 * scalar;
00779   t._m.m._22 = _m.m._22 * scalar;
00780   t._m.m._23 = _m.m._23 * scalar;
00781 
00782   t._m.m._30 = _m.m._30 * scalar;
00783   t._m.m._31 = _m.m._31 * scalar;
00784   t._m.m._32 = _m.m._32 * scalar;
00785   t._m.m._33 = _m.m._33 * scalar;
00786 
00787   return t;
00788 }
00789 
00790 ////////////////////////////////////////////////////////////////////
00791 //     Function: LMatrix4::matrix / scalar
00792 //       Access: Public
00793 //  Description:
00794 ////////////////////////////////////////////////////////////////////
00795 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
00796 operator / (FLOATTYPE scalar) const {
00797   FLOATNAME(LMatrix4) t;
00798   FLOATTYPE recip_scalar = 1.0f/scalar;
00799 
00800   t._m.m._00 = _m.m._00 * recip_scalar;
00801   t._m.m._01 = _m.m._01 * recip_scalar;
00802   t._m.m._02 = _m.m._02 * recip_scalar;
00803   t._m.m._03 = _m.m._03 * recip_scalar;
00804 
00805   t._m.m._10 = _m.m._10 * recip_scalar;
00806   t._m.m._11 = _m.m._11 * recip_scalar;
00807   t._m.m._12 = _m.m._12 * recip_scalar;
00808   t._m.m._13 = _m.m._13 * recip_scalar;
00809 
00810   t._m.m._20 = _m.m._20 * recip_scalar;
00811   t._m.m._21 = _m.m._21 * recip_scalar;
00812   t._m.m._22 = _m.m._22 * recip_scalar;
00813   t._m.m._23 = _m.m._23 * recip_scalar;
00814 
00815   t._m.m._30 = _m.m._30 * recip_scalar;
00816   t._m.m._31 = _m.m._31 * recip_scalar;
00817   t._m.m._32 = _m.m._32 * recip_scalar;
00818   t._m.m._33 = _m.m._33 * recip_scalar;
00819 
00820   return t;
00821 }
00822 
00823 ////////////////////////////////////////////////////////////////////
00824 //     Function: LMatrix4::matrix += matrix
00825 //       Access: Public
00826 //  Description: Performs a memberwise addition between two matrices.
00827 ////////////////////////////////////////////////////////////////////
00828 INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00829 operator += (const FLOATNAME(LMatrix4) &other) {
00830   _m.m._00 += other._m.m._00;
00831   _m.m._01 += other._m.m._01;
00832   _m.m._02 += other._m.m._02;
00833   _m.m._03 += other._m.m._03;
00834 
00835   _m.m._10 += other._m.m._10;
00836   _m.m._11 += other._m.m._11;
00837   _m.m._12 += other._m.m._12;
00838   _m.m._13 += other._m.m._13;
00839 
00840   _m.m._20 += other._m.m._20;
00841   _m.m._21 += other._m.m._21;
00842   _m.m._22 += other._m.m._22;
00843   _m.m._23 += other._m.m._23;
00844 
00845   _m.m._30 += other._m.m._30;
00846   _m.m._31 += other._m.m._31;
00847   _m.m._32 += other._m.m._32;
00848   _m.m._33 += other._m.m._33;
00849 
00850   return *this;
00851 }
00852 
00853 ////////////////////////////////////////////////////////////////////
00854 //     Function: LMatrix4::matrix -= matrix
00855 //       Access: Public
00856 //  Description: Performs a memberwise addition between two matrices.
00857 ////////////////////////////////////////////////////////////////////
00858 INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00859 operator -= (const FLOATNAME(LMatrix4) &other) {
00860   _m.m._00 -= other._m.m._00;
00861   _m.m._01 -= other._m.m._01;
00862   _m.m._02 -= other._m.m._02;
00863   _m.m._03 -= other._m.m._03;
00864 
00865   _m.m._10 -= other._m.m._10;
00866   _m.m._11 -= other._m.m._11;
00867   _m.m._12 -= other._m.m._12;
00868   _m.m._13 -= other._m.m._13;
00869 
00870   _m.m._20 -= other._m.m._20;
00871   _m.m._21 -= other._m.m._21;
00872   _m.m._22 -= other._m.m._22;
00873   _m.m._23 -= other._m.m._23;
00874 
00875   _m.m._30 -= other._m.m._30;
00876   _m.m._31 -= other._m.m._31;
00877   _m.m._32 -= other._m.m._32;
00878   _m.m._33 -= other._m.m._33;
00879 
00880   return *this;
00881 }
00882 
00883 ////////////////////////////////////////////////////////////////////
00884 //     Function: LMatrix4::matrix *= matrix
00885 //       Access: Public
00886 //  Description:
00887 ////////////////////////////////////////////////////////////////////
00888 INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00889 operator *= (const FLOATNAME(LMatrix4) &other) {
00890   (*this) = (*this) * other;
00891   return *this;
00892 }
00893 
00894 ////////////////////////////////////////////////////////////////////
00895 //     Function: LMatrix4::matrix *= scalar
00896 //       Access: Public
00897 //  Description:
00898 ////////////////////////////////////////////////////////////////////
00899 INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00900 operator *= (FLOATTYPE scalar) {
00901   _m.m._00 *= scalar;
00902   _m.m._01 *= scalar;
00903   _m.m._02 *= scalar;
00904   _m.m._03 *= scalar;
00905 
00906   _m.m._10 *= scalar;
00907   _m.m._11 *= scalar;
00908   _m.m._12 *= scalar;
00909   _m.m._13 *= scalar;
00910 
00911   _m.m._20 *= scalar;
00912   _m.m._21 *= scalar;
00913   _m.m._22 *= scalar;
00914   _m.m._23 *= scalar;
00915 
00916   _m.m._30 *= scalar;
00917   _m.m._31 *= scalar;
00918   _m.m._32 *= scalar;
00919   _m.m._33 *= scalar;
00920 
00921   return *this;
00922 }
00923 
00924 ////////////////////////////////////////////////////////////////////
00925 //     Function: LMatrix4::matrix /= scalar
00926 //       Access: Public
00927 //  Description:
00928 ////////////////////////////////////////////////////////////////////
00929 INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
00930 operator /= (FLOATTYPE scalar) {
00931   FLOATTYPE recip_scalar = 1.0f/scalar;
00932   _m.m._00 *= recip_scalar;
00933   _m.m._01 *= recip_scalar;
00934   _m.m._02 *= recip_scalar;
00935   _m.m._03 *= recip_scalar;
00936 
00937   _m.m._10 *= recip_scalar;
00938   _m.m._11 *= recip_scalar;
00939   _m.m._12 *= recip_scalar;
00940   _m.m._13 *= recip_scalar;
00941 
00942   _m.m._20 *= recip_scalar;
00943   _m.m._21 *= recip_scalar;
00944   _m.m._22 *= recip_scalar;
00945   _m.m._23 *= recip_scalar;
00946 
00947   _m.m._30 *= recip_scalar;
00948   _m.m._31 *= recip_scalar;
00949   _m.m._32 *= recip_scalar;
00950   _m.m._33 *= recip_scalar;
00951 
00952   return *this;
00953 }
00954 
00955 
00956 ////////////////////////////////////////////////////////////////////
00957 //     Function: LMatrix4::transpose_from
00958 //       Access: Public
00959 //  Description:
00960 ////////////////////////////////////////////////////////////////////
00961 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00962 transpose_from(const FLOATNAME(LMatrix4) &other) {
00963   _m.m._00 = other._m.m._00;
00964   _m.m._01 = other._m.m._10;
00965   _m.m._02 = other._m.m._20;
00966   _m.m._03 = other._m.m._30;
00967 
00968   _m.m._10 = other._m.m._01;
00969   _m.m._11 = other._m.m._11;
00970   _m.m._12 = other._m.m._21;
00971   _m.m._13 = other._m.m._31;
00972 
00973   _m.m._20 = other._m.m._02;
00974   _m.m._21 = other._m.m._12;
00975   _m.m._22 = other._m.m._22;
00976   _m.m._23 = other._m.m._32;
00977 
00978   _m.m._30 = other._m.m._03;
00979   _m.m._31 = other._m.m._13;
00980   _m.m._32 = other._m.m._23;
00981   _m.m._33 = other._m.m._33;
00982 }
00983 
00984 ////////////////////////////////////////////////////////////////////
00985 //     Function: LMatrix4::transpose_in_place
00986 //       Access: Public
00987 //  Description:
00988 ////////////////////////////////////////////////////////////////////
00989 INLINE_LINMATH void FLOATNAME(LMatrix4)::
00990 transpose_in_place() {
00991 //  FLOATNAME(LMatrix4) temp = (*this);
00992 //  transpose_from(temp);
00993 
00994   #define SWAP__(x,y) { FLOATTYPE temp = (x);  (x) = (y);  (y) = temp;}
00995   SWAP__(_m.m._01,_m.m._10);
00996   SWAP__(_m.m._02,_m.m._20);
00997   SWAP__(_m.m._03,_m.m._30);
00998   SWAP__(_m.m._12,_m.m._21);
00999   SWAP__(_m.m._13,_m.m._31);
01000   SWAP__(_m.m._23,_m.m._32);
01001   #undef SWAP__
01002 }
01003 
01004 ////////////////////////////////////////////////////////////////////
01005 //     Function: LMatrix4::invert_from
01006 //       Access: Public
01007 //  Description: Computes the inverse of the other matrix, and stores
01008 //               the result in this matrix.  This is a fully general
01009 //               operation and makes no assumptions about the type of
01010 //               transform represented by the matrix.
01011 //
01012 //               The other matrix must be a different object than this
01013 //               matrix.  However, if you need to invert a matrix in
01014 //               place, see invert_in_place.
01015 //
01016 //               The return value is true if the matrix was
01017 //               successfully inverted, false if the was a
01018 //               singularity.
01019 ////////////////////////////////////////////////////////////////////
01020 
01021 // bugbug: we could optimize this for rotation/scale/translation matrices
01022 //         (transpose upper 3x3 and take negative of translation component)
01023 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
01024 invert_from(const FLOATNAME(LMatrix4) &other) {
01025   if (IS_NEARLY_EQUAL(other._m.m._30, 0.0f) &&
01026       IS_NEARLY_EQUAL(other._m.m._31, 0.0f) &&
01027       IS_NEARLY_EQUAL(other._m.m._32, 0.0f) &&
01028       IS_NEARLY_EQUAL(other._m.m._33, 1.0f)) {
01029     return invert_affine_from(other);
01030   }
01031 
01032   (*this) = other;
01033 
01034   int index[4];
01035 
01036   if (!decompose_mat(index)) {
01037 #ifdef NDEBUG
01038     linmath_cat.warning() << "Tried to invert singular LMatrix4.\n";
01039 #endif
01040     return false;
01041   }
01042 
01043   FLOATNAME(LMatrix4) inv = FLOATNAME(LMatrix4)::ident_mat();
01044   int row;
01045 
01046   for (row = 0; row < 4; row++) {
01047     back_sub_mat(index, inv, row);
01048   }
01049 
01050   transpose_from(inv);
01051   return true;
01052 }
01053 
01054 ////////////////////////////////////////////////////////////////////
01055 //     Function: LMatrix4::invert_affine_from
01056 //       Access: Public
01057 //  Description: Performs an invert of the indicated matrix, storing
01058 //               the result in this matrix.  The calculation is only
01059 //               correct of the other matrix represents an affine
01060 //               transform.
01061 //
01062 //               The other matrix must be a different object than this
01063 //               matrix.  However, if you need to invert a matrix in
01064 //               place, see invert_in_place.
01065 //
01066 //               The return value is true if the matrix was
01067 //               successfully inverted, false if the was a
01068 //               singularity.
01069 ////////////////////////////////////////////////////////////////////
01070 
01071 // bugbug: we could optimize this for rotation/scale/translation matrices
01072 //         (transpose upper 3x3 and take negative of translation component)
01073 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
01074 invert_affine_from(const FLOATNAME(LMatrix4) &other) {
01075   FLOATNAME(LMatrix3) rot;
01076 
01077   // probably could use transpose here
01078   if (!rot.invert_from(other.get_upper_3())) {
01079     return false;
01080   }
01081 
01082   set_upper_3(rot);
01083 //  set_col(3, FLOATNAME(LVecBase4)(0.0f, 0.0f, 0.0f, 1.0f));
01084 
01085   _m.m._03 = 0.0f;
01086   _m.m._13 = 0.0f;
01087   _m.m._23 = 0.0f;
01088   _m.m._33 = 1.0f;
01089 
01090   // compute -C*inv(A)
01091 /*
01092   for (int i = 0; i < 3; i++) {
01093     (*this)(3, i) = 0.0f;
01094     for (int j = 0; j < 3; j++) {
01095       (*this)(3, i) -= other(3, j) * (*this)(j, i);
01096     }
01097   }
01098 */
01099 
01100     _m.m._30 = -(other._m.m._30 * _m.m._00 +
01101                other._m.m._31 * _m.m._10 +
01102                other._m.m._32 * _m.m._20);
01103 
01104     _m.m._31 = -(other._m.m._30 * _m.m._01 +
01105                    other._m.m._31 * _m.m._11 +
01106                other._m.m._32 * _m.m._21);
01107 
01108     _m.m._32 = -(other._m.m._30 * _m.m._02 +
01109                    other._m.m._31 * _m.m._12 +
01110                other._m.m._32 * _m.m._22);
01111 
01112   return true;
01113 }
01114 
01115 ////////////////////////////////////////////////////////////////////
01116 //     Function: LMatrix4::invert_in_place
01117 //       Access: Public
01118 //  Description: Inverts the current matrix.  Returns true if the
01119 //               inverse is successful, false if the matrix was
01120 //               singular.
01121 ////////////////////////////////////////////////////////////////////
01122 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
01123 invert_in_place() {
01124   FLOATNAME(LMatrix4) temp = (*this);
01125   return invert_from(temp);
01126 }
01127 
01128 ////////////////////////////////////////////////////////////////////
01129 //     Function: LMatrix::translate_mat
01130 //       Access: Public, Static
01131 //  Description: Returns a matrix that applies the indicated
01132 //               translation.
01133 ////////////////////////////////////////////////////////////////////
01134 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
01135 translate_mat(const FLOATNAME(LVecBase3) &trans) {
01136   return FLOATNAME(LMatrix4)(1.0f, 0.0f, 0.0f, 0.0f,
01137                            0.0f, 1.0f, 0.0f, 0.0f,
01138                            0.0f, 0.0f, 1.0f, 0.0f,
01139                            trans._v.v._0, trans._v.v._1, trans._v.v._2, 1.0f);
01140 }
01141 
01142 ////////////////////////////////////////////////////////////////////
01143 //     Function: LMatrix::translate_mat
01144 //       Access: Public, Static
01145 //  Description: Returns a matrix that applies the indicated
01146 //               translation.
01147 ////////////////////////////////////////////////////////////////////
01148 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
01149 translate_mat(FLOATTYPE tx, FLOATTYPE ty, FLOATTYPE tz) {
01150   return FLOATNAME(LMatrix4)(1.0f, 0.0f, 0.0f, 0.0f,
01151                            0.0f, 1.0f, 0.0f, 0.0f,
01152                            0.0f, 0.0f, 1.0f, 0.0f,
01153                            tx, ty, tz, 1.0f);
01154 }
01155 
01156 ////////////////////////////////////////////////////////////////////
01157 //     Function: LMatrix::rotate_mat
01158 //       Access: Public, Static
01159 //  Description: Returns a matrix that rotates by the given angle in
01160 //               degrees counterclockwise about the indicated vector.
01161 ////////////////////////////////////////////////////////////////////
01162 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
01163 rotate_mat(FLOATTYPE angle, FLOATNAME(LVecBase3) axis,
01164            CoordinateSystem cs) {
01165 
01166   if (cs == CS_default) {
01167     cs = default_coordinate_system;
01168   }
01169   FLOATNAME(LMatrix4) mat;
01170 
01171   if(IS_LEFT_HANDED_COORDSYSTEM(cs)) {
01172     // In a left-handed coordinate system, counterclockwise is the
01173     // other direction.
01174     angle = -angle;
01175   }
01176 
01177   FLOATTYPE axis_0 = axis._v.v._0;
01178   FLOATTYPE axis_1 = axis._v.v._1;
01179   FLOATTYPE axis_2 = axis._v.v._2;
01180 
01181   // Normalize the axis.
01182 
01183 /*
01184   // hack check for prenormalization, only works for simple unit vecs,
01185   // which is what we usually pass in anyway. screws up if you happen to
01186   // pass in something like (.5,.5,0).  need to add flag parameter so caller
01187   // can request normalization if needed
01188 
01189   if((cabs(axis_0)+cabs(axis_1)+cabs(axis_2)) != 1.0f) {
01190 */
01191 
01192           FLOATTYPE length_sq = axis_0 * axis_0 + axis_1 * axis_1 + axis_2 * axis_2;
01193           #ifdef _DEBUG
01194               nassertr(length_sq != 0.0f, ident_mat());
01195           #endif
01196           FLOATTYPE recip_length = 1.0f/csqrt(length_sq);
01197 
01198           axis_0 *= recip_length;
01199           axis_1 *= recip_length;
01200           axis_2 *= recip_length;
01201 //  }
01202 
01203   FLOATTYPE angle_rad=deg_2_rad(angle);
01204   FLOATTYPE s,c;
01205   csincos(angle_rad,&s,&c);
01206   FLOATTYPE t = 1.0f - c;
01207 
01208   FLOATTYPE t0,t1,t2,s0,s1,s2;
01209 
01210   t0 = t * axis_0;
01211   t1 = t * axis_1;
01212   t2 = t * axis_2;
01213   s0 = s * axis_0;
01214   s1 = s * axis_1;
01215   s2 = s * axis_2;
01216 
01217   mat._m.m._00 = t0 * axis_0 + c;
01218   mat._m.m._01 = t0 * axis_1 + s2;
01219   mat._m.m._02 = t0 * axis_2 - s1;
01220 
01221   mat._m.m._10 = t1 * axis_0 - s2;
01222   mat._m.m._11 = t1 * axis_1 + c;
01223   mat._m.m._12 = t1 * axis_2 + s0;
01224 
01225   mat._m.m._20 = t2 * axis_0 + s1;
01226   mat._m.m._21 = t2 * axis_1 - s0;
01227   mat._m.m._22 = t2 * axis_2 + c;
01228 
01229   mat._m.m._03 = 0.0f;
01230   mat._m.m._13 = 0.0f;
01231   mat._m.m._23 = 0.0f;
01232 
01233   mat._m.m._30 = 0.0f;
01234   mat._m.m._31 = 0.0f;
01235   mat._m.m._32 = 0.0f;
01236   mat._m.m._33 = 1.0f;
01237 
01238   return mat;
01239 }
01240 
01241 
01242 ////////////////////////////////////////////////////////////////////
01243 //     Function: LMatrix::rotate_mat_normaxis
01244 //       Access: Public, Static
01245 //  Description: Returns a matrix that rotates by the given angle in
01246 //               degrees counterclockwise about the indicated vector.
01247 //               Assumes axis has been prenormalized.
01248 ////////////////////////////////////////////////////////////////////
01249 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
01250 rotate_mat_normaxis(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
01251            CoordinateSystem cs) {
01252 
01253   FLOATNAME(LMatrix4) mat;
01254   rotate_mat_normaxis(angle,axis,mat,cs);
01255   return mat;
01256 }
01257 
01258 INLINE_LINMATH void FLOATNAME(LMatrix4)::
01259 rotate_mat_normaxis(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
01260                                         FLOATNAME(LMatrix4) &result_mat, CoordinateSystem cs) {
01261 
01262   if (cs == CS_default) {
01263     cs = default_coordinate_system;
01264   }
01265 
01266   if(IS_LEFT_HANDED_COORDSYSTEM(cs)) {
01267     // In a left-handed coordinate system, counterclockwise is the
01268     // other direction.
01269     angle = -angle;
01270   }
01271 
01272   FLOATTYPE axis_0 = axis._v.v._0;
01273   FLOATTYPE axis_1 = axis._v.v._1;
01274   FLOATTYPE axis_2 = axis._v.v._2;
01275 
01276   FLOATTYPE angle_rad=deg_2_rad(angle);
01277   FLOATTYPE s,c;
01278   csincos(angle_rad,&s,&c);
01279   FLOATTYPE t = 1.0f - c;
01280 
01281   FLOATTYPE t0,t1,t2,s0,s1,s2;
01282 
01283   t0 = t * axis_0;
01284   t1 = t * axis_1;
01285   t2 = t * axis_2;
01286   s0 = s * axis_0;
01287   s1 = s * axis_1;
01288   s2 = s * axis_2;
01289 
01290   result_mat._m.m._00 = t0 * axis_0 + c;
01291   result_mat._m.m._01 = t0 * axis_1 + s2;
01292   result_mat._m.m._02 = t0 * axis_2 - s1;
01293 
01294   result_mat._m.m._10 = t1 * axis_0 - s2;
01295   result_mat._m.m._11 = t1 * axis_1 + c;
01296   result_mat._m.m._12 = t1 * axis_2 + s0;
01297 
01298   result_mat._m.m._20 = t2 * axis_0 + s1;
01299   result_mat._m.m._21 = t2 * axis_1 - s0;
01300   result_mat._m.m._22 = t2 * axis_2 + c;
01301 
01302   result_mat._m.m._03 = 0.0f;
01303   result_mat._m.m._13 = 0.0f;
01304   result_mat._m.m._23 = 0.0f;
01305 
01306   result_mat._m.m._30 = 0.0f;
01307   result_mat._m.m._31 = 0.0f;
01308   result_mat._m.m._32 = 0.0f;
01309   result_mat._m.m._33 = 1.0f;
01310 }
01311 
01312 ////////////////////////////////////////////////////////////////////
01313 //     Function: LMatrix::scale_mat
01314 //       Access: Public, Static
01315 //  Description: Returns a matrix that applies the indicated
01316 //               scale in each of the three axes.
01317 ////////////////////////////////////////////////////////////////////
01318 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
01319 scale_mat(const FLOATNAME(LVecBase3) &scale) {
01320   return FLOATNAME(LMatrix4)(scale._v.v._0, 0.0f, 0.0f, 0.0f,
01321                            0.0f, scale._v.v._1, 0.0f, 0.0f,
01322                            0.0f, 0.0f, scale._v.v._2, 0.0f,
01323                            0.0f, 0.0f, 0.0f, 1.0f);
01324 }
01325 
01326 
01327 ////////////////////////////////////////////////////////////////////
01328 //     Function: LMatrix::scale_mat
01329 //       Access: Public, Static
01330 //  Description: Returns a matrix that applies the indicated
01331 //               scale in each of the three axes.
01332 ////////////////////////////////////////////////////////////////////
01333 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
01334 scale_mat(FLOATTYPE sx, FLOATTYPE sy, FLOATTYPE sz) {
01335   return FLOATNAME(LMatrix4)(
01336                            sx, 0.0f, 0.0f, 0.0f,
01337                            0.0f, sy, 0.0f, 0.0f,
01338                            0.0f, 0.0f, sz, 0.0f,
01339                            0.0f, 0.0f, 0.0f, 1.0f);
01340 }
01341 
01342 ////////////////////////////////////////////////////////////////////
01343 //     Function: LMatrix::scale_mat
01344 //       Access: Public, Static
01345 //  Description: Returns a matrix that applies the indicated
01346 //               uniform scale.
01347 ////////////////////////////////////////////////////////////////////
01348 INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
01349 scale_mat(FLOATTYPE scale) {
01350   return FLOATNAME(LMatrix4)(
01351                            scale, 0.0f, 0.0f, 0.0f,
01352                            0.0f, scale, 0.0f, 0.0f,
01353                            0.0f, 0.0f, scale, 0.0f,
01354                            0.0f, 0.0f, 0.0f, 1.0f);
01355 }
01356 
01357 ////////////////////////////////////////////////////////////////////
01358 //     Function: LMatrix::y_to_z_up_mat
01359 //       Access: Public, Static
01360 //  Description: Returns a matrix that transforms from the Y-up
01361 //               coordinate system to the Z-up coordinate system.
01362 ////////////////////////////////////////////////////////////////////
01363 INLINE_LINMATH const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
01364 y_to_z_up_mat() {
01365   return _y_to_z_up_mat;
01366 }
01367 
01368 ////////////////////////////////////////////////////////////////////
01369 //     Function: LMatrix::z_to_y_up_mat
01370 //       Access: Public, Static
01371 //  Description: Returns a matrix that transforms from the Y-up
01372 //               coordinate system to the Z-up coordinate system.
01373 ////////////////////////////////////////////////////////////////////
01374 INLINE_LINMATH const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
01375 z_to_y_up_mat() {
01376   return _z_to_y_up_mat;
01377 }
01378 
01379 ////////////////////////////////////////////////////////////////////
01380 //     Function: LMatrix4::almost_equal
01381 //       Access: Public
01382 //  Description: Returns true if two matrices are memberwise equal
01383 //               within a default tolerance based on the numeric type.
01384 ////////////////////////////////////////////////////////////////////
01385 INLINE_LINMATH bool FLOATNAME(LMatrix4)::
01386 almost_equal(const FLOATNAME(LMatrix4) &other) const {
01387   return almost_equal(other, NEARLY_ZERO(FLOATTYPE));
01388 }
01389 
01390 ////////////////////////////////////////////////////////////////////
01391 //     Function: LMatrix4::generate_hash
01392 //       Access: Public
01393 //  Description: Adds the vector to the indicated hash generator.
01394 ////////////////////////////////////////////////////////////////////
01395 INLINE_LINMATH void FLOATNAME(LMatrix4)::
01396 generate_hash(ChecksumHashGenerator &hashgen) const {
01397   generate_hash(hashgen, NEARLY_ZERO(FLOATTYPE));
01398 }
01399 
01400 ////////////////////////////////////////////////////////////////////
01401 //     Function: transpose
01402 //  Description: Transposes the given matrix and returns it.
01403 ////////////////////////////////////////////////////////////////////
01404 INLINE_LINMATH FLOATNAME(LMatrix4)
01405 transpose(const FLOATNAME(LMatrix4) &a) {
01406   FLOATNAME(LMatrix4) result;
01407   result.transpose_from(a);
01408   return result;
01409 }
01410 
01411 ////////////////////////////////////////////////////////////////////
01412 //     Function: invert
01413 //  Description: Inverts the given matrix and returns it.
01414 ////////////////////////////////////////////////////////////////////
01415 INLINE_LINMATH FLOATNAME(LMatrix4)
01416 invert(const FLOATNAME(LMatrix4) &a) {
01417   FLOATNAME(LMatrix4) result;
01418   bool nonsingular = result.invert_from(a);
01419   nassertr(nonsingular, FLOATNAME(LMatrix4)::ident_mat());
01420   return result;
01421 }
01422 

Generated on Fri May 2 00:40:09 2003 for Panda by doxygen1.3