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 #include <iosfwd>
00102 std::ostream & operator<<(std::ostream & out, mathSSE::Rot3F const & v);
00103 std::ostream & operator<<(std::ostream & out, mathSSE::Rot3D const & v);
00104
00105
00106 #endif // DataFormat_Math_SSERot_H