00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define ACG_MATRIX4X4_C
00053
00054
00055
00056
00057
00058 #include "Matrix4x4T.hh"
00059 #include "../Utils/NumLimitsT.hh"
00060
00061
00062
00063
00064
00065 namespace ACG {
00066
00067
00068 #define MAT(m,r,c) ((m)[(r)+((c)<<2)])
00069 #define M(r,w) (MAT(mat_,r,w))
00070
00071
00072
00073
00074
00075 template <typename Scalar>
00076 Matrix4x4T<Scalar>
00077 Matrix4x4T<Scalar>::
00078 operator* (const Matrix4x4T<Scalar>& _rhs) const
00079 {
00080 #define RHS(row,col) MAT(_rhs.mat_, row,col)
00081 #define TMP(row,col) MAT(tmp.mat_, row,col)
00082
00083 Matrix4x4T<Scalar> tmp;
00084 Scalar mi0, mi1, mi2, mi3;
00085 int i;
00086
00087 for (i = 0; i < 4; i++) {
00088 mi0=M(i,0); mi1=M(i,1); mi2=M(i,2); mi3=M(i,3);
00089 TMP(i,0) = mi0*RHS(0,0) + mi1*RHS(1,0) + mi2*RHS(2,0) + mi3*RHS(3,0);
00090 TMP(i,1) = mi0*RHS(0,1) + mi1*RHS(1,1) + mi2*RHS(2,1) + mi3*RHS(3,1);
00091 TMP(i,2) = mi0*RHS(0,2) + mi1*RHS(1,2) + mi2*RHS(2,2) + mi3*RHS(3,2);
00092 TMP(i,3) = mi0*RHS(0,3) + mi1*RHS(1,3) + mi2*RHS(2,3) + mi3*RHS(3,3);
00093 }
00094
00095 return tmp;
00096
00097 #undef RHS
00098 #undef TMP
00099 }
00100
00101
00102
00103
00104
00105 template <typename Scalar>
00106 Matrix4x4T<Scalar>&
00107 Matrix4x4T<Scalar>::
00108 operator*= (const Matrix4x4T<Scalar>& _rhs)
00109 {
00110 #define RHS(row,col) MAT(_rhs.mat_, row,col)
00111
00112 int i;
00113 Scalar mi0, mi1, mi2, mi3;
00114
00115 for (i = 0; i < 4; i++)
00116 {
00117 mi0=M(i,0); mi1=M(i,1); mi2=M(i,2); mi3=M(i,3);
00118 M(i,0) = mi0 * RHS(0,0) + mi1 * RHS(1,0) + mi2 * RHS(2,0) + mi3 * RHS(3,0);
00119 M(i,1) = mi0 * RHS(0,1) + mi1 * RHS(1,1) + mi2 * RHS(2,1) + mi3 * RHS(3,1);
00120 M(i,2) = mi0 * RHS(0,2) + mi1 * RHS(1,2) + mi2 * RHS(2,2) + mi3 * RHS(3,2);
00121 M(i,3) = mi0 * RHS(0,3) + mi1 * RHS(1,3) + mi2 * RHS(2,3) + mi3 * RHS(3,3);
00122 }
00123
00124 return *this;
00125
00126 #undef RHS
00127 }
00128
00129
00130
00131
00132
00133 template <typename Scalar>
00134 Matrix4x4T<Scalar>&
00135 Matrix4x4T<Scalar>::
00136 leftMult(const Matrix4x4T<Scalar>& _rhs)
00137 {
00138 #define RHS(row,col) MAT(_rhs.mat_, row,col)
00139 int i;
00140 Scalar m0i, m1i, m2i, m3i;
00141 for(i=0;i<4;i++)
00142 {
00143 m0i = M(0,i); m1i = M(1,i); m2i = M(2,i); m3i = M(3,i);
00144 M(0,i) = RHS(0,0)*m0i + RHS(0,1)*m1i + RHS(0,2)*m2i + RHS(0,3)*m3i;
00145 M(1,i) = RHS(1,0)*m0i + RHS(1,1)*m1i + RHS(1,2)*m2i + RHS(1,3)*m3i;
00146 M(2,i) = RHS(2,0)*m0i + RHS(2,1)*m1i + RHS(2,2)*m2i + RHS(2,3)*m3i;
00147 M(3,i) = RHS(3,0)*m0i + RHS(3,1)*m1i + RHS(3,2)*m2i + RHS(3,3)*m3i;
00148 }
00149 return *this;
00150 #undef RHS
00151 }
00152
00153
00154
00155
00156
00157 template <typename Scalar>
00158 template <typename T>
00159 VectorT<T,4>
00160 Matrix4x4T<Scalar>::
00161 operator*(const VectorT<T,4>& _v) const
00162 {
00163 return VectorT<T,4> (
00164 M(0,0)*_v[0] + M(0,1)*_v[1] + M(0,2)*_v[2] + M(0,3)*_v[3],
00165 M(1,0)*_v[0] + M(1,1)*_v[1] + M(1,2)*_v[2] + M(1,3)*_v[3],
00166 M(2,0)*_v[0] + M(2,1)*_v[1] + M(2,2)*_v[2] + M(2,3)*_v[3],
00167 M(3,0)*_v[0] + M(3,1)*_v[1] + M(3,2)*_v[2] + M(3,3)*_v[3]);
00168 }
00169
00170
00171
00172
00173
00174 template <typename Scalar>
00175 template <typename T>
00176 VectorT<T,3>
00177 Matrix4x4T<Scalar>::
00178 transform_point(const VectorT<T,3>& _v) const
00179 {
00180 Scalar x = M(0,0)*_v[0] + M(0,1)*_v[1] + M(0,2)*_v[2] + M(0,3);
00181 Scalar y = M(1,0)*_v[0] + M(1,1)*_v[1] + M(1,2)*_v[2] + M(1,3);
00182 Scalar z = M(2,0)*_v[0] + M(2,1)*_v[1] + M(2,2)*_v[2] + M(2,3);
00183 Scalar w = M(3,0)*_v[0] + M(3,1)*_v[1] + M(3,2)*_v[2] + M(3,3);
00184
00185 if (w)
00186 {
00187 w = 1.0 / w;
00188 return VectorT<T,3>(x*w, y*w, z*w);
00189 }
00190 else return VectorT<T,3>(x, y, z);
00191 }
00192
00193
00194
00195
00196
00197 template <typename Scalar>
00198 template <typename T>
00199 VectorT<T,3>
00200 Matrix4x4T<Scalar>::
00201 transform_vector(const VectorT<T,3>& _v) const
00202 {
00203 Scalar x = M(0,0)*_v[0] + M(0,1)*_v[1] + M(0,2)*_v[2];
00204 Scalar y = M(1,0)*_v[0] + M(1,1)*_v[1] + M(1,2)*_v[2];
00205 Scalar z = M(2,0)*_v[0] + M(2,1)*_v[1] + M(2,2)*_v[2];
00206 return VectorT<T,3>(x, y, z);
00207 }
00208
00209
00210
00211
00212
00213 template <typename Scalar>
00214 void
00215 Matrix4x4T<Scalar>::
00216 clear()
00217 {
00218 Scalar* m = mat_;
00219 *m++ = 0.0; *m++ = 0.0; *m++ = 0.0; *m++ = 0.0;
00220 *m++ = 0.0; *m++ = 0.0; *m++ = 0.0; *m++ = 0.0;
00221 *m++ = 0.0; *m++ = 0.0; *m++ = 0.0; *m++ = 0.0;
00222 *m++ = 0.0; *m++ = 0.0; *m++ = 0.0; *m = 0.0;
00223 }
00224
00225
00226
00227
00228
00229 template <typename Scalar>
00230 void
00231 Matrix4x4T<Scalar>::
00232 identity()
00233 {
00234 Scalar* m = mat_;
00235 *m++ = 1.0; *m++ = 0.0; *m++ = 0.0; *m++ = 0.0;
00236 *m++ = 0.0; *m++ = 1.0; *m++ = 0.0; *m++ = 0.0;
00237 *m++ = 0.0; *m++ = 0.0; *m++ = 1.0; *m++ = 0.0;
00238 *m++ = 0.0; *m++ = 0.0; *m++ = 0.0; *m = 1.0;
00239 }
00240
00241
00242
00243
00244
00245 template <typename Scalar>
00246 void
00247 Matrix4x4T<Scalar>::
00248 transpose()
00249 {
00250 Scalar tmp;
00251 for( int i=0; i<4; i++ )
00252 {
00253 for( int j=i+1; j<4; j++ )
00254 {
00255 tmp = MAT(mat_,i,j);
00256 MAT(mat_,i,j) = MAT(mat_,j,i);
00257 MAT(mat_,j,i) = tmp;
00258 }
00259 }
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 template <typename Scalar>
00271 bool
00272 Matrix4x4T<Scalar>::
00273 invert()
00274 {
00275 #define SWAP_ROWS(a, b) { Scalar *_tmp = a; (a)=(b); (b)=_tmp; }
00276
00277 Scalar wtmp[4][8];
00278 Scalar m0, m1, m2, m3, s;
00279 Scalar *r0, *r1, *r2, *r3;
00280
00281 r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
00282
00283 r0[0] = M(0,0); r0[1] = M(0,1);
00284 r0[2] = M(0,2); r0[3] = M(0,3);
00285 r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0;
00286
00287 r1[0] = M(1,0); r1[1] = M(1,1);
00288 r1[2] = M(1,2); r1[3] = M(1,3);
00289 r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0;
00290
00291 r2[0] = M(2,0); r2[1] = M(2,1);
00292 r2[2] = M(2,2); r2[3] = M(2,3);
00293 r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0;
00294
00295 r3[0] = M(3,0); r3[1] = M(3,1);
00296 r3[2] = M(3,2); r3[3] = M(3,3);
00297 r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
00298
00299
00300
00301 if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
00302 if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
00303 if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
00304 if (0.0 == r0[0]) return false;
00305
00306
00307
00308 m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
00309 s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
00310 s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
00311 s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
00312 s = r0[4];
00313 if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
00314 s = r0[5];
00315 if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
00316 s = r0[6];
00317 if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
00318 s = r0[7];
00319 if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
00320
00321
00322
00323 if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
00324 if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
00325 if (0.0 == r1[1]) return false;
00326
00327
00328
00329 m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
00330 r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
00331 r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
00332 s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
00333 s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
00334 s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
00335 s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
00336
00337
00338
00339 if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
00340 if (0.0 == r2[2]) return false;
00341
00342
00343 m3 = r3[2]/r2[2];
00344 r3[3] -= m3 * r2[3];
00345 r3[4] -= m3 * r2[4];
00346 r3[5] -= m3 * r2[5];
00347 r3[6] -= m3 * r2[6];
00348 r3[7] -= m3 * r2[7];
00349
00350
00351 if (0.0 == r3[3]) return false;
00352
00353 s = 1.0/r3[3];
00354 r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
00355
00356 m2 = r2[3];
00357 s = 1.0/r2[2];
00358 r2[4] = s * (r2[4] - r3[4] * m2); r2[5] = s * (r2[5] - r3[5] * m2);
00359 r2[6] = s * (r2[6] - r3[6] * m2); r2[7] = s * (r2[7] - r3[7] * m2);
00360 m1 = r1[3];
00361 r1[4] -= r3[4] * m1; r1[5] -= r3[5] * m1;
00362 r1[6] -= r3[6] * m1; r1[7] -= r3[7] * m1;
00363 m0 = r0[3];
00364 r0[4] -= r3[4] * m0; r0[5] -= r3[5] * m0;
00365 r0[6] -= r3[6] * m0; r0[7] -= r3[7] * m0;
00366
00367 m1 = r1[2];
00368 s = 1.0/r1[1];
00369 r1[4] = s * (r1[4] - r2[4] * m1); r1[5] = s * (r1[5] - r2[5] * m1);
00370 r1[6] = s * (r1[6] - r2[6] * m1); r1[7] = s * (r1[7] - r2[7] * m1);
00371 m0 = r0[2];
00372 r0[4] -= r2[4] * m0; r0[5] -= r2[5] * m0;
00373 r0[6] -= r2[6] * m0; r0[7] -= r2[7] * m0;
00374
00375 m0 = r0[1];
00376 s = 1.0/r0[0];
00377 r0[4] = s * (r0[4] - r1[4] * m0); r0[5] = s * (r0[5] - r1[5] * m0);
00378 r0[6] = s * (r0[6] - r1[6] * m0); r0[7] = s * (r0[7] - r1[7] * m0);
00379
00380 M(0,0) = r0[4]; M(0,1) = r0[5];
00381 M(0,2) = r0[6]; M(0,3) = r0[7];
00382 M(1,0) = r1[4]; M(1,1) = r1[5];
00383 M(1,2) = r1[6]; M(1,3) = r1[7];
00384 M(2,0) = r2[4]; M(2,1) = r2[5];
00385 M(2,2) = r2[6]; M(2,3) = r2[7];
00386 M(3,0) = r3[4]; M(3,1) = r3[5];
00387 M(3,2) = r3[6]; M(3,3) = r3[7];
00388
00389 return true;
00390 #undef SWAP_ROWS
00391 }
00392
00393
00394
00395
00396
00397 #undef MAT
00398 #undef M
00399
00400
00401
00402 }
00403