00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef __CS_VECTOR4_H__
00023 #define __CS_VECTOR4_H__
00024
00032 #include "csextern.h"
00033 #include "csgeom/vector3.h"
00034 #include "csutil/csstring.h"
00035
00039 template<typename T>
00040 class csVector4T
00041 {
00042 public:
00043 #if !defined(__STRICT_ANSI__) && !defined(SWIG)
00044 union
00045 {
00046 struct
00047 {
00048 #endif
00049
00050 T x;
00052 T y;
00054 T z;
00056 T w;
00057 #if !defined(__STRICT_ANSI__) && !defined(SWIG)
00058 };
00060 T m[4];
00061 };
00062 #endif
00063
00064
00065
00066
00067
00068
00073 csVector4T ()
00074 {}
00075
00081 csVector4T (const T& m)
00082 : x(m), y(m), z(m), w(m)
00083 {}
00084
00086 csVector4T (const T& ix, const T& iy, const T& iz = T(0),
00087 const T& iw = T(1))
00088 : x(ix), y(iy), z(iz), w(iw)
00089 {}
00090
00092 csVector4T (const csVector4T& v)
00093 : x(v.x), y(v.y), z(v.z), w(v.w)
00094 {}
00095
00097 csVector4T (const csVector3 &v, float w = 1.0f)
00098 : x(v.x), y(v.y), z(v.z), w(w)
00099 {}
00100
00102 template<typename T2>
00103 csVector4T& operator= (const csVector4T<T2>& other)
00104 {
00105 x = other.x;
00106 y = other.y;
00107 z = other.z;
00108 w = other.w;
00109 return *this;
00110 }
00111
00113 csString Description() const
00114 {
00115 csString str;
00116 str << x << "," << y << "," << z << "," << w;
00117 return str;
00118 }
00119
00121 inline friend csVector4T operator+ (const csVector4T& v1,
00122 const csVector4T& v2)
00123 { return csVector4T(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z, v1.w+v2.w); }
00124
00126 inline friend csVector4T operator- (const csVector4T& v1,
00127 const csVector4T& v2)
00128 { return csVector4T(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z, v1.w-v2.w); }
00129
00130
00132 inline friend float operator* (const csVector4T& v1,
00133 const csVector4T& v2)
00134 { return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z + v1.w*v2.w; }
00135
00137 inline friend csVector4T operator% (const csVector4T& v1,
00138 const csVector4T& v2)
00139 {
00140 return csVector4T<T> (
00141 (v1.x*v2.y-v1.y*v2.x) + (v1.x*v2.z-v1.z*v2.x) + (v1.y*v2.z-v1.z*v2.y),
00142 (v1.z*v2.y-v1.y*v2.z) + (v1.y*v2.w-v1.w*v2.y) + (v1.z*v2.w-v1.w*v2.z),
00143 (v1.x*v2.z-v1.z*v2.x) + (v1.w*v2.x-v1.x*v2.w) + (v1.z*v2.w-v1.w*v2.z),
00144 (v1.y*v2.x-v1.x*v2.y) + (v1.w*v2.x-v1.x*v2.w) + (v1.w*v2.y-v1.y*v2.w) );
00145 }
00146
00148 void Cross (const csVector4T & v1, const csVector4T & v2)
00149 {
00150 x = (v1.x*v2.y-v1.y*v2.x) + (v1.x*v2.z-v1.z*v2.x) + (v1.y*v2.z-v1.z*v2.y);
00151 y = (v1.z*v2.y-v1.y*v2.z) + (v1.y*v2.w-v1.w*v2.y) + (v1.z*v2.w-v1.w*v2.z);
00152 z = (v1.x*v2.z-v1.z*v2.x) + (v1.w*v2.x-v1.x*v2.w) + (v1.z*v2.w-v1.w*v2.z);
00153 w = (v1.y*v2.x-v1.x*v2.y) + (v1.w*v2.x-v1.x*v2.w) + (v1.w*v2.y-v1.y*v2.w);
00154 }
00155
00157 inline friend csVector4T operator* (const csVector4T& v, T f)
00158 { return csVector4T(v.x*f, v.y*f, v.z*f, v.w*f); }
00159
00161 inline friend csVector4T operator* (float f, const csVector4T& v)
00162 { return csVector4T(v.x*f, v.y*f, v.z*f, v.w*f); }
00163
00165 inline friend csVector4T operator* (const csVector4T& v, int f)
00166 { T _f = f; return v * _f; }
00167
00169 inline friend csVector4T operator* (int f, const csVector4T& v)
00170 { T _f = f; return v * _f; }
00171
00173 inline friend csVector4T operator/ (const csVector4T& v, T f)
00174 { f = 1.0f/f; return csVector4T(v.x*f, v.y*f, v.z*f, v.w*f); }
00175
00177 inline friend csVector4T operator/ (const csVector4T& v, int f)
00178 { T _f = f; return v / _f; }
00179
00181 inline friend bool operator== (const csVector4T& v1, const csVector4T& v2)
00182 { return v1.x==v2.x && v1.y==v2.y && v1.z==v2.z && v1.w==v2.w; }
00183
00185 inline friend bool operator!= (const csVector4T& v1, const csVector4T& v2)
00186 { return v1.x!=v2.x || v1.y!=v2.y || v1.z!=v2.z || v1.w!=v2.w; }
00187
00189 inline friend csVector4T operator>> (const csVector4T& v1, const csVector4T& v2)
00190 { return v2*(v1*v2)/(v2*v2); }
00191
00193 inline friend csVector4T operator<< (const csVector4T& v1, const csVector4T& v2)
00194 { return v1*(v1*v2)/(v1*v1); }
00195
00197 inline friend bool operator< (const csVector4T& v, float f)
00198 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f && ABS(v.w)<f; }
00199
00201 inline friend bool operator> (float f, const csVector4T& v)
00202 { return ABS(v.x)<f && ABS(v.y)<f && ABS(v.z)<f && ABS(v.w)<f; }
00203
00205 #if defined( __STRICT_ANSI__) || defined(SWIG)
00206 inline float operator[] (size_t n) const
00207 { return (n&2)?((n&1)?w:z):((n&1)?y:x); }
00208 #else
00209 inline float operator[] (size_t n) const { return m[n]; }
00210 #endif
00211
00213 #if defined( __STRICT_ANSI__) || defined(SWIG)
00214 inline float & operator[] (size_t n)
00215 { return (n&2)?((n&1)?w:z):((n&1)?y:x); }
00216 #else
00217 inline float & operator[] (size_t n)
00218 { return m[n]; }
00219 #endif
00220
00222 inline csVector4T& operator+= (const csVector4T& v)
00223 {
00224 x += v.x;
00225 y += v.y;
00226 z += v.z;
00227 w += v.w;
00228
00229 return *this;
00230 }
00231
00233 inline csVector4T& operator-= (const csVector4T& v)
00234 {
00235 x -= v.x;
00236 y -= v.y;
00237 z -= v.z;
00238 w -= v.w;
00239
00240 return *this;
00241 }
00242
00244 inline csVector4T& operator*= (T f)
00245 { x *= f; y *= f; z *= f; w *= f; return *this; }
00246
00248 inline csVector4T& operator/= (T f)
00249 { f = 1.0f / f; x *= f; y *= f; z *= f; w *= f; return *this; }
00250
00252 inline csVector4T operator+ () const
00253 { return *this; }
00254
00256 inline csVector4T operator- () const
00257 { return csVector4T(-x,-y,-z, -w); }
00258
00260 inline void Set (T sx, T sy, T sz, T sw)
00261 { x = sx; y = sy; z = sz; w = sw; }
00262
00264 inline void Set (csVector4T const& v)
00265 { x = v.x; y = v.y; z = v.z; w = v.w; }
00266
00268 inline void Set (T const* v)
00269 { x = v[0]; y = v[1]; z = v[2]; w = v[3]; }
00270
00272 inline void Set (T v)
00273 { x = y = z = w = v; }
00274
00276 inline void Get (T* v)
00277 { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
00278
00280 inline T Norm () const
00281 { return csQsqrt(SquaredNorm()); }
00282
00284 inline float InverseNorm () const
00285 { return csQisqrt(SquaredNorm()); }
00286
00288 inline T SquaredNorm () const
00289 { return x * x + y * y + z * z + w * w; }
00290
00296 inline csVector4T Unit () const
00297 { return (*this)*(this->InverseNorm()); }
00298
00300 inline static T Norm (const csVector4T& v)
00301 { return v.Norm(); }
00302
00304 inline static csVector4T Unit (const csVector4T& v)
00305 { return v.Unit(); }
00306
00308 inline void Normalize ()
00309 {
00310 T sqlen = SquaredNorm();
00311 if (sqlen < SMALL_EPSILON) return ;
00312
00313 T invlen = csQisqrt (sqlen);
00314 *this *= invlen;
00315 }
00316
00317
00319 inline bool IsZero (T precision = SMALL_EPSILON) const
00320 {
00321 return (ABS(x) < precision) && (ABS(y) < precision)
00322 && (ABS(z) < precision) && (ABS(w) < precision);
00323 }
00324 };
00325
00329 class csVector4 : public csVector4T<float>
00330 {
00331 public:
00336 csVector4 () {}
00337
00343 csVector4 (const float& m)
00344 : csVector4T<float> (m)
00345 {}
00346
00348 csVector4 (float ix, float iy, float iz = 0, float iw = 1)
00349 : csVector4T<float> (ix, iy, iz, iw)
00350 {}
00351
00353 csVector4 (const csVector4& v)
00354 : csVector4T<float> (v)
00355 {}
00356
00358 csVector4 (const csVector4T<float>& v)
00359 : csVector4T<float> (v)
00360 {}
00361
00363 csVector4 (const csVector3 &v, float w = 1.0f)
00364 : csVector4T<float> (v.x, v.y, v.z, w)
00365 {}
00366
00368 csVector4& operator= (const csVector4T<float>& other)
00369 {
00370 Set (other.x, other.y, other.z, other.w);
00371 return *this;
00372 }
00373
00375 csVector4& operator= (const csVector3& other)
00376 {
00377 Set (other.x, other.y, other.z, 1.0f);
00378 return *this;
00379 }
00380 };
00381
00384 #endif // __CS_VECTOR3_H__