• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

VecOps.h

Go to the documentation of this file.
00001 // GMTL is (C) Copyright 2001-2010 by Allen Bierbaum
00002 // Distributed under the GNU Lesser General Public License 2.1 with an
00003 // addendum covering inlined code. (See accompanying files LICENSE and
00004 // LICENSE.addendum or http://www.gnu.org/copyleft/lesser.txt)
00005 
00006 #ifndef _GMTL_VEC_OPS_H_
00007 #define _GMTL_VEC_OPS_H_
00008 
00009 #include <gmtl/Defines.h>
00010 #include <gmtl/Math.h>
00011 #include <gmtl/Vec.h>
00012 #ifndef GMTL_NO_METAPROG
00013 #include <gmtl/VecOpsMeta.h>
00014 #include <gmtl/VecExprMeta.h>
00015 #endif
00016 
00017 namespace gmtl
00018 {
00019 
00025 // --- Basic VEC types operations -- //
00026 
00034 #ifdef GMTL_NO_METAPROG
00035 template<typename DATA_TYPE, unsigned SIZE>
00036 Vec<DATA_TYPE, SIZE> operator- (const VecBase<DATA_TYPE, SIZE>& v1)
00037 {
00038    Vec<DATA_TYPE, SIZE> ret_val;
00039    for ( unsigned i=0; i < SIZE; ++i )
00040    {
00041       ret_val[i] = -v1[i];
00042    }
00043    return ret_val;
00044 }
00045 #else
00046 template<typename T, unsigned SIZE, typename R1>
00047 inline VecBase<T,SIZE, meta::VecUnaryExpr<VecBase<T,SIZE,R1>, meta::VecNegUnary> >
00048 operator-(const VecBase<T,SIZE,R1>& v1)
00049 {
00050    return VecBase<T,SIZE,
00051                   meta::VecUnaryExpr<VecBase<T,SIZE,R1>, meta::VecNegUnary> >
00052                         ( meta::VecUnaryExpr<VecBase<T,SIZE,R1>, meta::VecNegUnary>(v1) );
00053 }
00054 #endif
00055 
00065 #ifdef GMTL_NO_METAPROG
00066 template<class DATA_TYPE, unsigned SIZE>
00067 VecBase<DATA_TYPE, SIZE>& operator +=(VecBase<DATA_TYPE, SIZE>& v1,
00068                                       const VecBase<DATA_TYPE, SIZE>& v2)
00069 #else
00070 template<class DATA_TYPE, unsigned SIZE, typename REP2>
00071 VecBase<DATA_TYPE, SIZE>& operator +=(VecBase<DATA_TYPE, SIZE>& v1,
00072                                       const VecBase<DATA_TYPE, SIZE, REP2>& v2)
00073 #endif
00074 {
00075    for(unsigned i=0;i<SIZE;++i)
00076    {
00077       v1[i] += v2[i];
00078    }
00079 
00080    return v1;
00081 }
00082 
00091 #ifdef GMTL_NO_METAPROG
00092 template<class DATA_TYPE, unsigned SIZE>
00093 VecBase<DATA_TYPE, SIZE> operator +(const VecBase<DATA_TYPE, SIZE>& v1,
00094                                     const VecBase<DATA_TYPE, SIZE>& v2)
00095 {
00096    VecBase<DATA_TYPE, SIZE> ret_val(v1);
00097    ret_val += v2;
00098    return ret_val;
00099 }
00100 #else
00101 template<typename T, unsigned SIZE, typename R1, typename R2>
00102 inline VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE,R2>, meta::VecPlusBinary> >
00103 operator+(const VecBase<T,SIZE,R1>& v1, const VecBase<T,SIZE,R2>& v2)
00104 {
00105    return VecBase<T,SIZE,
00106                meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00107                                    VecBase<T,SIZE,R2>,
00108                                    meta::VecPlusBinary> >( meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00109                                                                                VecBase<T,SIZE,R2>,
00110                                                                                meta::VecPlusBinary>(v1,v2) );
00111 }
00112 #endif
00113 
00123 #ifdef GMTL_NO_METAPROG
00124 template<class DATA_TYPE, unsigned SIZE>
00125 VecBase<DATA_TYPE, SIZE>& operator -=(VecBase<DATA_TYPE, SIZE>& v1,
00126                                       const VecBase<DATA_TYPE, SIZE>& v2)
00127 #else
00128 template<class DATA_TYPE, unsigned SIZE, typename REP2>
00129 VecBase<DATA_TYPE, SIZE>& operator -=(VecBase<DATA_TYPE, SIZE>& v1,
00130                                       const VecBase<DATA_TYPE, SIZE, REP2>& v2)
00131 #endif
00132 {
00133    for(unsigned i=0;i<SIZE;++i)
00134    {
00135       v1[i] -= v2[i];
00136    }
00137 
00138    return v1;
00139 }
00140 
00149 #ifdef GMTL_NO_METAPROG
00150 template < class DATA_TYPE, unsigned SIZE>
00151 Vec<DATA_TYPE, SIZE> operator -(const VecBase<DATA_TYPE, SIZE>& v1,
00152                                 const VecBase<DATA_TYPE, SIZE>& v2)
00153 {
00154    Vec<DATA_TYPE, SIZE> ret_val(v1);
00155    ret_val -= v2;
00156    return ret_val;
00157 }
00158 #else
00159 template<typename T, unsigned SIZE, typename R1, typename R2>
00160 inline VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE,R2>, meta::VecMinusBinary> >
00161 operator-(const VecBase<T,SIZE,R1>& v1, const VecBase<T,SIZE,R2>& v2)
00162 {
00163    return VecBase<T,SIZE,
00164                meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00165                                    VecBase<T,SIZE,R2>,
00166                                    meta::VecMinusBinary> >( meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00167                                                                                VecBase<T,SIZE,R2>,
00168                                                                                meta::VecMinusBinary>(v1,v2) );
00169 }
00170 #endif
00171 
00181 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00182 VecBase<DATA_TYPE, SIZE>& operator *=(VecBase<DATA_TYPE, SIZE>& v1,
00183                                       const SCALAR_TYPE& scalar)
00184 {
00185    for(unsigned i=0;i<SIZE;++i)
00186    {
00187       v1[i] *= (DATA_TYPE)scalar;
00188    }
00189 
00190    return v1;
00191 }
00192 
00202 #ifdef GMTL_NO_METAPROG
00203 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00204 VecBase<DATA_TYPE, SIZE> operator *(const VecBase<DATA_TYPE, SIZE>& v1,
00205                                     const SCALAR_TYPE& scalar)
00206 {
00207    VecBase<DATA_TYPE, SIZE> ret_val(v1);
00208    ret_val *= scalar;
00209    return ret_val;
00210 
00211    //return VecBase<DATA_TYPE, SIZE>(v1) *= scalar;
00212 }
00213 #else
00214 template<typename T, unsigned SIZE, typename R1>
00215 inline VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE, meta::ScalarArg<T> >, meta::VecMultBinary> >
00216 operator*(const VecBase<T,SIZE,R1>& v1, const T scalar)
00217 {
00218    return VecBase<T,SIZE,
00219              meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00220                                  VecBase<T,SIZE, meta::ScalarArg<T> >,
00221                                  meta::VecMultBinary> >(
00222                                        meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00223                                                            VecBase<T,SIZE, meta::ScalarArg<T> >,
00224                                                            meta::VecMultBinary>(v1,
00225                                                                                 meta::ScalarArg<T>(scalar)) );
00226 }
00227 
00228 template<typename T, unsigned SIZE, typename R1>
00229 inline VecBase<T,SIZE, meta::VecBinaryExpr< VecBase<T,SIZE, meta::ScalarArg<T> >,
00230                                             VecBase<T,SIZE,R1>,
00231                                             meta::VecMultBinary> >
00232 operator*(const T scalar, const VecBase<T,SIZE,R1>& v1)
00233 {
00234    return VecBase<T,SIZE,
00235              meta::VecBinaryExpr<VecBase<T,SIZE, meta::ScalarArg<T> >,
00236                                  VecBase<T,SIZE,R1>,
00237                                  meta::VecMultBinary> >(
00238                                        meta::VecBinaryExpr<VecBase<T,SIZE, meta::ScalarArg<T> >,
00239                                                            VecBase<T,SIZE,R1>,
00240                                                            meta::VecMultBinary>(meta::ScalarArg<T>(scalar), v1 ) );
00241 }
00242 #endif
00243 
00253 #ifdef GMTL_NO_METAPROG
00254 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00255 VecBase<DATA_TYPE, SIZE> operator *(const SCALAR_TYPE& scalar,
00256                                     const VecBase<DATA_TYPE, SIZE>& v1)
00257 {
00258    VecBase<DATA_TYPE, SIZE> ret_val(v1);
00259    ret_val *= scalar;
00260    return ret_val;
00261 
00262    //return VecBase<DATA_TYPE, SIZE>(v1) *= scalar;
00263 }
00264 #endif
00265 
00275 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00276 VecBase<DATA_TYPE, SIZE>& operator /=(VecBase<DATA_TYPE, SIZE>& v1,
00277                                       const SCALAR_TYPE& scalar)
00278 {
00279    for(unsigned i=0;i<SIZE;++i)
00280    {
00281       v1[i] /= scalar;
00282    }
00283 
00284    return v1;
00285 }
00286 
00296 #ifdef GMTL_NO_METAPROG
00297 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00298 VecBase<DATA_TYPE, SIZE> operator /(const VecBase<DATA_TYPE, SIZE>& v1,
00299                                     const SCALAR_TYPE& scalar)
00300 {
00301    VecBase<DATA_TYPE, SIZE> ret_val(v1);
00302    ret_val /= scalar;
00303    return ret_val;
00304    // return VecBase<DATA_TYPE, SIZE>(v1)( /= scalar;
00305 }
00306 #else
00307 template<typename T, unsigned SIZE, typename R1>
00308 inline VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE, meta::ScalarArg<T> >, meta::VecDivBinary> >
00309 operator/(const VecBase<T,SIZE,R1>& v1, const T scalar)
00310 {
00311    return VecBase<T,SIZE,
00312              meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00313                                  VecBase<T,SIZE, meta::ScalarArg<T> >,
00314                                  meta::VecDivBinary> >(
00315                                        meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
00316                                                            VecBase<T,SIZE, meta::ScalarArg<T> >,
00317                                                            meta::VecDivBinary>(v1,
00318                                                                                meta::ScalarArg<T>(scalar)) );
00319 }
00320 #endif
00321 
00338 #ifdef GMTL_NO_METAPROG
00339 template<class DATA_TYPE, unsigned SIZE>
00340 DATA_TYPE dot(const VecBase<DATA_TYPE, SIZE>& v1, const VecBase<DATA_TYPE, SIZE>& v2)
00341 {
00342    DATA_TYPE ret_val(0);
00343    for(unsigned i=0;i<SIZE;++i)
00344    {
00345       ret_val += (v1[i] * v2[i]);
00346    }
00347    return ret_val;
00348 }
00349 #else
00350 template<class DATA_TYPE, unsigned SIZE, typename REP1, typename REP2>
00351 DATA_TYPE dot(const VecBase<DATA_TYPE, SIZE, REP1>& v1, const VecBase<DATA_TYPE, SIZE, REP2>& v2)
00352 {
00353    return gmtl::meta::DotVecUnrolled<SIZE-1,
00354                                      VecBase<DATA_TYPE,SIZE,REP1>,
00355                                      VecBase<DATA_TYPE,SIZE,REP2> >::func(v1,v2);
00356 }
00357 #endif
00358 
00366 template<class DATA_TYPE, unsigned SIZE>
00367 DATA_TYPE length(const Vec<DATA_TYPE, SIZE>& v1)
00368 {
00369    DATA_TYPE ret_val = lengthSquared(v1);
00370    if (ret_val == DATA_TYPE(0.0f))
00371       return DATA_TYPE(0.0f);
00372    else
00373       return Math::sqrt(ret_val);
00374 }
00375 
00385 template<class DATA_TYPE, unsigned SIZE>
00386 DATA_TYPE lengthSquared(const Vec<DATA_TYPE, SIZE>& v1)
00387 {
00388 #ifdef GMTL_NO_METAPROG
00389    DATA_TYPE ret_val(0);
00390    for(unsigned i=0;i<SIZE;++i)
00391    {
00392       ret_val += (v1[i] * v1[i]);
00393    }
00394 
00395    return ret_val;
00396 #else
00397    return gmtl::meta::LenSqrVecUnrolled<SIZE-1,Vec<DATA_TYPE,SIZE> >::func(v1);
00398 #endif
00399 }
00400 
00412 template<class DATA_TYPE, unsigned SIZE>
00413 DATA_TYPE normalize(Vec<DATA_TYPE, SIZE>& v1)
00414 {
00415    DATA_TYPE len = length(v1);
00416 
00417    if(len != 0.0f)
00418    {
00419       for(unsigned i=0;i<SIZE;++i)
00420       {
00421          v1[i] /= len;
00422       }
00423    }
00424 
00425    return len;
00426 }
00427 
00437 template< class DATA_TYPE, unsigned SIZE >
00438 bool isNormalized( const Vec<DATA_TYPE, SIZE>& v1,
00439                    const DATA_TYPE eps = (DATA_TYPE) 0.0001f )
00440 {
00441    return Math::isEqual( lengthSquared( v1 ), DATA_TYPE(1.0), eps );
00442 }
00443 
00459 template<class DATA_TYPE>
00460 Vec<DATA_TYPE,3>& cross( Vec<DATA_TYPE,3>& result, const Vec<DATA_TYPE, 3>& v1,
00461                          const Vec<DATA_TYPE, 3>& v2 )
00462 {
00463    result.set( (v1[Yelt]*v2[Zelt]) - (v1[Zelt]*v2[Yelt]),
00464                (v1[Zelt]*v2[Xelt]) - (v1[Xelt]*v2[Zelt]),
00465                (v1[Xelt]*v2[Yelt]) - (v1[Yelt]*v2[Xelt]) );
00466    return result;
00467 }
00468 
00490 template<class DATA_TYPE, unsigned SIZE>
00491 VecBase<DATA_TYPE, SIZE>& reflect( VecBase<DATA_TYPE, SIZE>& result, const
00492                            VecBase<DATA_TYPE, SIZE>& vec,
00493                            const Vec<DATA_TYPE, SIZE>& normal )
00494 {
00495    result = vec - (DATA_TYPE( 2.0 ) * (dot( (Vec<DATA_TYPE, SIZE>)vec, normal ) * normal));
00496    return result;
00497 }
00498 
00519 template <typename DATA_TYPE, unsigned SIZE>
00520 VecBase<DATA_TYPE, SIZE>& lerp( VecBase<DATA_TYPE, SIZE>& result,
00521                                 const DATA_TYPE& lerpVal,
00522                                 const VecBase<DATA_TYPE, SIZE>& from,
00523                                 const VecBase<DATA_TYPE, SIZE>& to )
00524 {
00526    for (unsigned int x = 0; x < SIZE; ++x)
00527    {
00528       Math::lerp( result[x], lerpVal, from[x], to[x] );
00529    }
00530    return result;
00531 }
00540 // --- VEC comparisons -- //
00541 
00550 template<class DATA_TYPE, unsigned SIZE>
00551 inline bool operator==(const VecBase<DATA_TYPE, SIZE>& v1,
00552                        const VecBase<DATA_TYPE, SIZE>& v2)
00553 {
00554 #ifdef GMTL_NO_METAPROG
00555    for(unsigned i=0;i<SIZE;++i)
00556    {
00557       if(v1[i] != v2[i])
00558       {
00559          return false;
00560       }
00561    }
00562 
00563    return true;
00564 #else
00565    return gmtl::meta::EqualVecUnrolled<SIZE-1,Vec<DATA_TYPE,SIZE> >::func(v1,v2);
00566 #endif
00567    /*  Would like this
00568    return(vec[0] == _v[0] &&
00569           vec[1] == _v[1] &&
00570           vec[2] == _v[2]);
00571           */
00572 }
00573 
00583 template<class DATA_TYPE, unsigned SIZE>
00584 inline bool operator!=(const VecBase<DATA_TYPE, SIZE>& v1,
00585                        const VecBase<DATA_TYPE, SIZE>& v2)
00586 {
00587    return(! (v1 == v2));
00588 }
00589 
00602 template<class DATA_TYPE, unsigned SIZE>
00603 inline bool isEqual(const VecBase<DATA_TYPE, SIZE>& v1,
00604                     const VecBase<DATA_TYPE, SIZE>& v2, const DATA_TYPE eps)
00605 {
00606    gmtlASSERT(eps >= 0);
00607 
00608    for(unsigned i=0;i<SIZE;++i)
00609    {
00610       if ( gmtl::Math::abs(v1[i] - v2[i]) > eps )
00611       {
00612          return false;
00613       }
00614    }
00615    return true;
00616 }
00617 
00620 }
00621 
00622 #endif

Generated on Sun Sep 19 2010 14:35:14 for GenericMathTemplateLibrary by  doxygen 1.7.1