00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GL_VECTOR_H
00021 #define GL_VECTOR_H
00022
00023 #include "GLFunctions.h"
00024
00025 #ifdef GLVECTOR_IOSTREAM
00026 #include <iostream>
00027 #endif
00028 #include <valarray>
00029
00030 namespace mathglpp
00031 {
00032
00034 template <typename T>
00036 class GLVector2
00037 {
00038 public:
00039 enum { D = 2 };
00040
00042 GLVector2()
00043 { }
00044
00046 GLVector2(const T& v)
00047 { x = y = v; }
00048
00050 GLVector2(const T& v1, const T& v2)
00051 { x = v1; y = v2; }
00052
00054 GLVector2(const GLVector2& gv)
00055 { memmove(val,gv.val,D*sizeof(T)); }
00056
00058 GLVector2(const T* f)
00059 { memmove(val,f,D*sizeof(T)); }
00060
00062 ~GLVector2(){}
00063
00065 inline void set(const T& v1, const T& v2)
00066 { x = v1; y = v2; }
00067
00069 inline T& operator[] (int ind)
00070 { return val[ind]; }
00071
00073 inline operator T* (void)
00074 { return val; }
00075
00077 inline operator const T* (void) const
00078 { return val; }
00079
00081 inline void glScale() const;
00083 inline void glRotate(const T& ang) const;
00085 inline void glTranslate() const;
00087 inline void glVertex() const { mathglpp::glVertexv<D,T>(val); }
00089 inline void glNormal() const;
00090
00092 inline void copyTo(T* vec) const
00093 { memmove(vec,val,2*sizeof(T)); }
00094
00096 inline const GLVector2 operator + (const GLVector2& gv) const
00097 {
00098 return GLVector2(x+gv.x,y+gv.y);
00099 }
00100
00102 inline const GLVector2 operator - (const GLVector2& gv) const
00103 {
00104 return GLVector2(x-gv.x,y-gv.y);
00105 }
00106
00108 inline const GLVector2 operator * (const GLVector2& gv) const
00109 {
00110 return GLVector2(x*gv.x,y*gv.y);
00111 }
00112
00114 inline const GLVector2 operator / (const GLVector2& gv) const
00115 {
00116 return GLVector2(x/gv.x,y/gv.y);
00117 }
00118
00120 inline const GLVector2 operator * (const T& v) const
00121 {
00122 return GLVector2(x*v,y*v);
00123 }
00124
00126 inline const GLVector2 operator / (const T& v) const
00127 {
00128 return GLVector2(x/v,y/v);
00129 }
00130
00132 GLVector2& operator += (const GLVector2& gv)
00133 {
00134 x += gv.x;
00135 y += gv.y;
00136 return *this;
00137 }
00138
00140 GLVector2& operator -= (const GLVector2& gv)
00141 {
00142 x -= gv.x;
00143 y -= gv.y;
00144 return *this;
00145 }
00146
00148 GLVector2& operator *= (const T& f)
00149 {
00150 x *= f;
00151 y *= f;
00152 return *this;
00153 }
00154
00156 GLVector2& operator /= (const T& f)
00157 {
00158 x /= f;
00159 y /= f;
00160 return *this;
00161 }
00162
00164 GLVector2& operator = (const GLVector2& v)
00165 { memmove(val, v.val, D*sizeof(T)); return *this; }
00166
00168 inline bool operator == (const GLVector2& v)
00169 { return memcmp(val, v.val, D*sizeof(T))==0; }
00170
00172 inline const GLVector2 operator - () const
00173 {
00174 return GLVector2(-x,-y);
00175 }
00176
00178 inline const T dot(const GLVector2& gv) const
00179 { return x*gv.x + y*gv.y; }
00180
00182 inline T length() const
00183 { return sqrt(lengthSqr()); }
00184
00186 inline T lengthSqr() const
00187 { return x * x + y * y; }
00188
00190 const GLVector2 unit() const
00191 {
00192 return (*this)/length();
00193 }
00194
00196 GLVector2& normalize()
00197 {
00198 (*this)/=length();
00199 return *this;
00200 }
00201
00203 inline const T projection(const GLVector2& in) const
00204 { return dot(in); }
00205
00207 inline GLVector2 orthogonalProjection(const GLVector2& in) const
00208 { return in - vectorProjection(in); }
00209
00211 GLVector2 vectorProjection(const GLVector2& in) const
00212 { return (*this) * dot(in); }
00213
00214 #ifdef GLVECTOR_IOSTREAM
00216 friend std::basic_istream<char, std::char_traits<char> >& operator >>
00217 ( std::basic_istream<char, std::char_traits<char> >& in, GLVector2& vec)
00218 { in>>vec.val[0]>>vec.val[1]; return in;};
00219
00221 friend std::basic_ostream<char, std::char_traits<char> >& operator <<
00222 ( std::basic_ostream<char, std::char_traits<char> >& out, GLVector2& vec)
00223 { out<<vec.val[0]<<" "<<vec.val[1]; return out;};
00224 #endif
00225
00228 union
00229 {
00230 T val[D];
00231 struct
00232 {
00233 T x,y;
00234 };
00235 };
00236 };
00237
00239 typedef GLVector2<GLbyte> GLVector2b;
00241 typedef GLVector2<GLshort> GLVector2s;
00243 typedef GLVector2<GLint> GLVector2i;
00245 typedef GLVector2<GLfloat> GLVector2f;
00247 typedef GLVector2<GLdouble> GLVector2d;
00248
00250 template <typename T>
00252 class GLIVector2
00253 {
00254 public:
00255 enum { D = 2 };
00256
00258 GLIVector2(const GLIVector2& gv)
00259 :val(gv.val)
00260 { }
00261
00263 GLIVector2(T* f)
00264 :val(f)
00265 { }
00266
00268 ~GLIVector2(){}
00269
00271 inline void set(const T& v1, const T& v2)
00272 { val[0] = v1; val[1] = v2; }
00273
00275 inline T& operator[] (int ind)
00276 { return val[ind]; }
00277
00279 inline operator T* (void)
00280 { return val; }
00281
00283 inline operator const T* (void) const
00284 { return val; }
00285
00287 inline void glScale() const;
00289 inline void glRotate(const T& ang) const;
00291 inline void glTranslate() const;
00293 inline void glVertex() const { mathglpp::glVertexv<D,T>(val); }
00295 inline void glNormal() const;
00296
00298 inline const GLVector2<T> operator + (const GLVector2<T>& gv) const
00299 {
00300 return GLVector2<T>(val[0]+gv.x,val[1]+gv.y);
00301 }
00302
00304 inline const GLVector2<T> operator + (const GLIVector2& gv) const
00305 {
00306 return GLVector2<T>(val[0]+gv.val[0],val[1]+gv.val[1]);
00307 }
00308
00310 inline const GLVector2<T> operator - (const GLVector2<T>& gv) const
00311 {
00312 return GLVector2<T>(val[0]-gv.x,val[1]-gv.y);
00313 }
00314
00316 inline const GLVector2<T> operator - (const GLIVector2& gv) const
00317 {
00318 return GLVector2<T>(val[0]-gv.val[0],val[1]-gv.val[1]);
00319 }
00320
00322 inline const GLVector2<T> operator * (const GLVector2<T>& gv) const
00323 {
00324 return GLVector2<T>(val[0]*gv.x,val[1]*gv.y);
00325 }
00326
00328 inline const GLVector2<T> operator * (const GLIVector2& gv) const
00329 {
00330 return GLVector2<T>(val[0]*gv.x,val[1]*gv.y);
00331 }
00332
00334 inline const GLVector2<T> operator / (const GLVector2<T>& gv) const
00335 {
00336 return GLVector2<T>(val[0]/gv.x,val[1]/gv.y);
00337 }
00338
00340 inline const GLVector2<T> operator / (const GLIVector2& gv) const
00341 {
00342 return GLVector2<T>(val[0]/gv.val[0],val[1]/gv.val[1]);
00343 }
00344
00346 inline const GLVector2<T> operator * (const T& v) const
00347 {
00348 return GLVector2<T>(val[0]*v,val[1]*v);
00349 }
00350
00352 inline const GLVector2<T> operator / (const T& v) const
00353 {
00354 return GLVector2<T>(val[0]/v,val[1]/v);
00355 }
00356
00358 GLIVector2& operator += (const GLVector2<T>& gv)
00359 {
00360 val[0] += gv.x;
00361 val[1] += gv.y;
00362 return *this;
00363 }
00364
00366 GLIVector2& operator += (const GLIVector2& gv)
00367 {
00368 val[0] += gv.val[0];
00369 val[1] += gv.val[0];
00370 return *this;
00371 }
00372
00374 GLIVector2& operator -= (const GLVector2<T>& gv)
00375 {
00376 val[0] -= gv.x;
00377 val[1] -= gv.y;
00378 return *this;
00379 }
00380
00382 GLIVector2& operator -= (const GLIVector2<T>& gv)
00383 {
00384 val[0] -= gv.val[0];
00385 val[1] -= gv.val[1];
00386 return *this;
00387 }
00388
00390 GLIVector2& operator *= (const T& f)
00391 {
00392 val[0] *= f;
00393 val[1] *= f;
00394 return *this;
00395 }
00396
00398 GLIVector2& operator /= (const T& f)
00399 {
00400 val[0] /= f;
00401 val[1] /= f;
00402 return *this;
00403 }
00404
00406 GLIVector2& operator = ( const GLVector2<T>& v )
00407 { memmove(val, v.val, D*sizeof(T)); return *this; }
00408
00410 GLIVector2& operator = ( const GLIVector2& v )
00411 { memmove(val, v.val, D*sizeof(T)); return *this; }
00412
00414 inline const GLVector2<T> operator - () const
00415 {
00416 return GLVector2<T>(-val[0],-val[1]);
00417 }
00418
00420 inline const T dot(const GLVector2<T>& gv) const
00421 { return val[0]*gv.x + val[1]*gv.y; }
00422
00424 inline const T dot(const GLIVector2& gv) const
00425 { return val[0]*gv.val[0] + val[1]*gv.val[1]; }
00426
00428 inline T length() const
00429 { return sqrt(lengthSqr()); }
00430
00432 inline T lengthSqr() const
00433 { return val[0]*val[0] + val[1]*val[1]; }
00434
00436 const GLVector2<T> unit() const
00437 {
00438 return (*this)/length();
00439 }
00440
00442 GLIVector2& normalize()
00443 {
00444 (*this)/=length();
00445 return *this;
00446 }
00447
00449 inline const T projection(const GLVector2<T>& in) const
00450 { return dot(in); }
00451
00453 inline const T projection(const GLIVector2& in) const
00454 { return dot(in); }
00455
00457 inline GLVector2<T> orthogonalProjection(const GLVector2<T>& in) const
00458 { return in - vectorProjection(in); }
00459
00461 inline GLVector2<T> orthogonalProjection(const GLIVector2& in) const
00462 { return in - vectorProjection(in); }
00463
00465 GLVector2<T> vectorProjection(const GLVector2<T>& in) const
00466 { return (*this) * dot(in); }
00467
00469 GLVector2<T> vectorProjection(const GLIVector2& in) const
00470 { return (*this) * dot(in); }
00471
00472 #ifdef GLVECTOR_IOSTREAM
00474 friend std::basic_istream<char, std::char_traits<char> >& operator >>
00475 ( std::basic_istream<char, std::char_traits<char> >& in, GLIVector2& vec)
00476 { in>>vec.val[0]>>vec.val[1]; return in;};
00477
00479 friend std::basic_ostream<char, std::char_traits<char> >& operator <<
00480 ( std::basic_ostream<char, std::char_traits<char> >& out, GLIVector2& vec)
00481 { out<<vec.val[0]<<" "<<vec.val[1]; return out;};
00482 #endif
00483
00484 T* val;
00485 };
00486
00488 typedef GLIVector2<GLbyte> GLIVector2b;
00490 typedef GLIVector2<GLshort> GLIVector2s;
00492 typedef GLIVector2<GLint> GLIVector2i;
00494 typedef GLIVector2<GLfloat> GLIVector2f;
00496 typedef GLIVector2<GLdouble> GLIVector2d;
00497
00499 template <typename T>
00501 class GLVector3
00502 {
00503 public:
00504 enum { D = 3 };
00505 typedef T value_type;
00506
00508 GLVector3() { }
00509
00511 GLVector3(const T& v)
00512 :x(v), y(v), z(v) { }
00513
00515 GLVector3(const T& a, const T& b, const T& c)
00516 :x(a),y(b),z(c){}
00517
00519 GLVector3(const GLVector3& gv)
00520 { memmove(val,gv.val,D*sizeof(T)); }
00521
00523 GLVector3(const T* f)
00524 { memmove(val,f,D*sizeof(T)); }
00525
00527 ~GLVector3(){}
00528
00530 inline void set(const T& v1, const T& v2, const T& v3)
00531 { x = v1; y = v2; z = v3; }
00532
00534 inline T& operator[] (int ind)
00535 { return val[ind]; }
00536
00538 inline operator T* (void)
00539 { return val; }
00540
00542 inline operator const T* (void) const
00543 { return val; }
00544
00546 void glScale() const;
00548 void glRotate(const T& ang) const;
00550 void glTranslate() const;
00552 inline void glVertex() const { mathglpp::glVertexv<D,T>(val); }
00554 void glNormal() const;
00555
00557 inline void copyTo(T* vec) const
00558 { memmove(vec,val,D*sizeof(T)); }
00559
00561 inline const GLVector3 operator + (const GLVector3& gv) const
00562 {
00563 return GLVector3(x+gv.x,y+gv.y,z+gv.z);
00564 }
00565
00567 inline const GLVector3 operator - (const GLVector3& gv) const
00568 {
00569 return GLVector3(x-gv.x,y-gv.y,z-gv.z);
00570 }
00571
00573 inline const GLVector3 operator * (const GLVector3& gv) const
00574 {
00575 return GLVector3(x*gv.x,y*gv.y,z*gv.z);
00576 }
00577
00579 inline const GLVector3 operator / (const GLVector3& gv) const
00580 {
00581 return GLVector3(x/gv.x,y/gv.y,z/gv.z);
00582 }
00583
00585 inline const GLVector3 operator * (const T& v) const
00586 {
00587 return GLVector3(x*v,y*v,z*v);
00588 }
00589
00590
00592 inline const GLVector3 operator / (const T& v) const
00593 {
00594 return GLVector3(x/v,y/v,z/v);
00595 }
00596
00598 GLVector3& operator += (const GLVector3& gv)
00599 {
00600 x += gv.x;
00601 y += gv.y;
00602 z += gv.z;
00603 return *this;
00604 }
00605
00607 GLVector3& operator -= (const GLVector3& gv)
00608 {
00609 x -= gv.x;
00610 y -= gv.y;
00611 z -= gv.z;
00612 return *this;
00613 }
00614
00616 GLVector3& operator *= (const T& f)
00617 {
00618 x *= f;
00619 y *= f;
00620 z *= f;
00621 return *this;
00622 }
00623
00625 GLVector3& operator /= (const T& f)
00626 {
00627 x /= f;
00628 y /= f;
00629 z /= f;
00630 return *this;
00631 }
00632
00634 GLVector3& operator = (const GLVector3& gv)
00635 { memmove(val, gv.val, D*sizeof(T)); return *this; }
00636
00638 inline bool operator == (const GLVector3& gv)
00639 { return memcmp(val, gv.val, D*sizeof(T))==0; }
00640
00642 inline const GLVector3 operator - () const
00643 {
00644 return GLVector3(-x,-y,-z);
00645 }
00646
00648 inline const T dot(const GLVector3& gv) const
00649 { return x*gv.x + y*gv.y + z*gv.z; }
00650
00652 inline T length() const
00653 { return sqrt(lengthSqr()); }
00654
00656 inline T lengthSqr() const
00657 { return x*x + y*y + z*z; }
00658
00660 const GLVector3 getCross(const GLVector3& gv) const
00661 {
00662 return GLVector3(y*gv.z-z*gv.y,z*gv.x-x*gv.z,x*gv.y-y*gv.x);
00663 }
00664
00666 GLVector3& cross(const GLVector3& gv)
00667 {
00668 T temp[] = { x, y, z };
00669
00670 x = temp[1] * gv.z - temp[2] * gv.y;
00671 y = temp[2] * gv.x - temp[0] * gv.z;
00672 z = temp[0] * gv.y - temp[1] * gv.x;
00673
00674 return *this;
00675 }
00676
00678 const GLVector3 unit() const
00679 {
00680 return (*this)/length();
00681 }
00682
00684 GLVector3& normalize()
00685 {
00686 (*this)/=length();
00687 return *this;
00688 }
00689
00691 inline const T projection(const GLVector3& in) const
00692 { return dot(in); }
00693
00695 inline GLVector3 orthogonalProjection(const GLVector3& in) const
00696 { return in - (*this) * dot(in); }
00697
00699 GLVector3 vectorProjection(const GLVector3& in) const
00700 { return (*this) * dot(in); }
00701
00702 #ifdef GLVECTOR_IOSTREAM
00704 friend std::basic_istream<char, std::char_traits<char> >& operator >>
00705 ( std::basic_istream<char, std::char_traits<char> >& in, GLVector3& vec)
00706 { in>>vec.val[0]>>vec.val[1]>>vec.val[2]; return in;};
00707
00709 friend std::basic_ostream<char, std::char_traits<char> >& operator <<
00710 ( std::basic_ostream<char, std::char_traits<char> >& out, GLVector3& vec)
00711 { out<<vec.val[0]<<" "<<vec.val[1]<<" "<<vec.val[2]; return out;};
00712 #endif
00713
00716 union
00717 {
00718 T val[D];
00719 struct
00720 {
00721 T x,y,z;
00722 };
00723 };
00724 };
00725
00726
00728 typedef GLVector3<GLbyte> GLVector3b;
00730 typedef GLVector3<GLshort> GLVector3s;
00732 typedef GLVector3<GLint> GLVector3i;
00734 typedef GLVector3<GLfloat> GLVector3f;
00736 typedef GLVector3<GLdouble> GLVector3d;
00737
00738
00740 template <typename T>
00742 class GLVectorArray3
00743 {
00744 public:
00745 enum { D = 3 };
00746 typedef T value_type;
00747 typedef std::valarray<value_type> vector_type;
00748
00750 GLVectorArray3():vec() { }
00751
00753 GLVectorArray3(const T& v)
00754 :vec(v) { }
00755
00757 GLVectorArray3(const GLVectorArray3& gv)
00758 :vec(gv.vec)
00759 { }
00760
00762 GLVectorArray3(const vector_type& v)
00763 :vec(v)
00764 { }
00765
00767 GLVectorArray3(const T* f, int nVec)
00768 :vec(f,nVec*D)
00769 { }
00770
00772 ~GLVectorArray3(){}
00773
00775 inline T& operator[] (int ind)
00776 { return vec[ind]; }
00777
00779 inline operator T* (void)
00780 { return &vec[0]; }
00781
00783 inline operator const T* (void) const
00784 { return &vec[0]; }
00785
00787 inline void copyTo(T* v) const
00788 { memmove(v,&vec[0],D*sizeof(T)); }
00789
00791 inline const GLVectorArray3 operator + (const GLVectorArray3& gv) const
00792 {
00793 return GLVectorArray3(*this)+=gv;
00794 }
00795
00797 inline const GLVectorArray3 operator - (const GLVectorArray3& gv) const
00798 {
00799 return GLVectorArray3(*this)-=gv;
00800 }
00801
00803 inline const GLVectorArray3 operator * (const GLVectorArray3& gv) const
00804 {
00805 return GLVectorArray3(*this)*=gv;
00806 }
00807
00809 inline const GLVectorArray3 operator / (const GLVectorArray3& gv) const
00810 {
00811 return GLVectorArray3(*this)/=gv;
00812 }
00813
00815 inline const GLVectorArray3 operator * (const T& v) const
00816 {
00817 return GLVectorArray3(*this)*=v;
00818 }
00819
00821 inline const GLVectorArray3 operator / (const T& v) const
00822 {
00823 return GLVectorArray3(*this)/=v;
00824 }
00825
00827 GLVectorArray3& operator += (const GLVectorArray3& gv)
00828 {
00829 vec += gv.vec;
00830 return *this;
00831 }
00832
00834 GLVectorArray3& operator -= (const GLVectorArray3& gv)
00835 {
00836 vec -= gv.vec;
00837 return *this;
00838 }
00839
00841 GLVectorArray3& operator *= (const T& f)
00842 {
00843 vec *= f;
00844 return *this;
00845 }
00846
00848 GLVectorArray3& operator /= (const T& f)
00849 {
00850 vec /= f;
00851 return *this;
00852 }
00853
00855 GLVectorArray3& operator = (const GLVectorArray3& gv)
00856 {
00857 vec = gv.vec;
00858 return *this;
00859 }
00860
00862 inline const GLVectorArray3 operator - () const
00863 {
00864 return GLVectorArray3(-vec);
00865 }
00866
00868 vector_type vec;
00869 };
00870
00872 typedef GLVectorArray3<GLbyte> GLVectorArray3b;
00874 typedef GLVectorArray3<GLshort> GLVectorArray3s;
00876 typedef GLVectorArray3<GLint> GLVectorArray3i;
00878 typedef GLVectorArray3<GLfloat> GLVectorArray3f;
00880 typedef GLVectorArray3<GLdouble> GLVectorArray3d;
00881
00883 template <typename T>
00885 class GLVector4
00886 {
00887 public:
00889 enum { D = 4 };
00890
00892 GLVector4()
00893 { }
00894
00896 GLVector4(const T& v)
00897 { x = y = z = w = v; }
00898
00900 GLVector4(const T& v1, const T& v2, const T& v3, const T& v4)
00901 { x = v1; y = v2; z = v3; w = v4; }
00902
00904 GLVector4(const GLVector4& gv)
00905 { memmove(val,gv.val,D*sizeof(T)); }
00906
00908 GLVector4(const T* f)
00909 { memmove(val,f,D*sizeof(T)); }
00910
00912 ~GLVector4(){}
00913
00915 inline void set(const T& v1, const T& v2, const T& v3, const T& v4)
00916 { x = v1; y = v2; z = v3; w = v4;}
00917
00919 inline T& operator[] (int ind)
00920 { return val[ind]; }
00921
00923 inline operator T* (void)
00924 { return val; }
00925
00927 inline operator const T* (void) const
00928 { return val; }
00929
00931 inline void glScale() const;
00933 inline void glRotate(const T& ang) const;
00935 inline void glTranslate() const;
00937 inline void glVertex() const { mathglpp::glVertexv<D,T>(val); }
00939 inline void glNormal() const;
00940
00942 inline void copyTo(T* vec) const
00943 { memmove(vec,val,D*sizeof(T)); }
00944
00946 inline const GLVector4 operator + (const GLVector4& gv) const
00947 {
00948 return GLVector4(x+gv.x,y+gv.y,z+gv.z,w+gv.w);
00949 }
00950
00952 inline const GLVector4 operator - (const GLVector4& gv) const
00953 {
00954 return GLVector4(x-gv.x,y-gv.y,z-gv.z,w-gv.w);
00955 }
00956
00958 inline const GLVector4 operator * (const GLVector4& gv) const
00959 {
00960 return GLVector4(x*gv.x,y*gv.y,z*gv.z,w*gv.w);
00961 }
00962
00964 inline const GLVector4 operator / (const GLVector4& gv) const
00965 {
00966 return GLVector4(x/gv.x,y/gv.y,z/gv.z,w/gv.w);
00967 }
00968
00970 inline const GLVector4 operator * (const T& v) const
00971 {
00972 return GLVector4(x*v,y*v,z*v,w*v);
00973 }
00974
00975
00977 inline const GLVector4 operator / (const T& v) const
00978 {
00979 return GLVector4(x/v,y/v,z/v,w/v);
00980 }
00981
00983 GLVector4& operator += (const GLVector4& gv)
00984 {
00985 x += gv.x;
00986 y += gv.y;
00987 z += gv.z;
00988 w += gv.w;
00989 return *this;
00990 }
00991
00993 GLVector4& operator -= (const GLVector4& gv)
00994 {
00995 x -= gv.x;
00996 y -= gv.y;
00997 z -= gv.z;
00998 w -= gv.w;
00999 return *this;
01000 }
01001
01003 GLVector4& operator *= (const T& f)
01004 {
01005 x *= f;
01006 y *= f;
01007 z *= f;
01008 w *= f;
01009 return *this;
01010 }
01011
01013 GLVector4& operator /= (const T& f)
01014 {
01015 x /= f;
01016 y /= f;
01017 z /= f;
01018 w /= f;
01019 return *this;
01020 }
01021
01023 GLVector4& operator = (const GLVector4& gv)
01024 { memmove(val,gv.val,D*sizeof(T)); return *this; }
01025
01027 inline bool operator == (const GLVector4& v)
01028 { return memcmp(val, v.val, D*sizeof(T))==0; }
01029
01031 inline const GLVector4 operator - () const
01032 {
01033 return GLVector4(-x,-y,-z,-w);
01034 }
01035
01037 inline const T dot(const GLVector4& gv) const
01038 { return x*gv.x + y*gv.y + z*gv.z + w*gv.w; }
01039
01041 inline T length() const
01042 { return sqrt(lengthSqr()); }
01043
01045 inline T lengthSqr() const
01046 { return x*x + y*y + z*z + w*w; }
01047
01049 const GLVector4 getCross(const GLVector4& gv) const
01050 {
01051 return GLVector4(y*gv.z-z*gv.y,z*gv.w-w*gv.z,w*gv.x-x*gv.w,x*gv.y-y*gv.x);
01052 }
01053
01055 GLVector4& cross(const GLVector4& gv)
01056 {
01057 T temp[] = { x, y, z, w };
01058
01059 x = temp[1] * gv.z - temp[2] * gv.y;
01060 y = temp[2] * gv.w - temp[3] * gv.z;
01061 z = temp[3] * gv.x - temp[0] * gv.w;
01062 w = temp[0] * gv.y - temp[1] * gv.x;
01063
01064 return *this;
01065 }
01066
01068 const GLVector4 unit() const
01069 {
01070 return (*this)/length();
01071 }
01072
01074 GLVector4& normalize()
01075 {
01076 (*this)/=length();
01077 return *this;
01078 }
01079
01081 inline const T projection(const GLVector4& in) const
01082 { return dot(in); }
01083
01085 inline GLVector4 orthogonalProjection(const GLVector4& in) const
01086 { return in - vectorProjection(in); }
01087
01089 GLVector4 vectorProjection(const GLVector4& in) const
01090 { return (*this) * dot(in); }
01091
01092 #ifdef GLVECTOR_IOSTREAM
01094 friend std::basic_istream<char, std::char_traits<char> >& operator >>
01095 ( std::basic_istream<char, std::char_traits<char> >& in, GLVector4& vec)
01096 { in>>vec.val[0]>>vec.val[1]>>vec.val[2]>>vec.val[3]; return in;}
01097
01099 friend std::basic_ostream<char, std::char_traits<char> >& operator <<
01100 ( std::basic_ostream<char, std::char_traits<char> >& out, GLVector4& vec)
01101 { out<<vec.val[0]<<" "<<vec.val[1]<<" "<<vec.val[2]<<" "<<vec.val[3]; return out;}
01102 #endif
01103
01106 union
01107 {
01108 T val[D];
01109 struct
01110 {
01111 T x,y,z,w;
01112 };
01113 };
01114 };
01115
01117 typedef GLVector4<GLbyte> GLVector4b;
01119 typedef GLVector4<GLshort> GLVector4s;
01121 typedef GLVector4<GLint> GLVector4i;
01123 typedef GLVector4<GLfloat> GLVector4f;
01125 typedef GLVector4<GLdouble> GLVector4d;
01126
01127 };
01128
01129 #endif