From 7293af59ed7b8deb2cde4fad8d47759460b94674 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 5 Feb 2002 21:51:06 +0000 Subject: [PATCH] Have removed the old lazy initialization of Matrix since it was causing bugs and adding checks to many mothods which in the end slow it down more than not intilizing the code! The code is now simpler, more robust and faster:-) --- include/osg/Matrix | 33 +++++++++---- src/osg/Matrix.cpp | 120 ++++++++++++++++++--------------------------- 2 files changed, 73 insertions(+), 80 deletions(-) diff --git a/include/osg/Matrix b/include/osg/Matrix index 233e489e9..1eedae981 100644 --- a/include/osg/Matrix +++ b/include/osg/Matrix @@ -15,6 +15,16 @@ namespace osg { class Quat; +/** The range of matrix modes that the scene graph might utilize. + * Similar in concept to different modes in OpenGL glMatrixMode().*/ +enum MatrixMode +{ + PROJECTION, + VIEW, + MODEL, + MODELVIEW +}; + class SG_EXPORT Matrix : public Object { @@ -37,14 +47,22 @@ class SG_EXPORT Matrix : public Object Matrix& operator = (const Matrix& ); - int compare(const Matrix& m) const { ensureRealized(); m.ensureRealized(); return memcmp(_mat,m._mat,sizeof(_mat)); } + int compare(const Matrix& m) const { return memcmp(_mat,m._mat,sizeof(_mat)); } bool operator < (const Matrix& m) const { return compare(m)<0; } bool operator == (const Matrix& m) const { return compare(m)==0; } bool operator != (const Matrix& m) const { return compare(m)!=0; } - inline float& operator()(int row, int col) { ensureRealized(); return _mat[row][col]; } - inline float operator()(int row, int col) const { ensureRealized(); return _mat[row][col]; } + inline float& operator()(int row, int col) { return _mat[row][col]; } + inline float operator()(int row, int col) const { return _mat[row][col]; } + + inline const bool valid() const { return !isNaN(); } + inline const bool isNaN() const { return osg::isNaN(_mat[0][0]) || osg::isNaN(_mat[0][1]) || osg::isNaN(_mat[0][2]) || osg::isNaN(_mat[0][3]) || + osg::isNaN(_mat[1][0]) || osg::isNaN(_mat[1][1]) || osg::isNaN(_mat[1][2]) || osg::isNaN(_mat[1][3]) || + osg::isNaN(_mat[2][0]) || osg::isNaN(_mat[2][1]) || osg::isNaN(_mat[2][2]) || osg::isNaN(_mat[2][3]) || + osg::isNaN(_mat[3][0]) || osg::isNaN(_mat[3][1]) || osg::isNaN(_mat[3][2]) || osg::isNaN(_mat[3][3]); } + + void set( float const * const ); void set( float a00, float a01, float a02, float a03, @@ -52,10 +70,8 @@ class SG_EXPORT Matrix : public Object float a20, float a21, float a22, float a23, float a30, float a31, float a32, float a33); - float * ptr() { ensureRealized(); return (float *)_mat; } - const float * ptr() const { ensureRealized(); return (const float *)_mat; } - - inline void ensureRealized() const { if (!fully_realized) const_cast(this)->makeIdentity();} + float * ptr() { return (float *)_mat; } + const float * ptr() const { return (const float *)_mat; } void makeIdentity(); @@ -94,7 +110,7 @@ class SG_EXPORT Matrix : public Object void setTrans( float tx, float ty, float tz ); void setTrans( const Vec3& v ); - Vec3 getTrans() const { ensureRealized(); return Vec3(_mat[3][0],_mat[3][1],_mat[3][2]); } + Vec3 getTrans() const { return Vec3(_mat[3][0],_mat[3][1],_mat[3][2]); } /** apply apply an 3x3 transform of v*M[0..2,0..2] */ inline static Vec3 transform3x3(const Vec3& v,const Matrix& m); @@ -149,7 +165,6 @@ class SG_EXPORT Matrix : public Object private: float _mat[4][4]; - bool fully_realized; }; diff --git a/src/osg/Matrix.cpp b/src/osg/Matrix.cpp index b0d7325ea..642377749 100644 --- a/src/osg/Matrix.cpp +++ b/src/osg/Matrix.cpp @@ -21,7 +21,10 @@ using namespace osg; +((a)._mat[r][3] * (b)._mat[3][c]) -Matrix::Matrix() : Object(), fully_realized(false) {} +Matrix::Matrix() : Object() +{ + makeIdentity(); +} Matrix::Matrix( const Matrix& other) : Object() { @@ -42,20 +45,19 @@ Matrix::Matrix( float a00, float a01, float a02, float a03, SET_ROW(1, a10, a11, a12, a13 ) SET_ROW(2, a20, a21, a22, a23 ) SET_ROW(3, a30, a31, a32, a33 ) - - fully_realized = true; } -Matrix& Matrix::operator = (const Matrix& other ) { +Matrix& Matrix::operator = (const Matrix& other ) +{ if( &other == this ) return *this; set((const float*)other._mat); return *this; } -void Matrix::set( float const * const def ) { +void Matrix::set( float const * const def ) +{ memcpy( _mat, def, sizeof(_mat) ); - fully_realized = true; } @@ -68,14 +70,10 @@ void Matrix::set( float a00, float a01, float a02, float a03, SET_ROW(1, a10, a11, a12, a13 ) SET_ROW(2, a20, a21, a22, a23 ) SET_ROW(3, a30, a31, a32, a33 ) - - fully_realized = true; } void Matrix::setTrans( float tx, float ty, float tz ) { - ensureRealized(); - _mat[3][0] = tx; _mat[3][1] = ty; _mat[3][2] = tz; @@ -95,8 +93,6 @@ void Matrix::makeIdentity() SET_ROW(1, 0, 1, 0, 0 ) SET_ROW(2, 0, 0, 1, 0 ) SET_ROW(3, 0, 0, 0, 1 ) - - fully_realized = true; } void Matrix::makeScale( const Vec3& v ) @@ -110,8 +106,6 @@ void Matrix::makeScale( float x, float y, float z ) SET_ROW(1, 0, y, 0, 0 ) SET_ROW(2, 0, 0, z, 0 ) SET_ROW(3, 0, 0, 0, 1 ) - - fully_realized = true; } void Matrix::makeTranslate( const Vec3& v ) @@ -125,8 +119,6 @@ void Matrix::makeTranslate( float x, float y, float z ) SET_ROW(1, 0, 1, 0, 0 ) SET_ROW(2, 0, 0, 1, 0 ) SET_ROW(3, x, y, z, 1 ) - - fully_realized = true; } void Matrix::makeRotate( const Vec3& from, const Vec3& to ) @@ -153,7 +145,6 @@ void Matrix::makeRotate( float angle, float x, float y, float z ) void Matrix::makeRotate( const Quat& q ) { q.get(*this); - fully_realized = true; } void Matrix::makeRotate( float yaw, float pitch, float roll) @@ -177,7 +168,8 @@ void Matrix::makeRotate( float yaw, float pitch, float roll) } void Matrix::mult( const Matrix& lhs, const Matrix& rhs ) -{ +{ + // PRECONDITION: We assume neither &lhs nor &rhs == this // if it did, use preMult or postMult instead _mat[0][0] = INNER_PRODUCT(lhs, rhs, 0, 0); @@ -196,17 +188,10 @@ void Matrix::mult( const Matrix& lhs, const Matrix& rhs ) _mat[3][1] = INNER_PRODUCT(lhs, rhs, 3, 1); _mat[3][2] = INNER_PRODUCT(lhs, rhs, 3, 2); _mat[3][3] = INNER_PRODUCT(lhs, rhs, 3, 3); - fully_realized = true; } void Matrix::preMult( const Matrix& other ) { - if( !fully_realized ) { - //act as if this were an identity Matrix - set((const float*)other._mat); - return; - } - // brute force method requiring a copy //Matrix tmp(other* *this); // *this = tmp; @@ -228,11 +213,6 @@ void Matrix::preMult( const Matrix& other ) void Matrix::postMult( const Matrix& other ) { - if( !fully_realized ) { - //act as if this were an identity Matrix - set((const float*)other._mat); - return; - } // brute force method requiring a copy //Matrix tmp(*this * other); // *this = tmp; @@ -252,31 +232,31 @@ void Matrix::postMult( const Matrix& other ) #undef SET_ROW #undef INNER_PRODUCT -bool Matrix::invert( const Matrix& _m ) +bool Matrix::invert( const Matrix& other ) { - - if (&_m==this) + if (&other==this) { - Matrix tm(_m); + Matrix tm(other); return invert(tm); } - /*if ( _m._mat[0][3] == 0.0 - && _m._mat[1][3] == 0.0 - && _m._mat[2][3] == 0.0 - && _m._mat[3][3] == 1.0 ) - { - return invertAffine( _m ); - }*/ + +// if ( other._mat[0][3] == 0.0 +// && other._mat[1][3] == 0.0 +// && other._mat[2][3] == 0.0 +// && other._mat[3][3] == 1.0 ) +// { +// return invertAffine( other ); +// } // code lifted from VR Juggler. // not cleanly added, but seems to work. RO. - const float* a = reinterpret_cast(_m._mat); + const float* a = reinterpret_cast(other._mat); float* b = reinterpret_cast(_mat); int n = 4; int i, j, k; int r[ 4], c[ 4], row[ 4], col[ 4]; - float m[ 4][ 4*2], pivot, max_m, tmp_m, fac; + float m[ 4][ 4*2], pivot, maxother, tmpother, fac; /* Initialization */ for ( i = 0; i < n; i ++ ) @@ -299,16 +279,16 @@ bool Matrix::invert( const Matrix& _m ) for ( k = 0; k < n; k++ ) { /* Choosing the pivot */ - for ( i = 0, max_m = 0; i < n; i++ ) + for ( i = 0, maxother = 0; i < n; i++ ) { if ( row[ i] ) continue; for ( j = 0; j < n; j++ ) { if ( col[ j] ) continue; - tmp_m = fabs( m[ i][j]); - if ( tmp_m > max_m) + tmpother = fabs( m[ i][j]); + if ( tmpother > maxother) { - max_m = tmp_m; + maxother = tmpother; r[ k] = i; c[ k] = j; } @@ -319,8 +299,9 @@ bool Matrix::invert( const Matrix& _m ) if ( fabs( pivot) <= 1e-20) { - notify(WARN) << "*** pivot = %f in mat_inv. ***"<