File indexing completed on 2024-05-10 02:20:34
0001 #ifndef DataFormat_Math_ExtVec_H
0002 #define DataFormat_Math_ExtVec_H
0003
0004 #include <type_traits>
0005
0006 #define VECTOR_EXT(N) __attribute__((vector_size(N)))
0007
0008 typedef float VECTOR_EXT(8) cms_float32x2_t;
0009 typedef float VECTOR_EXT(16) cms_float32x4_t;
0010 typedef float VECTOR_EXT(32) cms_float32x8_t;
0011 typedef double VECTOR_EXT(16) cms_float64x2_t;
0012 typedef double VECTOR_EXT(32) cms_float64x4_t;
0013 typedef double VECTOR_EXT(64) cms_float64x8_t;
0014
0015 typedef long double VECTOR_EXT(32) cms_float128x2_t;
0016 typedef long double VECTOR_EXT(64) cms_float128x4_t;
0017 typedef long double VECTOR_EXT(128) cms_float128x8_t;
0018
0019
0020
0021 template <typename T, int N>
0022 struct ExtVecTraits {
0023
0024 };
0025
0026 template <>
0027 struct ExtVecTraits<float, 2> {
0028 typedef float VECTOR_EXT(2 * sizeof(float)) type;
0029 };
0030
0031 template <>
0032 struct ExtVecTraits<float, 4> {
0033 typedef float VECTOR_EXT(4 * sizeof(float)) type;
0034 };
0035
0036 template <>
0037 struct ExtVecTraits<double, 2> {
0038 typedef double VECTOR_EXT(2 * sizeof(double)) type;
0039 };
0040
0041 template <>
0042 struct ExtVecTraits<double, 4> {
0043 typedef double VECTOR_EXT(4 * sizeof(double)) type;
0044 };
0045
0046 template <>
0047 struct ExtVecTraits<long double, 2> {
0048 typedef long double VECTOR_EXT(2 * sizeof(long double)) type;
0049 };
0050
0051 template <>
0052 struct ExtVecTraits<long double, 4> {
0053 typedef long double VECTOR_EXT(4 * sizeof(long double)) type;
0054 };
0055
0056 template <typename T, int N>
0057 using ExtVec = typename ExtVecTraits<T, N>::type;
0058
0059 template <typename T>
0060 using Vec4 = ExtVec<T, 4>;
0061 template <typename T>
0062 using Vec2 = ExtVec<T, 2>;
0063
0064
0065 template <typename W, typename V>
0066 inline W convert(V v) {
0067
0068
0069 typedef typename std::remove_reference<decltype(v[0])>::type T;
0070 constexpr int N = sizeof(V) / sizeof(T);
0071 W w;
0072 for (int i = 0; i != N; ++i)
0073 w[i] = v[i];
0074 return w;
0075 }
0076
0077 template <typename V>
0078 inline auto xy(V v) -> Vec2<typename std::remove_reference<decltype(v[0])>::type> {
0079 typedef typename std::remove_reference<decltype(v[0])>::type T;
0080 return Vec2<T>{v[0], v[1]};
0081 }
0082
0083 template <typename V>
0084 inline auto zw(V v) -> Vec2<typename std::remove_reference<decltype(v[0])>::type> {
0085 typedef typename std::remove_reference<decltype(v[0])>::type T;
0086 return Vec2<T>{v[2], v[3]};
0087 }
0088
0089 template <typename Vec, typename F>
0090 inline Vec apply(Vec v, F f) {
0091 typedef typename std::remove_reference<decltype(v[0])>::type T;
0092 constexpr int N = sizeof(Vec) / sizeof(T);
0093 Vec ret;
0094 for (int i = 0; i != N; ++i)
0095 ret[i] = f(v[i]);
0096 return ret;
0097 }
0098
0099 template <typename Vec>
0100 inline Vec cross3(Vec x, Vec y) {
0101
0102
0103 Vec x1200{x[1], x[2], x[0], x[0]};
0104 Vec y2010{y[2], y[0], y[1], y[0]};
0105 Vec x2010{x[2], x[0], x[1], x[0]};
0106 Vec y1200{y[1], y[2], y[0], y[0]};
0107 return x1200 * y2010 - x2010 * y1200;
0108 }
0109
0110 template <typename V1, typename V2>
0111 inline auto cross2(V1 x, V2 y) -> typename std::remove_reference<decltype(x[0])>::type {
0112 return x[0] * y[1] - x[1] * y[0];
0113 }
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 template <typename V>
0142 inline auto dot(V x, V y) -> typename std::remove_reference<decltype(x[0])>::type {
0143 typedef typename std::remove_reference<decltype(x[0])>::type T;
0144 constexpr int N = sizeof(V) / sizeof(T);
0145 T ret = 0;
0146 for (int i = 0; i != N; ++i)
0147 ret += x[i] * y[i];
0148 return ret;
0149 }
0150
0151 template <typename V1, typename V2>
0152 inline auto dot2(V1 x, V2 y) -> typename std::remove_reference<decltype(x[0])>::type {
0153 return x[0] * y[0] + x[1] * y[1];
0154 }
0155
0156 template <typename V1, typename V2>
0157 inline auto dot3(V1 x, V2 y) -> typename std::remove_reference<decltype(x[0])>::type {
0158 auto z = x * y;
0159 return z[0] + z[1] + z[2];
0160 }
0161
0162 typedef Vec2<float> Vec2F;
0163 typedef Vec4<float> Vec4F;
0164 typedef Vec4<float> Vec3F;
0165 typedef Vec2<double> Vec2D;
0166 typedef Vec4<double> Vec3D;
0167 typedef Vec4<double> Vec4D;
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179 template <typename V>
0180 struct As3D {
0181 V const& v;
0182 As3D(V const& iv) : v(iv) {}
0183 };
0184 template <typename V>
0185 inline As3D<V> as3D(V const& v) {
0186 return v;
0187 }
0188
0189
0190
0191 template <typename T>
0192 struct Rot3 {
0193 typedef Vec4<T> Vec;
0194 Vec axis[3];
0195
0196 constexpr Rot3() : axis{{(Vec){T(1), 0, 0, 0}}, {(Vec){0, T(1), 0, 0}}, {(Vec){0, 0, T(1), 0}}} {}
0197
0198 constexpr Rot3(Vec4<T> ix, Vec4<T> iy, Vec4<T> iz) : axis{ix, iy, iz} {}
0199
0200 constexpr Rot3(T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz)
0201 : axis{{(Vec){xx, xy, xz, 0}}, {(Vec){yx, yy, yz, 0}}, {(Vec){zx, zy, zz, 0}}} {}
0202
0203 constexpr Rot3 transpose() const {
0204 return Rot3(
0205 axis[0][0], axis[1][0], axis[2][0], axis[0][1], axis[1][1], axis[2][1], axis[0][2], axis[1][2], axis[2][2]);
0206 }
0207
0208 constexpr Vec4<T> x() const { return axis[0]; }
0209 constexpr Vec4<T> y() const { return axis[1]; }
0210 constexpr Vec4<T> z() const { return axis[2]; }
0211
0212
0213 constexpr Vec4<T> rotate(Vec4<T> v) const { return transpose().rotateBack(v); }
0214
0215
0216 constexpr Vec4<T> rotateBack(Vec4<T> v) const { return v[0] * axis[0] + v[1] * axis[1] + v[2] * axis[2]; }
0217
0218 Rot3 rotate(Rot3 const& r) const {
0219 Rot3 tr = transpose();
0220 return Rot3(tr.rotateBack(r.axis[0]), tr.rotateBack(r.axis[1]), tr.rotateBack(r.axis[2]));
0221 }
0222
0223 constexpr Rot3 rotateBack(Rot3 const& r) const {
0224 return Rot3(rotateBack(r.axis[0]), rotateBack(r.axis[1]), rotateBack(r.axis[2]));
0225 }
0226 };
0227
0228 typedef Rot3<float> Rot3F;
0229
0230 typedef Rot3<double> Rot3D;
0231
0232 template <typename T>
0233 inline constexpr Rot3<T> operator*(Rot3<T> const& rh, Rot3<T> const& lh) {
0234 return lh.rotateBack(rh);
0235 }
0236
0237 template <typename T>
0238 struct Rot2 {
0239 typedef Vec2<T> Vec;
0240 Vec2<T> axis[2];
0241
0242 constexpr Rot2() : axis{{(Vec){T(1), 0}}, {(Vec){0, T(1)}}} {}
0243
0244 constexpr Rot2(Vec2<T> ix, Vec2<T> iy) : axis{ix, iy} {}
0245
0246 constexpr Rot2(T xx, T xy, T yx, T yy) : Rot2((Vec){xx, xy}, (Vec){yx, yy}) {}
0247
0248 constexpr Rot2 transpose() const { return Rot2(axis[0][0], axis[1][0], axis[0][1], axis[1][1]); }
0249
0250 constexpr Vec2<T> x() const { return axis[0]; }
0251 constexpr Vec2<T> y() const { return axis[1]; }
0252
0253
0254 constexpr Vec2<T> rotate(Vec2<T> v) const { return transpose().rotateBack(v); }
0255
0256
0257 constexpr Vec2<T> rotateBack(Vec2<T> v) const { return v[0] * axis[0] + v[1] * axis[1]; }
0258
0259 Rot2 rotate(Rot2 const& r) const {
0260 Rot2 tr = transpose();
0261 return Rot2(tr.rotateBack(r.axis[0]), tr.rotateBack(r.axis[1]));
0262 }
0263
0264 constexpr Rot2 rotateBack(Rot2 const& r) const { return Rot2(rotateBack(r.axis[0]), rotateBack(r.axis[1])); }
0265 };
0266
0267 typedef Rot2<float> Rot2F;
0268
0269 typedef Rot2<double> Rot2D;
0270
0271 template <typename T>
0272 inline constexpr Rot2<T> operator*(Rot2<T> const& rh, Rot2<T> const& lh) {
0273 return lh.rotateBack(rh);
0274 }
0275
0276 #include <iosfwd>
0277 std::ostream& operator<<(std::ostream& out, Vec2D const& v);
0278 std::ostream& operator<<(std::ostream& out, Vec2F const& v);
0279 std::ostream& operator<<(std::ostream& out, Vec4F const& v);
0280 std::ostream& operator<<(std::ostream& out, Vec4D const& v);
0281
0282 std::ostream& operator<<(std::ostream& out, As3D<Vec4F> const& v);
0283 std::ostream& operator<<(std::ostream& out, As3D<Vec4D> const& v);
0284
0285 std::ostream& operator<<(std::ostream& out, Rot3F const& v);
0286 std::ostream& operator<<(std::ostream& out, Rot3D const& v);
0287 std::ostream& operator<<(std::ostream& out, Rot2F const& v);
0288 std::ostream& operator<<(std::ostream& out, Rot2D const& v);
0289
0290 #ifdef USE_INLINE_IO
0291 #include <ostream>
0292 std::ostream& operator<<(std::ostream& out, ::Vec4F const& v) {
0293 return out << '(' << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ')';
0294 }
0295 std::ostream& operator<<(std::ostream& out, ::Vec4D const& v) {
0296 return out << '(' << v[0] << ", " << v[1] << ", " << v[2] << ", " << v[3] << ')';
0297 }
0298 std::ostream& operator<<(std::ostream& out, ::Vec2F const& v) { return out << '(' << v[0] << ", " << v[1] << ')'; }
0299 std::ostream& operator<<(std::ostream& out, ::Vec2D const& v) { return out << '(' << v[0] << ", " << v[1] << ')'; }
0300
0301 std::ostream& operator<<(std::ostream& out, ::As3D<Vec4F> const& v) {
0302 return out << '(' << v.v[0] << ", " << v.v[1] << ", " << v.v[2] << ')';
0303 }
0304
0305 std::ostream& operator<<(std::ostream& out, ::As3D<Vec4D> const& v) {
0306 return out << '(' << v.v[0] << ", " << v.v[1] << ", " << v.v[2] << ')';
0307 }
0308
0309 std::ostream& operator<<(std::ostream& out, ::Rot3F const& r) {
0310 return out << as3D(r.axis[0]) << '\n' << as3D(r.axis[1]) << '\n' << as3D(r.axis[2]);
0311 }
0312
0313 std::ostream& operator<<(std::ostream& out, ::Rot3D const& r) {
0314 return out << as3D(r.axis[0]) << '\n' << as3D(r.axis[1]) << '\n' << as3D(r.axis[2]);
0315 }
0316
0317 std::ostream& operator<<(std::ostream& out, ::Rot2F const& r) { return out << r.axis[0] << '\n' << r.axis[1]; }
0318
0319 std::ostream& operator<<(std::ostream& out, ::Rot2D const& r) { return out << r.axis[0] << '\n' << r.axis[1]; }
0320 #endif
0321
0322 #endif