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. ***"<