Go to the documentation of this file.00001 #ifndef OPENTISSUE_UTILITY_GL_MATRIX_UTIL_H
00002 #define OPENTISSUE_UTILITY_GL_MATRIX_UTIL_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/gl/gl.h>
00013 #include <cassert>
00014
00015 namespace OpenTissue
00016 {
00017
00018 namespace gl
00019 {
00020
00029 template<typename real_type, typename vector3_type>
00030 inline vector3_type xform( real_type * M, vector3_type const & v )
00031 {
00032 real_type x = (M[ 0 ] * v[ 0 ]) + (M[ 4 ] * v[ 1 ]) + (M[ 8 ] * v[ 2 ]) + M[ 12 ];
00033 real_type y = (M[ 1 ] * v[ 0 ]) + (M[ 5 ] * v[ 1 ]) + (M[ 9 ] * v[ 2 ]) + M[ 13 ];
00034 real_type z = (M[ 2 ] * v[ 0 ]) + (M[ 6 ] * v[ 1 ]) + (M[ 10 ] * v[ 2 ]) + M[ 14 ];
00035 real_type w = (M[ 3 ] * v[ 0 ]) + (M[ 7 ] * v[ 1 ]) + (M[ 11 ] * v[ 2 ]) + M[ 15 ];
00036 assert(w || !"mul(M,v): w was zero");
00037 return vector3_type( x / w, y / w, z / w);
00038 }
00039
00052 template<typename real_type>
00053 inline void mul(real_type const* A,real_type const * B,real_type * C)
00054 {
00055 assert(A!=C || !"mul(A,B,C): A and C matrices must be different");
00056 assert(B!=C || !"mul(A,B,C): B and C matrices must be different");
00057
00058 C[ 0] = A[0]*B[ 0] + A[4]*B[ 1] + A[ 8]*B[ 2] + A[12]*B[ 3];
00059 C[ 1] = A[1]*B[ 0] + A[5]*B[ 1] + A[ 9]*B[ 2] + A[13]*B[ 3];
00060 C[ 2] = A[2]*B[ 0] + A[6]*B[ 1] + A[10]*B[ 2] + A[14]*B[ 3];
00061 C[ 3] = A[3]*B[ 0] + A[7]*B[ 1] + A[11]*B[ 2] + A[15]*B[ 3];
00062 C[ 4] = A[0]*B[ 4] + A[4]*B[ 5] + A[ 8]*B[ 6] + A[12]*B[ 7];
00063 C[ 5] = A[1]*B[ 4] + A[5]*B[ 5] + A[ 9]*B[ 6] + A[13]*B[ 7];
00064 C[ 6] = A[2]*B[ 4] + A[6]*B[ 5] + A[10]*B[ 6] + A[14]*B[ 7];
00065 C[ 7] = A[3]*B[ 4] + A[7]*B[ 5] + A[11]*B[ 6] + A[15]*B[ 7];
00066 C[ 8] = A[0]*B[ 8] + A[4]*B[ 9] + A[ 8]*B[10] + A[12]*B[11];
00067 C[ 9] = A[1]*B[ 8] + A[5]*B[ 9] + A[ 9]*B[10] + A[13]*B[11];
00068 C[10] = A[2]*B[ 8] + A[6]*B[ 9] + A[10]*B[10] + A[14]*B[11];
00069 C[11] = A[3]*B[ 8] + A[7]*B[ 9] + A[11]*B[10] + A[15]*B[11];
00070 C[12] = A[0]*B[12] + A[4]*B[13] + A[ 8]*B[14] + A[12]*B[15];
00071 C[13] = A[1]*B[12] + A[5]*B[13] + A[ 9]*B[14] + A[13]*B[15];
00072 C[14] = A[2]*B[12] + A[6]*B[13] + A[10]*B[14] + A[14]*B[15];
00073 C[15] = A[3]*B[12] + A[7]*B[13] + A[11]*B[14] + A[15]*B[15];
00074 }
00075
00082 template<typename real_type>
00083 inline void transpose( real_type const * M, real_type * T )
00084 {
00085 assert(M!=T || !"transpose(): M and T must be two different matrices!" );
00086
00087 T[0] = M[0]; T[4] = M[1]; T[8] = M[2]; T[12] = M[3];
00088 T[1] = M[4]; T[5] = M[5]; T[9] = M[6]; T[13] = M[7];
00089 T[2] = M[8]; T[6] = M[9]; T[10] = M[10]; T[14] = M[11];
00090 T[3] = M[12]; T[7] = M[13]; T[11] = M[14]; T[15] = M[15];
00091
00092 }
00093
00099 template<typename real_type>
00100 inline void transpose( real_type * M )
00101 {
00102 real_type temp;
00103
00104 temp = M[ 0 * 4 + 1 ];
00105 M[ 0 * 4 + 1 ] = M[ 1 * 4 + 0 ];
00106 M[ 1 * 4 + 0 ] = temp;
00107 temp = M[ 0 * 4 + 2 ];
00108 M[ 0 * 4 + 2 ] = M[ 2 * 4 + 0 ];
00109 M[ 2 * 4 + 0 ] = temp;
00110 temp = M[ 0 * 4 + 3 ];
00111 M[ 0 * 4 + 3 ] = M[ 3 * 4 + 0 ];
00112 M[ 3 * 4 + 0 ] = temp;
00113
00114 temp = M[ 1 * 4 + 2 ];
00115 M[ 1 * 4 + 2 ] = M[ 2 * 4 + 1 ];
00116 M[ 2 * 4 + 1 ] = temp;
00117
00118 temp = M[ 1 * 4 + 3 ];
00119 M[ 1 * 4 + 3 ] = M[ 3 * 4 + 1 ];
00120 M[ 3 * 4 + 1 ] = temp;
00121
00122 temp = M[ 2 * 4 + 3 ];
00123 M[ 2 * 4 + 3 ] = M[ 3 * 4 + 2 ];
00124 M[ 3 * 4 + 2 ] = temp;
00125 }
00126
00135 template<typename real_type>
00136 inline real_type invert( real_type const * M, real_type * I )
00137 {
00138 assert(M!=I || !"invert(): M and I must be two different matrices!" );
00139
00140 real_type const & a = M[ 0 ]; real_type const & e = M[ 1 ]; real_type const & i = M[ 2 ]; real_type const & m = M[ 3 ];
00141 real_type const & b = M[ 4 ]; real_type const & f = M[ 5 ]; real_type const & j = M[ 6 ]; real_type const & n = M[ 7 ];
00142 real_type const & c = M[ 8 ]; real_type const & g = M[ 9 ]; real_type const & k = M[ 10 ]; real_type const & o = M[ 11 ];
00143 real_type const & d = M[ 12 ]; real_type const & h = M[ 13 ]; real_type const & l = M[ 14 ]; real_type const & p = M[ 15 ];
00144
00145 real_type det = d * g * j * m - c * h * j * m - d * f * k * m + b * h * k * m + c * f * l * m -
00146 b * g * l * m - d * g * i * n + c * h * i * n + d * e * k * n - a * h * k * n -
00147 c * e * l * n + a * g * l * n + d * f * i * o - b * h * i * o - d * e * j * o +
00148 a * h * j * o + b * e * l * o - a * f * l * o - c * f * i * p + b * g * i * p +
00149 c * e * j * p - a * g * j * p - b * e * k * p + a * f * k * p;
00150
00151 if ( !det )
00152 {
00153 std::cout << "invert(): Cannot invert matrix (determinant is zero)." << std::endl;
00154 return real_type(0.0);
00155 }
00156
00157 real_type inv_det = 1.0 / det;
00158
00159 I[ 0 * 4 + 0 ] = ( -( h * k * n ) + g * l * n + h * j * o - f * l * o - g * j * p + f * k * p ) * inv_det;
00160 I[ 1 * 4 + 0 ] = ( d * k * n - c * l * n - d * j * o + b * l * o + c * j * p - b * k * p ) * inv_det;
00161 I[ 2 * 4 + 0 ] = ( -( d * g * n ) + c * h * n + d * f * o - b * h * o - c * f * p + b * g * p ) * inv_det;
00162 I[ 3 * 4 + 0 ] = ( d * g * j - c * h * j - d * f * k + b * h * k + c * f * l - b * g * l ) * inv_det;
00163 I[ 0 * 4 + 1 ] = ( h * k * m - g * l * m - h * i * o + e * l * o + g * i * p - e * k * p ) * inv_det;
00164 I[ 1 * 4 + 1 ] = ( -( d * k * m ) + c * l * m + d * i * o - a * l * o - c * i * p + a * k * p ) * inv_det;
00165 I[ 2 * 4 + 1 ] = ( d * g * m - c * h * m - d * e * o + a * h * o + c * e * p - a * g * p ) * inv_det;
00166 I[ 3 * 4 + 1 ] = ( -( d * g * i ) + c * h * i + d * e * k - a * h * k - c * e * l + a * g * l ) * inv_det;
00167 I[ 0 * 4 + 2 ] = ( -( h * j * m ) + f * l * m + h * i * n - e * l * n - f * i * p + e * j * p ) * inv_det;
00168 I[ 1 * 4 + 2 ] = ( d * j * m - b * l * m - d * i * n + a * l * n + b * i * p - a * j * p ) * inv_det;
00169 I[ 2 * 4 + 2 ] = ( -( d * f * m ) + b * h * m + d * e * n - a * h * n - b * e * p + a * f * p ) * inv_det;
00170 I[ 3 * 4 + 2 ] = ( d * f * i - b * h * i - d * e * j + a * h * j + b * e * l - a * f * l ) * inv_det;
00171 I[ 0 * 4 + 3 ] = ( g * j * m - f * k * m - g * i * n + e * k * n + f * i * o - e * j * o ) * inv_det;
00172 I[ 1 * 4 + 3 ] = ( -( c * j * m ) + b * k * m + c * i * n - a * k * n - b * i * o + a * j * o ) * inv_det;
00173 I[ 2 * 4 + 3 ] = ( c * f * m - b * g * m - c * e * n + a * g * n + b * e * o - a * f * o ) * inv_det;
00174 I[ 3 * 4 + 3 ] = ( -( c * f * i ) + b * g * i + c * e * j - a * g * j - b * e * k + a * f * k ) * inv_det;
00175
00176 return det;
00177 }
00178
00179
00186 template<typename real_type>
00187 inline void orthonormalize( real_type const * M, real_type * O )
00188 {
00189 using std::sqrt;
00190
00191 real_type len, temp[ 3 ][ 3 ];
00192
00193 temp[ 0 ][ 0 ] = M[ 0 * 4 + 0 ];
00194 temp[ 0 ][ 1 ] = M[ 0 * 4 + 1 ];
00195 temp[ 0 ][ 2 ] = M[ 0 * 4 + 2 ];
00196 temp[ 1 ][ 0 ] = M[ 1 * 4 + 0 ];
00197 temp[ 1 ][ 1 ] = M[ 1 * 4 + 1 ];
00198 temp[ 1 ][ 2 ] = M[ 1 * 4 + 2 ];
00199
00200
00201 len = sqrt ( temp[ 0 ][ 0 ] * temp[ 0 ][ 0 ] + temp[ 0 ][ 1 ] * temp[ 0 ][ 1 ] + temp[ 0 ][ 2 ] * temp[ 0 ][ 2 ] );
00202 len = ( len == 0.0f ) ? 1.0f : 1.0f / len;
00203 temp[ 0 ][ 0 ] *= len;
00204 temp[ 0 ][ 1 ] *= len;
00205 temp[ 0 ][ 2 ] *= len;
00206
00207
00208 temp[ 2 ][ 0 ] = temp[ 0 ][ 1 ] * temp[ 1 ][ 2 ] - temp[ 0 ][ 2 ] * temp[ 1 ][ 1 ];
00209 temp[ 2 ][ 1 ] = temp[ 0 ][ 2 ] * temp[ 1 ][ 0 ] - temp[ 0 ][ 0 ] * temp[ 1 ][ 2 ];
00210 temp[ 2 ][ 2 ] = temp[ 0 ][ 0 ] * temp[ 1 ][ 1 ] - temp[ 0 ][ 1 ] * temp[ 1 ][ 0 ];
00211
00212
00213 len = sqrt ( temp[ 2 ][ 0 ] * temp[ 2 ][ 0 ] + temp[ 2 ][ 1 ] * temp[ 2 ][ 1 ] + temp[ 2 ][ 2 ] * temp[ 2 ][ 2 ] );
00214 len = ( len == 0.0f ) ? 1.0f : 1.0f / len;
00215 temp[ 2 ][ 0 ] *= len;
00216 temp[ 2 ][ 1 ] *= len;
00217 temp[ 2 ][ 2 ] *= len;
00218
00219
00220 temp[ 1 ][ 0 ] = temp[ 2 ][ 1 ] * temp[ 0 ][ 2 ] - temp[ 2 ][ 2 ] * temp[ 0 ][ 1 ];
00221 temp[ 1 ][ 1 ] = temp[ 2 ][ 2 ] * temp[ 0 ][ 0 ] - temp[ 2 ][ 0 ] * temp[ 0 ][ 2 ];
00222 temp[ 1 ][ 2 ] = temp[ 2 ][ 0 ] * temp[ 0 ][ 1 ] - temp[ 2 ][ 1 ] * temp[ 0 ][ 0 ];
00223
00224
00225 len = sqrt ( temp[ 1 ][ 0 ] * temp[ 1 ][ 0 ] + temp[ 1 ][ 1 ] * temp[ 1 ][ 1 ] + temp[ 1 ][ 2 ] * temp[ 1 ][ 2 ] );
00226 len = ( len == 0.0f ) ? 1.0f : 1.0f / len;
00227 temp[ 1 ][ 0 ] *= len;
00228 temp[ 1 ][ 1 ] *= len;
00229 temp[ 1 ][ 2 ] *= len;
00230
00231
00232 O[ 0 * 4 + 0 ] = temp[ 0 ][ 0 ];
00233 O[ 0 * 4 + 1 ] = temp[ 0 ][ 1 ];
00234 O[ 0 * 4 + 2 ] = temp[ 0 ][ 2 ];
00235 O[ 1 * 4 + 0 ] = temp[ 1 ][ 0 ];
00236 O[ 1 * 4 + 1 ] = temp[ 1 ][ 1 ];
00237 O[ 1 * 4 + 2 ] = temp[ 1 ][ 2 ];
00238 O[ 2 * 4 + 0 ] = temp[ 2 ][ 0 ];
00239 O[ 2 * 4 + 1 ] = temp[ 2 ][ 1 ];
00240 O[ 2 * 4 + 2 ] = temp[ 2 ][ 2 ];
00241 }
00242
00243 }
00244
00245 }
00246
00247
00248 #endif