X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2FSGVec3.hxx;h=64ceac0a88ac141ed6273738c624779745b2573f;hb=7a52c2fa71355631a559d74e0860fa6c5efa424e;hp=4ec4145a399f005a05ab88d85d1271f2cb919488;hpb=006f90997a8eef6704de2511e38fcc786672308d;p=simgear.git diff --git a/simgear/math/SGVec3.hxx b/simgear/math/SGVec3.hxx index 4ec4145a..64ceac0a 100644 --- a/simgear/math/SGVec3.hxx +++ b/simgear/math/SGVec3.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 SGVec3_H #define SGVec3_H +#ifndef NO_OPENSCENEGRAPH_INTERFACE #include #include - -template -struct SGVec3Storage { - /// Readonly raw storage interface - const T (&data(void) const)[3] - { return _data; } - /// Readonly raw storage interface - T (&data(void))[3] - { return _data; } - - void osg() const - { } - -private: - T _data[3]; -}; - -template<> -struct SGVec3Storage : public osg::Vec3f { - /// Access raw data by index, the index is unchecked - const float (&data(void) const)[3] - { return osg::Vec3f::_v; } - /// Access raw data by index, the index is unchecked - float (&data(void))[3] - { return osg::Vec3f::_v; } - - const osg::Vec3f& osg() const - { return *this; } - osg::Vec3f& osg() - { return *this; } -}; - -template<> -struct SGVec3Storage : public osg::Vec3d { - /// Access raw data by index, the index is unchecked - const double (&data(void) const)[3] - { return osg::Vec3d::_v; } - /// Access raw data by index, the index is unchecked - double (&data(void))[3] - { return osg::Vec3d::_v; } - - const osg::Vec3d& osg() const - { return *this; } - osg::Vec3d& osg() - { return *this; } -}; +#endif /// 3D Vector Class template -class SGVec3 : protected SGVec3Storage { +class SGVec3 { public: typedef T value_type; @@ -95,10 +51,6 @@ public: template explicit SGVec3(const SGVec3& d) { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } - explicit SGVec3(const osg::Vec3f& d) - { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } - explicit SGVec3(const osg::Vec3d& d) - { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; } explicit SGVec3(const SGVec2& v2, const T& v3 = 0) { data()[0] = v2[0]; data()[1] = v2[1]; data()[2] = v3; } @@ -135,18 +87,12 @@ public: T& z(void) { return data()[2]; } - /// Get the data pointer - using SGVec3Storage::data; - - /// Readonly interface function to ssg's sgVec3/sgdVec3 - const T (&sg(void) const)[3] - { return data(); } - /// Interface function to ssg's sgVec3/sgdVec3 - T (&sg(void))[3] - { return data(); } - - /// Interface function to osg's Vec3* - using SGVec3Storage::osg; + /// Readonly raw storage interface + const T (&data(void) const)[3] + { return _data; } + /// Readonly raw storage interface + T (&data(void))[3] + { return _data; } /// Inplace addition SGVec3& operator+=(const SGVec3& v) @@ -180,6 +126,9 @@ public: /// Constructor. Initialize by a geocentric coordinate /// Note that this conversion is relatively expensive to compute static SGVec3 fromGeoc(const SGGeoc& geoc); + +private: + T _data[3]; }; template<> @@ -403,12 +352,18 @@ perpendicular(const SGVec3& v) } } -/// The euclidean norm of the vector, that is what most people call length +/// Construct a unit vector in the given direction. +/// or the zero vector if the input vector is zero. template inline SGVec3 normalize(const SGVec3& v) -{ return (1/norm(v))*v; } +{ + T normv = norm(v); + if (normv <= SGLimits::min()) + return SGVec3::zeros(); + return (1/normv)*v; +} /// Return true if exactly the same template @@ -499,6 +454,18 @@ T distSqr(const SGVec3& v1, const SGVec3& v2) { SGVec3 tmp = v1 - v2; return dot(tmp, tmp); } +// calculate the projection of u along the direction of d. +template +inline +SGVec3 +projection(const SGVec3& u, const SGVec3& 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 @@ -527,4 +494,26 @@ SGVec3d toVec3d(const SGVec3f& v) { return SGVec3d(v(0), v(1), v(2)); } +#ifndef NO_OPENSCENEGRAPH_INTERFACE +inline +SGVec3d +toSG(const osg::Vec3d& v) +{ return SGVec3d(v[0], v[1], v[2]); } + +inline +SGVec3f +toSG(const osg::Vec3f& v) +{ return SGVec3f(v[0], v[1], v[2]); } + +inline +osg::Vec3d +toOsg(const SGVec3d& v) +{ return osg::Vec3d(v[0], v[1], v[2]); } + +inline +osg::Vec3f +toOsg(const SGVec3f& v) +{ return osg::Vec3f(v[0], v[1], v[2]); } +#endif + #endif