00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __mitkMatrix_h
00012 #define __mitkMatrix_h
00013
00014 #include <math.h>
00015
00016 #include "mitkSIMD.h"
00017
00018 #ifdef USE_SIMD
00019 #pragma pack(push,16)
00020 #endif
00021
00027 class MITK_COMMON_API mitkMatrix
00028 {
00029 public:
00030
00031 #ifdef USE_SIMD
00032 union
00033 {
00034 struct
00035 {
00036 __m128 r1, r2, r3, r4;
00037 };
00038 struct
00039 {
00040 float ele[16];
00041 };
00042 };
00043
00044 static void* operator new(size_t size)
00045 {
00046 return _aligned_malloc(size, 16);
00047 }
00048
00049 static void operator delete(void *p)
00050 {
00051 _aligned_free(p);
00052 }
00053
00054 static void* operator new[](size_t size)
00055 {
00056 return _aligned_malloc(size, 16);
00057 }
00058
00059 static void operator delete[](void *p)
00060 {
00061 _aligned_free(p);
00062 }
00063 #else
00064 float ele[16];
00065 #endif
00066
00067 mitkMatrix() {}
00068 mitkMatrix(const mitkMatrix &m)
00069 {
00070 #ifdef USE_SIMD
00071 r1 = m.r1;
00072 r2 = m.r2;
00073 r3 = m.r3;
00074 r4 = m.r4;
00075 #else
00076 ele[0] = m.ele[0];
00077 ele[1] = m.ele[1];
00078 ele[2] = m.ele[2];
00079 ele[3] = m.ele[3];
00080 ele[4] = m.ele[4];
00081 ele[5] = m.ele[5];
00082 ele[6] = m.ele[6];
00083 ele[7] = m.ele[7];
00084 ele[8] = m.ele[8];
00085 ele[9] = m.ele[9];
00086 ele[10] = m.ele[10];
00087 ele[11] = m.ele[11];
00088 ele[12] = m.ele[12];
00089 ele[13] = m.ele[13];
00090 ele[14] = m.ele[14];
00091 ele[15] = m.ele[15];
00092 #endif
00093 }
00094
00095 mitkMatrix(float e0, float e1, float e2, float e3,
00096 float e4, float e5, float e6, float e7,
00097 float e8, float e9, float e10, float e11,
00098 float e12, float e13, float e14, float e15)
00099 {
00100 #ifdef USE_SIMD
00101 r1 = _mm_setr_ps(e0, e1, e2, e3);
00102 r2 = _mm_setr_ps(e4, e5, e6, e7);
00103 r3 = _mm_setr_ps(e8, e9, e10, e11);
00104 r4 = _mm_setr_ps(e12, e13, e14, e15);
00105 #else
00106 ele[0] = e0;
00107 ele[1] = e1;
00108 ele[2] = e2;
00109 ele[3] = e3;
00110 ele[4] = e4;
00111 ele[5] = e5;
00112 ele[6] = e6;
00113 ele[7] = e7;
00114 ele[8] = e8;
00115 ele[9] = e9;
00116 ele[10] = e10;
00117 ele[11] = e11;
00118 ele[12] = e12;
00119 ele[13] = e13;
00120 ele[14] = e14;
00121 ele[15] = e15;
00122 #endif
00123 }
00124
00125 mitkMatrix& operator = (const mitkMatrix &m)
00126 {
00127 #ifdef USE_SIMD
00128 r1 = m.r1;
00129 r2 = m.r2;
00130 r3 = m.r3;
00131 r4 = m.r4;
00132 #else
00133 ele[0] = m.ele[0];
00134 ele[1] = m.ele[1];
00135 ele[2] = m.ele[2];
00136 ele[3] = m.ele[3];
00137 ele[4] = m.ele[4];
00138 ele[5] = m.ele[5];
00139 ele[6] = m.ele[6];
00140 ele[7] = m.ele[7];
00141 ele[8] = m.ele[8];
00142 ele[9] = m.ele[9];
00143 ele[10] = m.ele[10];
00144 ele[11] = m.ele[11];
00145 ele[12] = m.ele[12];
00146 ele[13] = m.ele[13];
00147 ele[14] = m.ele[14];
00148 ele[15] = m.ele[15];
00149 #endif
00150 return *this;
00151 }
00152
00153 friend mitkMatrix operator * (const mitkMatrix&, const mitkMatrix&);
00154 friend mitkMatrix operator + (const mitkMatrix&, const mitkMatrix&);
00155 friend mitkMatrix operator - (const mitkMatrix&, const mitkMatrix&);
00156 friend mitkMatrix operator + (const mitkMatrix&);
00157 friend mitkMatrix operator - (const mitkMatrix&);
00158 friend mitkMatrix operator * (const mitkMatrix&, const float);
00159 friend mitkMatrix operator * (const float, const mitkMatrix&);
00160
00161 mitkMatrix& operator *= (const mitkMatrix &);
00162 mitkMatrix& operator *= (const float);
00163 mitkMatrix& operator += (const mitkMatrix &);
00164 mitkMatrix& operator -= (const mitkMatrix &);
00165
00166 operator const float* () const { return ele; }
00167 operator float* () { return ele; }
00168
00172 void Transpose();
00173
00177 float Inverse();
00178
00182 float Determinant();
00183
00187 void Adjoint();
00188
00192 float MinValue();
00193
00197 float MaxValue();
00198
00202 void ZeroMatrix();
00203
00207 void IdentityMatrix();
00208
00212 void TranslateMatrix(const float dx, const float dy, const float dz);
00213
00217 void ScaleMatrix(const float a, const float b, const float c);
00218
00222 void ScaleMatrix(const float a);
00223
00227 void RotateXMatrix(const float angle);
00228
00232 void RotateYMatrix(const float angle);
00233
00237 void RotateZMatrix(const float angle);
00238
00242 void Translate(const float dx, const float dy, const float dz);
00243
00247 void Scale(const float a, const float b, const float c);
00248
00252 void Rotate(const float angle, const float x, const float y, const float z);
00253
00257 void RotateX(const float angle);
00258
00262 void RotateY(const float angle);
00263
00267 void RotateZ(const float angle);
00268 };
00269
00273 class MITK_COMMON_API mitkVector
00274 {
00275 public:
00276 #ifdef USE_SIMD
00277 union
00278 {
00279 __m128 vec;
00280 struct
00281 {
00282 float ele[4];
00283 };
00284 };
00285
00286 static void* operator new(size_t size)
00287 {
00288 return _aligned_malloc(size, 16);
00289 }
00290
00291 static void operator delete(void *p)
00292 {
00293 _aligned_free(p);
00294 }
00295
00296 static void* operator new[](size_t size)
00297 {
00298 return _aligned_malloc(size, 16);
00299 }
00300
00301 static void operator delete[](void *p)
00302 {
00303 _aligned_free(p);
00304 }
00305 #else
00306 float ele[4];
00307 #endif
00308
00309 mitkVector()
00310 {
00311 #ifdef USE_SIMD
00312 vec = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
00313 #else
00314 ele[0] = 0.0f;
00315 ele[1] = 0.0f;
00316 ele[2] = 0.0f;
00317 ele[3] = 1.0f;
00318 #endif
00319 }
00320
00321 mitkVector(const mitkVector &v)
00322 {
00323 #ifdef USE_SIMD
00324 vec = v.vec;
00325 #else
00326 ele[0] = v.ele[0];
00327 ele[1] = v.ele[1];
00328 ele[2] = v.ele[2];
00329 ele[3] = v.ele[3];
00330 #endif
00331 }
00332
00333 mitkVector(const float x, const float y, const float z, const float w = 1.0f)
00334 {
00335 #ifdef USE_SIMD
00336 vec = _mm_setr_ps(x, y, z, w);
00337 #else
00338 ele[0] = x;
00339 ele[1] = y;
00340 ele[2] = z;
00341 ele[3] = w;
00342 #endif
00343 }
00344
00345 mitkVector(const float srcVector[4])
00346 {
00347 ele[0] = srcVector[0];
00348 ele[1] = srcVector[1];
00349 ele[2] = srcVector[2];
00350 ele[3] = srcVector[3];
00351 }
00352
00353
00354 operator float* () { return ele; }
00355 operator const float* () const { return ele; }
00356
00357 mitkVector& operator = (const mitkVector &a)
00358 {
00359 #ifdef USE_SIMD
00360 vec = a.vec;
00361 #else
00362 ele[0] = a.ele[0];
00363 ele[1] = a.ele[1];
00364 ele[2] = a.ele[2];
00365 ele[3] = a.ele[3];
00366 #endif
00367 return *this;
00368 }
00369
00370 friend mitkVector operator * (const mitkVector&, const mitkMatrix&);
00371 friend float operator * (const mitkVector &, const mitkVector &);
00372 friend mitkVector operator % (const mitkVector &, const mitkVector &);
00373 friend mitkVector operator * (const mitkVector &, const float);
00374 friend mitkVector operator * (const float, const mitkVector &);
00375 friend mitkVector operator + (const mitkVector&);
00376 friend mitkVector operator + (const mitkVector&, const mitkVector&);
00377 friend mitkVector operator - (const mitkVector&);
00378 friend mitkVector operator - (const mitkVector&, const mitkVector&);
00379 friend mitkVector operator ~ (const mitkVector&);
00380
00381 mitkVector& operator *= (const mitkMatrix &);
00382 mitkVector& operator *= (const float);
00383 mitkVector& operator += (const mitkVector &);
00384 mitkVector& operator -= (const mitkVector &);
00385
00386 float Length();
00387 float Length2();
00388 void Normalize();
00389 };
00390
00391 #ifdef USE_SIMD
00392 #define _mm_ror_ps(vec,i) \
00393 (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec))
00394 #define _mm_rol_ps(vec,i) \
00395 (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(7-i)%4,(unsigned char)(6-i)%4,(unsigned char)(5-i)%4,(unsigned char)(4-i)%4))) : (vec))
00396 const float _NEGMASK = 0.0f * -1.0f;
00397 const __m128 _MASKSIGN_ = _mm_set_ps(_NEGMASK, _NEGMASK, _NEGMASK, _NEGMASK);
00398 #define _mm_abs_ps(vec) _mm_andnot_ps(_MASKSIGN_,vec)
00399 #define _mm_neg_ps(vec) _mm_xor_ps(_MASKSIGN_,vec)
00400
00401 #pragma pack(pop)
00402 #endif
00403
00404
00405 inline void mitkMatrix::ZeroMatrix()
00406 {
00407 #ifdef USE_SIMD
00408 r1 = _mm_setzero_ps();
00409 r2 = _mm_setzero_ps();
00410 r3 = _mm_setzero_ps();
00411 r4 = _mm_setzero_ps();
00412 #else
00413 ele[0] = ele[1] = ele[2] = ele[3] = 0.0f;
00414 ele[4] = ele[5] = ele[6] = ele[7] = 0.0f;
00415 ele[8] = ele[9] = ele[10] = ele[11] = 0.0f;
00416 ele[12] = ele[13] = ele[14] = ele[15] = 0.0f;
00417 #endif
00418 }
00419
00420 inline void mitkMatrix::IdentityMatrix()
00421 {
00422 #ifdef USE_SIMD
00423 r1 = _mm_setr_ps(1.0f, 0.0f, 0.0f, 0.0f);
00424 r2 = _mm_setr_ps(0.0f, 1.0f, 0.0f, 0.0f);
00425 r3 = _mm_setr_ps(0.0f, 0.0f, 1.0f, 0.0f);
00426 r4 = _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f);
00427 #else
00428 ele[0] = ele[5] = ele[10] = ele[15] = 1.0f;
00429 ele[1] = ele[2] = ele[3] = ele[4] = 0.0f;
00430 ele[6] = ele[7] = ele[8] = ele[9] = 0.0f;
00431 ele[11] = ele[12] = ele[13] = ele[14] = 0.0f;
00432 #endif
00433 }
00434
00435 inline mitkMatrix operator * (const mitkMatrix &A, const mitkMatrix &B)
00436 {
00437 mitkMatrix Res;
00438
00439 #ifdef USE_SIMD
00440
00441 __m128 Result;
00442
00443 Result = _mm_mul_ps(_mm_set_ps1(B.ele[0]), A.r1);
00444 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[1]), A.r2));
00445 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[2]), A.r3));
00446 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[3]), A.r4));
00447 Res.r1 = Result;
00448
00449 Result = _mm_mul_ps(_mm_set_ps1(B.ele[4]), A.r1);
00450 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[5]), A.r2));
00451 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[6]), A.r3));
00452 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[7]), A.r4));
00453 Res.r2 = Result;
00454
00455 Result = _mm_mul_ps(_mm_set_ps1(B.ele[8]), A.r1);
00456 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[9]), A.r2));
00457 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[10]), A.r3));
00458 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[11]), A.r4));
00459 Res.r3 = Result;
00460
00461 Result = _mm_mul_ps(_mm_set_ps1(B.ele[12]), A.r1);
00462 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[13]), A.r2));
00463 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[14]), A.r3));
00464 Result = _mm_add_ps(Result, _mm_mul_ps(_mm_set_ps1(B.ele[15]), A.r4));
00465 Res.r4 = Result;
00466
00467 return Res;
00468
00469 #else
00470
00471 Res.ele[0] = A.ele[0]*B.ele[0] + A.ele[4]*B.ele[1] + A.ele[8]*B.ele[2] + A.ele[12]*B.ele[3];
00472 Res.ele[1] = A.ele[1]*B.ele[0] + A.ele[5]*B.ele[1] + A.ele[9]*B.ele[2] + A.ele[13]*B.ele[3];
00473 Res.ele[2] = A.ele[2]*B.ele[0] + A.ele[6]*B.ele[1] + A.ele[10]*B.ele[2] + A.ele[14]*B.ele[3];
00474 Res.ele[3] = A.ele[3]*B.ele[0] + A.ele[7]*B.ele[1] + A.ele[11]*B.ele[2] + A.ele[15]*B.ele[3];
00475
00476 Res.ele[4] = A.ele[0]*B.ele[4] + A.ele[4]*B.ele[5] + A.ele[8]*B.ele[6] + A.ele[12]*B.ele[7];
00477 Res.ele[5] = A.ele[1]*B.ele[4] + A.ele[5]*B.ele[5] + A.ele[9]*B.ele[6] + A.ele[13]*B.ele[7];
00478 Res.ele[6] = A.ele[2]*B.ele[4] + A.ele[6]*B.ele[5] + A.ele[10]*B.ele[6] + A.ele[14]*B.ele[7];
00479 Res.ele[7] = A.ele[3]*B.ele[4] + A.ele[7]*B.ele[5] + A.ele[11]*B.ele[6] + A.ele[15]*B.ele[7];
00480
00481 Res.ele[8] = A.ele[0]*B.ele[8] + A.ele[4]*B.ele[9] + A.ele[8]*B.ele[10] + A.ele[12]*B.ele[11];
00482 Res.ele[9] = A.ele[1]*B.ele[8] + A.ele[5]*B.ele[9] + A.ele[9]*B.ele[10] + A.ele[13]*B.ele[11];
00483 Res.ele[10] = A.ele[2]*B.ele[8] + A.ele[6]*B.ele[9] + A.ele[10]*B.ele[10] + A.ele[14]*B.ele[11];
00484 Res.ele[11] = A.ele[3]*B.ele[8] + A.ele[7]*B.ele[9] + A.ele[11]*B.ele[10] + A.ele[15]*B.ele[11];
00485
00486 Res.ele[12] = A.ele[0]*B.ele[12] + A.ele[4]*B.ele[13] + A.ele[8]*B.ele[14] + A.ele[12]*B.ele[15];
00487 Res.ele[13] = A.ele[1]*B.ele[12] + A.ele[5]*B.ele[13] + A.ele[9]*B.ele[14] + A.ele[13]*B.ele[15];
00488 Res.ele[14] = A.ele[2]*B.ele[12] + A.ele[6]*B.ele[13] + A.ele[10]*B.ele[14] + A.ele[14]*B.ele[15];
00489 Res.ele[15] = A.ele[3]*B.ele[12] + A.ele[7]*B.ele[13] + A.ele[11]*B.ele[14] + A.ele[15]*B.ele[15];
00490 return Res;
00491
00492 #endif
00493 }
00494
00495 inline mitkMatrix& mitkMatrix::operator *= (const mitkMatrix &B)
00496 {
00497 #ifdef USE_SIMD
00498
00499 __m128 Result1, Result2, Result3, Result4;
00500
00501 Result1 = _mm_mul_ps(_mm_set_ps1(B.ele[0]), r1);
00502 Result1 = _mm_add_ps(Result1, _mm_mul_ps(_mm_set_ps1(B.ele[1]), r2));
00503 Result1 = _mm_add_ps(Result1, _mm_mul_ps(_mm_set_ps1(B.ele[2]), r3));
00504 Result1 = _mm_add_ps(Result1, _mm_mul_ps(_mm_set_ps1(B.ele[3]), r4));
00505
00506 Result2 = _mm_mul_ps(_mm_set_ps1(B.ele[4]), r1);
00507 Result2 = _mm_add_ps(Result2, _mm_mul_ps(_mm_set_ps1(B.ele[5]), r2));
00508 Result2 = _mm_add_ps(Result2, _mm_mul_ps(_mm_set_ps1(B.ele[6]), r3));
00509 Result2 = _mm_add_ps(Result2, _mm_mul_ps(_mm_set_ps1(B.ele[7]), r4));
00510
00511 Result3 = _mm_mul_ps(_mm_set_ps1(B.ele[8]), r1);
00512 Result3 = _mm_add_ps(Result3, _mm_mul_ps(_mm_set_ps1(B.ele[9]), r2));
00513 Result3 = _mm_add_ps(Result3, _mm_mul_ps(_mm_set_ps1(B.ele[10]), r3));
00514 Result3 = _mm_add_ps(Result3, _mm_mul_ps(_mm_set_ps1(B.ele[11]), r4));
00515
00516 Result4 = _mm_mul_ps(_mm_set_ps1(B.ele[12]), r1);
00517 Result4 = _mm_add_ps(Result4, _mm_mul_ps(_mm_set_ps1(B.ele[13]), r2));
00518 Result4 = _mm_add_ps(Result4, _mm_mul_ps(_mm_set_ps1(B.ele[14]), r3));
00519 Result4 = _mm_add_ps(Result4, _mm_mul_ps(_mm_set_ps1(B.ele[15]), r4));
00520
00521 r1 = Result1;
00522 r2 = Result2;
00523 r3 = Result3;
00524 r4 = Result4;
00525 return *this;
00526
00527 #else
00528
00529 mitkMatrix Res;
00530 Res.ele[0] = ele[0]*B.ele[0] + ele[4]*B.ele[1] + ele[8]*B.ele[2] + ele[12]*B.ele[3];
00531 Res.ele[1] = ele[1]*B.ele[0] + ele[5]*B.ele[1] + ele[9]*B.ele[2] + ele[13]*B.ele[3];
00532 Res.ele[2] = ele[2]*B.ele[0] + ele[6]*B.ele[1] + ele[10]*B.ele[2] + ele[14]*B.ele[3];
00533 Res.ele[3] = ele[3]*B.ele[0] + ele[7]*B.ele[1] + ele[11]*B.ele[2] + ele[15]*B.ele[3];
00534
00535 Res.ele[4] = ele[0]*B.ele[4] + ele[4]*B.ele[5] + ele[8]*B.ele[6] + ele[12]*B.ele[7];
00536 Res.ele[5] = ele[1]*B.ele[4] + ele[5]*B.ele[5] + ele[9]*B.ele[6] + ele[13]*B.ele[7];
00537 Res.ele[6] = ele[2]*B.ele[4] + ele[6]*B.ele[5] + ele[10]*B.ele[6] + ele[14]*B.ele[7];
00538 Res.ele[7] = ele[3]*B.ele[4] + ele[7]*B.ele[5] + ele[11]*B.ele[6] + ele[15]*B.ele[7];
00539
00540 Res.ele[8] = ele[0]*B.ele[8] + ele[4]*B.ele[9] + ele[8]*B.ele[10] + ele[12]*B.ele[11];
00541 Res.ele[9] = ele[1]*B.ele[8] + ele[5]*B.ele[9] + ele[9]*B.ele[10] + ele[13]*B.ele[11];
00542 Res.ele[10] = ele[2]*B.ele[8] + ele[6]*B.ele[9] + ele[10]*B.ele[10] + ele[14]*B.ele[11];
00543 Res.ele[11] = ele[3]*B.ele[8] + ele[7]*B.ele[9] + ele[11]*B.ele[10] + ele[15]*B.ele[11];
00544
00545 Res.ele[12] = ele[0]*B.ele[12] + ele[4]*B.ele[13] + ele[8]*B.ele[14] + ele[12]*B.ele[15];
00546 Res.ele[13] = ele[1]*B.ele[12] + ele[5]*B.ele[13] + ele[9]*B.ele[14] + ele[13]*B.ele[15];
00547 Res.ele[14] = ele[2]*B.ele[12] + ele[6]*B.ele[13] + ele[10]*B.ele[14] + ele[14]*B.ele[15];
00548 Res.ele[15] = ele[3]*B.ele[12] + ele[7]*B.ele[13] + ele[11]*B.ele[14] + ele[15]*B.ele[15];
00549 *this = Res;
00550 return *this;
00551
00552 #endif
00553 }
00554
00555 inline mitkMatrix operator * (const mitkMatrix &A, const float s)
00556 {
00557 mitkMatrix Res;
00558
00559 #ifdef USE_SIMD
00560
00561 __m128 S = _mm_set_ps1(s);
00562 Res.r1 = _mm_mul_ps(A.r1, S);
00563 Res.r2 = _mm_mul_ps(A.r2, S);
00564 Res.r3 = _mm_mul_ps(A.r3, S);
00565 Res.r4 = _mm_mul_ps(A.r4, S);
00566 return Res;
00567
00568 #else
00569
00570 Res.ele[0] = A.ele[0] * s;
00571 Res.ele[1] = A.ele[1] * s;
00572 Res.ele[2] = A.ele[2] * s;
00573 Res.ele[3] = A.ele[3] * s;
00574 Res.ele[4] = A.ele[4] * s;
00575 Res.ele[5] = A.ele[5] * s;
00576 Res.ele[6] = A.ele[6] * s;
00577 Res.ele[7] = A.ele[7] * s;
00578 Res.ele[8] = A.ele[8] * s;
00579 Res.ele[9] = A.ele[9] * s;
00580 Res.ele[10] = A.ele[10] * s;
00581 Res.ele[11] = A.ele[11] * s;
00582 Res.ele[12] = A.ele[12] * s;
00583 Res.ele[13] = A.ele[13] * s;
00584 Res.ele[14] = A.ele[14] * s;
00585 Res.ele[15] = A.ele[15] * s;
00586 return Res;
00587
00588 #endif
00589 }
00590
00591 inline mitkMatrix operator * (const float s, const mitkMatrix &A)
00592 {
00593 mitkMatrix Res;
00594
00595 #ifdef USE_SIMD
00596
00597 __m128 S = _mm_set_ps1(s);
00598 Res.r1 = _mm_mul_ps(A.r1, S);
00599 Res.r2 = _mm_mul_ps(A.r2, S);
00600 Res.r3 = _mm_mul_ps(A.r3, S);
00601 Res.r4 = _mm_mul_ps(A.r4, S);
00602 return Res;
00603
00604 #else
00605
00606 Res.ele[0] = A.ele[0] * s;
00607 Res.ele[1] = A.ele[1] * s;
00608 Res.ele[2] = A.ele[2] * s;
00609 Res.ele[3] = A.ele[3] * s;
00610 Res.ele[4] = A.ele[4] * s;
00611 Res.ele[5] = A.ele[5] * s;
00612 Res.ele[6] = A.ele[6] * s;
00613 Res.ele[7] = A.ele[7] * s;
00614 Res.ele[8] = A.ele[8] * s;
00615 Res.ele[9] = A.ele[9] * s;
00616 Res.ele[10] = A.ele[10] * s;
00617 Res.ele[11] = A.ele[11] * s;
00618 Res.ele[12] = A.ele[12] * s;
00619 Res.ele[13] = A.ele[13] * s;
00620 Res.ele[14] = A.ele[14] * s;
00621 Res.ele[15] = A.ele[15] * s;
00622 return Res;
00623
00624 #endif
00625 }
00626
00627 inline mitkMatrix& mitkMatrix::operator *= (const float s)
00628 {
00629 #ifdef USE_SIMD
00630 __m128 S = _mm_set_ps1(s);
00631 r1 = _mm_mul_ps(r1, S);
00632 r2 = _mm_mul_ps(r2, S);
00633 r3 = _mm_mul_ps(r3, S);
00634 r4 = _mm_mul_ps(r4, S);
00635 return *this;
00636 #else
00637 ele[0] *= s;
00638 ele[1] *= s;
00639 ele[2] *= s;
00640 ele[3] *= s;
00641 ele[4] *= s;
00642 ele[5] *= s;
00643 ele[6] *= s;
00644 ele[7] *= s;
00645 ele[8] *= s;
00646 ele[9] *= s;
00647 ele[10] *= s;
00648 ele[11] *= s;
00649 ele[12] *= s;
00650 ele[13] *= s;
00651 ele[14] *= s;
00652 ele[15] *= s;
00653 return *this;
00654 #endif
00655 }
00656
00657 inline mitkMatrix operator + (const mitkMatrix &A, const mitkMatrix &B)
00658 {
00659 mitkMatrix Res;
00660
00661 #ifdef USE_SIMD
00662
00663 Res.r1 = _mm_add_ps(A.r1, B.r1);
00664 Res.r2 = _mm_add_ps(A.r2, B.r2);
00665 Res.r3 = _mm_add_ps(A.r3, B.r3);
00666 Res.r4 = _mm_add_ps(A.r4, B.r4);
00667 return Res;
00668
00669 #else
00670
00671 Res.ele[0] = A.ele[0] + B.ele[0];
00672 Res.ele[1] = A.ele[1] + B.ele[1];
00673 Res.ele[2] = A.ele[2] + B.ele[2];
00674 Res.ele[3] = A.ele[3] + B.ele[3];
00675 Res.ele[4] = A.ele[4] + B.ele[4];
00676 Res.ele[5] = A.ele[5] + B.ele[5];
00677 Res.ele[6] = A.ele[6] + B.ele[6];
00678 Res.ele[7] = A.ele[7] + B.ele[7];
00679 Res.ele[8] = A.ele[8] + B.ele[8];
00680 Res.ele[9] = A.ele[9] + B.ele[9];
00681 Res.ele[10] = A.ele[10] + B.ele[10];
00682 Res.ele[11] = A.ele[11] + B.ele[11];
00683 Res.ele[12] = A.ele[12] + B.ele[12];
00684 Res.ele[13] = A.ele[13] + B.ele[13];
00685 Res.ele[14] = A.ele[14] + B.ele[14];
00686 Res.ele[15] = A.ele[15] + B.ele[15];
00687 return Res;
00688
00689 #endif
00690 }
00691
00692 inline mitkMatrix & mitkMatrix::operator += (const mitkMatrix &B)
00693 {
00694 #ifdef USE_SIMD
00695 r1 = _mm_add_ps(r1, B.r1);
00696 r2 = _mm_add_ps(r2, B.r2);
00697 r3 = _mm_add_ps(r3, B.r3);
00698 r4 = _mm_add_ps(r4, B.r4);
00699 return *this;
00700 #else
00701 ele[0] += B.ele[0];
00702 ele[1] += B.ele[1];
00703 ele[2] += B.ele[2];
00704 ele[3] += B.ele[3];
00705 ele[4] += B.ele[4];
00706 ele[5] += B.ele[5];
00707 ele[6] += B.ele[6];
00708 ele[7] += B.ele[7];
00709 ele[8] += B.ele[8];
00710 ele[9] += B.ele[9];
00711 ele[10] += B.ele[10];
00712 ele[11] += B.ele[11];
00713 ele[12] += B.ele[12];
00714 ele[13] += B.ele[13];
00715 ele[14] += B.ele[14];
00716 ele[15] += B.ele[15];
00717 return *this;
00718 #endif
00719 }
00720
00721 inline mitkMatrix operator - (const mitkMatrix &A, const mitkMatrix &B)
00722 {
00723 mitkMatrix Res;
00724
00725 #ifdef USE_SIMD
00726
00727 Res.r1 = _mm_sub_ps(A.r1, B.r1);
00728 Res.r2 = _mm_sub_ps(A.r2, B.r2);
00729 Res.r3 = _mm_sub_ps(A.r3, B.r3);
00730 Res.r4 = _mm_sub_ps(A.r4, B.r4);
00731 return Res;
00732
00733 #else
00734
00735 Res.ele[0] = A.ele[0] - B.ele[0];
00736 Res.ele[1] = A.ele[1] - B.ele[1];
00737 Res.ele[2] = A.ele[2] - B.ele[2];
00738 Res.ele[3] = A.ele[3] - B.ele[3];
00739 Res.ele[4] = A.ele[4] - B.ele[4];
00740 Res.ele[5] = A.ele[5] - B.ele[5];
00741 Res.ele[6] = A.ele[6] - B.ele[6];
00742 Res.ele[7] = A.ele[7] - B.ele[7];
00743 Res.ele[8] = A.ele[8] - B.ele[8];
00744 Res.ele[9] = A.ele[9] - B.ele[9];
00745 Res.ele[10] = A.ele[10] - B.ele[10];
00746 Res.ele[11] = A.ele[11] - B.ele[11];
00747 Res.ele[12] = A.ele[12] - B.ele[12];
00748 Res.ele[13] = A.ele[13] - B.ele[13];
00749 Res.ele[14] = A.ele[14] - B.ele[14];
00750 Res.ele[15] = A.ele[15] - B.ele[15];
00751 return Res;
00752
00753 #endif
00754 }
00755
00756 inline mitkMatrix operator - (const mitkMatrix &A)
00757 {
00758 mitkMatrix Res;
00759
00760 #ifdef USE_SIMD
00761
00762 Res.r1 = _mm_neg_ps(A.r1);
00763 Res.r2 = _mm_neg_ps(A.r2);
00764 Res.r3 = _mm_neg_ps(A.r3);
00765 Res.r4 = _mm_neg_ps(A.r4);
00766 return Res;
00767
00768 #else
00769
00770 Res.ele[0] = - A.ele[0];
00771 Res.ele[1] = - A.ele[1];
00772 Res.ele[2] = - A.ele[2];
00773 Res.ele[3] = - A.ele[3];
00774 Res.ele[4] = - A.ele[4];
00775 Res.ele[5] = - A.ele[5];
00776 Res.ele[6] = - A.ele[6];
00777 Res.ele[7] = - A.ele[7];
00778 Res.ele[8] = - A.ele[8];
00779 Res.ele[9] = - A.ele[9];
00780 Res.ele[10] = - A.ele[10];
00781 Res.ele[11] = - A.ele[11];
00782 Res.ele[12] = - A.ele[12];
00783 Res.ele[13] = - A.ele[13];
00784 Res.ele[14] = - A.ele[14];
00785 Res.ele[15] = - A.ele[15];
00786 return Res;
00787
00788 #endif
00789 }
00790
00791 inline mitkMatrix & mitkMatrix::operator -= (const mitkMatrix &B)
00792 {
00793 #ifdef USE_SIMD
00794 r1 = _mm_add_ps(r1, B.r1);
00795 r2 = _mm_add_ps(r2, B.r2);
00796 r3 = _mm_add_ps(r3, B.r3);
00797 r4 = _mm_add_ps(r4, B.r4);
00798 return *this;
00799 #else
00800 ele[0] -= B.ele[0];
00801 ele[1] -= B.ele[1];
00802 ele[2] -= B.ele[2];
00803 ele[3] -= B.ele[3];
00804 ele[4] -= B.ele[4];
00805 ele[5] -= B.ele[5];
00806 ele[6] -= B.ele[6];
00807 ele[7] -= B.ele[7];
00808 ele[8] -= B.ele[8];
00809 ele[9] -= B.ele[9];
00810 ele[10] -= B.ele[10];
00811 ele[11] -= B.ele[11];
00812 ele[12] -= B.ele[12];
00813 ele[13] -= B.ele[13];
00814 ele[14] -= B.ele[14];
00815 ele[15] -= B.ele[15];
00816 return *this;
00817 #endif
00818 }
00819
00820 inline mitkVector operator * (const mitkVector& Vec, const mitkMatrix& Mat)
00821 {
00822 mitkVector Res;
00823
00824 #ifdef USE_SIMD
00825
00826 mitkVector temp;
00827
00828 temp.vec = _mm_mul_ps(Vec.vec, Mat.r1);
00829 Res.ele[0] = temp.ele[0] + temp.ele[1] + temp.ele[2] + temp.ele[3];
00830
00831 temp.vec = _mm_mul_ps(Vec.vec, Mat.r2);
00832 Res.ele[1] = temp.ele[0] + temp.ele[1] + temp.ele[2] + temp.ele[3];
00833
00834 temp.vec = _mm_mul_ps(Vec.vec, Mat.r3);
00835 Res.ele[2] = temp.ele[0] + temp.ele[1] + temp.ele[2] + temp.ele[3];
00836
00837 temp.vec = _mm_mul_ps(Vec.vec, Mat.r4);
00838 Res.ele[3] = temp.ele[0] + temp.ele[1] + temp.ele[2] + temp.ele[3];
00839 return Res;
00840
00841 #else
00842
00843 Res.ele[0] = Mat.ele[0]*Vec.ele[0] + Mat.ele[1]*Vec.ele[1] + Mat.ele[2]*Vec.ele[2] + Mat.ele[3]*Vec.ele[3];
00844 Res.ele[1] = Mat.ele[4]*Vec.ele[0] + Mat.ele[5]*Vec.ele[1] + Mat.ele[6]*Vec.ele[2] + Mat.ele[7]*Vec.ele[3];
00845 Res.ele[2] = Mat.ele[8]*Vec.ele[0] + Mat.ele[9]*Vec.ele[1] + Mat.ele[10]*Vec.ele[2] + Mat.ele[11]*Vec.ele[3];
00846 Res.ele[3] = Mat.ele[12]*Vec.ele[0] + Mat.ele[13]*Vec.ele[1] + Mat.ele[14]*Vec.ele[2] + Mat.ele[15]*Vec.ele[3];
00847 return Res;
00848
00849 #endif
00850 }
00851
00852 inline mitkVector operator * (const mitkMatrix& Mat, mitkVector& Vec)
00853 {
00854 mitkVector Res;
00855
00856 #ifdef USE_SIMD
00857
00858 Res.vec = _mm_mul_ps(Mat.r1, _mm_set_ps1(Vec.ele[0]));
00859 Res.vec = _mm_add_ps(Res.vec, _mm_mul_ps(Mat.r2, _mm_set_ps1(Vec.ele[1])));
00860 Res.vec = _mm_add_ps(Res.vec, _mm_mul_ps(Mat.r3, _mm_set_ps1(Vec.ele[2])));
00861 Res.vec = _mm_add_ps(Res.vec, _mm_mul_ps(Mat.r4, _mm_set_ps1(Vec.ele[3])));
00862 return Res;
00863
00864 #else
00865
00866 Res.ele[0] = Mat.ele[0]*Vec.ele[0] + Mat.ele[4]*Vec.ele[1] + Mat.ele[8]*Vec.ele[2] + Mat.ele[12]*Vec.ele[3];
00867 Res.ele[1] = Mat.ele[1]*Vec.ele[0] + Mat.ele[5]*Vec.ele[1] + Mat.ele[9]*Vec.ele[2] + Mat.ele[13]*Vec.ele[3];
00868 Res.ele[2] = Mat.ele[2]*Vec.ele[0] + Mat.ele[6]*Vec.ele[1] + Mat.ele[10]*Vec.ele[2] + Mat.ele[14]*Vec.ele[3];
00869 Res.ele[3] = Mat.ele[3]*Vec.ele[0] + Mat.ele[7]*Vec.ele[1] + Mat.ele[11]*Vec.ele[2] + Mat.ele[15]*Vec.ele[3];
00870 return Res;
00871
00872 #endif
00873 }
00874
00875 inline mitkVector& mitkVector::operator *= (const mitkMatrix& Mat)
00876 {
00877 #ifdef USE_SIMD
00878
00879 __m128 temp;
00880 temp = _mm_mul_ps(Mat.r1, _mm_set_ps1(ele[0]));
00881 temp = _mm_add_ps(temp, _mm_mul_ps(Mat.r2, _mm_set_ps1(ele[1])));
00882 temp = _mm_add_ps(temp, _mm_mul_ps(Mat.r3, _mm_set_ps1(ele[2])));
00883 temp = _mm_add_ps(temp, _mm_mul_ps(Mat.r4, _mm_set_ps1(ele[3])));
00884 vec = temp;
00885 return *this;
00886
00887 #else
00888
00889 float temp[4];
00890 temp[0] = Mat.ele[0]*ele[0] + Mat.ele[4]*ele[1] + Mat.ele[8]*ele[2] + Mat.ele[12]*ele[3];
00891 temp[1] = Mat.ele[1]*ele[0] + Mat.ele[5]*ele[1] + Mat.ele[9]*ele[2] + Mat.ele[13]*ele[3];
00892 temp[2] = Mat.ele[2]*ele[0] + Mat.ele[6]*ele[1] + Mat.ele[10]*ele[2] + Mat.ele[14]*ele[3];
00893 temp[3] = Mat.ele[3]*ele[0] + Mat.ele[7]*ele[1] + Mat.ele[11]*ele[2] + Mat.ele[15]*ele[3];
00894 ele[0] = temp[0];
00895 ele[1] = temp[1];
00896 ele[2] = temp[2];
00897 ele[3] = temp[3];
00898 return *this;
00899
00900 #endif
00901 }
00902
00903 inline float operator * (const mitkVector& A, const mitkVector& B)
00904 {
00905 #ifdef USE_SIMD
00906 mitkVector r;
00907 r.vec = _mm_mul_ps(A.vec, B.vec);
00908 return r.ele[0] + r.ele[1] + r.ele[2];
00909 #else
00910 return A.ele[0]*B.ele[0] + A.ele[1]*B.ele[1] + A.ele[2]*B.ele[2];
00911 #endif
00912 }
00913
00914
00915 inline mitkVector operator % (const mitkVector& A, const mitkVector& B)
00916 {
00917 mitkVector Res;
00918
00919 #ifdef USE_SIMD
00920 __m128 l1, l2, m1, m2;
00921 l1 = _mm_shuffle_ps(A.vec,A.vec, _MM_SHUFFLE(3,1,0,2));
00922 l2 = _mm_shuffle_ps(B.vec,B.vec, _MM_SHUFFLE(3,0,2,1));
00923 m2 = _mm_mul_ps(l1, l2);
00924
00925 l1 = _mm_shuffle_ps(A.vec,A.vec, _MM_SHUFFLE(3,0,2,1));
00926 l2 = _mm_shuffle_ps(B.vec,B.vec, _MM_SHUFFLE(3,1,0,2));
00927 m1 = _mm_mul_ps(l1, l2);
00928
00929 Res.vec = _mm_sub_ps(m1, m2);
00930 return Res;
00931 #else
00932 Res.ele[0] = A.ele[1] * B.ele[2] - A.ele[2] * B.ele[1];
00933 Res.ele[1] = A.ele[2] * B.ele[0] - A.ele[0] * B.ele[2];
00934 Res.ele[2] = A.ele[0] * B.ele[1] - A.ele[1] * B.ele[0];
00935 Res.ele[3] = 0.0f;
00936 return Res;
00937 #endif
00938 }
00939
00940 inline mitkVector operator * (const mitkVector &V, const float s)
00941 {
00942 mitkVector Res;
00943 #ifdef USE_SIMD
00944 Res.vec = _mm_mul_ps(V.vec, _mm_set_ps1(s));
00945 return Res;
00946 #else
00947 Res.ele[0] = V.ele[0] * s;
00948 Res.ele[1] = V.ele[1] * s;
00949 Res.ele[2] = V.ele[2] * s;
00950 Res.ele[3] = V.ele[3] * s;
00951 return Res;
00952 #endif
00953 }
00954
00955 inline mitkVector operator * (const float s, const mitkVector &V)
00956 {
00957 mitkVector Res;
00958 #ifdef USE_SIMD
00959 Res.vec = _mm_mul_ps(V.vec, _mm_set_ps1(s));
00960 return Res;
00961 #else
00962 Res.ele[0] = V.ele[0] * s;
00963 Res.ele[1] = V.ele[1] * s;
00964 Res.ele[2] = V.ele[2] * s;
00965 Res.ele[3] = V.ele[3] * s;
00966 return Res;
00967 #endif
00968 }
00969
00970 inline mitkVector& mitkVector::operator *= (const float s)
00971 {
00972 #ifdef USE_SIMD
00973 vec = _mm_mul_ps(vec, _mm_set_ps1(s));
00974 return *this;
00975 #else
00976 ele[0] *= s;
00977 ele[1] *= s;
00978 ele[2] *= s;
00979 ele[3] *= s;
00980 return *this;
00981 #endif
00982 }
00983
00984 inline mitkVector operator + (const mitkVector& A, const mitkVector& B)
00985 {
00986 mitkVector Res;
00987 #ifdef USE_SIMD
00988 Res.vec = _mm_add_ps(A.vec, B.vec);
00989 return Res;
00990 #else
00991 Res.ele[0] = A.ele[0] + B.ele[0];
00992 Res.ele[1] = A.ele[1] + B.ele[1];
00993 Res.ele[2] = A.ele[2] + B.ele[2];
00994 Res.ele[3] = A.ele[3] + B.ele[3];
00995 return Res;
00996 #endif
00997 }
00998
00999 inline mitkVector operator - (const mitkVector& A, const mitkVector& B)
01000 {
01001 mitkVector Res;
01002 #ifdef USE_SIMD
01003 Res.vec = _mm_sub_ps(A.vec, B.vec);
01004 return Res;
01005 #else
01006 Res.ele[0] = A.ele[0] - B.ele[0];
01007 Res.ele[1] = A.ele[1] - B.ele[1];
01008 Res.ele[2] = A.ele[2] - B.ele[2];
01009 Res.ele[3] = A.ele[3] - B.ele[3];
01010 return Res;
01011 #endif
01012 }
01013
01014 inline mitkVector operator - (const mitkVector& A)
01015 {
01016 mitkVector Res;
01017 #ifdef USE_SIMD
01018 Res.vec = _mm_neg_ps(A.vec);
01019 return Res;
01020 #else
01021 Res.ele[0] = - A.ele[0];
01022 Res.ele[1] = - A.ele[1];
01023 Res.ele[2] = - A.ele[2];
01024 Res.ele[3] = - A.ele[3];
01025 return Res;
01026 #endif
01027 }
01028
01029 inline mitkVector & mitkVector::operator += (const mitkVector &B)
01030 {
01031 #ifdef USE_SIMD
01032 vec = _mm_add_ps(vec, B.vec);
01033 return *this;
01034 #else
01035 ele[0] += B.ele[0];
01036 ele[1] += B.ele[1];
01037 ele[2] += B.ele[2];
01038 ele[3] += B.ele[3];
01039 return *this;
01040 #endif
01041 }
01042
01043 inline mitkVector & mitkVector::operator -= (const mitkVector &B)
01044 {
01045 #ifdef USE_SIMD
01046 vec = _mm_sub_ps(vec, B.vec);
01047 return *this;
01048 #else
01049 ele[0] -= B.ele[0];
01050 ele[1] -= B.ele[1];
01051 ele[2] -= B.ele[2];
01052 ele[3] -= B.ele[3];
01053 return *this;
01054 #endif
01055 }
01056
01057 inline float mitkVector::Length()
01058 {
01059 #ifdef USE_SIMD
01060 __m128 r = _mm_mul_ps(vec, vec);
01061 r = _mm_add_ss(_mm_movehl_ps(r, r), r);
01062 r = _mm_add_ss(_mm_shuffle_ps(r, r, 1), r);
01063 r = _mm_sqrt_ss(r);
01064 return *(float *)&r;
01065 #else
01066 return sqrtf(ele[0]*ele[0] + ele[1]*ele[1] + ele[2]*ele[2]);
01067 #endif
01068 }
01069
01070 inline float mitkVector::Length2()
01071 {
01072 #ifdef USE_SIMD
01073 __m128 r = _mm_mul_ps(vec, vec);
01074 r = _mm_add_ss(_mm_movehl_ps(r, r), r);
01075 r = _mm_add_ss(_mm_shuffle_ps(r, r, 1), r);
01076 return *(float *)&r;
01077 #else
01078 return (ele[0]*ele[0] + ele[1]*ele[1] + ele[2]*ele[2]);
01079 #endif
01080 }
01081
01082 inline void mitkVector::Normalize()
01083 {
01084 #ifdef USE_SIMD
01085 __m128 r = _mm_mul_ps(vec, vec);
01086 r = _mm_add_ps(_mm_movehl_ps(r, r), r);
01087 r = _mm_add_ss(_mm_shuffle_ps(r, r, 1), r);
01088 r = _mm_rsqrt_ps(r);
01089 vec = _mm_mul_ps(vec, _mm_shuffle_ps(r, r, 0));
01090 #else
01091 float vecLenInv = 1.0f / sqrtf(ele[0]*ele[0] + ele[1]*ele[1] + ele[2]*ele[2]);
01092 ele[0] *= vecLenInv;
01093 ele[1] *= vecLenInv;
01094 ele[2] *= vecLenInv;
01095 #endif
01096 }
01097
01098 #endif
01099