#include #include #include #include #include #include using namespace osg; #define DEG2RAD(x) ((x)*M_PI/180.0) #define RAD2DEG(x) ((x)*180.0/M_PI) #define SET_ROW(row, v1, v2, v3, v4 ) \ _mat[(row)][0] = (v1); \ _mat[(row)][1] = (v2); \ _mat[(row)][2] = (v3); \ _mat[(row)][3] = (v4); #define INNER_PRODUCT(a,b,r,c) \ ((a)._mat[r][0] * (b)._mat[0][c]) \ +((a)._mat[r][1] * (b)._mat[1][c]) \ +((a)._mat[r][2] * (b)._mat[2][c]) \ +((a)._mat[r][3] * (b)._mat[3][c]) Matrix::Matrix() : Object(), fully_realized(false) {} Matrix::Matrix( const Matrix& other ) : Object() { set( (const float *) other._mat ); } Matrix::Matrix( const float * def ) { set( def ); } Matrix::Matrix( float a00, float a01, float a02, float a03, float a10, float a11, float a12, float a13, float a20, float a21, float a22, float a23, float a30, float a31, float a32, float a33) { SET_ROW(0, a00, a01, a02, 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 ) { if( &other == this ) return *this; set((const float*)other._mat); return *this; } void Matrix::set( float const * const def ) { memcpy( _mat, def, sizeof(_mat) ); fully_realized = true; } void Matrix::set( float a00, float a01, float a02, float a03, float a10, float a11, float a12, float a13, float a20, float a21, float a22, float a23, float a30, float a31, float a32, float a33) { SET_ROW(0, a00, a01, a02, 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; } void Matrix::setTrans( const Vec3& v ) { #ifdef WARN_DEPRECATED notify(NOTICE) << "Matrix::setTrans is deprecated."<(_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) || (fabs(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; }