00001 #ifndef DataFormat_Math_ExtVec_H
00002 #define DataFormat_Math_ExtVec_H
00003
00004 #include<type_traits>
00005
00006 typedef float __attribute__( ( vector_size( 8 ) ) ) float32x2_t;
00007 typedef float __attribute__( ( vector_size( 16 ) ) ) float32x4_t;
00008 typedef float __attribute__( ( vector_size( 32 ) ) ) float32x8_t;
00009 typedef double __attribute__( ( vector_size( 16 ) ) ) float64x2_t;
00010 typedef double __attribute__( ( vector_size( 32 ) ) ) float64x4_t;
00011 typedef double __attribute__( ( vector_size( 64 ) ) ) float64x8_t;
00012
00013
00014
00015
00016 template<typename T, int N>
00017 struct ExtVecTraits {
00018 typedef T __attribute__( ( vector_size( N*sizeof(T) ) ) ) type;
00019 };
00020
00021 template<typename T, int N> using ExtVec = typename ExtVecTraits<T,N>::type;
00022
00023 template<typename T> using Vec4 = ExtVec<T,4>;
00024 template<typename T> using Vec2 = ExtVec<T,2>;
00025
00026 template<typename V>
00027 inline
00028 auto xy(V v)-> Vec2<typename std::remove_reference<decltype(v[0])>::type>
00029 {
00030 typedef typename std::remove_reference<decltype(v[0])>::type T;
00031 return Vec2<T>{v[0],v[1]};
00032 }
00033
00034 template<typename V>
00035 inline
00036 auto zw(V v) -> Vec2<typename std::remove_reference<decltype(v[0])>::type>
00037 {
00038 typedef typename std::remove_reference<decltype(v[0])>::type T;
00039 return Vec2<T>{v[2],v[3]};
00040 }
00041
00042 template<typename Vec, typename F>
00043 inline
00044 Vec apply(Vec v, F f) {
00045 typedef typename std::remove_reference<decltype(v[0])>::type T;
00046 constexpr int N = sizeof(Vec)/sizeof(T);
00047 Vec ret;
00048 for (int i=0;i!=N;++i) ret[i] = f(v[i]);
00049 return ret;
00050 }
00051
00052
00053 template<typename Vec>
00054 inline
00055 Vec cross3(Vec x, Vec y) {
00056
00057
00058 Vec x1200{ x[1], x[2], x[0], x[0] };
00059 Vec y2010{ y[2], y[0], y[1], y[0] };
00060 Vec x2010{ x[2], x[0], x[1], x[0] };
00061 Vec y1200{ y[1], y[2], y[0], y[0] };
00062 return x1200 * y2010 - x2010 * y1200;
00063 }
00064
00065 template<typename V1,typename V2>
00066 inline
00067 auto cross2(V1 x, V2 y) ->typename std::remove_reference<decltype(x[0])>::type {
00068 return x[0]*y[1]-x[1]*y[0];
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 template<typename V>
00100 inline
00101 auto dot(V x, V y) ->typename std::remove_reference<decltype(x[0])>::type {
00102 typedef typename std::remove_reference<decltype(x[0])>::type T;
00103 constexpr int N = sizeof(V)/sizeof(T);
00104 T ret=0;
00105 for (int i=0;i!=N;++i) ret+=x[i]*y[i];
00106 return ret;
00107 }
00108
00109 template<typename V1,typename V2 >
00110 inline
00111 auto dot2(V1 x, V2 y) ->typename std::remove_reference<decltype(x[0])>::type {
00112 typedef typename std::remove_reference<decltype(x[0])>::type T;
00113 T ret=0;
00114 for (int i=0;i!=2;++i) ret+=x[i]*y[i];
00115 return ret;
00116 }
00117
00118
00119
00120
00121 typedef Vec2<float> Vec2F;
00122 typedef Vec4<float> Vec4F;
00123 typedef Vec4<float> Vec3F;
00124 typedef Vec2<double> Vec2D;
00125 typedef Vec4<double> Vec3D;
00126 typedef Vec4<double> Vec4D;
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 template<typename V>
00139 struct As3D {
00140 V const & v;
00141 As3D(V const &iv ) : v(iv){}
00142 };
00143 template<typename V>
00144 inline As3D<V> as3D(V const &v ) { return v;}
00145
00146
00147
00148
00149 template<typename T>
00150 struct Rot3 {
00151 typedef Vec4<T> Vec;
00152 Vec axis[3];
00153
00154 constexpr Rot3() :
00155 axis{ (Vec){T(1),0,0,0},
00156 (Vec){0,T(1),0,0},
00157 (Vec){0,0,T(1),0}
00158 }{}
00159
00160 constexpr Rot3( Vec4<T> ix, Vec4<T> iy, Vec4<T> iz) :
00161 axis{ix,iy,iz}{}
00162
00163 constexpr Rot3( T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz) :
00164 axis{ (Vec){xx,xy,xz,0},
00165 (Vec){yx,yy,yz,0},
00166 (Vec){zx,zy,zz,0}
00167 }{}
00168
00169 constexpr Rot3 transpose() const {
00170 return Rot3( axis[0][0], axis[1][0], axis[2][0],
00171 axis[0][1], axis[1][1], axis[2][1],
00172 axis[0][2], axis[1][2], axis[2][2]
00173 );
00174 }
00175
00176 constexpr Vec4<T> x() const { return axis[0];}
00177 constexpr Vec4<T> y() const { return axis[1];}
00178 constexpr Vec4<T> z() const { return axis[2];}
00179
00180
00181 constexpr Vec4<T> rotate(Vec4<T> v) const {
00182 return transpose().rotateBack(v);
00183 }
00184
00185
00186
00187 constexpr Vec4<T> rotateBack(Vec4<T> v) const {
00188 return v[0]*axis[0] + v[1]*axis[1] + v[2]*axis[2];
00189 }
00190
00191 Rot3 rotate(Rot3 const& r) const {
00192 Rot3 tr = transpose();
00193 return Rot3(tr.rotateBack(r.axis[0]),tr.rotateBack(r.axis[1]),tr.rotateBack(r.axis[2]));
00194 }
00195
00196 constexpr Rot3 rotateBack(Rot3 const& r) const {
00197 return Rot3(rotateBack(r.axis[0]),rotateBack(r.axis[1]),rotateBack(r.axis[2]));
00198 }
00199
00200
00201 };
00202
00203 typedef Rot3<float> Rot3F;
00204
00205 typedef Rot3<double> Rot3D;
00206
00207 template<typename T>
00208 inline constexpr Rot3<T> operator *(Rot3<T> const & rh, Rot3<T> const & lh) {
00209 return lh.rotateBack(rh);
00210 }
00211
00212
00213 template<typename T>
00214 struct Rot2 {
00215 typedef Vec2<T> Vec;
00216 Vec2<T> axis[2];
00217
00218 constexpr Rot2() :
00219 axis{ (Vec){T(1),0},
00220 (Vec){0,T(1)}
00221 }{}
00222
00223 constexpr Rot2( Vec2<T> ix, Vec2<T> iy) :
00224 axis{ix, iy}{}
00225
00226 constexpr Rot2( T xx, T xy, T yx, T yy) :
00227 Rot2( (Vec){xx,xy},
00228 (Vec){yx,yy}
00229 ){}
00230
00231 constexpr Rot2 transpose() const {
00232 return Rot2( axis[0][0], axis[1][0],
00233 axis[0][1], axis[1][1]
00234 );
00235 }
00236
00237 constexpr Vec2<T> x() { return axis[0];}
00238 constexpr Vec2<T> y() { return axis[1];}
00239
00240
00241 constexpr Vec2<T> rotate(Vec2<T> v) const {
00242 return transpose().rotateBack(v);
00243 }
00244
00245
00246
00247 constexpr Vec2<T> rotateBack(Vec2<T> v) const {
00248 return v[0]*axis[0] + v[1]*axis[1];
00249 }
00250
00251 Rot2 rotate(Rot2 const& r) const {
00252 Rot2 tr = transpose();
00253 return Rot2(tr.rotateBack(r.axis[0]),tr.rotateBack(r.axis[1]));
00254 }
00255
00256 constexpr Rot2 rotateBack(Rot2 const& r) const {
00257 return Rot2(rotateBack(r.axis[0]),rotateBack(r.axis[1]));
00258 }
00259
00260
00261 };
00262
00263 typedef Rot2<float> Rot2F;
00264
00265 typedef Rot2<double> Rot2D;
00266
00267
00268
00269 template<typename T>
00270 inline constexpr Rot2<T> operator *(Rot2<T> const & rh, Rot2<T> const & lh) {
00271 return lh.rotateBack(rh);
00272 }
00273
00274
00275
00276 #include <iosfwd>
00277 std::ostream & operator<<(std::ostream & out, Vec2D const & v);
00278 std::ostream & operator<<(std::ostream & out, Vec2F const & v);
00279 std::ostream & operator<<(std::ostream & out, Vec4F const & v);
00280 std::ostream & operator<<(std::ostream & out, Vec4D const & v);
00281
00282 std::ostream & operator<<(std::ostream & out, As3D<Vec4F> const & v);
00283 std::ostream & operator<<(std::ostream & out, As3D<Vec4D> const & v);
00284
00285 std::ostream & operator<<(std::ostream & out, Rot3F const & v);
00286 std::ostream & operator<<(std::ostream & out, Rot3D const & v);
00287 std::ostream & operator<<(std::ostream & out, Rot2F const & v);
00288 std::ostream & operator<<(std::ostream & out, Rot2D const & v);
00289
00290
00291 #ifdef USE_INLINE_IO
00292 #include <ostream>
00293 std::ostream & operator<<(std::ostream & out, ::Vec4F const & v) {
00294 return out << '(' << v[0] <<", " << v[1] <<", "<< v[2] <<", "<< v[3] <<')';
00295 }
00296 std::ostream & operator<<(std::ostream & out, ::Vec4D const & v) {
00297 return out << '(' << v[0] <<", " << v[1] <<", "<< v[2] <<", "<< v[3] <<')';
00298 }
00299 std::ostream & operator<<(std::ostream & out, ::Vec2F const & v) {
00300 return out << '(' << v[0] <<", " << v[1] <<')';
00301 }
00302 std::ostream & operator<<(std::ostream & out, ::Vec2D const & v) {
00303 return out << '(' << v[0] <<", " << v[1] <<')';
00304 }
00305
00306 std::ostream & operator<<(std::ostream & out, ::As3D<Vec4F> const & v) {
00307 return out << '(' << v.v[0] <<", " << v.v[1] <<", "<< v.v[2] <<')';
00308 }
00309
00310 std::ostream & operator<<(std::ostream & out, ::As3D<Vec4D> const & v) {
00311 return out << '(' << v.v[0] <<", " << v.v[1] <<", "<< v.v[2] <<')';
00312 }
00313
00314 std::ostream & operator<<(std::ostream & out, ::Rot3F const & r){
00315 return out << as3D(r.axis[0]) << '\n' << as3D(r.axis[1]) << '\n' << as3D(r.axis[2]);
00316 }
00317
00318 std::ostream & operator<<(std::ostream & out, ::Rot3D const & r){
00319 return out << as3D(r.axis[0]) << '\n' << as3D(r.axis[1]) << '\n' << as3D(r.axis[2]);
00320 }
00321
00322 std::ostream & operator<<(std::ostream & out, ::Rot2F const & r){
00323 return out << r.axis[0] << '\n' << r.axis[1];
00324 }
00325
00326 std::ostream & operator<<(std::ostream & out, ::Rot2D const & r){
00327 return out << r.axis[0] << '\n' << r.axis[1];
00328 }
00329 #endif
00330
00331
00332 #endif