diff --git a/simgear/math/SGVec2.hxx b/simgear/math/SGVec2.hxx index 49d8b619..64bb30da 100644 --- a/simgear/math/SGVec2.hxx +++ b/simgear/math/SGVec2.hxx @@ -24,6 +24,8 @@ #include #include +#include "simd.hxx" + /// 2D Vector Class template class SGVec2 { @@ -48,7 +50,7 @@ public: /// Constructor. Initialize by the content of a plain array, /// make sure it has at least 2 elements explicit SGVec2(const T* d) - { data()[0] = d[0]; data()[1] = d[1]; } + { simd4_t r(d); _data = r; } template explicit SGVec2(const SGVec2& d) { data()[0] = d[0]; data()[1] = d[1]; } @@ -82,25 +84,30 @@ public: /// Access raw data const T (&data(void) const)[2] - { return _data; } + { return _data.ptr(); } /// Access raw data T (&data(void))[2] + { return _data.ptr(); } + const simd4_t (&simd2(void) const) + { return _data; } + /// Readonly raw storage interface + simd4_t (&simd2(void)) { return _data; } /// Inplace addition SGVec2& operator+=(const SGVec2& v) - { data()[0] += v(0); data()[1] += v(1); return *this; } + { _data += v.simd2(); return *this; } /// Inplace subtraction SGVec2& operator-=(const SGVec2& v) - { data()[0] -= v(0); data()[1] -= v(1); return *this; } + { _data -= v.simd2(); return *this; } /// Inplace scalar multiplication template SGVec2& operator*=(S s) - { data()[0] *= s; data()[1] *= s; return *this; } + { _data *= s; return *this; } /// Inplace scalar multiplication by 1/s template SGVec2& operator/=(S s) - { return operator*=(1/T(s)); } + { _data*=(1/T(s)); return *this; } /// Return an all zero vector static SGVec2 zeros(void) @@ -112,7 +119,7 @@ public: { return SGVec2(0, 1); } private: - T _data[2]; + simd4_t _data; }; /// Unary +, do nothing ... @@ -126,36 +133,36 @@ operator+(const SGVec2& v) template inline SGVec2 -operator-(const SGVec2& v) -{ return SGVec2(-v(0), -v(1)); } +operator-(SGVec2 v) +{ v *= -1; return v; } /// Binary + template inline SGVec2 -operator+(const SGVec2& v1, const SGVec2& v2) -{ return SGVec2(v1(0)+v2(0), v1(1)+v2(1)); } +operator+(SGVec2 v1, const SGVec2& v2) +{ v1.simd2() += v2.simd2(); return v1; } /// Binary - template inline SGVec2 -operator-(const SGVec2& v1, const SGVec2& v2) -{ return SGVec2(v1(0)-v2(0), v1(1)-v2(1)); } +operator-(SGVec2 v1, const SGVec2& v2) +{ v1.simd2() -= v2.simd2(); return v1; } /// Scalar multiplication template inline SGVec2 -operator*(S s, const SGVec2& v) -{ return SGVec2(s*v(0), s*v(1)); } +operator*(S s, SGVec2 v) +{ v.simd2() *= s; return v; } /// Scalar multiplication template inline SGVec2 -operator*(const SGVec2& v, S s) -{ return SGVec2(s*v(0), s*v(1)); } +operator*(SGVec2 v, S s) +{ v.simd2() *= s; return v; } /// multiplication as a multiplicator, that is assume that the first vector /// represents a 2x2 diagonal matrix with the diagonal elements in the vector. @@ -163,8 +170,8 @@ operator*(const SGVec2& v, S s) template inline SGVec2 -mult(const SGVec2& v1, const SGVec2& v2) -{ return SGVec2(v1(0)*v2(0), v1(1)*v2(1)); } +mult(SGVec2 v1, const SGVec2& v2) +{ v1.simd2() *= v2.simd2(); return v1; } /// component wise min template @@ -215,8 +222,8 @@ SGVec2 addClipOverflow(SGVec2 const& lhs, SGVec2 const& rhs) template inline T -dot(const SGVec2& v1, const SGVec2& v2) -{ return v1(0)*v2(0) + v1(1)*v2(1); } +dot(SGVec2 v1, const SGVec2& v2) +{ v1.simd2() *= v2.simd2(); return (v1(0)+v1(1)+v1(2)); } /// The euclidean norm of the vector, that is what most people call length template @@ -341,8 +348,8 @@ dist(const SGVec2& v1, const SGVec2& v2) template inline T -distSqr(const SGVec2& v1, const SGVec2& v2) -{ SGVec2 tmp = v1 - v2; return dot(tmp, tmp); } +distSqr(SGVec2 v1, const SGVec2& v2) +{ v1 -= v2; return dot(v1, v1); } // calculate the projection of u along the direction of d. template diff --git a/simgear/math/SGVec3.hxx b/simgear/math/SGVec3.hxx index 68c9c83b..0d0f96bd 100644 --- a/simgear/math/SGVec3.hxx +++ b/simgear/math/SGVec3.hxx @@ -23,6 +23,8 @@ #include #include +#include "simd.hxx" + /// 3D Vector Class template class SGVec3 { @@ -58,7 +60,7 @@ public: /// Constructor. Initialize by the content of a plain array, /// make sure it has at least 3 elements explicit SGVec3(const T* d) - { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } + { simd4_t r(d); _data = r; } template explicit SGVec3(const SGVec3& d) { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } @@ -100,25 +102,31 @@ public: /// Readonly raw storage interface const T (&data(void) const)[3] - { return _data; } + { return _data.ptr(); } /// Readonly raw storage interface T (&data(void))[3] + { return _data.ptr(); } + /// Readonly raw storage interface + const simd4_t (&simd3(void) const) + { return _data; } + /// Readonly raw storage interface + simd4_t (&simd3(void)) { return _data; } /// Inplace addition SGVec3& operator+=(const SGVec3& v) - { data()[0] += v(0); data()[1] += v(1); data()[2] += v(2); return *this; } + { _data += v.simd3(); return *this; } /// Inplace subtraction SGVec3& operator-=(const SGVec3& v) - { data()[0] -= v(0); data()[1] -= v(1); data()[2] -= v(2); return *this; } + { _data -= v.simd3(); return *this; } /// Inplace scalar multiplication template SGVec3& operator*=(S s) - { data()[0] *= s; data()[1] *= s; data()[2] *= s; return *this; } + { _data *= s; return *this; } /// Inplace scalar multiplication by 1/s template SGVec3& operator/=(S s) - { return operator*=(1/T(s)); } + { _data*=(1/T(s)); return *this; } /// Return an all zero vector static SGVec3 zeros(void) @@ -139,7 +147,8 @@ public: static SGVec3 fromGeoc(const SGGeoc& geoc); private: - T _data[3]; + simd4_t _data; + }; template<> @@ -193,36 +202,36 @@ operator+(const SGVec3& v) template inline SGVec3 -operator-(const SGVec3& v) -{ return SGVec3(-v(0), -v(1), -v(2)); } +operator-(SGVec3 v) +{ v *= -1; return v; } /// Binary + template inline SGVec3 -operator+(const SGVec3& v1, const SGVec3& v2) -{ return SGVec3(v1(0)+v2(0), v1(1)+v2(1), v1(2)+v2(2)); } +operator+(SGVec3 v1, const SGVec3& v2) +{ v1.simd3() += v2.simd3(); return v1; } /// Binary - template inline SGVec3 -operator-(const SGVec3& v1, const SGVec3& v2) -{ return SGVec3(v1(0)-v2(0), v1(1)-v2(1), v1(2)-v2(2)); } +operator-(SGVec3 v1, const SGVec3& v2) +{ v1.simd3() -= v2.simd3(); return v1; } /// Scalar multiplication template inline SGVec3 -operator*(S s, const SGVec3& v) -{ return SGVec3(s*v(0), s*v(1), s*v(2)); } +operator*(S s, SGVec3 v) +{ v.simd3() *= s; return v; } /// Scalar multiplication template inline SGVec3 -operator*(const SGVec3& v, S s) -{ return SGVec3(s*v(0), s*v(1), s*v(2)); } +operator*(SGVec3 v, S s) +{ v.simd3() *= s; return v; } /// multiplication as a multiplicator, that is assume that the first vector /// represents a 3x3 diagonal matrix with the diagonal elements in the vector. @@ -230,8 +239,8 @@ operator*(const SGVec3& v, S s) template inline SGVec3 -mult(const SGVec3& v1, const SGVec3& v2) -{ return SGVec3(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2)); } +mult(SGVec3 v1, const SGVec3& v2) +{ v1.simd3() *= v2.simd3(); return v1; } /// component wise min template @@ -307,8 +316,8 @@ SGVec3 addClipOverflow(SGVec3 const& lhs, SGVec3 const& rhs) template inline T -dot(const SGVec3& v1, const SGVec3& v2) -{ return v1(0)*v2(0) + v1(1)*v2(1) + v1(2)*v2(2); } +dot(SGVec3 v1, const SGVec3& v2) +{ v1.simd3() *= v2.simd3(); return (v1(0)+v1(1)+v1(2)); } /// The euclidean norm of the vector, that is what most people call length template @@ -474,8 +483,8 @@ dist(const SGVec3& v1, const SGVec3& v2) template inline T -distSqr(const SGVec3& v1, const SGVec3& v2) -{ SGVec3 tmp = v1 - v2; return dot(tmp, tmp); } +distSqr(SGVec3 v1, const SGVec3& v2) +{ v1 -= v2; return dot(v1, v1); } // calculate the projection of u along the direction of d. template diff --git a/simgear/math/SGVec4.hxx b/simgear/math/SGVec4.hxx index 4339dfd9..9083e325 100644 --- a/simgear/math/SGVec4.hxx +++ b/simgear/math/SGVec4.hxx @@ -20,6 +20,8 @@ #include +#include "simd.hxx" + /// 4D Vector Class template class SGVec4 { @@ -44,7 +46,7 @@ public: /// Constructor. Initialize by the content of a plain array, /// make sure it has at least 3 elements explicit SGVec4(const T* d) - { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } + { simd4_t r(d); _data = r; } template explicit SGVec4(const SGVec4& d) { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } @@ -92,25 +94,31 @@ public: /// Readonly raw storage interface const T (&data(void) const)[4] - { return _data; } + { return _data.ptr(); } /// Readonly raw storage interface T (&data(void))[4] + { return _data.ptr(); } + /// Readonly raw storage interface + const simd4_t (&simd4(void) const) + { return _data; } + /// Readonly raw storage interface + simd4_t (&simd4(void)) { return _data; } /// Inplace addition SGVec4& operator+=(const SGVec4& v) - { data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; } + { _data += v.simd4(); return *this; } /// Inplace subtraction SGVec4& operator-=(const SGVec4& v) - { data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; } + { _data -= v.simd4(); return *this; } /// Inplace scalar multiplication template SGVec4& operator*=(S s) - { data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; } + { _data *= s; return *this; } /// Inplace scalar multiplication by 1/s template SGVec4& operator/=(S s) - { return operator*=(1/T(s)); } + { _data*=(1/T(s)); return *this; } /// Return an all zero vector static SGVec4 zeros(void) @@ -126,7 +134,7 @@ public: { return SGVec4(0, 0, 0, 1); } private: - T _data[4]; + simd4_t _data; }; /// Unary +, do nothing ... @@ -140,36 +148,36 @@ operator+(const SGVec4& v) template inline SGVec4 -operator-(const SGVec4& v) -{ return SGVec4(-v(0), -v(1), -v(2), -v(3)); } +operator-(SGVec4 v) +{ v *= -1; return v; } /// Binary + template inline SGVec4 -operator+(const SGVec4& v1, const SGVec4& v2) -{ return SGVec4(v1(0)+v2(0), v1(1)+v2(1), v1(2)+v2(2), v1(3)+v2(3)); } +operator+(SGVec4 v1, const SGVec4& v2) +{ v1.simd4() += v2.simd4(); return v1; } /// Binary - template inline SGVec4 -operator-(const SGVec4& v1, const SGVec4& v2) -{ return SGVec4(v1(0)-v2(0), v1(1)-v2(1), v1(2)-v2(2), v1(3)-v2(3)); } +operator-(SGVec4 v1, const SGVec4& v2) +{ v1.simd4() -= v2.simd4(); return v1; } /// Scalar multiplication template inline SGVec4 -operator*(S s, const SGVec4& v) -{ return SGVec4(s*v(0), s*v(1), s*v(2), s*v(3)); } +operator*(S s, SGVec4 v) +{ v.simd4() *= s; return v; } /// Scalar multiplication template inline SGVec4 -operator*(const SGVec4& v, S s) -{ return SGVec4(s*v(0), s*v(1), s*v(2), s*v(3)); } +operator*(SGVec4 v, S s) +{ v.simd4() *= s; return v; } /// multiplication as a multiplicator, that is assume that the first vector /// represents a 4x4 diagonal matrix with the diagonal elements in the vector. @@ -177,8 +185,8 @@ operator*(const SGVec4& v, S s) template inline SGVec4 -mult(const SGVec4& v1, const SGVec4& v2) -{ return SGVec4(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2), v1(3)*v2(3)); } +mult(SGVec4 v1, const SGVec4& v2) +{ v1.simd4() *= v2.simd4(); return v1; } /// component wise min template @@ -261,8 +269,8 @@ SGVec4 addClipOverflow(SGVec4 const& lhs, SGVec4 const& rhs) template inline T -dot(const SGVec4& v1, const SGVec4& v2) -{ return v1(0)*v2(0) + v1(1)*v2(1) + v1(2)*v2(2) + v1(3)*v2(3); } +dot(SGVec4 v1, const SGVec4& v2) +{ v1.simd4() *= v2.simd4(); return (v1(0)+v1(1)+v1(2)+v1(3)); } /// The euclidean norm of the vector, that is what most people call length template @@ -395,8 +403,8 @@ dist(const SGVec4& v1, const SGVec4& v2) template inline T -distSqr(const SGVec4& v1, const SGVec4& v2) -{ SGVec4 tmp = v1 - v2; return dot(tmp, tmp); } +distSqr(SGVec4 v1, const SGVec4& v2) +{ v1 -= v2; return dot(v1, v1); } // calculate the projection of u along the direction of d. template