X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2FSGVec4.hxx;h=6030c48ba03e2ea331b43442cebfd2df509fdf1b;hb=578af00b0d48100c540154f54293a1b77a0655fe;hp=7c714323f102ec8a0ee42c874c53a2a683461579;hpb=360d3834ca57d89c396635b613afaeb9186c3b83;p=simgear.git diff --git a/simgear/math/SGVec4.hxx b/simgear/math/SGVec4.hxx index 7c714323..6030c48b 100644 --- a/simgear/math/SGVec4.hxx +++ b/simgear/math/SGVec4.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2006 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2006-2009 Mathias Froehlich - Mathias.Froehlich@web.de // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -18,58 +18,14 @@ #ifndef SGVec4_H #define SGVec4_H +#ifndef NO_OPENSCENEGRAPH_INTERFACE #include #include - -template -struct SGVec4Storage { - /// Readonly raw storage interface - const T (&data(void) const)[4] - { return _data; } - /// Readonly raw storage interface - T (&data(void))[4] - { return _data; } - - void osg() const - { } - -private: - T _data[4]; -}; - -template<> -struct SGVec4Storage : public osg::Vec4f { - /// Access raw data by index, the index is unchecked - const float (&data(void) const)[4] - { return osg::Vec4f::_v; } - /// Access raw data by index, the index is unchecked - float (&data(void))[4] - { return osg::Vec4f::_v; } - - const osg::Vec4f& osg() const - { return *this; } - osg::Vec4f& osg() - { return *this; } -}; - -template<> -struct SGVec4Storage : public osg::Vec4d { - /// Access raw data by index, the index is unchecked - const double (&data(void) const)[4] - { return osg::Vec4d::_v; } - /// Access raw data by index, the index is unchecked - double (&data(void))[4] - { return osg::Vec4d::_v; } - - const osg::Vec4d& osg() const - { return *this; } - osg::Vec4d& osg() - { return *this; } -}; +#endif /// 4D Vector Class template -class SGVec4 : protected SGVec4Storage { +class SGVec4 { public: typedef T value_type; @@ -92,14 +48,12 @@ public: /// 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]; } - explicit SGVec4(const osg::Vec4f& d) - { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } - explicit SGVec4(const osg::Vec4d& d) + template + explicit SGVec4(const SGVec4& d) { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; } explicit SGVec4(const SGVec3& v3, const T& v4 = 0) { data()[0] = v3[0]; data()[1] = v3[1]; data()[2] = v3[2]; data()[3] = v4; } - /// Access by index, the index is unchecked const T& operator()(unsigned i) const { return data()[i]; } @@ -139,18 +93,12 @@ public: T& w(void) { return data()[3]; } - /// Get the data pointer - using SGVec4Storage::data; - - /// Readonly interface function to ssg's sgVec4/sgdVec4 - const T (&sg(void) const)[4] - { return data(); } - /// Interface function to ssg's sgVec4/sgdVec4 - T (&sg(void))[4] - { return data(); } - - /// Interface function to osg's Vec4* - using SGVec4Storage::osg; + /// Readonly raw storage interface + const T (&data(void) const)[4] + { return _data; } + /// Readonly raw storage interface + T (&data(void))[4] + { return _data; } /// Inplace addition SGVec4& operator+=(const SGVec4& v) @@ -179,6 +127,9 @@ public: { return SGVec4(0, 0, 1, 0); } static SGVec4 e4(void) { return SGVec4(0, 0, 0, 1); } + +private: + T _data[4]; }; /// Unary +, do nothing ... @@ -223,6 +174,15 @@ SGVec4 operator*(const SGVec4& v, S s) { return SGVec4(s*v(0), s*v(1), s*v(2), s*v(3)); } +/// multiplication as a multiplicator, that is assume that the first vector +/// represents a 4x4 diagonal matrix with the diagonal elements in the vector. +/// Then the result is the product of that matrix times the second vector. +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)); } + /// component wise min template inline @@ -328,7 +288,12 @@ template inline SGVec4 normalize(const SGVec4& v) -{ return (1/norm(v))*v; } +{ + T normv = norm(v); + if (normv <= SGLimits::min()) + return SGVec4::zeros(); + return (1/normv)*v; +} /// Return true if exactly the same template @@ -344,6 +309,47 @@ bool operator!=(const SGVec4& v1, const SGVec4& v2) { return ! (v1 == v2); } +/// Return true if smaller, good for putting that into a std::map +template +inline +bool +operator<(const SGVec4& v1, const SGVec4& v2) +{ + if (v1(0) < v2(0)) return true; + else if (v2(0) < v1(0)) return false; + else if (v1(1) < v2(1)) return true; + else if (v2(1) < v1(1)) return false; + else if (v1(2) < v2(2)) return true; + else if (v2(2) < v1(2)) return false; + else return (v1(3) < v2(3)); +} + +template +inline +bool +operator<=(const SGVec4& v1, const SGVec4& v2) +{ + if (v1(0) < v2(0)) return true; + else if (v2(0) < v1(0)) return false; + else if (v1(1) < v2(1)) return true; + else if (v2(1) < v1(1)) return false; + else if (v1(2) < v2(2)) return true; + else if (v2(2) < v1(2)) return false; + else return (v1(3) <= v2(3)); +} + +template +inline +bool +operator>(const SGVec4& v1, const SGVec4& v2) +{ return operator<(v2, v1); } + +template +inline +bool +operator>=(const SGVec4& v1, const SGVec4& v2) +{ return operator<=(v2, v1); } + /// Return true if equal to the relative tolerance tol template inline @@ -382,6 +388,18 @@ T distSqr(const SGVec4& v1, const SGVec4& v2) { SGVec4 tmp = v1 - v2; return dot(tmp, tmp); } +// calculate the projection of u along the direction of d. +template +inline +SGVec4 +projection(const SGVec4& u, const SGVec4& d) +{ + T denom = dot(d, d); + T ud = dot(u, d); + if (SGLimits::min() < denom) return u; + else return d * (dot(u, d) / denom); +} + #ifndef NDEBUG template inline @@ -410,4 +428,26 @@ SGVec4d toVec4d(const SGVec4f& v) { return SGVec4d(v(0), v(1), v(2), v(3)); } +#ifndef NO_OPENSCENEGRAPH_INTERFACE +inline +SGVec4d +toSG(const osg::Vec4d& v) +{ return SGVec4d(v[0], v[1], v[2], v[3]); } + +inline +SGVec4f +toSG(const osg::Vec4f& v) +{ return SGVec4f(v[0], v[1], v[2], v[3]); } + +inline +osg::Vec4d +toOsg(const SGVec4d& v) +{ return osg::Vec4d(v[0], v[1], v[2], v[3]); } + +inline +osg::Vec4f +toOsg(const SGVec4f& v) +{ return osg::Vec4f(v[0], v[1], v[2], v[3]); } +#endif + #endif