00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef SGVec4_H
00019 #define SGVec4_H
00020
00021 #ifndef NO_OPENSCENEGRAPH_INTERFACE
00022 #include <osg/Vec4f>
00023 #include <osg/Vec4d>
00024 #endif
00025
00027 template<typename T>
00028 class SGVec4 {
00029 public:
00030 typedef T value_type;
00031
00034 SGVec4(void)
00035 {
00039 #ifndef NDEBUG
00040 for (unsigned i = 0; i < 4; ++i)
00041 data()[i] = SGLimits<T>::quiet_NaN();
00042 #endif
00043 }
00045 SGVec4(T x, T y, T z, T w)
00046 { data()[0] = x; data()[1] = y; data()[2] = z; data()[3] = w; }
00049 explicit SGVec4(const T* d)
00050 { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
00051 template<typename S>
00052 explicit SGVec4(const SGVec4<S>& d)
00053 { data()[0] = d[0]; data()[1] = d[1]; data()[2] = d[2]; data()[3] = d[3]; }
00054 explicit SGVec4(const SGVec3<T>& v3, const T& v4 = 0)
00055 { data()[0] = v3[0]; data()[1] = v3[1]; data()[2] = v3[2]; data()[3] = v4; }
00056
00058 const T& operator()(unsigned i) const
00059 { return data()[i]; }
00061 T& operator()(unsigned i)
00062 { return data()[i]; }
00063
00065 const T& operator[](unsigned i) const
00066 { return data()[i]; }
00068 T& operator[](unsigned i)
00069 { return data()[i]; }
00070
00072 const T& x(void) const
00073 { return data()[0]; }
00075 T& x(void)
00076 { return data()[0]; }
00078 const T& y(void) const
00079 { return data()[1]; }
00081 T& y(void)
00082 { return data()[1]; }
00084 const T& z(void) const
00085 { return data()[2]; }
00087 T& z(void)
00088 { return data()[2]; }
00090 const T& w(void) const
00091 { return data()[3]; }
00093 T& w(void)
00094 { return data()[3]; }
00095
00097 const T (&data(void) const)[4]
00098 { return _data; }
00100 T (&data(void))[4]
00101 { return _data; }
00102
00104 SGVec4& operator+=(const SGVec4& v)
00105 { data()[0]+=v(0);data()[1]+=v(1);data()[2]+=v(2);data()[3]+=v(3);return *this; }
00107 SGVec4& operator-=(const SGVec4& v)
00108 { data()[0]-=v(0);data()[1]-=v(1);data()[2]-=v(2);data()[3]-=v(3);return *this; }
00110 template<typename S>
00111 SGVec4& operator*=(S s)
00112 { data()[0] *= s; data()[1] *= s; data()[2] *= s; data()[3] *= s; return *this; }
00114 template<typename S>
00115 SGVec4& operator/=(S s)
00116 { return operator*=(1/T(s)); }
00117
00119 static SGVec4 zeros(void)
00120 { return SGVec4(0, 0, 0, 0); }
00122 static SGVec4 e1(void)
00123 { return SGVec4(1, 0, 0, 0); }
00124 static SGVec4 e2(void)
00125 { return SGVec4(0, 1, 0, 0); }
00126 static SGVec4 e3(void)
00127 { return SGVec4(0, 0, 1, 0); }
00128 static SGVec4 e4(void)
00129 { return SGVec4(0, 0, 0, 1); }
00130
00131 private:
00132 T _data[4];
00133 };
00134
00136 template<typename T>
00137 inline
00138 const SGVec4<T>&
00139 operator+(const SGVec4<T>& v)
00140 { return v; }
00141
00143 template<typename T>
00144 inline
00145 SGVec4<T>
00146 operator-(const SGVec4<T>& v)
00147 { return SGVec4<T>(-v(0), -v(1), -v(2), -v(3)); }
00148
00150 template<typename T>
00151 inline
00152 SGVec4<T>
00153 operator+(const SGVec4<T>& v1, const SGVec4<T>& v2)
00154 { return SGVec4<T>(v1(0)+v2(0), v1(1)+v2(1), v1(2)+v2(2), v1(3)+v2(3)); }
00155
00157 template<typename T>
00158 inline
00159 SGVec4<T>
00160 operator-(const SGVec4<T>& v1, const SGVec4<T>& v2)
00161 { return SGVec4<T>(v1(0)-v2(0), v1(1)-v2(1), v1(2)-v2(2), v1(3)-v2(3)); }
00162
00164 template<typename S, typename T>
00165 inline
00166 SGVec4<T>
00167 operator*(S s, const SGVec4<T>& v)
00168 { return SGVec4<T>(s*v(0), s*v(1), s*v(2), s*v(3)); }
00169
00171 template<typename S, typename T>
00172 inline
00173 SGVec4<T>
00174 operator*(const SGVec4<T>& v, S s)
00175 { return SGVec4<T>(s*v(0), s*v(1), s*v(2), s*v(3)); }
00176
00180 template<typename T>
00181 inline
00182 SGVec4<T>
00183 mult(const SGVec4<T>& v1, const SGVec4<T>& v2)
00184 { return SGVec4<T>(v1(0)*v2(0), v1(1)*v2(1), v1(2)*v2(2), v1(3)*v2(3)); }
00185
00187 template<typename T>
00188 inline
00189 SGVec4<T>
00190 min(const SGVec4<T>& v1, const SGVec4<T>& v2)
00191 {
00192 return SGVec4<T>(SGMisc<T>::min(v1(0), v2(0)),
00193 SGMisc<T>::min(v1(1), v2(1)),
00194 SGMisc<T>::min(v1(2), v2(2)),
00195 SGMisc<T>::min(v1(3), v2(3)));
00196 }
00197 template<typename S, typename T>
00198 inline
00199 SGVec4<T>
00200 min(const SGVec4<T>& v, S s)
00201 {
00202 return SGVec4<T>(SGMisc<T>::min(s, v(0)),
00203 SGMisc<T>::min(s, v(1)),
00204 SGMisc<T>::min(s, v(2)),
00205 SGMisc<T>::min(s, v(3)));
00206 }
00207 template<typename S, typename T>
00208 inline
00209 SGVec4<T>
00210 min(S s, const SGVec4<T>& v)
00211 {
00212 return SGVec4<T>(SGMisc<T>::min(s, v(0)),
00213 SGMisc<T>::min(s, v(1)),
00214 SGMisc<T>::min(s, v(2)),
00215 SGMisc<T>::min(s, v(3)));
00216 }
00217
00219 template<typename T>
00220 inline
00221 SGVec4<T>
00222 max(const SGVec4<T>& v1, const SGVec4<T>& v2)
00223 {
00224 return SGVec4<T>(SGMisc<T>::max(v1(0), v2(0)),
00225 SGMisc<T>::max(v1(1), v2(1)),
00226 SGMisc<T>::max(v1(2), v2(2)),
00227 SGMisc<T>::max(v1(3), v2(3)));
00228 }
00229 template<typename S, typename T>
00230 inline
00231 SGVec4<T>
00232 max(const SGVec4<T>& v, S s)
00233 {
00234 return SGVec4<T>(SGMisc<T>::max(s, v(0)),
00235 SGMisc<T>::max(s, v(1)),
00236 SGMisc<T>::max(s, v(2)),
00237 SGMisc<T>::max(s, v(3)));
00238 }
00239 template<typename S, typename T>
00240 inline
00241 SGVec4<T>
00242 max(S s, const SGVec4<T>& v)
00243 {
00244 return SGVec4<T>(SGMisc<T>::max(s, v(0)),
00245 SGMisc<T>::max(s, v(1)),
00246 SGMisc<T>::max(s, v(2)),
00247 SGMisc<T>::max(s, v(3)));
00248 }
00249
00251 template<typename T>
00252 inline
00253 T
00254 dot(const SGVec4<T>& v1, const SGVec4<T>& v2)
00255 { return v1(0)*v2(0) + v1(1)*v2(1) + v1(2)*v2(2) + v1(3)*v2(3); }
00256
00258 template<typename T>
00259 inline
00260 T
00261 norm(const SGVec4<T>& v)
00262 { return sqrt(dot(v, v)); }
00263
00265 template<typename T>
00266 inline
00267 T
00268 length(const SGVec4<T>& v)
00269 { return sqrt(dot(v, v)); }
00270
00273 template<typename T>
00274 inline
00275 T
00276 norm1(const SGVec4<T>& v)
00277 { return fabs(v(0)) + fabs(v(1)) + fabs(v(2)) + fabs(v(3)); }
00278
00280 template<typename T>
00281 inline
00282 T
00283 normI(const SGVec4<T>& v)
00284 { return SGMisc<T>::max(fabs(v(0)), fabs(v(1)), fabs(v(2)), fabs(v(2))); }
00285
00287 template<typename T>
00288 inline
00289 SGVec4<T>
00290 normalize(const SGVec4<T>& v)
00291 {
00292 T normv = norm(v);
00293 if (normv <= SGLimits<T>::min())
00294 return SGVec4<T>::zeros();
00295 return (1/normv)*v;
00296 }
00297
00299 template<typename T>
00300 inline
00301 bool
00302 operator==(const SGVec4<T>& v1, const SGVec4<T>& v2)
00303 { return v1(0)==v2(0) && v1(1)==v2(1) && v1(2)==v2(2) && v1(3)==v2(3); }
00304
00306 template<typename T>
00307 inline
00308 bool
00309 operator!=(const SGVec4<T>& v1, const SGVec4<T>& v2)
00310 { return ! (v1 == v2); }
00311
00313 template<typename T>
00314 inline
00315 bool
00316 operator<(const SGVec4<T>& v1, const SGVec4<T>& v2)
00317 {
00318 if (v1(0) < v2(0)) return true;
00319 else if (v2(0) < v1(0)) return false;
00320 else if (v1(1) < v2(1)) return true;
00321 else if (v2(1) < v1(1)) return false;
00322 else if (v1(2) < v2(2)) return true;
00323 else if (v2(2) < v1(2)) return false;
00324 else return (v1(3) < v2(3));
00325 }
00326
00327 template<typename T>
00328 inline
00329 bool
00330 operator<=(const SGVec4<T>& v1, const SGVec4<T>& v2)
00331 {
00332 if (v1(0) < v2(0)) return true;
00333 else if (v2(0) < v1(0)) return false;
00334 else if (v1(1) < v2(1)) return true;
00335 else if (v2(1) < v1(1)) return false;
00336 else if (v1(2) < v2(2)) return true;
00337 else if (v2(2) < v1(2)) return false;
00338 else return (v1(3) <= v2(3));
00339 }
00340
00341 template<typename T>
00342 inline
00343 bool
00344 operator>(const SGVec4<T>& v1, const SGVec4<T>& v2)
00345 { return operator<(v2, v1); }
00346
00347 template<typename T>
00348 inline
00349 bool
00350 operator>=(const SGVec4<T>& v1, const SGVec4<T>& v2)
00351 { return operator<=(v2, v1); }
00352
00354 template<typename T>
00355 inline
00356 bool
00357 equivalent(const SGVec4<T>& v1, const SGVec4<T>& v2, T rtol, T atol)
00358 { return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)) + atol; }
00359
00361 template<typename T>
00362 inline
00363 bool
00364 equivalent(const SGVec4<T>& v1, const SGVec4<T>& v2, T rtol)
00365 { return norm1(v1 - v2) < rtol*(norm1(v1) + norm1(v2)); }
00366
00368 template<typename T>
00369 inline
00370 bool
00371 equivalent(const SGVec4<T>& v1, const SGVec4<T>& v2)
00372 {
00373 T tol = 100*SGLimits<T>::epsilon();
00374 return equivalent(v1, v2, tol, tol);
00375 }
00376
00378 template<typename T>
00379 inline
00380 T
00381 dist(const SGVec4<T>& v1, const SGVec4<T>& v2)
00382 { return norm(v1 - v2); }
00383
00385 template<typename T>
00386 inline
00387 T
00388 distSqr(const SGVec4<T>& v1, const SGVec4<T>& v2)
00389 { SGVec4<T> tmp = v1 - v2; return dot(tmp, tmp); }
00390
00391
00392 template<typename T>
00393 inline
00394 SGVec4<T>
00395 projection(const SGVec4<T>& u, const SGVec4<T>& d)
00396 {
00397 T denom = dot(d, d);
00398 T ud = dot(u, d);
00399 if (SGLimits<T>::min() < denom) return u;
00400 else return d * (dot(u, d) / denom);
00401 }
00402
00403 #ifndef NDEBUG
00404 template<typename T>
00405 inline
00406 bool
00407 isNaN(const SGVec4<T>& v)
00408 {
00409 return SGMisc<T>::isNaN(v(0)) || SGMisc<T>::isNaN(v(1))
00410 || SGMisc<T>::isNaN(v(2)) || SGMisc<T>::isNaN(v(3));
00411 }
00412 #endif
00413
00415 template<typename char_type, typename traits_type, typename T>
00416 inline
00417 std::basic_ostream<char_type, traits_type>&
00418 operator<<(std::basic_ostream<char_type, traits_type>& s, const SGVec4<T>& v)
00419 { return s << "[ " << v(0) << ", " << v(1) << ", " << v(2) << ", " << v(3) << " ]"; }
00420
00421 inline
00422 SGVec4f
00423 toVec4f(const SGVec4d& v)
00424 { return SGVec4f((float)v(0), (float)v(1), (float)v(2), (float)v(3)); }
00425
00426 inline
00427 SGVec4d
00428 toVec4d(const SGVec4f& v)
00429 { return SGVec4d(v(0), v(1), v(2), v(3)); }
00430
00431 #ifndef NO_OPENSCENEGRAPH_INTERFACE
00432 inline
00433 SGVec4d
00434 toSG(const osg::Vec4d& v)
00435 { return SGVec4d(v[0], v[1], v[2], v[3]); }
00436
00437 inline
00438 SGVec4f
00439 toSG(const osg::Vec4f& v)
00440 { return SGVec4f(v[0], v[1], v[2], v[3]); }
00441
00442 inline
00443 osg::Vec4d
00444 toOsg(const SGVec4d& v)
00445 { return osg::Vec4d(v[0], v[1], v[2], v[3]); }
00446
00447 inline
00448 osg::Vec4f
00449 toOsg(const SGVec4f& v)
00450 { return osg::Vec4f(v[0], v[1], v[2], v[3]); }
00451 #endif
00452
00453 #endif