00001 #ifndef DataFormat_Math_SSERot_H
00002 #define DataFormat_Math_SSERot_H
00003
00004
00005 #include "DataFormats/Math/interface/SSEVec.h"
00006
00007 namespace mathSSE {
00008
00009 template<typename T>
00010 struct OldRot {
00011 T R11, R12, R13;
00012 T R21, R22, R23;
00013 T R31, R32, R33;
00014 } __attribute__ ((aligned (16)));
00015
00016
00017 template<typename T>
00018 struct Rot3 {
00019 Vec4<T> axis[3];
00020
00021 Rot3() {
00022 axis[0].arr[0]=1;
00023 axis[1].arr[1]=1;
00024 axis[2].arr[2]=1;
00025 }
00026
00027 Rot3( Vec4<T> ix, Vec4<T> iy, Vec4<T> iz) {
00028 axis[0] =ix;
00029 axis[1] =iy;
00030 axis[2] =iz;
00031 }
00032
00033 Rot3( T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz) {
00034 axis[0].set(xx,xy,xz);
00035 axis[1].set(yx,yy,yz);
00036 axis[2].set(zx,zy,zz);
00037 }
00038
00039 Rot3 transpose() const {
00040 return Rot3( axis[0].arr[0], axis[1].arr[0], axis[2].arr[0],
00041 axis[0].arr[1], axis[1].arr[1], axis[2].arr[1],
00042 axis[0].arr[2], axis[1].arr[2], axis[2].arr[2]
00043 );
00044 }
00045
00046 Vec4<T> x() { return axis[0];}
00047 Vec4<T> y() { return axis[1];}
00048 Vec4<T> z() { return axis[2];}
00049
00050
00051 Vec4<T> rotate(Vec4<T> v) const {
00052 return transpose().rotateBack(v);
00053 }
00054
00055
00056
00057 Vec4<T> rotateBack(Vec4<T> v) const {
00058 return v.template get1<0>()*axis[0] + v.template get1<1>()*axis[1] + v.template get1<2>()*axis[2];
00059 }
00060
00061 Rot3 rotate(Rot3 const& r) const {
00062 Rot3 tr = transpose();
00063 return Rot3(tr.rotateBack(r.axis[0]),tr.rotateBack(r.axis[1]),tr.rotateBack(r.axis[2]));
00064 }
00065
00066 Rot3 rotateBack(Rot3 const& r) const {
00067 return Rot3(rotateBack(r.axis[0]),rotateBack(r.axis[1]),rotateBack(r.axis[2]));
00068 }
00069
00070
00071 };
00072
00073 typedef Rot3<float> Rot3F;
00074
00075 typedef Rot3<double> Rot3D;
00076
00077 #ifdef __SSE4_1__
00078 template<>
00079 inline Vec4<float> Rot3<float>::rotate(Vec4<float> v) const {
00080 return _mm_or_ps(_mm_or_ps(_mm_dp_ps(axis[0].vec,v.vec,0x71),
00081 _mm_dp_ps(axis[1].vec,v.vec,0x72)),
00082 _mm_dp_ps(axis[2].vec,v.vec,0x74)
00083 );
00084 }
00085 template<>
00086 inline Rot3<float> Rot3<float>::rotate(Rot3<float> const& r) const {
00087 return Rot3<float> (rotate(r.axis[0]),rotate(r.axis[1]),rotate(r.axis[2]));
00088 }
00089
00090 #endif
00091
00092
00093 }
00094
00095 template<typename T>
00096 inline mathSSE::Rot3<T> operator *(mathSSE::Rot3<T> const & rh, mathSSE::Rot3<T> const & lh) {
00097
00098 return lh.rotateBack(rh);
00099 }
00100
00101 namespace mathSSE {
00102
00103 template<typename T>
00104 struct Rot2 {
00105 Vec2<T> axis[2];
00106
00107 Rot2() {
00108 axis[0].arr[0]=1;
00109 axis[1].arr[1]=1;
00110 }
00111
00112 Rot2( Vec2<T> ix, Vec2<T> iy) {
00113 axis[0] =ix;
00114 axis[1] =iy;
00115 }
00116
00117 Rot2( T xx, T xy, T yx, T yy) {
00118 axis[0].set(xx,xy);
00119 axis[1].set(yx,yy);
00120 }
00121
00122 Rot2 transpose() const {
00123 return Rot2( axis[0].arr[0], axis[1].arr[0],
00124 axis[0].arr[1], axis[1].arr[1]
00125 );
00126 }
00127
00128 Vec2<T> x() { return axis[0];}
00129 Vec2<T> y() { return axis[1];}
00130
00131
00132 Vec2<T> rotate(Vec2<T> v) const {
00133 return transpose().rotateBack(v);
00134 }
00135
00136
00137
00138 Vec2<T> rotateBack(Vec2<T> v) const {
00139 return v.template get1<0>()*axis[0] + v.template get1<1>()*axis[1];
00140 }
00141
00142 Rot2 rotate(Rot2 const& r) const {
00143 Rot2 tr = transpose();
00144 return Rot2(tr.rotateBack(r.axis[0]),tr.rotateBack(r.axis[1]));
00145 }
00146
00147 Rot2 rotateBack(Rot2 const& r) const {
00148 return Rot2(rotateBack(r.axis[0]),rotateBack(r.axis[1]));
00149 }
00150
00151
00152 };
00153
00154 typedef Rot2<float> Rot2F;
00155
00156 typedef Rot2<double> Rot2D;
00157
00158
00159 }
00160
00161 template<typename T>
00162 inline mathSSE::Rot2<T> operator *(mathSSE::Rot2<T> const & rh, mathSSE::Rot2<T> const & lh) {
00163 return lh.rotateBack(rh);
00164 }
00165
00166
00167
00168 #include <iosfwd>
00169 std::ostream & operator<<(std::ostream & out, mathSSE::Rot3F const & v);
00170 std::ostream & operator<<(std::ostream & out, mathSSE::Rot3D const & v);
00171 std::ostream & operator<<(std::ostream & out, mathSSE::Rot2F const & v);
00172 std::ostream & operator<<(std::ostream & out, mathSSE::Rot2D const & v);
00173
00174
00175 #endif // DataFormat_Math_SSERot_H