00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef LUX_MATRIX4X4_H
00025 #define LUX_MATRIX4X4_H
00026
00027 #include <xmmintrin.h>
00028
00029 namespace lux {
00030 static float _matrix44_sse_ident[16] = {
00031 1.0f, 0.0f, 0.0f, 0.0f,
00032 0.0f, 1.0f, 0.0f, 0.0f,
00033 0.0f, 0.0f, 1.0f, 0.0f,
00034 0.0f, 0.0f, 0.0f, 1.0f,
00035 };
00036
00037 class Matrix4x4 {
00038 public:
00039
00040 Matrix4x4() {
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 memcpy(&_11, _matrix44_sse_ident, sizeof(_matrix44_sse_ident));
00054 }
00055 Matrix4x4(const Matrix4x4 & m):_L1(m._L1), _L2(m._L2), _L3(m._L3),
00056 _L4(m._L4)
00057 {}
00058
00059 Matrix4x4(const __m128 &l1, const __m128 &l2, const __m128 &l3, const __m128 &l4):_L1(l1), _L2(l2), _L3(l3), _L4(l4)
00060 {}
00061
00062 Matrix4x4(float mat[4][4]);
00063 Matrix4x4(float t00, float t01, float t02, float t03,
00064 float t10, float t11, float t12, float t13,
00065 float t20, float t21, float t22, float t23,
00066 float t30, float t31, float t32, float t33);
00067 boost::shared_ptr<Matrix4x4> Transpose() const;
00068 void Print(ostream &os) const {
00069 os<<"[ ";
00070 for(int i=0;i<4;i++) {
00071 os<<"[ ";
00072 for(int j=0;j<4;j++) {
00073 os<<(*this)[j][i];
00074 if(j!=3) os<<", ";
00075 }
00076 os<<" ] ";
00077 }
00078 os<<"]";
00079 }
00080 static boost::shared_ptr<Matrix4x4>
00081 Mul(const boost::shared_ptr<Matrix4x4> &A,
00082 const boost::shared_ptr<Matrix4x4> &B) {
00083 __m128 r1, r2, r3, r4;
00084 __m128 B1 = A->_L1, B2 = A->_L2, B3 = A->_L3, B4 = A->_L4;
00085
00086 r1 = _mm_mul_ps(_mm_set_ps1(B->_11) , B1);
00087 r2 = _mm_mul_ps(_mm_set_ps1(B->_21) , B1);
00088 r1 = _mm_add_ps(r1, _mm_mul_ps(_mm_set_ps1(B->_12) , B2));
00089 r2 = _mm_add_ps(r2, _mm_mul_ps(_mm_set_ps1(B->_22) , B2));
00090 r1 = _mm_add_ps(r1, _mm_mul_ps(_mm_set_ps1(B->_13) , B3));
00091 r2 = _mm_add_ps(r2, _mm_mul_ps(_mm_set_ps1(B->_23) , B3));
00092 r1 = _mm_add_ps(r1, _mm_mul_ps(_mm_set_ps1(B->_14) , B4));
00093 r2 = _mm_add_ps(r2, _mm_mul_ps(_mm_set_ps1(B->_24) , B4));
00094
00095
00096
00097 r3 = _mm_mul_ps(_mm_set_ps1(B->_31) , B1);
00098 r4 = _mm_mul_ps(_mm_set_ps1(B->_41) , B1);
00099 r3 = _mm_add_ps(r3, _mm_mul_ps(_mm_set_ps1(B->_32) , B2));
00100 r4 = _mm_add_ps(r4, _mm_mul_ps(_mm_set_ps1(B->_42) , B2));
00101 r3 = _mm_add_ps(r3, _mm_mul_ps(_mm_set_ps1(B->_33) , B3));
00102 r4 = _mm_add_ps(r4, _mm_mul_ps(_mm_set_ps1(B->_43) , B3));
00103 r3 = _mm_add_ps(r3, _mm_mul_ps(_mm_set_ps1(B->_34) , B4));
00104 r4 = _mm_add_ps(r4, _mm_mul_ps(_mm_set_ps1(B->_44) , B4));
00105
00106
00107
00108
00109
00110 boost::shared_ptr<Matrix4x4> o(new Matrix4x4(r1, r2, r3, r4));
00111 return o;
00112 }
00113 boost::shared_ptr<Matrix4x4> Inverse() const;
00114
00115
00116 union {
00117 struct {
00118 __m128 _L1, _L2, _L3, _L4;
00119 };
00120 struct {
00121 float _11, _12, _13, _14;
00122 float _21, _22, _23, _24;
00123 float _31, _32, _33, _34;
00124 float _41, _42, _43, _44;
00125 };
00126 struct {
00127 float _t11, _t21, _t31, _t41;
00128 float _t12, _t22, _t32, _t42;
00129 float _t13, _t23, _t33, _t43;
00130 float _t14, _t24, _t34, _t44;
00131 };
00132 };
00133
00134 void* operator new(size_t t) { return _mm_malloc(t, 16); }
00135 void operator delete(void* ptr, size_t t) { _mm_free(ptr); }
00136 void* operator new[](size_t t) { return _mm_malloc(t, 16); }
00137 void operator delete[] (void* ptr) { _mm_free(ptr); }
00138
00139 private:
00140
00141 float* operator [] (int i) const {
00142
00143 return (float*)((&_L1)+i);
00144 }
00145 };
00146
00147 }
00148
00149 #endif //LUX_MATRIX4X4_H