#include #include #include #include #include //memcpy #include //acos #include using namespace osg; #define DEG2RAD(x) ((x)*M_PI/180.0) #define RAD2DEG(x) ((x)*180.0/M_PI) // temporary #define's for warning that deprecated methods are being // used which should be replaced by the new variants. #define WARN_DEPRECATED //#define ABORT_DEPRECATED #ifdef WARN_DEPRECATED #ifdef ABORT_DEPRECATED #define DEPRECATED(message) \ notify(NOTICE) << message<(_m._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; /* Initialization */ for ( i = 0; i < n; i ++ ) { r[ i] = c[ i] = 0; row[ i] = col[ i] = 0; } /* Set working Matrix */ for ( i = 0; i < n; i++ ) { for ( j = 0; j < n; j++ ) { m[ i][ j] = a[ i * n + j]; m[ i][ j + n] = ( i == j ) ? 1.0 : 0.0 ; } } /* Begin of loop */ for ( k = 0; k < n; k++ ) { /* Choosing the pivot */ for ( i = 0, max_m = 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) { max_m = tmp_m; r[ k] = i; c[ k] = j; } } } row[ r[k] ] = col[ c[k] ] = 1; pivot = m[ r[ k] ][ c[ k] ]; if ( fabs( pivot) <= 1e-20) { notify(WARN) << "*** pivot = %f in mat_inv. ***"<isAffine())? double det_1, pos, neg, temp; pos = neg = 0.0; #define ACCUMULATE \ { \ if(temp >= 0.0) pos += temp; \ else neg += temp; \ } temp = _m._mat[0][0] * _m._mat[1][1] * _m._mat[2][2]; ACCUMULATE; temp = _m._mat[0][1] * _m._mat[1][2] * _m._mat[2][0]; ACCUMULATE; temp = _m._mat[0][2] * _m._mat[1][0] * _m._mat[2][1]; ACCUMULATE; temp = - _m._mat[0][2] * _m._mat[1][1] * _m._mat[2][0]; ACCUMULATE; temp = - _m._mat[0][1] * _m._mat[1][0] * _m._mat[2][2]; ACCUMULATE; temp = - _m._mat[0][0] * _m._mat[1][2] * _m._mat[2][1]; ACCUMULATE; det_1 = pos + neg; if( (det_1 == 0.0) || (abs(det_1/(pos-neg)) < PRECISION_LIMIT )) { // _m has no inverse notify(WARN) << "Matrix::invert(): Matrix has no inverse." << endl; return false; } // inverse is adj(A)/det(A) det_1 = 1.0 / det_1; _mat[0][0] = (_m._mat[1][1] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][1]) * det_1; _mat[1][0] = (_m._mat[1][0] * _m._mat[2][2] - _m._mat[1][2] * _m._mat[2][0]) * det_1; _mat[2][0] = (_m._mat[1][0] * _m._mat[2][1] - _m._mat[1][1] * _m._mat[2][0]) * det_1; _mat[0][1] = (_m._mat[0][1] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][1]) * det_1; _mat[1][1] = (_m._mat[0][0] * _m._mat[2][2] - _m._mat[0][2] * _m._mat[2][0]) * det_1; _mat[2][1] = (_m._mat[0][0] * _m._mat[2][1] - _m._mat[0][1] * _m._mat[2][0]) * det_1; _mat[0][2] = (_m._mat[0][1] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][1]) * det_1; _mat[1][2] = (_m._mat[0][0] * _m._mat[1][2] - _m._mat[0][2] * _m._mat[1][0]) * det_1; _mat[2][2] = (_m._mat[0][0] * _m._mat[1][1] - _m._mat[0][1] * _m._mat[1][0]) * det_1; // calculate -C * inv(A) _mat[3][0] = -(_m._mat[3][0] * _mat[0][0] + _m._mat[3][1] * _mat[1][0] + _m._mat[3][2] * _mat[2][0] ); _mat[3][1] = -(_m._mat[3][0] * _mat[0][1] + _m._mat[3][1] * _mat[1][1] + _m._mat[3][2] * _mat[2][1] ); _mat[3][2] = -(_m._mat[3][0] * _mat[0][2] + _m._mat[3][1] * _mat[1][2] + _m._mat[3][2] * _mat[2][2] ); _mat[0][3] = 0.0; _mat[1][3] = 0.0; _mat[2][3] = 0.0; _mat[3][3] = 1.0; fully_realized = true; return true; } #ifdef USE_DEPRECATED_MATRIX_METHODS //Deprecated methods void Matrix::copy( const Matrix& other) { DEPRECATED("Matrix::copy is deprecated. Use = instead.") (*this) = other; } void Matrix::preScale( float sx, float sy, float sz, const Matrix& m ) { DEPRECATED("Matrix::preScale is deprecated. Use result = (Matrix::scale * m) instead.") (*this) = ( scale(sx,sy,sz) * m ); } void Matrix::postScale( const Matrix& m, float sx, float sy, float sz ) { DEPRECATED("Matrix::postScale is deprecated. Use result = (m * Matrix::scale()) instead.") (*this) = ( m * scale(sx,sy,sz) ); } void Matrix::preScale( float sx, float sy, float sz ) { DEPRECATED("Matrix::preScale is deprecated. Use M.preMult( Matrix::scale ) instead.") preMult( scale(sx,sy,sz) ); } void Matrix::postScale( float sx, float sy, float sz ) { DEPRECATED("Matrix::postScale is deprecated. Use M.postMult( Matrix::scale ) instead.") postMult( scale(sx,sy,sz) ); } void Matrix::preTrans( float tx, float ty, float tz, const Matrix& m ) { DEPRECATED("Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.") (*this) = trans(tx,ty,tz) * m; } void Matrix::postTrans( const Matrix& m, float tx, float ty, float tz ) { DEPRECATED("Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.") (*this) = m * trans(tx,ty,tz); } void Matrix::preTrans( float tx, float ty, float tz ) { DEPRECATED("Matrix::preTrans is deprecated. Use result = Matrix::trans * m instead.") preMult( trans(tx,ty,tz) ); } void Matrix::postTrans( float sx, float sy, float sz ) { DEPRECATED("Matrix::postTrans is deprecated. Use result = m * Matrix::trans instead.") postMult( trans(sx,sy,sz) ); } void Matrix::preRot( float deg, float x, float y, float z, const Matrix& m ) { DEPRECATED("Matrix::preRot is deprecated. Use result = Matrix::rot * m instead.") (*this) = rotate(deg,x,y,z) * m; } void Matrix::postRot( const Matrix& m, float deg, float x, float y, float z ) { DEPRECATED("Matrix::postRot is deprecated. Use result = m * Matrix::rotate instead.") (*this) = m * rotate(deg,x,y,z); } void Matrix::preRot( float deg, float x, float y, float z ) { DEPRECATED("Matrix::preRot is deprecated. Use m.preMult( Matrix::rotate ) instead.") preMult( rotate(deg,x,y,z) ); } void Matrix::postRot( float deg, float x, float y, float z ) { DEPRECATED("Matrix::postRot is deprecated. Use m.postMult( Matrix::rotate ) instead.") postMult( rotate(deg,x,y,z) ); } #endif