VCRA-SZCZERBACKI-PointBasedRendering/ssMatrix.cpp

00001 #include "ssDefs.hpp"
00002 #include "ssVector.hpp"
00003 #include "ssMatrix.hpp"
00004 
00005 #include <cstring>
00006 
00007 using namespace SS;
00008 
00009 //===================================================================
00010 //                                      Vector-Matrix functions
00011 //===================================================================
00012 
00013 Vector2 SS::operator* (const Vector2& v,  const Matrix2x2& m)
00014 {
00015         Vector2 t = v;
00016         t *= m;
00017         return t;
00018 }
00019 
00020 Vector3 SS::operator* (const Vector3& v,  const Matrix3x3& m)
00021 {
00022         Vector3 t = v;
00023         t *= m;
00024         return t;
00025 }
00026 
00027 Vector4 SS::operator* (const Vector4& v,  const Matrix4x4& m)
00028 {
00029         Vector4 t = v;
00030         t *= m;
00031         return t;
00032 }
00033 
00034 
00035 //===================================================================
00036 //                                      Binary Matrix Multiplications
00037 //===================================================================
00038 
00039 Matrix4x4       SS::operator* (const Matrix4x4& m1, const Matrix4x4& m2)
00040 {
00041         Matrix4x4 m(m1);
00042         m*=m2;
00043         return m;
00044 }
00045 
00046 Matrix3x3       SS::operator* (const Matrix3x3& m1, const Matrix3x3& m2)
00047 {
00048         Matrix3x3 m(m1);
00049         m*=m2;
00050         return m;
00051 }
00052 
00053 Matrix2x2       SS::operator* (const Matrix2x2& m1, const Matrix2x2& m2)
00054 {
00055         Matrix2x2 m(m1);
00056         m*=m2;
00057         return m;
00058 }
00059 
00060 //===================================================================
00061 //                                              Matrix3x4
00062 //===================================================================
00063 
00064 bool Matrix3x4::operator== (const Matrix3x4& n) const
00065 {
00066         return ((*this)[0]==n[0] && (*this)[1]==n[1] && (*this)[2]==n[2]);
00067 }
00068 
00069 void Matrix3x4::clear(void)
00070 {
00071         float* t = &m[0][0];
00072         for (int i = 0; i < 12; i++)
00073                 t[i] = 0.0f;
00074 }
00075                 
00076 void Matrix3x4::ident(void)
00077 {
00078         m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f;
00079         m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f;
00080         m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f;
00081 }
00082 
00083 // NOTE: used to be productFromLeft()
00084 void Matrix3x4::operator*= (const Matrix3x4& m2)
00085 {
00086         SS_ASSERT(&m2 != this);
00087 
00088         Matrix3x4 m1 = *this;
00089         m[0][0] = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0] + m1[0][2]*m2[2][0];
00090         m[0][1] = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1] + m1[0][2]*m2[2][1];
00091         m[0][2] = m1[0][0]*m2[0][2] + m1[0][1]*m2[1][2] + m1[0][2]*m2[2][2];
00092         m[0][3] = m1[0][0]*m2[0][3] + m1[0][1]*m2[1][3] + m1[0][2]*m2[2][3] + m1[0][3];
00093         m[1][0] = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0] + m1[1][2]*m2[2][0];
00094         m[1][1] = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1] + m1[1][2]*m2[2][1];
00095         m[1][2] = m1[1][0]*m2[0][2] + m1[1][1]*m2[1][2] + m1[1][2]*m2[2][2];
00096         m[1][3] = m1[1][0]*m2[0][3] + m1[1][1]*m2[1][3] + m1[1][2]*m2[2][3] + m1[1][3];
00097         m[2][0] = m1[2][0]*m2[0][0] + m1[2][1]*m2[1][0] + m1[2][2]*m2[2][0];
00098         m[2][1] = m1[2][0]*m2[0][1] + m1[2][1]*m2[1][1] + m1[2][2]*m2[2][1];
00099         m[2][2] = m1[2][0]*m2[0][2] + m1[2][1]*m2[1][2] + m1[2][2]*m2[2][2];
00100         m[2][3] = m1[2][0]*m2[0][3] + m1[2][1]*m2[1][3] + m1[2][2]*m2[2][3] + m1[2][3];
00101 }
00102 
00103 void Matrix3x4::operator*= (float f)
00104 {
00105         for (int j = 0; j < 3; j++)
00106         for (int i = 0; i < 4; i++)
00107                 m[j][i] *= f;
00108 }
00109 
00110 void Matrix3x4::flushToZero (void)                      
00111 {
00112         const double EPSILON = 1e-15;
00113 
00114         for (int j = 0; j < 3; j++)
00115         for (int i = 0; i < 4; i++)
00116         if (fabs(m[j][i]) <= EPSILON)
00117                 m[j][i] = 0.0f;
00118 }
00119 
00120 
00121 /******************************************************************************
00122  *
00123  * Function:            SS::Matrx4x3::invert()
00124  *
00125  * Description:         
00126  *
00127  * Notes:                       TIME-CRITICAL
00128  *
00129  *                                      m may be equal to src...
00130  *
00131  ******************************************************************************/
00132 
00133 bool Matrix3x4::invert  ()
00134 {
00135         Matrix3x4 src = *this;
00136 
00137         float a1 = src[0][0]; 
00138         float b1 = src[0][1];
00139         float c1 = src[0][2]; 
00140         float d1 = src[0][3];
00141         float a2 = src[1][0]; 
00142         float b2 = src[1][1]; 
00143         float c2 = src[1][2]; 
00144         float d2 = src[1][3];
00145         float a3 = src[2][0]; 
00146         float b3 = src[2][1]; 
00147         float c3 = src[2][2]; 
00148         float d3 = src[2][3];
00149 
00150         float b2c3_b3c2 = b2 * c3 - b3 * c2;
00151         float a3c2_a2c3 = a3 * c2 - a2 * c3;
00152         float a2b3_a3b2 = a2 * b3 - a3 * b2;
00153 
00154         float rDet      = (a1 * (b2c3_b3c2) + b1 * (a3c2_a2c3) + c1 * (a2b3_a3b2));
00155         if(rDet == 0.0f) return false;
00156         rDet = 1.0f / rDet;
00157 
00158         b2c3_b3c2       *= rDet;
00159         a3c2_a2c3       *= rDet;
00160         a2b3_a3b2       *= rDet;
00161         a1                      *= rDet;
00162         b1                      *= rDet;
00163         c1                      *= rDet;
00164 
00165         float c1b3_b1c3 = c1 * b3 - b1 * c3;
00166         float b1c2_c1b2 = b1 * c2 - c1 * b2;
00167 
00168         m[0][0] = b2c3_b3c2;
00169         m[0][1] = c1b3_b1c3;
00170         m[0][2] = b1c2_c1b2;
00171         m[0][3] =-(d1 * (b2c3_b3c2) + d2 * (c1b3_b1c3) + d3 * (b1c2_c1b2));
00172 
00173         float c1a2_a1c2 = c1 * a2 - a1 * c2;
00174         float a1c3_c1a3 = a1 * c3 - c1 * a3;
00175 
00176         m[1][0] = a3c2_a2c3;
00177         m[1][1] = a1c3_c1a3;
00178         m[1][2] = c1a2_a1c2;
00179         m[1][3] =-(d1 * (a3c2_a2c3) + d2 * (a1c3_c1a3) + d3 * (c1a2_a1c2));
00180 
00181         float b1a3_a1b3 = b1 * a3 - a1 * b3;
00182         float a1b2_b1a2 = a1 * b2 - b1 * a2;
00183 
00184         m[2][0] = a2b3_a3b2;
00185         m[2][1] = b1a3_a1b3;
00186         m[2][2] = a1b2_b1a2;
00187         m[2][3] =-(d1 * (a2b3_a3b2) + d2 * (b1a3_a1b3) + d3 * (a1b2_b1a2));
00188 
00189         return true;
00190 }
00191 
00192 //===================================================================
00193 //                                              Matrix4x4
00194 //===================================================================
00195 
00196 // avoid underflow in any of the components...
00197 void Matrix4x4::flushToZero (void)                      
00198 {
00199         const double EPSILON = 1e-15;
00200 
00201         for (int j = 0; j < 4; j++)
00202         for (int i = 0; i < 4; i++)
00203         if (fabs(m[j][i]) <= EPSILON)
00204                 m[j][i] = 0.0f;
00205 }
00206 
00207 void Matrix4x4::transpose (const Matrix4x4& src)
00208 {
00209         if (&src == this)
00210         {
00211                 this->transpose();
00212                 return;
00213         }
00214 
00215         // note that transposition is _not_ the same as matrix inversion
00216         // with generic 4x4 matrices (see Matrix4x4::invert)
00217 
00218         m[0][0] = src[0][0];
00219         m[0][1] = src[1][0];
00220         m[0][2] = src[2][0];
00221         m[0][3] = src[3][0];
00222         m[1][0] = src[0][1];
00223         m[1][1] = src[1][1];
00224         m[1][2] = src[2][1];
00225         m[1][3] = src[3][1];
00226         m[2][0] = src[0][2];
00227         m[2][1] = src[1][2];
00228         m[2][2] = src[2][2];
00229         m[2][3] = src[3][2];
00230         m[3][0] = src[0][3];
00231         m[3][1] = src[1][3];
00232         m[3][2] = src[2][3];
00233         m[3][3] = src[3][3];
00234 }
00235 
00236 void Matrix4x4::transpose (void)
00237 {
00238         float tmp;
00239         tmp = m[0][1]; m[0][1] = m[1][0]; m[1][0] = tmp;
00240         tmp = m[0][2]; m[0][2] = m[2][0]; m[2][0] = tmp;
00241         tmp = m[0][3]; m[0][3] = m[3][0]; m[3][0] = tmp;
00242         tmp = m[1][2]; m[1][2] = m[2][1]; m[2][1] = tmp;
00243         tmp = m[1][3]; m[1][3] = m[3][1]; m[3][1] = tmp;
00244         tmp = m[2][3]; m[2][3] = m[3][2]; m[3][2] = tmp;
00245 }
00246 
00247 float Matrix4x4::det2x2( float a, float b, float c, float d ) const
00248 {
00249         return a * d - b * c;
00250 }
00251 
00252 float Matrix4x4::det3x3( float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3 ) const
00253 {
00254         return a1 * det2x2 (b2, b3, c2, c3) - b1 * det2x2 (a2, a3, c2, c3) + c1 * det2x2 (a2, a3, b2, b3);
00255 }
00256 
00257 float Matrix4x4::det() const
00258 {
00259         return m[0][0] * det3x3( m[1][1], m[2][1], m[3][1], m[1][2], m[2][2], m[3][2], m[1][3], m[2][3], m[3][3] ) -
00260                    m[0][1] * det3x3( m[1][0], m[2][0], m[3][0], m[1][2], m[2][2], m[3][2], m[1][3], m[2][3], m[3][3] ) +
00261                    m[0][2] * det3x3( m[1][0], m[2][0], m[3][0], m[1][1], m[2][1], m[3][1], m[1][3], m[2][3], m[3][3] ) -
00262                    m[0][3] * det3x3( m[1][0], m[2][0], m[3][0], m[1][1], m[2][1], m[3][1], m[1][2], m[2][2], m[3][2] );
00263 }
00264 
00265 bool Matrix4x4::operator== (const Matrix4x4& n) const
00266 {
00267         const float* d = (const float*)&(m[0][0]);
00268         const float* s = (const float*)&(n[0][0]);
00269         for (int i = 0; i < 16; i++)
00270         if (d[i]!=s[i])
00271                 return false;
00272         return true;
00273 }
00274 
00275 void Matrix4x4::operator*= (const Matrix4x4& m2)
00276 {
00277         SS_ASSERT(&m2 != this);
00278 
00279         Matrix4x4 m1 = *this;
00280         m[0][0] = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0] + m1[0][2]*m2[2][0] + m1[0][3]*m2[3][0];
00281         m[0][1] = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1] + m1[0][2]*m2[2][1] + m1[0][3]*m2[3][1];
00282         m[0][2] = m1[0][0]*m2[0][2] + m1[0][1]*m2[1][2] + m1[0][2]*m2[2][2] + m1[0][3]*m2[3][2];
00283         m[0][3] = m1[0][0]*m2[0][3] + m1[0][1]*m2[1][3] + m1[0][2]*m2[2][3] + m1[0][3]*m2[3][3];
00284         m[1][0] = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0] + m1[1][2]*m2[2][0] + m1[1][3]*m2[3][0];
00285         m[1][1] = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1] + m1[1][2]*m2[2][1] + m1[1][3]*m2[3][1];
00286         m[1][2] = m1[1][0]*m2[0][2] + m1[1][1]*m2[1][2] + m1[1][2]*m2[2][2] + m1[1][3]*m2[3][2];
00287         m[1][3] = m1[1][0]*m2[0][3] + m1[1][1]*m2[1][3] + m1[1][2]*m2[2][3] + m1[1][3]*m2[3][3];
00288         m[2][0] = m1[2][0]*m2[0][0] + m1[2][1]*m2[1][0] + m1[2][2]*m2[2][0] + m1[2][3]*m2[3][0];
00289         m[2][1] = m1[2][0]*m2[0][1] + m1[2][1]*m2[1][1] + m1[2][2]*m2[2][1] + m1[2][3]*m2[3][1];
00290         m[2][2] = m1[2][0]*m2[0][2] + m1[2][1]*m2[1][2] + m1[2][2]*m2[2][2] + m1[2][3]*m2[3][2];
00291         m[2][3] = m1[2][0]*m2[0][3] + m1[2][1]*m2[1][3] + m1[2][2]*m2[2][3] + m1[2][3]*m2[3][3];
00292         m[3][0] = m1[3][0]*m2[0][0] + m1[3][1]*m2[1][0] + m1[3][2]*m2[2][0] + m1[3][3]*m2[3][0];
00293         m[3][1] = m1[3][0]*m2[0][1] + m1[3][1]*m2[1][1] + m1[3][2]*m2[2][1] + m1[3][3]*m2[3][1];
00294         m[3][2] = m1[3][0]*m2[0][2] + m1[3][1]*m2[1][2] + m1[3][2]*m2[2][2] + m1[3][3]*m2[3][2];
00295         m[3][3] = m1[3][0]*m2[0][3] + m1[3][1]*m2[1][3] + m1[3][2]*m2[2][3] + m1[3][3]*m2[3][3];
00296 }
00297 
00298 void Matrix4x4::operator*= (float f)
00299 {
00300         for (int j = 0; j < 4; j++)
00301         for (int i = 0; i < 4; i++)
00302                 m[j][i] *= f;
00303 }
00304 
00305 void Matrix4x4::clear (void)
00306 {
00307         memset (this, 0, sizeof(Matrix4x4));
00308 }
00309 
00310 void Matrix4x4::ident (void)
00311 {
00312         m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f;
00313         m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f;
00314         m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f;
00315         m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f;
00316 }
00317 
00318 /******************************************************************************
00319  *
00320  * Function:            
00321  *
00322  * Description:         Matrix4x4 inversion code
00323  *
00324  * Notes:                       this == &src is supported
00325  *
00326  ******************************************************************************/
00327 
00328 bool Matrix4x4::invert  ()
00329 {
00330         // perform 4x3 inversion if possible
00331         if(is3x4Matrix())
00332         {
00333                 Matrix3x4& m = reinterpret_cast<Matrix3x4&>(*this);             // consider 4x3
00334                 bool invertible = m.invert();                   // invert 4x3
00335                 this->m[3][0] = 0;                                                                              // clear 4th row
00336                 this->m[3][1] = 0;
00337                 this->m[3][2] = 0;
00338                 this->m[3][3] = 1.0f;
00339                 return invertible;
00340         }
00341 
00342         // perform full 4x4 inversion
00343         Matrix4x4 src = *this;
00344 
00345         const float a4 = src[3][0]; 
00346         const float b4 = src[3][1]; 
00347         const float c4 = src[3][2]; 
00348         const float d4 = src[3][3];
00349         const float a1 = src[0][0]; 
00350         const float b1 = src[0][1]; 
00351         const float c1 = src[0][2]; 
00352         const float d1 = src[0][3];
00353         const float a2 = src[1][0]; 
00354         const float b2 = src[1][1]; 
00355         const float c2 = src[1][2]; 
00356         const float d2 = src[1][3];
00357         const float a3 = src[2][0];
00358         const float b3 = src[2][1]; 
00359         const float c3 = src[2][2]; 
00360         const float d3 = src[2][3];
00361 
00362         float a3b4_a4b3 = a3 * b4 - a4 * b3 ;
00363         float a3c4_a4c3 = a3 * c4 - a4 * c3 ;
00364         float a3d4_a4d3 = a3 * d4 - a4 * d3 ;
00365         float b3c4_b4c3 = b3 * c4 - b4 * c3 ;
00366         float b3d4_b4d3 = b3 * d4 - b4 * d3 ;
00367         float c3d4_c4d3 = c3 * d4 - c4 * d3 ;
00368         
00369         m[0][0]                 = (b2 * c3d4_c4d3 - c2 * b3d4_b4d3 + d2 * b3c4_b4c3);
00370         m[1][0]                 =-(a2 * c3d4_c4d3 - c2 * a3d4_a4d3 + d2 * a3c4_a4c3);
00371         m[2][0]                 = (a2 * b3d4_b4d3 - b2 * a3d4_a4d3 + d2 * a3b4_a4b3);
00372         m[3][0]                 =-(a2 * b3c4_b4c3 - b2 * a3c4_a4c3 + c2 * a3b4_a4b3);
00373         m[0][1]                 =-(b1 * c3d4_c4d3 - c1 * b3d4_b4d3 + d1 * b3c4_b4c3);
00374         m[1][1]                 = (a1 * c3d4_c4d3 - c1 * a3d4_a4d3 + d1 * a3c4_a4c3);
00375         m[2][1]                 =-(a1 * b3d4_b4d3 - b1 * a3d4_a4d3 + d1 * a3b4_a4b3);
00376         m[3][1]                 = (a1 * b3c4_b4c3 - b1 * a3c4_a4c3 + c1 * a3b4_a4b3);
00377 
00378         float a2d4_a4d2 = a2 * d4 - a4 * d2;
00379         float a2b4_a4b2 = a2 * b4 - a4 * b2;
00380         float a2c4_a4c2 = a2 * c4 - a4 * c2;
00381         float b2c4_b4c2 = b2 * c4 - b4 * c2;
00382         float b2d4_b4d2 = b2 * d4 - b4 * d2;
00383         float c2d4_c4d2 = c2 * d4 - c4 * d2;
00384 
00385         m[0][2]                 = (b1 * c2d4_c4d2 - c1 * b2d4_b4d2 + d1 * b2c4_b4c2);
00386         m[1][2]                 =-(a1 * c2d4_c4d2 - c1 * a2d4_a4d2 + d1 * a2c4_a4c2);
00387         m[2][2]                 = (a1 * b2d4_b4d2 - b1 * a2d4_a4d2 + d1 * a2b4_a4b2);
00388         m[3][2]                 =-(a1 * b2c4_b4c2 - b1 * a2c4_a4c2 + c1 * a2b4_a4b2);
00389 
00390         float a2b3_a3b2 = a2 * b3 - a3 * b2;
00391         float a2c3_a3c2 = a2 * c3 - a3 * c2;
00392         float a2d3_a3d2 = a2 * d3 - a3 * d2;
00393         float b2c3_b3c2 = b2 * c3 - b3 * c2;
00394         float b2d3_b3d2 = b2 * d3 - b3 * d2;
00395         float c2d3_c3d2 = c2 * d3 - c3 * d2;
00396 
00397         m[0][3]                 =-(b1 * c2d3_c3d2 - c1 * b2d3_b3d2 + d1 * b2c3_b3c2);
00398         m[1][3]                 = (a1 * c2d3_c3d2 - c1 * a2d3_a3d2 + d1 * a2c3_a3c2);
00399         m[2][3]                 =-(a1 * b2d3_b3d2 - b1 * a2d3_a3d2 + d1 * a2b3_a3b2);
00400         m[3][3]                 = (a1 * b2c3_b3c2 - b1 * a2c3_a3c2 + c1 * a2b3_a3b2);
00401 
00402         float  det              = a1 * m[0][0] + b1 * m[1][0] + c1 * m[2][0] + d1 * m[3][0];
00403         if (det == 0.0f) return false;
00404 
00405         if (det != 1.0f)
00406         {
00407                 det = 1.0f/det;
00408                 m[0][0] = m[0][0]*det;
00409                 m[0][1] = m[0][1]*det;
00410                 m[0][2] = m[0][2]*det;
00411                 m[0][3] = m[0][3]*det;
00412                 m[1][0] = m[1][0]*det;
00413                 m[1][1] = m[1][1]*det;
00414                 m[1][2] = m[1][2]*det;
00415                 m[1][3] = m[1][3]*det;
00416                 m[2][0] = m[2][0]*det;
00417                 m[2][1] = m[2][1]*det;
00418                 m[2][2] = m[2][2]*det;
00419                 m[2][3] = m[2][3]*det;
00420                 m[3][0] = m[3][0]*det;
00421                 m[3][1] = m[3][1]*det;
00422                 m[3][2] = m[3][2]*det;
00423                 m[3][3] = m[3][3]*det;
00424         } 
00425 
00426         return true;
00427 }
00428 
00429 
00430 //===================================================================
00431 //                                              Matrix3x3
00432 //===================================================================
00433 
00434 // avoid underflow in any of the components...
00435 void Matrix3x3::flushToZero (void)                      
00436 {
00437         const double EPSILON = 1e-15;
00438 
00439         for (int j = 0; j < 3; j++)
00440         for (int i = 0; i < 3; i++)
00441         if (fabs(m[j][i]) <= EPSILON)
00442                 m[j][i] = 0.0f;
00443 }
00444 
00445 void Matrix3x3::transpose (const Matrix3x3& src)
00446 {
00447         if (&src == this)
00448         {
00449                 this->transpose();
00450                 return;
00451         }
00452 
00453         // note that transposition is _not_ the same as matrix inversion
00454         // with generic 3x3 matrices (see Matrix3x3::invert)
00455 
00456         m[0][0] = src[0][0];
00457         m[0][1] = src[1][0];
00458         m[0][2] = src[2][0];
00459         m[1][0] = src[0][1];
00460         m[1][1] = src[1][1];
00461         m[1][2] = src[2][1];
00462         m[2][0] = src[0][2];
00463         m[2][1] = src[1][2];
00464         m[2][2] = src[2][2];
00465 }
00466 
00467 void Matrix3x3::transpose (void)
00468 {
00469         float tmp;
00470         tmp = m[0][1]; m[0][1] = m[1][0]; m[1][0] = tmp;
00471         tmp = m[0][2]; m[0][2] = m[2][0]; m[2][0] = tmp;
00472         tmp = m[1][2]; m[1][2] = m[2][1]; m[2][1] = tmp;
00473 }
00474 
00475 float Matrix3x3::det (void)
00476 {
00477     return m[0][0] * (m[1][1]*m[2][2] - m[2][1]*m[1][2]) +
00478            m[0][1] * (m[2][0]*m[1][2] - m[1][0]*m[2][2]) +
00479            m[0][2] * (m[1][0]*m[2][1] - m[2][0]*m[1][1]);
00480 }
00481 
00482 
00483 bool Matrix3x3::operator== (const Matrix3x3& n) const
00484 {
00485         const float* d = (const float*)&(m[0][0]);
00486         const float* s = (const float*)&(n[0][0]);
00487         for (int i = 0; i < 9; i++)
00488         if (d[i]!=s[i])
00489                 return false;
00490         return true;
00491 }
00492 
00493 void Matrix3x3::operator*= (const Matrix3x3& m2)
00494 {
00495         SS_ASSERT(&m2 != this);
00496 
00497         Matrix3x3 m1 = *this;
00498         m[0][0] = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0] + m1[0][2]*m2[2][0];
00499         m[0][1] = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1] + m1[0][2]*m2[2][1];
00500         m[0][2] = m1[0][0]*m2[0][2] + m1[0][1]*m2[1][2] + m1[0][2]*m2[2][2];
00501         m[1][0] = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0] + m1[1][2]*m2[2][0];
00502         m[1][1] = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1] + m1[1][2]*m2[2][1];
00503         m[1][2] = m1[1][0]*m2[0][2] + m1[1][1]*m2[1][2] + m1[1][2]*m2[2][2];
00504         m[2][0] = m1[2][0]*m2[0][0] + m1[2][1]*m2[1][0] + m1[2][2]*m2[2][0];
00505         m[2][1] = m1[2][0]*m2[0][1] + m1[2][1]*m2[1][1] + m1[2][2]*m2[2][1];
00506         m[2][2] = m1[2][0]*m2[0][2] + m1[2][1]*m2[1][2] + m1[2][2]*m2[2][2];
00507 }
00508 
00509 void Matrix3x3::operator*= (float f)
00510 {
00511         for (int j = 0; j < 3; j++)
00512         for (int i = 0; i < 3; i++)
00513                 m[j][i] *= f;
00514 }
00515 
00516 void Matrix3x3::clear (void)
00517 {
00518         memset (this, 0, sizeof(Matrix3x3));
00519 }
00520 
00521 void Matrix3x3::ident (void)
00522 {
00523         m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f;
00524         m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f;
00525         m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f;
00526 }
00527 
00528 
00529 /******************************************************************************
00530  *
00531  * Function:            
00532  *
00533  * Description:         Matrix3x3 inversion code
00534  *
00535  * Notes:                       this == &src is supported
00536  *
00537  ******************************************************************************/
00538 
00539 bool Matrix3x3::invert  ()
00540 {
00541         Matrix3x3 t = *this;
00542 
00543         float t1122_2112, t2012_1022, t1021_2011;
00544         float det;
00545 
00546         t1122_2112 = t[1][1]*t[2][2] - t[2][1]*t[1][2];
00547         t2012_1022 = t[2][0]*t[1][2] - t[1][0]*t[2][2];
00548         t1021_2011 = t[1][0]*t[2][1] - t[2][0]*t[1][1];
00549 
00550         det = t[0][0]*t1122_2112 + t[0][1]*t2012_1022 + t[0][2]*t1021_2011;
00551         if( det == 0.0f ) return false;
00552 
00553         det = 1.0f / det;
00554         m[0][0] = det * t1122_2112;
00555         m[1][0] = det * t2012_1022;
00556         m[2][0] = det * t1021_2011;
00557         m[0][1] = det * (t[2][1]*t[0][2] - t[0][1]*t[2][2]);
00558         m[1][1] = det * (t[0][0]*t[2][2] - t[2][0]*t[0][2]);
00559         m[2][1] = det * (t[2][0]*t[0][1] - t[0][0]*t[2][1]);
00560         m[0][2] = det * (t[0][1]*t[1][2] - t[1][1]*t[0][2]);
00561         m[1][2] = det * (t[1][0]*t[0][2] - t[0][0]*t[1][2]);
00562         m[2][2] = det * (t[0][0]*t[1][1] - t[1][0]*t[0][1]);
00563 
00564         return true;
00565 }
00566 
00567 
00568 //===================================================================
00569 //                                              Matrix3x3
00570 //===================================================================
00571 
00572 // avoid underflow in any of the components...
00573 void Matrix2x2::flushToZero (void)                      
00574 {
00575         const double EPSILON = 1e-15;
00576 
00577         for (int j = 0; j < 2; j++)
00578         for (int i = 0; i < 2; i++)
00579         if (fabs(m[j][i]) <= EPSILON)
00580                 m[j][i] = 0.0f;
00581 }
00582 
00583 void Matrix2x2::transpose (const Matrix2x2& src)
00584 {
00585         if (&src == this)
00586         {
00587                 this->transpose();
00588                 return;
00589         }
00590 
00591         // note that transposition is _not_ the same as matrix inversion
00592         // with generic 2x2 matrices (see Matrix2x2::invert)
00593 
00594         m[0][0] = src[0][0];
00595         m[0][1] = src[1][0];
00596         m[1][0] = src[0][1];
00597         m[1][1] = src[1][1];
00598 }
00599 
00600 void Matrix2x2::transpose (void)
00601 {
00602         float tmp;
00603         tmp = m[0][1]; m[0][1] = m[1][0]; m[1][0] = tmp;
00604 }
00605 
00606 float Matrix2x2::det (void)
00607 {
00608     return m[0][0] * m[1][1] - m[0][1]*m[1][0];
00609 }
00610 
00611 bool Matrix2x2::operator== (const Matrix2x2& n) const
00612 {
00613         const float* d = (const float*)&(m[0][0]);
00614         const float* s = (const float*)&(n[0][0]);
00615         for (int i = 0; i < 4; i++)
00616         if (d[i]!=s[i])
00617                 return false;
00618         return true;
00619 }
00620 
00621 void Matrix2x2::operator*= (const Matrix2x2& m2)
00622 {
00623         SS_ASSERT(&m2 != this);
00624 
00625         Matrix2x2 m1 = *this;
00626         m[0][0] = m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0];
00627         m[0][1] = m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1];
00628         m[1][0] = m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0];
00629         m[1][1] = m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1];
00630 }
00631 
00632 void Matrix2x2::operator*= (float f)
00633 {
00634         for (int j = 0; j < 2; j++)
00635         for (int i = 0; i < 2; i++)
00636                 m[j][i] *= f;
00637 }
00638 
00639 void Matrix2x2::clear (void)
00640 {
00641         memset (this, 0, sizeof(Matrix2x2));
00642 }
00643 
00644 void Matrix2x2::ident (void)
00645 {
00646         m[0][0] = 1.0f; m[0][1] = 0.0f;
00647         m[1][0] = 0.0f; m[1][1] = 1.0f;
00648 }
00649 
00650 /******************************************************************************
00651  *
00652  * Function:            
00653  *
00654  * Description:         Matrix2x2 inversion code
00655  *
00656  * Notes:                       this == &src is supported
00657  *
00658  ******************************************************************************/
00659 
00660 bool Matrix2x2::invert  ()
00661 {
00662         Matrix2x2 t = *this;
00663 
00664         float d = t.det();
00665         if( d == 0.0f ) return false;
00666         d = 1.0f / d;
00667 
00668         m[0][0] = t[1][1] * d;
00669         m[0][1] = -t[0][1] * d;
00670         m[1][0] = -t[1][0] * d;
00671         m[1][1] = t[0][0] * d;
00672 
00673         return true;
00674 }

Generated on Thu Feb 15 09:09:20 2007 for Surface Splating by  doxygen 1.5.1-p1