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 #ifndef __UT_Vector4_h__
00027 #define __UT_Vector4_h__
00028
00029 #include "UT_API.h"
00030 #include <math.h>
00031 #include <limits>
00032 #include <iostream.h>
00033 #include "UT_Assert.h"
00034 #include "UT_Math.h"
00035 #include <vector>
00036
00037 #include "UT_VectorTypes.h"
00038
00039 class UT_IStream;
00040 class UT_JSONWriter;
00041 class UT_JSONValue;
00042 class UT_JSONParser;
00043
00044
00045
00046
00047
00048
00049
00050
00051 template <typename T, typename S>
00052 inline UT_Vector4T<T> operator*(const UT_Vector4T<T> &v, const UT_Matrix4T<S> &m);
00053 template <typename T>
00054 inline UT_Vector4T<T> operator+(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2);
00055 template <typename T>
00056 inline UT_Vector4T<T> operator-(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2);
00057 template <typename T, typename S>
00058 inline UT_Vector4T<T> operator+(const UT_Vector4T<T> &v, S scalar);
00059 template <typename T, typename S>
00060 inline UT_Vector4T<T> operator-(const UT_Vector4T<T> &v, S scalar);
00061 template <typename T, typename S>
00062 inline UT_Vector4T<T> operator*(const UT_Vector4T<T> &v, S scalar);
00063 template <typename T, typename S>
00064 inline UT_Vector4T<T> operator/(const UT_Vector4T<T> &v, S scalar);
00065 template <typename T, typename S>
00066 inline UT_Vector4T<T> operator+(S scalar, const UT_Vector4T<T> &v);
00067 template <typename T, typename S>
00068 inline UT_Vector4T<T> operator-(S scalar, const UT_Vector4T<T> &v);
00069 template <typename T, typename S>
00070 inline UT_Vector4T<T> operator*(S scalar, const UT_Vector4T<T> &v);
00071 template <typename T, typename S>
00072 inline UT_Vector4T<T> operator/(S scalar, const UT_Vector4T<T> &v);
00073
00074
00075
00076
00077 template <typename T>
00078 UT_API UT_Vector3T<T> cross(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2);
00079 template <typename T>
00080 UT_API UT_Vector3T<T> cross(const UT_Vector3T<T> &v1, const UT_Vector4T<T> &v2);
00081 template <typename T>
00082 UT_API UT_Vector3T<T> cross(const UT_Vector4T<T> &v1, const UT_Vector3T<T> &v2);
00083
00084
00085
00086 template <typename T>
00087 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2);
00088 template <typename T>
00089 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector3T<T> &v2);
00090 template <typename T>
00091 inline T dot(const UT_Vector3T<T> &v1, const UT_Vector4T<T> &v2);
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 template <typename T, typename S>
00112 UT_API UT_Vector4T<T> rowVecMult(const UT_Vector4T<T> &v, const UT_Matrix4T<S> &m);
00113 template <typename T, typename S>
00114 UT_API UT_Vector4T<T> colVecMult(const UT_Matrix4T<S> &m, const UT_Vector4T<T> &v);
00115
00116 template <typename T, typename S>
00117 UT_API UT_Vector4T<T> rowVecMult3(const UT_Vector4T<T> &v, const UT_Matrix4T<S> &m);
00118 template <typename T, typename S>
00119 UT_API UT_Vector4T<T> colVecMult3(const UT_Matrix4T<S> &m, const UT_Vector4T<T> &v);
00120
00121
00122
00123
00124 template <typename T>
00125 inline T distance4(const UT_Vector4T<T> &p1, const UT_Vector4T<T> &p2);
00126 template <typename T>
00127 inline T distance3(const UT_Vector4T<T> &p1, const UT_Vector4T<T> &p2);
00128 template <typename T>
00129 inline T distance3d(const UT_Vector4T<T> &p1, const UT_Vector4T<T> &p2)
00130 { return distance3(p1, p2); }
00131 template <typename T>
00132 inline T distance3d(const UT_Vector3T<T> &p1, const UT_Vector4T<T> &p2)
00133 { return distance3d(p1, UT_Vector3T<T>(p2)); }
00134 template <typename T>
00135 inline T distance3d(const UT_Vector4T<T> &p1, const UT_Vector3T<T> &p2)
00136 { return distance3d(UT_Vector3T<T>(p1), p2); }
00137
00138
00139
00140 template <typename T>
00141 class UT_API UT_Vector4T
00142 {
00143 public:
00144
00145 typedef T value_type;
00146 static const int tuple_size = 4;
00147
00148
00149
00150 inline UT_Vector4T(void)
00151 {
00152 }
00153 inline UT_Vector4T(T vx, T vy, T vz, T vw = 1.0f)
00154 {
00155 vec[0] = vx; vec[1] = vy; vec[2] = vz; vec[3] = vw;
00156 }
00157 inline UT_Vector4T(const fpreal32 v[tuple_size])
00158 {
00159 vec[0] = v[0]; vec[1] = v[1]; vec[2] = v[2]; vec[3] = v[3];
00160 }
00161 inline UT_Vector4T(const fpreal64 v[tuple_size])
00162 {
00163 vec[0] = v[0]; vec[1] = v[1]; vec[2] = v[2]; vec[3] = v[3];
00164 }
00165 inline
00166 explicit UT_Vector4T(const UT_Vector3T<T> &v, T w = 1.f);
00167
00168 template <typename S>
00169 inline UT_Vector4T(const UT_Vector4T<S> &v)
00170 { vec[0] = v.x(); vec[1] = v.y(); vec[2] = v.z(); vec[3] = v.w(); }
00171
00172
00173 template <typename S>
00174 inline UT_Vector4T<T> &operator=(const UT_Vector4T<S> &v)
00175 { vec[0] = v.x(); vec[1] = v.y(); vec[2] = v.z(); vec[3] = v.w();
00176 return *this; }
00177
00178
00179
00180
00181
00182
00183
00184
00185 UT_Vector4T<T> &operator=(const UT_Vector3T<T> &v);
00186
00187
00188
00189
00190
00191
00192 inline
00193 UT_Vector4T<T> &operator+=(const UT_Vector4T<T> &v)
00194 {
00195 vec[0] += v.vec[0];
00196 vec[1] += v.vec[1];
00197 vec[2] += v.vec[2];
00198 vec[3] += v.vec[3];
00199 return *this;
00200 }
00201 inline
00202 UT_Vector4T<T> &operator-=(const UT_Vector4T<T> &v)
00203 {
00204 vec[0] -= v.vec[0];
00205 vec[1] -= v.vec[1];
00206 vec[2] -= v.vec[2];
00207 vec[3] -= v.vec[3];
00208 return *this;
00209 }
00210 unsigned operator==(const UT_Vector4T<T> &v) const
00211 {
00212 return (vec[0] == v.vec[0] && vec[1] == v.vec[1] &&
00213 vec[2] == v.vec[2] && vec[3] == v.vec[3] );
00214
00215 }
00216 unsigned operator!=(const UT_Vector4T<T> &v) const
00217 { return !(*this == v); }
00218 int equalZero(T tol = 0.00001f) const
00219 {
00220 return (vec[0] >= -tol && vec[0] <= tol) &&
00221 (vec[1] >= -tol && vec[1] <= tol) &&
00222 (vec[2] >= -tol && vec[2] <= tol) &&
00223 (vec[3] >= -tol && vec[3] <= tol);
00224 }
00225 int equalZero3(T tol = 0.00001f) const
00226 {
00227 return (vec[0] >= -tol && vec[0] <= tol) &&
00228 (vec[1] >= -tol && vec[1] <= tol) &&
00229 (vec[2] >= -tol && vec[2] <= tol);
00230 }
00231
00232 void clampZero(T tol = 0.00001f)
00233 {
00234 if (vec[0] >= -tol && vec[0] <= tol) vec[0] = 0;
00235 if (vec[1] >= -tol && vec[1] <= tol) vec[1] = 0;
00236 if (vec[2] >= -tol && vec[2] <= tol) vec[2] = 0;
00237 if (vec[3] >= -tol && vec[3] <= tol) vec[3] = 0;
00238 }
00239
00240 void clampZero3(T tol = 0.00001f)
00241 {
00242 if (vec[0] >= -tol && vec[0] <= tol) vec[0] = 0;
00243 if (vec[1] >= -tol && vec[1] <= tol) vec[1] = 0;
00244 if (vec[2] >= -tol && vec[2] <= tol) vec[2] = 0;
00245 }
00246
00247 void negate3()
00248 { vec[0]= -vec[0]; vec[1]= -vec[1]; vec[2]= -vec[2]; }
00249 void negate() { vec[0]= -vec[0]; vec[1]= -vec[1]; vec[2]= -vec[2];
00250 vec[3] = -vec[3]; }
00251
00252 void multiplyComponents(const UT_Vector4T<T> &v)
00253 {
00254 vec[0] *= v.vec[0];
00255 vec[1] *= v.vec[1];
00256 vec[2] *= v.vec[2];
00257 vec[3] *= v.vec[3];
00258 }
00259
00260 int isEqual(const UT_Vector4T<T> &v, T tol = 0.00001f) const
00261 {
00262 return ((vec[0]>=v.vec[0]-tol) && (vec[0]<=v.vec[0]+tol) &&
00263 (vec[1]>=v.vec[1]-tol) && (vec[1]<=v.vec[1]+tol) &&
00264 (vec[2]>=v.vec[2]-tol) && (vec[2]<=v.vec[2]+tol) &&
00265 (vec[3]>=v.vec[3]-tol) && (vec[3]<=v.vec[3]+tol));
00266 }
00267 inline int isEqual(const UT_Vector3T<T> &vect, T tol = 0.00001f) const;
00268
00269 bool isNan() const
00270 { return SYSisNan(vec[0]) || SYSisNan(vec[1]) || SYSisNan(vec[2]) || SYSisNan(vec[3]); }
00271
00272
00273
00274
00275
00276
00277 template <typename S>
00278 inline void rowVecMult(const UT_Matrix4T<S> &m)
00279 { operator=(::rowVecMult(*this, m)); }
00280 template <typename S>
00281 inline void colVecMult(const UT_Matrix4T<S> &m)
00282 { operator=(::colVecMult(m, *this)); }
00283
00284
00285
00286
00287
00288
00289
00290 template <typename S>
00291 void rowVecMult3(const UT_Matrix4T<S> &m)
00292 { operator=(::rowVecMult3(*this, m)); }
00293
00294
00295
00296
00297
00298
00299
00300 template <typename S>
00301 inline
00302 UT_Vector4T<T> &operator*=(const UT_Matrix4T<S> &mat)
00303 { rowVecMult(mat); return *this; }
00304
00305 template <typename S>
00306 inline void multiply3(const UT_Matrix4T<S> &mat)
00307 { rowVecMult3(mat); }
00308 template <typename S>
00309 inline void multiply3(UT_Vector4T<T> &dest, const UT_Matrix4T<S> &mat) const
00310 { dest = ::rowVecMult3(*this, mat); }
00311
00312
00313 UT_Vector4T<T> &operator=(T scalar)
00314 {
00315 vec[0] = vec[1] = vec[2] = vec[3] = scalar;
00316 return *this;
00317 }
00318 UT_Vector4T<T> &operator+=(T scalar)
00319 {
00320 vec[0] += scalar; vec[1] += scalar;
00321 vec[2] += scalar; vec[3] += scalar;
00322 return *this;
00323 }
00324 UT_Vector4T<T> &operator-=(T scalar)
00325 {
00326 return operator+=(-scalar);
00327 }
00328 inline
00329 UT_Vector4T<T> &operator*=(T scalar)
00330 {
00331 vec[0] *= scalar; vec[1] *= scalar;
00332 vec[2] *= scalar; vec[3] *= scalar;
00333 return *this;
00334 }
00335 inline
00336 UT_Vector4T<T> &operator*=(const UT_Vector4T<T> &v)
00337 {
00338 vec[0] *= v.vec[0];
00339 vec[1] *= v.vec[1];
00340 vec[2] *= v.vec[2];
00341 vec[3] *= v.vec[3];
00342 return *this;
00343 }
00344 inline
00345 UT_Vector4T<T> &operator/=(T scalar)
00346 {
00347 return operator*=( 1.0f/scalar );
00348 }
00349 inline
00350 UT_Vector4T<T> &operator/=(const UT_Vector4T<T> &v)
00351 {
00352 vec[0] /= v.vec[0];
00353 vec[1] /= v.vec[1];
00354 vec[2] /= v.vec[2];
00355 vec[3] /= v.vec[3];
00356 return *this;
00357 }
00358
00359 T maxComponent() const
00360 {
00361 T m = vec[0];
00362 if (vec[1] > m) m = vec[1];
00363 if (vec[2] > m) m = vec[2];
00364 if (vec[3] > m) m = vec[3];
00365 return m;
00366 }
00367 T minComponent() const
00368 {
00369 T m = vec[0];
00370 if (vec[1] < m) m = vec[1];
00371 if (vec[2] < m) m = vec[2];
00372 if (vec[3] < m) m = vec[3];
00373 return m;
00374 }
00375 T avgComponent() const
00376 {
00377 return (vec[0]+vec[1]+vec[2]+vec[3])*0.25F;
00378 }
00379
00380
00381
00382 int findMinAbsAxis() const
00383 {
00384 if (SYSabs(x()) < SYSabs(y()))
00385 if (SYSabs(z()) < SYSabs(x()))
00386 if (SYSabs(w()) < SYSabs(z()))
00387 return 3;
00388 else
00389 return 2;
00390 else
00391 if (SYSabs(w()) < SYSabs(x()))
00392 return 3;
00393 else
00394 return 0;
00395 else
00396 if (SYSabs(z()) < SYSabs(y()))
00397 if (SYSabs(w()) < SYSabs(z()))
00398 return 3;
00399 else
00400 return 2;
00401 else
00402 if (SYSabs(w()) < SYSabs(y()))
00403 return 3;
00404 else
00405 return 1;
00406 }
00407 int findMaxAbsAxis() const
00408 {
00409 if (SYSabs(x()) >= SYSabs(y()))
00410 if (SYSabs(z()) >= SYSabs(x()))
00411 if (SYSabs(w()) >= SYSabs(z()))
00412 return 3;
00413 else
00414 return 2;
00415 else
00416 if (SYSabs(w()) >= SYSabs(x()))
00417 return 3;
00418 else
00419 return 0;
00420 else
00421 if (SYSabs(z()) >= SYSabs(y()))
00422 if (SYSabs(w()) >= SYSabs(z()))
00423 return 3;
00424 else
00425 return 2;
00426 else
00427 if (SYSabs(w()) >= SYSabs(y()))
00428 return 3;
00429 else
00430 return 1;
00431 }
00432
00433
00434 inline
00435 T dot(const UT_Vector4T<T> &v) const
00436 {
00437 return ::dot(*this, v);
00438 }
00439 void normalize (void)
00440 {
00441 T dn = vec[0]*vec[0] + vec[1]*vec[1] +
00442 vec[2]*vec[2] + vec[3]*vec[3];
00443 if (dn > std::numeric_limits<T>::min())
00444 (*this) *= (((T)1.)/SYSsqrt(dn) );
00445 }
00446
00447
00448 inline
00449 T length(void) const
00450 { return SYSsqrt(dot(*this)); }
00451
00452 inline
00453 T length2(void) const
00454 { return dot(*this); }
00455
00456
00457
00458
00459 const T *data(void) const { return &vec[0]; }
00460 T *data(void) { return &vec[0]; }
00461 inline T &x(void) { return vec[0]; }
00462 inline T x(void) const { return vec[0]; }
00463 inline T &y(void) { return vec[1]; }
00464 inline T y(void) const { return vec[1]; }
00465 inline T &z(void) { return vec[2]; }
00466 inline T z(void) const { return vec[2]; }
00467 inline T &w(void) { return vec[3]; }
00468 inline T w(void) const { return vec[3]; }
00469 inline T &operator()(unsigned i)
00470 {
00471 UT_ASSERT_P(i < tuple_size);
00472 return vec[i];
00473 }
00474 inline T operator()(unsigned i) const
00475 {
00476 UT_ASSERT_P(i < tuple_size);
00477 return vec[i];
00478 }
00479 inline T &operator[](unsigned i)
00480 {
00481 UT_ASSERT_P(i < tuple_size);
00482 return vec[i];
00483 }
00484 inline T operator[](unsigned i) const
00485 {
00486 UT_ASSERT_P(i < tuple_size);
00487 return vec[i];
00488 }
00489 std::vector<T> asStdVector() const;
00490
00491
00492
00493 unsigned hash() const { return SYSvector_hash(data(), tuple_size); }
00494
00495
00496
00497
00498 void assign(T xx = 0.0f, T yy = 0.0f, T zz = 0.0f,
00499 T ww = 1.0f)
00500 {
00501 vec[0] = xx; vec[1] = yy; vec[2] = zz; vec[3] = ww;
00502 }
00503
00504 void assign(const T *v, int size = tuple_size)
00505 {
00506 vec[0] = v[0];
00507 vec[1] = v[1];
00508 vec[2] = v[2];
00509 if (size == tuple_size) vec[3] = v[3];
00510 }
00511
00512
00513
00514 void homogenize(void)
00515 {
00516 vec[0] *= vec[3];
00517 vec[1] *= vec[3];
00518 vec[2] *= vec[3];
00519 }
00520 void dehomogenize(void)
00521 {
00522 if (vec[3] != 0)
00523 {
00524 T denom = 1.0f / vec[3];
00525 vec[0] *= denom;
00526 vec[1] *= denom;
00527 vec[2] *= denom;
00528 }
00529 }
00530
00531
00532 void save(ostream &os, int binary=0) const;
00533 bool load(UT_IStream &is);
00534
00535
00536
00537
00538 bool save(UT_JSONWriter &w) const;
00539 bool save(UT_JSONValue &v) const;
00540 bool load(UT_JSONParser &p);
00541
00542
00543
00544 static int entries() { return tuple_size; }
00545
00546 private:
00547
00548
00549 friend ostream &operator<<(ostream &os, const UT_Vector4T<T> &v)
00550 {
00551 v.save(os);
00552 return os;
00553 }
00554
00555
00556
00557 T vec[tuple_size];
00558 };
00559
00560 #include "UT_Vector3.h"
00561
00562 template <typename T>
00563 inline UT_Vector4T<T>::UT_Vector4T(const UT_Vector3T<T> &v, T vw)
00564 {
00565 vec[0] = v.x();
00566 vec[1] = v.y();
00567 vec[2] = v.z();
00568 vec[3] = vw;
00569 }
00570
00571 template <typename T>
00572 inline int
00573 UT_Vector4T<T>::isEqual(const UT_Vector3T<T> &vect, T tol) const
00574 {
00575 return ((vec[0]>=vect.x()-tol) && (vec[0]<=vect.x()+tol) &&
00576 (vec[1]>=vect.y()-tol) && (vec[1]<=vect.y()+tol) &&
00577 (vec[2]>=vect.z()-tol) && (vec[2]<=vect.z()+tol));
00578 }
00579
00580
00581 template <typename T>
00582 inline UT_Vector4T<T> operator+(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
00583 {
00584 return UT_Vector4T<T>(v1.x()+v2.x(), v1.y()+v2.y(),
00585 v1.z()+v2.z(), v1.w()+v2.w());
00586 }
00587 template <typename T>
00588 inline UT_Vector3T<T> operator+(const UT_Vector4T<T> &v1, const UT_Vector3T<T> &v2)
00589 {
00590 return UT_Vector3T<T>(v1.x()+v2.x(), v1.y()+v2.y(),
00591 v1.z()+v2.z());
00592 }
00593 template <typename T>
00594 inline UT_Vector3T<T> operator+(const UT_Vector3T<T> &v1, const UT_Vector4T<T> &v2)
00595 {
00596 return UT_Vector3T<T>(v1.x()+v2.x(), v1.y()+v2.y(),
00597 v1.z()+v2.z());
00598 }
00599 template <typename T>
00600 inline UT_Vector4T<T> operator-(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
00601 {
00602 return UT_Vector4T<T>(v1.x()-v2.x(), v1.y()-v2.y(),
00603 v1.z()-v2.z(), v1.w()-v2.w());
00604 }
00605 template <typename T>
00606 inline UT_Vector3T<T> operator-(const UT_Vector4T<T> &v1, const UT_Vector3T<T> &v2)
00607 {
00608 return UT_Vector3T<T>(v1.x()-v2.x(), v1.y()-v2.y(),
00609 v1.z()-v2.z());
00610 }
00611 template <typename T>
00612 inline UT_Vector3T<T> operator-(const UT_Vector3T<T> &v1, const UT_Vector4T<T> &v2)
00613 {
00614 return UT_Vector3T<T>(v1.x()-v2.x(), v1.y()-v2.y(),
00615 v1.z()-v2.z());
00616 }
00617 template <typename T>
00618 inline UT_Vector4T<T> operator*(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
00619 {
00620 return UT_Vector4T<T>(v1.x()*v2.x(), v1.y()*v2.y(), v1.z()*v2.z(), v1.w()*v2.w());
00621 }
00622
00623 template <typename T>
00624 inline UT_Vector4T<T> operator/(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
00625 {
00626 return UT_Vector4T<T>(v1.x()/v2.x(), v1.y()/v2.y(), v1.z()/v2.z(), v1.w()/v2.w());
00627 }
00628
00629 template <typename T, typename S>
00630 inline UT_Vector4T<T> operator+(const UT_Vector4T<T> &v, S scalar)
00631 {
00632 return UT_Vector4T<T>(v.x()+scalar, v.y()+scalar, v.z()+scalar, v.w()+scalar);
00633 }
00634 template <typename T, typename S>
00635 inline UT_Vector4T<T> operator+(S scalar, const UT_Vector4T<T> &v)
00636 {
00637 return UT_Vector4T<T>(v.x()+scalar, v.y()+scalar, v.z()+scalar, v.w()+scalar);
00638 }
00639 template <typename T, typename S>
00640 inline UT_Vector4T<T> operator-(const UT_Vector4T<T> &v, S scalar)
00641 {
00642 return UT_Vector4T<T>(v.x()-scalar, v.y()-scalar, v.z()-scalar, v.w()-scalar);
00643 }
00644 template <typename T, typename S>
00645 inline UT_Vector4T<T> operator-(S scalar, const UT_Vector4T<T> &v)
00646 {
00647 return UT_Vector4T<T>(scalar-v.x(), scalar-v.y(), scalar-v.z(), v.w()-scalar);
00648 }
00649 template <typename T, typename S>
00650 inline UT_Vector4T<T> operator*(const UT_Vector4T<T> &v, S scalar)
00651 {
00652 return UT_Vector4T<T>(v.x()*scalar, v.y()*scalar, v.z()*scalar, v.w()*scalar);
00653 }
00654 template <typename T, typename S>
00655 inline UT_Vector4T<T> operator*(S scalar, const UT_Vector4T<T> &v)
00656 {
00657 return UT_Vector4T<T>(v.x()*scalar, v.y()*scalar, v.z()*scalar, v.w()*scalar);
00658 }
00659 template <typename T, typename S>
00660 inline UT_Vector4T<T> operator/(const UT_Vector4T<T> &v, S scalar)
00661 {
00662
00663
00664 T inv = ((T)1) / scalar;
00665 return UT_Vector4T<T>(v.x()*inv, v.y()*inv, v.z()*inv, v.w()*inv);
00666 }
00667 template <typename T, typename S>
00668 inline UT_Vector4T<T> operator/(S scalar, const UT_Vector4T<T> &v)
00669 {
00670 return UT_Vector4T<T>(scalar/v.x(), scalar/v.y(), scalar/v.z(), scalar/v.w());
00671 }
00672 template <typename T>
00673 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
00674 {
00675 return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z() + v1.w()*v2.w();
00676 }
00677 template <typename T>
00678 inline T dot(const UT_Vector4T<T> &v1, const UT_Vector3T<T> &v2)
00679 {
00680 return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z();
00681 }
00682 template <typename T>
00683 inline T dot(const UT_Vector3T<T> &v1, const UT_Vector4T<T> &v2)
00684 {
00685 return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z();
00686 }
00687
00688 template <typename T, typename S>
00689 inline UT_Vector4T<T> operator*(const UT_Vector4T<T> &v, const UT_Matrix4T<S> &m)
00690 {
00691 return rowVecMult(v, m);
00692 }
00693 template <typename T>
00694 inline T distance(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
00695 {
00696 T x = v1.x()-v2.x();
00697 T y = v1.y()-v2.y();
00698 T z = v1.z()-v2.z();
00699 T w = v1.w()-v2.w();
00700 return SYSsqrt(x*x + y*y + z*z + w*w);
00701 }
00702 template <typename T>
00703 inline T distance3(const UT_Vector4T<T> &v1, const UT_Vector4T<T> &v2)
00704 {
00705 T x = v1.x()-v2.x();
00706 T y = v1.y()-v2.y();
00707 T z = v1.z()-v2.z();
00708 return SYSsqrt(x*x + y*y + z*z);
00709 }
00710
00711 #endif