00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _GMTL_VEC_OPS_H_
00036 #define _GMTL_VEC_OPS_H_
00037
00038 #include <gmtl/Defines.h>
00039 #include <gmtl/Math.h>
00040 #include <gmtl/Vec.h>
00041
00042 namespace gmtl
00043 {
00044
00050
00051
00059 template<typename DATA_TYPE, unsigned SIZE>
00060 Vec<DATA_TYPE, SIZE> operator- (const VecBase<DATA_TYPE, SIZE>& v1)
00061 {
00062 Vec<DATA_TYPE, SIZE> ret_val;
00063 for ( unsigned i=0; i < SIZE; ++i )
00064 {
00065 ret_val[i] = -v1[i];
00066 }
00067 return ret_val;
00068 }
00069
00079 template<class DATA_TYPE, unsigned SIZE>
00080 VecBase<DATA_TYPE, SIZE>& operator +=(VecBase<DATA_TYPE, SIZE>& v1,
00081 const VecBase<DATA_TYPE, SIZE>& v2)
00082 {
00083 for(unsigned i=0;i<SIZE;++i)
00084 {
00085 v1[i] += v2[i];
00086 }
00087
00088 return v1;
00089 }
00090
00099 template<class DATA_TYPE, unsigned SIZE>
00100 VecBase<DATA_TYPE, SIZE> operator +(const VecBase<DATA_TYPE, SIZE>& v1,
00101 const VecBase<DATA_TYPE, SIZE>& v2)
00102 {
00103 VecBase<DATA_TYPE, SIZE> ret_val(v1);
00104 ret_val += v2;
00105 return ret_val;
00106 }
00107
00117 template<class DATA_TYPE, unsigned SIZE>
00118 VecBase<DATA_TYPE, SIZE>& operator -=(VecBase<DATA_TYPE, SIZE>& v1,
00119 const VecBase<DATA_TYPE, SIZE>& v2)
00120 {
00121 for(unsigned i=0;i<SIZE;++i)
00122 {
00123 v1[i] -= v2[i];
00124 }
00125
00126 return v1;
00127 }
00128
00137 template < class DATA_TYPE, unsigned SIZE>
00138 Vec<DATA_TYPE, SIZE> operator -(const VecBase<DATA_TYPE, SIZE>& v1,
00139 const VecBase<DATA_TYPE, SIZE>& v2)
00140 {
00141 Vec<DATA_TYPE, SIZE> ret_val(v1);
00142 ret_val -= v2;
00143 return ret_val;
00144 }
00145
00155 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00156 VecBase<DATA_TYPE, SIZE>& operator *=(VecBase<DATA_TYPE, SIZE>& v1,
00157 const SCALAR_TYPE& scalar)
00158 {
00159 for(unsigned i=0;i<SIZE;++i)
00160 {
00161 v1[i] *= (DATA_TYPE)scalar;
00162 }
00163
00164 return v1;
00165 }
00166
00176 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00177 VecBase<DATA_TYPE, SIZE> operator *(const VecBase<DATA_TYPE, SIZE>& v1,
00178 const SCALAR_TYPE& scalar)
00179 {
00180 VecBase<DATA_TYPE, SIZE> ret_val(v1);
00181 ret_val *= scalar;
00182 return ret_val;
00183
00184
00185 }
00186
00196 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00197 VecBase<DATA_TYPE, SIZE> operator *(const SCALAR_TYPE& scalar,
00198 const VecBase<DATA_TYPE, SIZE>& v1)
00199 {
00200 VecBase<DATA_TYPE, SIZE> ret_val(v1);
00201 ret_val *= scalar;
00202 return ret_val;
00203
00204
00205 }
00206
00216 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00217 VecBase<DATA_TYPE, SIZE>& operator /=(VecBase<DATA_TYPE, SIZE>& v1,
00218 const SCALAR_TYPE& scalar)
00219 {
00220 for(unsigned i=0;i<SIZE;++i)
00221 {
00222 v1[i] /= scalar;
00223 }
00224
00225 return v1;
00226 }
00227
00237 template<class DATA_TYPE, unsigned SIZE, class SCALAR_TYPE>
00238 VecBase<DATA_TYPE, SIZE> operator /(const VecBase<DATA_TYPE, SIZE>& v1,
00239 const SCALAR_TYPE& scalar)
00240 {
00241 VecBase<DATA_TYPE, SIZE> ret_val(v1);
00242 ret_val /= scalar;
00243 return ret_val;
00244
00245 }
00246
00262 template<class DATA_TYPE, unsigned SIZE>
00263 DATA_TYPE dot(const Vec<DATA_TYPE, SIZE>& v1, const Vec<DATA_TYPE, SIZE>& v2)
00264 {
00265 DATA_TYPE ret_val(0);
00266 for(unsigned i=0;i<SIZE;++i)
00267 {
00268 ret_val += (v1[i] * v2[i]);
00269 }
00270 return ret_val;
00271 }
00272
00280 template<class DATA_TYPE, unsigned SIZE>
00281 DATA_TYPE length(const Vec<DATA_TYPE, SIZE>& v1)
00282 {
00283 DATA_TYPE ret_val = lengthSquared(v1);
00284 if (ret_val == 0.0f)
00285 return 0.0f;
00286 else
00287 return Math::sqrt(ret_val);
00288 }
00289
00299 template<class DATA_TYPE, unsigned SIZE>
00300 DATA_TYPE lengthSquared(const Vec<DATA_TYPE, SIZE>& v1)
00301 {
00302 DATA_TYPE ret_val(0);
00303 for(unsigned i=0;i<SIZE;++i)
00304 {
00305 ret_val += (v1[i] * v1[i]);
00306 }
00307
00308 return ret_val;
00309 }
00310
00322 template<class DATA_TYPE, unsigned SIZE>
00323 DATA_TYPE normalize(Vec<DATA_TYPE, SIZE>& v1)
00324 {
00325 DATA_TYPE len = length(v1);
00326
00327 if(len != 0.0f)
00328 {
00329 for(unsigned i=0;i<SIZE;++i)
00330 {
00331 v1[i] /= len;
00332 }
00333 }
00334
00335 return len;
00336 }
00337
00347 template< class DATA_TYPE, unsigned SIZE >
00348 bool isNormalized( const Vec<DATA_TYPE, SIZE>& v1,
00349 const DATA_TYPE eps = (DATA_TYPE)0.0001 )
00350 {
00351 return Math::isEqual( lengthSquared( v1 ), (DATA_TYPE)1.0, eps );
00352 }
00353
00366 template<class DATA_TYPE>
00367 Vec<DATA_TYPE,3> cross(const Vec<DATA_TYPE, 3>& v1, const Vec<DATA_TYPE, 3>& v2)
00368 {
00369 return Vec<DATA_TYPE,3>( ((v1[Yelt]*v2[Zelt]) - (v1[Zelt]*v2[Yelt])),
00370 ((v1[Zelt]*v2[Xelt]) - (v1[Xelt]*v2[Zelt])),
00371 ((v1[Xelt]*v2[Yelt]) - (v1[Yelt]*v2[Xelt])) );
00372 }
00373
00389 template<class DATA_TYPE>
00390 Vec<DATA_TYPE,3>& cross( Vec<DATA_TYPE,3>& result, const Vec<DATA_TYPE, 3>& v1,
00391 const Vec<DATA_TYPE, 3>& v2 )
00392 {
00393 result.set( (v1[Yelt]*v2[Zelt]) - (v1[Zelt]*v2[Yelt]),
00394 (v1[Zelt]*v2[Xelt]) - (v1[Xelt]*v2[Zelt]),
00395 (v1[Xelt]*v2[Yelt]) - (v1[Yelt]*v2[Xelt]) );
00396 return result;
00397 }
00398
00407 template<class DATA_TYPE, unsigned SIZE>
00408 VecBase<DATA_TYPE, SIZE>& reflect( VecBase<DATA_TYPE, SIZE>& result, const
00409 VecBase<DATA_TYPE, SIZE>& vec,
00410 const Vec<DATA_TYPE, SIZE>& normal )
00411 {
00412 result = vec - DATA_TYPE( 2.0 ) * dot( (Vec<DATA_TYPE, SIZE>)vec, normal ) * normal;
00413 return result;
00414 }
00415
00436 template <typename DATA_TYPE, unsigned SIZE>
00437 VecBase<DATA_TYPE, SIZE>& lerp( VecBase<DATA_TYPE, SIZE>& result,
00438 const DATA_TYPE& lerpVal,
00439 const VecBase<DATA_TYPE, SIZE>& from,
00440 const VecBase<DATA_TYPE, SIZE>& to )
00441 {
00443 for (unsigned int x = 0; x < SIZE; ++x)
00444 {
00445 Math::lerp( result[x], lerpVal, from[x], to[x] );
00446 }
00447 return result;
00448 }
00457
00458
00467 template<class DATA_TYPE, unsigned SIZE>
00468 inline bool operator==(const VecBase<DATA_TYPE, SIZE>& v1,
00469 const VecBase<DATA_TYPE, SIZE>& v2)
00470 {
00471 for(unsigned i=0;i<SIZE;++i)
00472 {
00473 if(v1[i] != v2[i])
00474 {
00475 return false;
00476 }
00477 }
00478
00479 return true;
00480
00481
00482
00483
00484
00485
00486 }
00487
00497 template<class DATA_TYPE, unsigned SIZE>
00498 inline bool operator!=(const VecBase<DATA_TYPE, SIZE>& v1,
00499 const VecBase<DATA_TYPE, SIZE>& v2)
00500 {
00501 return(! (v1 == v2));
00502 }
00503
00516 template<class DATA_TYPE, unsigned SIZE>
00517 inline bool isEqual(const VecBase<DATA_TYPE, SIZE>& v1,
00518 const VecBase<DATA_TYPE, SIZE>& v2, const DATA_TYPE& eps)
00519 {
00520 gmtlASSERT(eps >= 0);
00521
00522 for(unsigned i=0;i<SIZE;++i)
00523 {
00524 if (fabs(v1[i] - v2[i]) > eps)
00525 {
00526 return false;
00527 }
00528 }
00529 return true;
00530 }
00531
00534 }
00535
00536 #endif