PBRT
|
00001 00002 // 00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 00004 // Digital Ltd. LLC 00005 // 00006 // All rights reserved. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are 00010 // met: 00011 // * Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // * Redistributions in binary form must reproduce the above 00014 // copyright notice, this list of conditions and the following disclaimer 00015 // in the documentation and/or other materials provided with the 00016 // distribution. 00017 // * Neither the name of Industrial Light & Magic nor the names of 00018 // its contributors may be used to endorse or promote products derived 00019 // from this software without specific prior written permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00034 00035 00036 00037 #ifndef INCLUDED_IMATHVEC_H 00038 #define INCLUDED_IMATHVEC_H 00039 00040 //---------------------------------------------------- 00041 // 00042 // 2D, 3D and 4D point/vector class templates 00043 // 00044 //---------------------------------------------------- 00045 00046 #include "ImathExc.h" 00047 #include "ImathLimits.h" 00048 #include "ImathMath.h" 00049 00050 #include <iostream> 00051 00052 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER 00053 // suppress exception specification warnings 00054 #pragma warning(push) 00055 #pragma warning(disable:4290) 00056 #endif 00057 00058 00059 namespace Imath { 00060 00061 template <class T> class Vec2; 00062 template <class T> class Vec3; 00063 template <class T> class Vec4; 00064 00065 enum InfException {INF_EXCEPTION}; 00066 00067 00068 template <class T> class Vec2 00069 { 00070 public: 00071 00072 //------------------- 00073 // Access to elements 00074 //------------------- 00075 00076 T x, y; 00077 00078 T & operator [] (int i); 00079 const T & operator [] (int i) const; 00080 00081 00082 //------------- 00083 // Constructors 00084 //------------- 00085 00086 Vec2 (); // no initialization 00087 explicit Vec2 (T a); // (a a) 00088 Vec2 (T a, T b); // (a b) 00089 00090 00091 //--------------------------------- 00092 // Copy constructors and assignment 00093 //--------------------------------- 00094 00095 Vec2 (const Vec2 &v); 00096 template <class S> Vec2 (const Vec2<S> &v); 00097 00098 const Vec2 & operator = (const Vec2 &v); 00099 00100 00101 //---------------------- 00102 // Compatibility with Sb 00103 //---------------------- 00104 00105 template <class S> 00106 void setValue (S a, S b); 00107 00108 template <class S> 00109 void setValue (const Vec2<S> &v); 00110 00111 template <class S> 00112 void getValue (S &a, S &b) const; 00113 00114 template <class S> 00115 void getValue (Vec2<S> &v) const; 00116 00117 T * getValue (); 00118 const T * getValue () const; 00119 00120 00121 //--------- 00122 // Equality 00123 //--------- 00124 00125 template <class S> 00126 bool operator == (const Vec2<S> &v) const; 00127 00128 template <class S> 00129 bool operator != (const Vec2<S> &v) const; 00130 00131 00132 //----------------------------------------------------------------------- 00133 // Compare two vectors and test if they are "approximately equal": 00134 // 00135 // equalWithAbsError (v, e) 00136 // 00137 // Returns true if the coefficients of this and v are the same with 00138 // an absolute error of no more than e, i.e., for all i 00139 // 00140 // abs (this[i] - v[i]) <= e 00141 // 00142 // equalWithRelError (v, e) 00143 // 00144 // Returns true if the coefficients of this and v are the same with 00145 // a relative error of no more than e, i.e., for all i 00146 // 00147 // abs (this[i] - v[i]) <= e * abs (this[i]) 00148 //----------------------------------------------------------------------- 00149 00150 bool equalWithAbsError (const Vec2<T> &v, T e) const; 00151 bool equalWithRelError (const Vec2<T> &v, T e) const; 00152 00153 //------------ 00154 // Dot product 00155 //------------ 00156 00157 T dot (const Vec2 &v) const; 00158 T operator ^ (const Vec2 &v) const; 00159 00160 00161 //------------------------------------------------ 00162 // Right-handed cross product, i.e. z component of 00163 // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0) 00164 //------------------------------------------------ 00165 00166 T cross (const Vec2 &v) const; 00167 T operator % (const Vec2 &v) const; 00168 00169 00170 //------------------------ 00171 // Component-wise addition 00172 //------------------------ 00173 00174 const Vec2 & operator += (const Vec2 &v); 00175 Vec2 operator + (const Vec2 &v) const; 00176 00177 00178 //--------------------------- 00179 // Component-wise subtraction 00180 //--------------------------- 00181 00182 const Vec2 & operator -= (const Vec2 &v); 00183 Vec2 operator - (const Vec2 &v) const; 00184 00185 00186 //------------------------------------ 00187 // Component-wise multiplication by -1 00188 //------------------------------------ 00189 00190 Vec2 operator - () const; 00191 const Vec2 & negate (); 00192 00193 00194 //------------------------------ 00195 // Component-wise multiplication 00196 //------------------------------ 00197 00198 const Vec2 & operator *= (const Vec2 &v); 00199 const Vec2 & operator *= (T a); 00200 Vec2 operator * (const Vec2 &v) const; 00201 Vec2 operator * (T a) const; 00202 00203 00204 //------------------------ 00205 // Component-wise division 00206 //------------------------ 00207 00208 const Vec2 & operator /= (const Vec2 &v); 00209 const Vec2 & operator /= (T a); 00210 Vec2 operator / (const Vec2 &v) const; 00211 Vec2 operator / (T a) const; 00212 00213 00214 //---------------------------------------------------------------- 00215 // Length and normalization: If v.length() is 0.0, v.normalize() 00216 // and v.normalized() produce a null vector; v.normalizeExc() and 00217 // v.normalizedExc() throw a NullVecExc. 00218 // v.normalizeNonNull() and v.normalizedNonNull() are slightly 00219 // faster than the other normalization routines, but if v.length() 00220 // is 0.0, the result is undefined. 00221 //---------------------------------------------------------------- 00222 00223 T length () const; 00224 T length2 () const; 00225 00226 const Vec2 & normalize (); // modifies *this 00227 const Vec2 & normalizeExc () throw (Iex::MathExc); 00228 const Vec2 & normalizeNonNull (); 00229 00230 Vec2<T> normalized () const; // does not modify *this 00231 Vec2<T> normalizedExc () const throw (Iex::MathExc); 00232 Vec2<T> normalizedNonNull () const; 00233 00234 00235 //-------------------------------------------------------- 00236 // Number of dimensions, i.e. number of elements in a Vec2 00237 //-------------------------------------------------------- 00238 00239 static unsigned int dimensions() {return 2;} 00240 00241 00242 //------------------------------------------------- 00243 // Limitations of type T (see also class limits<T>) 00244 //------------------------------------------------- 00245 00246 static T baseTypeMin() {return limits<T>::min();} 00247 static T baseTypeMax() {return limits<T>::max();} 00248 static T baseTypeSmallest() {return limits<T>::smallest();} 00249 static T baseTypeEpsilon() {return limits<T>::epsilon();} 00250 00251 00252 //-------------------------------------------------------------- 00253 // Base type -- in templates, which accept a parameter, V, which 00254 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 00255 // refer to T as V::BaseType 00256 //-------------------------------------------------------------- 00257 00258 typedef T BaseType; 00259 00260 private: 00261 00262 T lengthTiny () const; 00263 }; 00264 00265 00266 template <class T> class Vec3 00267 { 00268 public: 00269 00270 //------------------- 00271 // Access to elements 00272 //------------------- 00273 00274 T x, y, z; 00275 00276 T & operator [] (int i); 00277 const T & operator [] (int i) const; 00278 00279 00280 //------------- 00281 // Constructors 00282 //------------- 00283 00284 Vec3 (); // no initialization 00285 explicit Vec3 (T a); // (a a a) 00286 Vec3 (T a, T b, T c); // (a b c) 00287 00288 00289 //--------------------------------- 00290 // Copy constructors and assignment 00291 //--------------------------------- 00292 00293 Vec3 (const Vec3 &v); 00294 template <class S> Vec3 (const Vec3<S> &v); 00295 00296 const Vec3 & operator = (const Vec3 &v); 00297 00298 00299 //--------------------------------------------------------- 00300 // Vec4 to Vec3 conversion, divides x, y and z by w: 00301 // 00302 // The one-argument conversion function divides by w even 00303 // if w is zero. The result depends on how the environment 00304 // handles floating-point exceptions. 00305 // 00306 // The two-argument version thows an InfPointExc exception 00307 // if w is zero or if division by w would overflow. 00308 //--------------------------------------------------------- 00309 00310 template <class S> explicit Vec3 (const Vec4<S> &v); 00311 template <class S> explicit Vec3 (const Vec4<S> &v, InfException); 00312 00313 00314 //---------------------- 00315 // Compatibility with Sb 00316 //---------------------- 00317 00318 template <class S> 00319 void setValue (S a, S b, S c); 00320 00321 template <class S> 00322 void setValue (const Vec3<S> &v); 00323 00324 template <class S> 00325 void getValue (S &a, S &b, S &c) const; 00326 00327 template <class S> 00328 void getValue (Vec3<S> &v) const; 00329 00330 T * getValue(); 00331 const T * getValue() const; 00332 00333 00334 //--------- 00335 // Equality 00336 //--------- 00337 00338 template <class S> 00339 bool operator == (const Vec3<S> &v) const; 00340 00341 template <class S> 00342 bool operator != (const Vec3<S> &v) const; 00343 00344 //----------------------------------------------------------------------- 00345 // Compare two vectors and test if they are "approximately equal": 00346 // 00347 // equalWithAbsError (v, e) 00348 // 00349 // Returns true if the coefficients of this and v are the same with 00350 // an absolute error of no more than e, i.e., for all i 00351 // 00352 // abs (this[i] - v[i]) <= e 00353 // 00354 // equalWithRelError (v, e) 00355 // 00356 // Returns true if the coefficients of this and v are the same with 00357 // a relative error of no more than e, i.e., for all i 00358 // 00359 // abs (this[i] - v[i]) <= e * abs (this[i]) 00360 //----------------------------------------------------------------------- 00361 00362 bool equalWithAbsError (const Vec3<T> &v, T e) const; 00363 bool equalWithRelError (const Vec3<T> &v, T e) const; 00364 00365 //------------ 00366 // Dot product 00367 //------------ 00368 00369 T dot (const Vec3 &v) const; 00370 T operator ^ (const Vec3 &v) const; 00371 00372 00373 //--------------------------- 00374 // Right-handed cross product 00375 //--------------------------- 00376 00377 Vec3 cross (const Vec3 &v) const; 00378 const Vec3 & operator %= (const Vec3 &v); 00379 Vec3 operator % (const Vec3 &v) const; 00380 00381 00382 //------------------------ 00383 // Component-wise addition 00384 //------------------------ 00385 00386 const Vec3 & operator += (const Vec3 &v); 00387 Vec3 operator + (const Vec3 &v) const; 00388 00389 00390 //--------------------------- 00391 // Component-wise subtraction 00392 //--------------------------- 00393 00394 const Vec3 & operator -= (const Vec3 &v); 00395 Vec3 operator - (const Vec3 &v) const; 00396 00397 00398 //------------------------------------ 00399 // Component-wise multiplication by -1 00400 //------------------------------------ 00401 00402 Vec3 operator - () const; 00403 const Vec3 & negate (); 00404 00405 00406 //------------------------------ 00407 // Component-wise multiplication 00408 //------------------------------ 00409 00410 const Vec3 & operator *= (const Vec3 &v); 00411 const Vec3 & operator *= (T a); 00412 Vec3 operator * (const Vec3 &v) const; 00413 Vec3 operator * (T a) const; 00414 00415 00416 //------------------------ 00417 // Component-wise division 00418 //------------------------ 00419 00420 const Vec3 & operator /= (const Vec3 &v); 00421 const Vec3 & operator /= (T a); 00422 Vec3 operator / (const Vec3 &v) const; 00423 Vec3 operator / (T a) const; 00424 00425 00426 //---------------------------------------------------------------- 00427 // Length and normalization: If v.length() is 0.0, v.normalize() 00428 // and v.normalized() produce a null vector; v.normalizeExc() and 00429 // v.normalizedExc() throw a NullVecExc. 00430 // v.normalizeNonNull() and v.normalizedNonNull() are slightly 00431 // faster than the other normalization routines, but if v.length() 00432 // is 0.0, the result is undefined. 00433 //---------------------------------------------------------------- 00434 00435 T length () const; 00436 T length2 () const; 00437 00438 const Vec3 & normalize (); // modifies *this 00439 const Vec3 & normalizeExc () throw (Iex::MathExc); 00440 const Vec3 & normalizeNonNull (); 00441 00442 Vec3<T> normalized () const; // does not modify *this 00443 Vec3<T> normalizedExc () const throw (Iex::MathExc); 00444 Vec3<T> normalizedNonNull () const; 00445 00446 00447 //-------------------------------------------------------- 00448 // Number of dimensions, i.e. number of elements in a Vec3 00449 //-------------------------------------------------------- 00450 00451 static unsigned int dimensions() {return 3;} 00452 00453 00454 //------------------------------------------------- 00455 // Limitations of type T (see also class limits<T>) 00456 //------------------------------------------------- 00457 00458 static T baseTypeMin() {return limits<T>::min();} 00459 static T baseTypeMax() {return limits<T>::max();} 00460 static T baseTypeSmallest() {return limits<T>::smallest();} 00461 static T baseTypeEpsilon() {return limits<T>::epsilon();} 00462 00463 00464 //-------------------------------------------------------------- 00465 // Base type -- in templates, which accept a parameter, V, which 00466 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 00467 // refer to T as V::BaseType 00468 //-------------------------------------------------------------- 00469 00470 typedef T BaseType; 00471 00472 private: 00473 00474 T lengthTiny () const; 00475 }; 00476 00477 00478 00479 template <class T> class Vec4 00480 { 00481 public: 00482 00483 //------------------- 00484 // Access to elements 00485 //------------------- 00486 00487 T x, y, z, w; 00488 00489 T & operator [] (int i); 00490 const T & operator [] (int i) const; 00491 00492 00493 //------------- 00494 // Constructors 00495 //------------- 00496 00497 Vec4 (); // no initialization 00498 explicit Vec4 (T a); // (a a a a) 00499 Vec4 (T a, T b, T c, T d); // (a b c d) 00500 00501 00502 //--------------------------------- 00503 // Copy constructors and assignment 00504 //--------------------------------- 00505 00506 Vec4 (const Vec4 &v); 00507 template <class S> Vec4 (const Vec4<S> &v); 00508 00509 const Vec4 & operator = (const Vec4 &v); 00510 00511 00512 //------------------------------------- 00513 // Vec3 to Vec4 conversion, sets w to 1 00514 //------------------------------------- 00515 00516 template <class S> explicit Vec4 (const Vec3<S> &v); 00517 00518 00519 //--------- 00520 // Equality 00521 //--------- 00522 00523 template <class S> 00524 bool operator == (const Vec4<S> &v) const; 00525 00526 template <class S> 00527 bool operator != (const Vec4<S> &v) const; 00528 00529 00530 //----------------------------------------------------------------------- 00531 // Compare two vectors and test if they are "approximately equal": 00532 // 00533 // equalWithAbsError (v, e) 00534 // 00535 // Returns true if the coefficients of this and v are the same with 00536 // an absolute error of no more than e, i.e., for all i 00537 // 00538 // abs (this[i] - v[i]) <= e 00539 // 00540 // equalWithRelError (v, e) 00541 // 00542 // Returns true if the coefficients of this and v are the same with 00543 // a relative error of no more than e, i.e., for all i 00544 // 00545 // abs (this[i] - v[i]) <= e * abs (this[i]) 00546 //----------------------------------------------------------------------- 00547 00548 bool equalWithAbsError (const Vec4<T> &v, T e) const; 00549 bool equalWithRelError (const Vec4<T> &v, T e) const; 00550 00551 00552 //------------ 00553 // Dot product 00554 //------------ 00555 00556 T dot (const Vec4 &v) const; 00557 T operator ^ (const Vec4 &v) const; 00558 00559 00560 //----------------------------------- 00561 // Cross product is not defined in 4D 00562 //----------------------------------- 00563 00564 //------------------------ 00565 // Component-wise addition 00566 //------------------------ 00567 00568 const Vec4 & operator += (const Vec4 &v); 00569 Vec4 operator + (const Vec4 &v) const; 00570 00571 00572 //--------------------------- 00573 // Component-wise subtraction 00574 //--------------------------- 00575 00576 const Vec4 & operator -= (const Vec4 &v); 00577 Vec4 operator - (const Vec4 &v) const; 00578 00579 00580 //------------------------------------ 00581 // Component-wise multiplication by -1 00582 //------------------------------------ 00583 00584 Vec4 operator - () const; 00585 const Vec4 & negate (); 00586 00587 00588 //------------------------------ 00589 // Component-wise multiplication 00590 //------------------------------ 00591 00592 const Vec4 & operator *= (const Vec4 &v); 00593 const Vec4 & operator *= (T a); 00594 Vec4 operator * (const Vec4 &v) const; 00595 Vec4 operator * (T a) const; 00596 00597 00598 //------------------------ 00599 // Component-wise division 00600 //------------------------ 00601 00602 const Vec4 & operator /= (const Vec4 &v); 00603 const Vec4 & operator /= (T a); 00604 Vec4 operator / (const Vec4 &v) const; 00605 Vec4 operator / (T a) const; 00606 00607 00608 //---------------------------------------------------------------- 00609 // Length and normalization: If v.length() is 0.0, v.normalize() 00610 // and v.normalized() produce a null vector; v.normalizeExc() and 00611 // v.normalizedExc() throw a NullVecExc. 00612 // v.normalizeNonNull() and v.normalizedNonNull() are slightly 00613 // faster than the other normalization routines, but if v.length() 00614 // is 0.0, the result is undefined. 00615 //---------------------------------------------------------------- 00616 00617 T length () const; 00618 T length2 () const; 00619 00620 const Vec4 & normalize (); // modifies *this 00621 const Vec4 & normalizeExc () throw (Iex::MathExc); 00622 const Vec4 & normalizeNonNull (); 00623 00624 Vec4<T> normalized () const; // does not modify *this 00625 Vec4<T> normalizedExc () const throw (Iex::MathExc); 00626 Vec4<T> normalizedNonNull () const; 00627 00628 00629 //-------------------------------------------------------- 00630 // Number of dimensions, i.e. number of elements in a Vec4 00631 //-------------------------------------------------------- 00632 00633 static unsigned int dimensions() {return 4;} 00634 00635 00636 //------------------------------------------------- 00637 // Limitations of type T (see also class limits<T>) 00638 //------------------------------------------------- 00639 00640 static T baseTypeMin() {return limits<T>::min();} 00641 static T baseTypeMax() {return limits<T>::max();} 00642 static T baseTypeSmallest() {return limits<T>::smallest();} 00643 static T baseTypeEpsilon() {return limits<T>::epsilon();} 00644 00645 00646 //-------------------------------------------------------------- 00647 // Base type -- in templates, which accept a parameter, V, which 00648 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 00649 // refer to T as V::BaseType 00650 //-------------------------------------------------------------- 00651 00652 typedef T BaseType; 00653 00654 private: 00655 00656 T lengthTiny () const; 00657 }; 00658 00659 00660 //-------------- 00661 // Stream output 00662 //-------------- 00663 00664 template <class T> 00665 std::ostream & operator << (std::ostream &s, const Vec2<T> &v); 00666 00667 template <class T> 00668 std::ostream & operator << (std::ostream &s, const Vec3<T> &v); 00669 00670 template <class T> 00671 std::ostream & operator << (std::ostream &s, const Vec4<T> &v); 00672 00673 //---------------------------------------------------- 00674 // Reverse multiplication: S * Vec2<T> and S * Vec3<T> 00675 //---------------------------------------------------- 00676 00677 template <class T> Vec2<T> operator * (T a, const Vec2<T> &v); 00678 template <class T> Vec3<T> operator * (T a, const Vec3<T> &v); 00679 template <class T> Vec4<T> operator * (T a, const Vec4<T> &v); 00680 00681 00682 //------------------------- 00683 // Typedefs for convenience 00684 //------------------------- 00685 00686 typedef Vec2 <short> V2s; 00687 typedef Vec2 <int> V2i; 00688 typedef Vec2 <float> V2f; 00689 typedef Vec2 <double> V2d; 00690 typedef Vec3 <short> V3s; 00691 typedef Vec3 <int> V3i; 00692 typedef Vec3 <float> V3f; 00693 typedef Vec3 <double> V3d; 00694 typedef Vec4 <short> V4s; 00695 typedef Vec4 <int> V4i; 00696 typedef Vec4 <float> V4f; 00697 typedef Vec4 <double> V4d; 00698 00699 00700 //------------------------------------------- 00701 // Specializations for VecN<short>, VecN<int> 00702 //------------------------------------------- 00703 00704 // Vec2<short> 00705 00706 template <> short 00707 Vec2<short>::length () const; 00708 00709 template <> const Vec2<short> & 00710 Vec2<short>::normalize (); 00711 00712 template <> const Vec2<short> & 00713 Vec2<short>::normalizeExc () throw (Iex::MathExc); 00714 00715 template <> const Vec2<short> & 00716 Vec2<short>::normalizeNonNull (); 00717 00718 template <> Vec2<short> 00719 Vec2<short>::normalized () const; 00720 00721 template <> Vec2<short> 00722 Vec2<short>::normalizedExc () const throw (Iex::MathExc); 00723 00724 template <> Vec2<short> 00725 Vec2<short>::normalizedNonNull () const; 00726 00727 00728 // Vec2<int> 00729 00730 template <> int 00731 Vec2<int>::length () const; 00732 00733 template <> const Vec2<int> & 00734 Vec2<int>::normalize (); 00735 00736 template <> const Vec2<int> & 00737 Vec2<int>::normalizeExc () throw (Iex::MathExc); 00738 00739 template <> const Vec2<int> & 00740 Vec2<int>::normalizeNonNull (); 00741 00742 template <> Vec2<int> 00743 Vec2<int>::normalized () const; 00744 00745 template <> Vec2<int> 00746 Vec2<int>::normalizedExc () const throw (Iex::MathExc); 00747 00748 template <> Vec2<int> 00749 Vec2<int>::normalizedNonNull () const; 00750 00751 00752 // Vec3<short> 00753 00754 template <> short 00755 Vec3<short>::length () const; 00756 00757 template <> const Vec3<short> & 00758 Vec3<short>::normalize (); 00759 00760 template <> const Vec3<short> & 00761 Vec3<short>::normalizeExc () throw (Iex::MathExc); 00762 00763 template <> const Vec3<short> & 00764 Vec3<short>::normalizeNonNull (); 00765 00766 template <> Vec3<short> 00767 Vec3<short>::normalized () const; 00768 00769 template <> Vec3<short> 00770 Vec3<short>::normalizedExc () const throw (Iex::MathExc); 00771 00772 template <> Vec3<short> 00773 Vec3<short>::normalizedNonNull () const; 00774 00775 00776 // Vec3<int> 00777 00778 template <> int 00779 Vec3<int>::length () const; 00780 00781 template <> const Vec3<int> & 00782 Vec3<int>::normalize (); 00783 00784 template <> const Vec3<int> & 00785 Vec3<int>::normalizeExc () throw (Iex::MathExc); 00786 00787 template <> const Vec3<int> & 00788 Vec3<int>::normalizeNonNull (); 00789 00790 template <> Vec3<int> 00791 Vec3<int>::normalized () const; 00792 00793 template <> Vec3<int> 00794 Vec3<int>::normalizedExc () const throw (Iex::MathExc); 00795 00796 template <> Vec3<int> 00797 Vec3<int>::normalizedNonNull () const; 00798 00799 // Vec4<short> 00800 00801 template <> short 00802 Vec4<short>::length () const; 00803 00804 template <> const Vec4<short> & 00805 Vec4<short>::normalize (); 00806 00807 template <> const Vec4<short> & 00808 Vec4<short>::normalizeExc () throw (Iex::MathExc); 00809 00810 template <> const Vec4<short> & 00811 Vec4<short>::normalizeNonNull (); 00812 00813 template <> Vec4<short> 00814 Vec4<short>::normalized () const; 00815 00816 template <> Vec4<short> 00817 Vec4<short>::normalizedExc () const throw (Iex::MathExc); 00818 00819 template <> Vec4<short> 00820 Vec4<short>::normalizedNonNull () const; 00821 00822 00823 // Vec4<int> 00824 00825 template <> int 00826 Vec4<int>::length () const; 00827 00828 template <> const Vec4<int> & 00829 Vec4<int>::normalize (); 00830 00831 template <> const Vec4<int> & 00832 Vec4<int>::normalizeExc () throw (Iex::MathExc); 00833 00834 template <> const Vec4<int> & 00835 Vec4<int>::normalizeNonNull (); 00836 00837 template <> Vec4<int> 00838 Vec4<int>::normalized () const; 00839 00840 template <> Vec4<int> 00841 Vec4<int>::normalizedExc () const throw (Iex::MathExc); 00842 00843 template <> Vec4<int> 00844 Vec4<int>::normalizedNonNull () const; 00845 00846 00847 //------------------------ 00848 // Implementation of Vec2: 00849 //------------------------ 00850 00851 template <class T> 00852 inline T & 00853 Vec2<T>::operator [] (int i) 00854 { 00855 return (&x)[i]; 00856 } 00857 00858 template <class T> 00859 inline const T & 00860 Vec2<T>::operator [] (int i) const 00861 { 00862 return (&x)[i]; 00863 } 00864 00865 template <class T> 00866 inline 00867 Vec2<T>::Vec2 () 00868 { 00869 // empty 00870 } 00871 00872 template <class T> 00873 inline 00874 Vec2<T>::Vec2 (T a) 00875 { 00876 x = y = a; 00877 } 00878 00879 template <class T> 00880 inline 00881 Vec2<T>::Vec2 (T a, T b) 00882 { 00883 x = a; 00884 y = b; 00885 } 00886 00887 template <class T> 00888 inline 00889 Vec2<T>::Vec2 (const Vec2 &v) 00890 { 00891 x = v.x; 00892 y = v.y; 00893 } 00894 00895 template <class T> 00896 template <class S> 00897 inline 00898 Vec2<T>::Vec2 (const Vec2<S> &v) 00899 { 00900 x = T (v.x); 00901 y = T (v.y); 00902 } 00903 00904 template <class T> 00905 inline const Vec2<T> & 00906 Vec2<T>::operator = (const Vec2 &v) 00907 { 00908 x = v.x; 00909 y = v.y; 00910 return *this; 00911 } 00912 00913 template <class T> 00914 template <class S> 00915 inline void 00916 Vec2<T>::setValue (S a, S b) 00917 { 00918 x = T (a); 00919 y = T (b); 00920 } 00921 00922 template <class T> 00923 template <class S> 00924 inline void 00925 Vec2<T>::setValue (const Vec2<S> &v) 00926 { 00927 x = T (v.x); 00928 y = T (v.y); 00929 } 00930 00931 template <class T> 00932 template <class S> 00933 inline void 00934 Vec2<T>::getValue (S &a, S &b) const 00935 { 00936 a = S (x); 00937 b = S (y); 00938 } 00939 00940 template <class T> 00941 template <class S> 00942 inline void 00943 Vec2<T>::getValue (Vec2<S> &v) const 00944 { 00945 v.x = S (x); 00946 v.y = S (y); 00947 } 00948 00949 template <class T> 00950 inline T * 00951 Vec2<T>::getValue() 00952 { 00953 return (T *) &x; 00954 } 00955 00956 template <class T> 00957 inline const T * 00958 Vec2<T>::getValue() const 00959 { 00960 return (const T *) &x; 00961 } 00962 00963 template <class T> 00964 template <class S> 00965 inline bool 00966 Vec2<T>::operator == (const Vec2<S> &v) const 00967 { 00968 return x == v.x && y == v.y; 00969 } 00970 00971 template <class T> 00972 template <class S> 00973 inline bool 00974 Vec2<T>::operator != (const Vec2<S> &v) const 00975 { 00976 return x != v.x || y != v.y; 00977 } 00978 00979 template <class T> 00980 bool 00981 Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const 00982 { 00983 for (int i = 0; i < 2; i++) 00984 if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) 00985 return false; 00986 00987 return true; 00988 } 00989 00990 template <class T> 00991 bool 00992 Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const 00993 { 00994 for (int i = 0; i < 2; i++) 00995 if (!Imath::equalWithRelError ((*this)[i], v[i], e)) 00996 return false; 00997 00998 return true; 00999 } 01000 01001 template <class T> 01002 inline T 01003 Vec2<T>::dot (const Vec2 &v) const 01004 { 01005 return x * v.x + y * v.y; 01006 } 01007 01008 template <class T> 01009 inline T 01010 Vec2<T>::operator ^ (const Vec2 &v) const 01011 { 01012 return dot (v); 01013 } 01014 01015 template <class T> 01016 inline T 01017 Vec2<T>::cross (const Vec2 &v) const 01018 { 01019 return x * v.y - y * v.x; 01020 01021 } 01022 01023 template <class T> 01024 inline T 01025 Vec2<T>::operator % (const Vec2 &v) const 01026 { 01027 return x * v.y - y * v.x; 01028 } 01029 01030 template <class T> 01031 inline const Vec2<T> & 01032 Vec2<T>::operator += (const Vec2 &v) 01033 { 01034 x += v.x; 01035 y += v.y; 01036 return *this; 01037 } 01038 01039 template <class T> 01040 inline Vec2<T> 01041 Vec2<T>::operator + (const Vec2 &v) const 01042 { 01043 return Vec2 (x + v.x, y + v.y); 01044 } 01045 01046 template <class T> 01047 inline const Vec2<T> & 01048 Vec2<T>::operator -= (const Vec2 &v) 01049 { 01050 x -= v.x; 01051 y -= v.y; 01052 return *this; 01053 } 01054 01055 template <class T> 01056 inline Vec2<T> 01057 Vec2<T>::operator - (const Vec2 &v) const 01058 { 01059 return Vec2 (x - v.x, y - v.y); 01060 } 01061 01062 template <class T> 01063 inline Vec2<T> 01064 Vec2<T>::operator - () const 01065 { 01066 return Vec2 (-x, -y); 01067 } 01068 01069 template <class T> 01070 inline const Vec2<T> & 01071 Vec2<T>::negate () 01072 { 01073 x = -x; 01074 y = -y; 01075 return *this; 01076 } 01077 01078 template <class T> 01079 inline const Vec2<T> & 01080 Vec2<T>::operator *= (const Vec2 &v) 01081 { 01082 x *= v.x; 01083 y *= v.y; 01084 return *this; 01085 } 01086 01087 template <class T> 01088 inline const Vec2<T> & 01089 Vec2<T>::operator *= (T a) 01090 { 01091 x *= a; 01092 y *= a; 01093 return *this; 01094 } 01095 01096 template <class T> 01097 inline Vec2<T> 01098 Vec2<T>::operator * (const Vec2 &v) const 01099 { 01100 return Vec2 (x * v.x, y * v.y); 01101 } 01102 01103 template <class T> 01104 inline Vec2<T> 01105 Vec2<T>::operator * (T a) const 01106 { 01107 return Vec2 (x * a, y * a); 01108 } 01109 01110 template <class T> 01111 inline const Vec2<T> & 01112 Vec2<T>::operator /= (const Vec2 &v) 01113 { 01114 x /= v.x; 01115 y /= v.y; 01116 return *this; 01117 } 01118 01119 template <class T> 01120 inline const Vec2<T> & 01121 Vec2<T>::operator /= (T a) 01122 { 01123 x /= a; 01124 y /= a; 01125 return *this; 01126 } 01127 01128 template <class T> 01129 inline Vec2<T> 01130 Vec2<T>::operator / (const Vec2 &v) const 01131 { 01132 return Vec2 (x / v.x, y / v.y); 01133 } 01134 01135 template <class T> 01136 inline Vec2<T> 01137 Vec2<T>::operator / (T a) const 01138 { 01139 return Vec2 (x / a, y / a); 01140 } 01141 01142 template <class T> 01143 T 01144 Vec2<T>::lengthTiny () const 01145 { 01146 T absX = (x >= 0)? x: -x; 01147 T absY = (y >= 0)? y: -y; 01148 01149 T max = absX; 01150 01151 if (max < absY) 01152 max = absY; 01153 01154 if (max == 0) 01155 return 0; 01156 01157 // 01158 // Do not replace the divisions by max with multiplications by 1/max. 01159 // Computing 1/max can overflow but the divisions below will always 01160 // produce results less than or equal to 1. 01161 // 01162 01163 absX /= max; 01164 absY /= max; 01165 01166 return max * Math<T>::sqrt (absX * absX + absY * absY); 01167 } 01168 01169 template <class T> 01170 inline T 01171 Vec2<T>::length () const 01172 { 01173 T length2 = dot (*this); 01174 01175 if (length2 < 2 * limits<T>::smallest()) 01176 return lengthTiny(); 01177 01178 return Math<T>::sqrt (length2); 01179 } 01180 01181 template <class T> 01182 inline T 01183 Vec2<T>::length2 () const 01184 { 01185 return dot (*this); 01186 } 01187 01188 template <class T> 01189 const Vec2<T> & 01190 Vec2<T>::normalize () 01191 { 01192 T l = length(); 01193 01194 if (l != 0) 01195 { 01196 // 01197 // Do not replace the divisions by l with multiplications by 1/l. 01198 // Computing 1/l can overflow but the divisions below will always 01199 // produce results less than or equal to 1. 01200 // 01201 01202 x /= l; 01203 y /= l; 01204 } 01205 01206 return *this; 01207 } 01208 01209 template <class T> 01210 const Vec2<T> & 01211 Vec2<T>::normalizeExc () throw (Iex::MathExc) 01212 { 01213 T l = length(); 01214 01215 if (l == 0) 01216 throw NullVecExc ("Cannot normalize null vector."); 01217 01218 x /= l; 01219 y /= l; 01220 return *this; 01221 } 01222 01223 template <class T> 01224 inline 01225 const Vec2<T> & 01226 Vec2<T>::normalizeNonNull () 01227 { 01228 T l = length(); 01229 x /= l; 01230 y /= l; 01231 return *this; 01232 } 01233 01234 template <class T> 01235 Vec2<T> 01236 Vec2<T>::normalized () const 01237 { 01238 T l = length(); 01239 01240 if (l == 0) 01241 return Vec2 (T (0)); 01242 01243 return Vec2 (x / l, y / l); 01244 } 01245 01246 template <class T> 01247 Vec2<T> 01248 Vec2<T>::normalizedExc () const throw (Iex::MathExc) 01249 { 01250 T l = length(); 01251 01252 if (l == 0) 01253 throw NullVecExc ("Cannot normalize null vector."); 01254 01255 return Vec2 (x / l, y / l); 01256 } 01257 01258 template <class T> 01259 inline 01260 Vec2<T> 01261 Vec2<T>::normalizedNonNull () const 01262 { 01263 T l = length(); 01264 return Vec2 (x / l, y / l); 01265 } 01266 01267 01268 //----------------------- 01269 // Implementation of Vec3 01270 //----------------------- 01271 01272 template <class T> 01273 inline T & 01274 Vec3<T>::operator [] (int i) 01275 { 01276 return (&x)[i]; 01277 } 01278 01279 template <class T> 01280 inline const T & 01281 Vec3<T>::operator [] (int i) const 01282 { 01283 return (&x)[i]; 01284 } 01285 01286 template <class T> 01287 inline 01288 Vec3<T>::Vec3 () 01289 { 01290 // empty 01291 } 01292 01293 template <class T> 01294 inline 01295 Vec3<T>::Vec3 (T a) 01296 { 01297 x = y = z = a; 01298 } 01299 01300 template <class T> 01301 inline 01302 Vec3<T>::Vec3 (T a, T b, T c) 01303 { 01304 x = a; 01305 y = b; 01306 z = c; 01307 } 01308 01309 template <class T> 01310 inline 01311 Vec3<T>::Vec3 (const Vec3 &v) 01312 { 01313 x = v.x; 01314 y = v.y; 01315 z = v.z; 01316 } 01317 01318 template <class T> 01319 template <class S> 01320 inline 01321 Vec3<T>::Vec3 (const Vec3<S> &v) 01322 { 01323 x = T (v.x); 01324 y = T (v.y); 01325 z = T (v.z); 01326 } 01327 01328 template <class T> 01329 inline const Vec3<T> & 01330 Vec3<T>::operator = (const Vec3 &v) 01331 { 01332 x = v.x; 01333 y = v.y; 01334 z = v.z; 01335 return *this; 01336 } 01337 01338 template <class T> 01339 template <class S> 01340 inline 01341 Vec3<T>::Vec3 (const Vec4<S> &v) 01342 { 01343 x = T (v.x / v.w); 01344 y = T (v.y / v.w); 01345 z = T (v.z / v.w); 01346 } 01347 01348 template <class T> 01349 template <class S> 01350 Vec3<T>::Vec3 (const Vec4<S> &v, InfException) 01351 { 01352 T vx = T (v.x); 01353 T vy = T (v.y); 01354 T vz = T (v.z); 01355 T vw = T (v.w); 01356 01357 T absW = (vw >= 0)? vw: -vw; 01358 01359 if (absW < 1) 01360 { 01361 T m = baseTypeMax() * absW; 01362 01363 if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m) 01364 throw InfPointExc ("Cannot normalize point at infinity."); 01365 } 01366 01367 x = vx / vw; 01368 y = vy / vw; 01369 z = vz / vw; 01370 } 01371 01372 template <class T> 01373 template <class S> 01374 inline void 01375 Vec3<T>::setValue (S a, S b, S c) 01376 { 01377 x = T (a); 01378 y = T (b); 01379 z = T (c); 01380 } 01381 01382 template <class T> 01383 template <class S> 01384 inline void 01385 Vec3<T>::setValue (const Vec3<S> &v) 01386 { 01387 x = T (v.x); 01388 y = T (v.y); 01389 z = T (v.z); 01390 } 01391 01392 template <class T> 01393 template <class S> 01394 inline void 01395 Vec3<T>::getValue (S &a, S &b, S &c) const 01396 { 01397 a = S (x); 01398 b = S (y); 01399 c = S (z); 01400 } 01401 01402 template <class T> 01403 template <class S> 01404 inline void 01405 Vec3<T>::getValue (Vec3<S> &v) const 01406 { 01407 v.x = S (x); 01408 v.y = S (y); 01409 v.z = S (z); 01410 } 01411 01412 template <class T> 01413 inline T * 01414 Vec3<T>::getValue() 01415 { 01416 return (T *) &x; 01417 } 01418 01419 template <class T> 01420 inline const T * 01421 Vec3<T>::getValue() const 01422 { 01423 return (const T *) &x; 01424 } 01425 01426 template <class T> 01427 template <class S> 01428 inline bool 01429 Vec3<T>::operator == (const Vec3<S> &v) const 01430 { 01431 return x == v.x && y == v.y && z == v.z; 01432 } 01433 01434 template <class T> 01435 template <class S> 01436 inline bool 01437 Vec3<T>::operator != (const Vec3<S> &v) const 01438 { 01439 return x != v.x || y != v.y || z != v.z; 01440 } 01441 01442 template <class T> 01443 bool 01444 Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const 01445 { 01446 for (int i = 0; i < 3; i++) 01447 if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) 01448 return false; 01449 01450 return true; 01451 } 01452 01453 template <class T> 01454 bool 01455 Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const 01456 { 01457 for (int i = 0; i < 3; i++) 01458 if (!Imath::equalWithRelError ((*this)[i], v[i], e)) 01459 return false; 01460 01461 return true; 01462 } 01463 01464 template <class T> 01465 inline T 01466 Vec3<T>::dot (const Vec3 &v) const 01467 { 01468 return x * v.x + y * v.y + z * v.z; 01469 } 01470 01471 template <class T> 01472 inline T 01473 Vec3<T>::operator ^ (const Vec3 &v) const 01474 { 01475 return dot (v); 01476 } 01477 01478 template <class T> 01479 inline Vec3<T> 01480 Vec3<T>::cross (const Vec3 &v) const 01481 { 01482 return Vec3 (y * v.z - z * v.y, 01483 z * v.x - x * v.z, 01484 x * v.y - y * v.x); 01485 } 01486 01487 template <class T> 01488 inline const Vec3<T> & 01489 Vec3<T>::operator %= (const Vec3 &v) 01490 { 01491 T a = y * v.z - z * v.y; 01492 T b = z * v.x - x * v.z; 01493 T c = x * v.y - y * v.x; 01494 x = a; 01495 y = b; 01496 z = c; 01497 return *this; 01498 } 01499 01500 template <class T> 01501 inline Vec3<T> 01502 Vec3<T>::operator % (const Vec3 &v) const 01503 { 01504 return Vec3 (y * v.z - z * v.y, 01505 z * v.x - x * v.z, 01506 x * v.y - y * v.x); 01507 } 01508 01509 template <class T> 01510 inline const Vec3<T> & 01511 Vec3<T>::operator += (const Vec3 &v) 01512 { 01513 x += v.x; 01514 y += v.y; 01515 z += v.z; 01516 return *this; 01517 } 01518 01519 template <class T> 01520 inline Vec3<T> 01521 Vec3<T>::operator + (const Vec3 &v) const 01522 { 01523 return Vec3 (x + v.x, y + v.y, z + v.z); 01524 } 01525 01526 template <class T> 01527 inline const Vec3<T> & 01528 Vec3<T>::operator -= (const Vec3 &v) 01529 { 01530 x -= v.x; 01531 y -= v.y; 01532 z -= v.z; 01533 return *this; 01534 } 01535 01536 template <class T> 01537 inline Vec3<T> 01538 Vec3<T>::operator - (const Vec3 &v) const 01539 { 01540 return Vec3 (x - v.x, y - v.y, z - v.z); 01541 } 01542 01543 template <class T> 01544 inline Vec3<T> 01545 Vec3<T>::operator - () const 01546 { 01547 return Vec3 (-x, -y, -z); 01548 } 01549 01550 template <class T> 01551 inline const Vec3<T> & 01552 Vec3<T>::negate () 01553 { 01554 x = -x; 01555 y = -y; 01556 z = -z; 01557 return *this; 01558 } 01559 01560 template <class T> 01561 inline const Vec3<T> & 01562 Vec3<T>::operator *= (const Vec3 &v) 01563 { 01564 x *= v.x; 01565 y *= v.y; 01566 z *= v.z; 01567 return *this; 01568 } 01569 01570 template <class T> 01571 inline const Vec3<T> & 01572 Vec3<T>::operator *= (T a) 01573 { 01574 x *= a; 01575 y *= a; 01576 z *= a; 01577 return *this; 01578 } 01579 01580 template <class T> 01581 inline Vec3<T> 01582 Vec3<T>::operator * (const Vec3 &v) const 01583 { 01584 return Vec3 (x * v.x, y * v.y, z * v.z); 01585 } 01586 01587 template <class T> 01588 inline Vec3<T> 01589 Vec3<T>::operator * (T a) const 01590 { 01591 return Vec3 (x * a, y * a, z * a); 01592 } 01593 01594 template <class T> 01595 inline const Vec3<T> & 01596 Vec3<T>::operator /= (const Vec3 &v) 01597 { 01598 x /= v.x; 01599 y /= v.y; 01600 z /= v.z; 01601 return *this; 01602 } 01603 01604 template <class T> 01605 inline const Vec3<T> & 01606 Vec3<T>::operator /= (T a) 01607 { 01608 x /= a; 01609 y /= a; 01610 z /= a; 01611 return *this; 01612 } 01613 01614 template <class T> 01615 inline Vec3<T> 01616 Vec3<T>::operator / (const Vec3 &v) const 01617 { 01618 return Vec3 (x / v.x, y / v.y, z / v.z); 01619 } 01620 01621 template <class T> 01622 inline Vec3<T> 01623 Vec3<T>::operator / (T a) const 01624 { 01625 return Vec3 (x / a, y / a, z / a); 01626 } 01627 01628 template <class T> 01629 T 01630 Vec3<T>::lengthTiny () const 01631 { 01632 T absX = (x >= 0)? x: -x; 01633 T absY = (y >= 0)? y: -y; 01634 T absZ = (z >= 0)? z: -z; 01635 01636 T max = absX; 01637 01638 if (max < absY) 01639 max = absY; 01640 01641 if (max < absZ) 01642 max = absZ; 01643 01644 if (max == 0) 01645 return 0; 01646 01647 // 01648 // Do not replace the divisions by max with multiplications by 1/max. 01649 // Computing 1/max can overflow but the divisions below will always 01650 // produce results less than or equal to 1. 01651 // 01652 01653 absX /= max; 01654 absY /= max; 01655 absZ /= max; 01656 01657 return max * Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ); 01658 } 01659 01660 template <class T> 01661 inline T 01662 Vec3<T>::length () const 01663 { 01664 T length2 = dot (*this); 01665 01666 if (length2 < 2 * limits<T>::smallest()) 01667 return lengthTiny(); 01668 01669 return Math<T>::sqrt (length2); 01670 } 01671 01672 template <class T> 01673 inline T 01674 Vec3<T>::length2 () const 01675 { 01676 return dot (*this); 01677 } 01678 01679 template <class T> 01680 const Vec3<T> & 01681 Vec3<T>::normalize () 01682 { 01683 T l = length(); 01684 01685 if (l != 0) 01686 { 01687 // 01688 // Do not replace the divisions by l with multiplications by 1/l. 01689 // Computing 1/l can overflow but the divisions below will always 01690 // produce results less than or equal to 1. 01691 // 01692 01693 x /= l; 01694 y /= l; 01695 z /= l; 01696 } 01697 01698 return *this; 01699 } 01700 01701 template <class T> 01702 const Vec3<T> & 01703 Vec3<T>::normalizeExc () throw (Iex::MathExc) 01704 { 01705 T l = length(); 01706 01707 if (l == 0) 01708 throw NullVecExc ("Cannot normalize null vector."); 01709 01710 x /= l; 01711 y /= l; 01712 z /= l; 01713 return *this; 01714 } 01715 01716 template <class T> 01717 inline 01718 const Vec3<T> & 01719 Vec3<T>::normalizeNonNull () 01720 { 01721 T l = length(); 01722 x /= l; 01723 y /= l; 01724 z /= l; 01725 return *this; 01726 } 01727 01728 template <class T> 01729 Vec3<T> 01730 Vec3<T>::normalized () const 01731 { 01732 T l = length(); 01733 01734 if (l == 0) 01735 return Vec3 (T (0)); 01736 01737 return Vec3 (x / l, y / l, z / l); 01738 } 01739 01740 template <class T> 01741 Vec3<T> 01742 Vec3<T>::normalizedExc () const throw (Iex::MathExc) 01743 { 01744 T l = length(); 01745 01746 if (l == 0) 01747 throw NullVecExc ("Cannot normalize null vector."); 01748 01749 return Vec3 (x / l, y / l, z / l); 01750 } 01751 01752 template <class T> 01753 inline 01754 Vec3<T> 01755 Vec3<T>::normalizedNonNull () const 01756 { 01757 T l = length(); 01758 return Vec3 (x / l, y / l, z / l); 01759 } 01760 01761 01762 //----------------------- 01763 // Implementation of Vec4 01764 //----------------------- 01765 01766 template <class T> 01767 inline T & 01768 Vec4<T>::operator [] (int i) 01769 { 01770 return (&x)[i]; 01771 } 01772 01773 template <class T> 01774 inline const T & 01775 Vec4<T>::operator [] (int i) const 01776 { 01777 return (&x)[i]; 01778 } 01779 01780 template <class T> 01781 inline 01782 Vec4<T>::Vec4 () 01783 { 01784 // empty 01785 } 01786 01787 template <class T> 01788 inline 01789 Vec4<T>::Vec4 (T a) 01790 { 01791 x = y = z = w = a; 01792 } 01793 01794 template <class T> 01795 inline 01796 Vec4<T>::Vec4 (T a, T b, T c, T d) 01797 { 01798 x = a; 01799 y = b; 01800 z = c; 01801 w = d; 01802 } 01803 01804 template <class T> 01805 inline 01806 Vec4<T>::Vec4 (const Vec4 &v) 01807 { 01808 x = v.x; 01809 y = v.y; 01810 z = v.z; 01811 w = v.w; 01812 } 01813 01814 template <class T> 01815 template <class S> 01816 inline 01817 Vec4<T>::Vec4 (const Vec4<S> &v) 01818 { 01819 x = T (v.x); 01820 y = T (v.y); 01821 z = T (v.z); 01822 w = T (v.w); 01823 } 01824 01825 template <class T> 01826 inline const Vec4<T> & 01827 Vec4<T>::operator = (const Vec4 &v) 01828 { 01829 x = v.x; 01830 y = v.y; 01831 z = v.z; 01832 w = v.w; 01833 return *this; 01834 } 01835 01836 template <class T> 01837 template <class S> 01838 inline 01839 Vec4<T>::Vec4 (const Vec3<S> &v) 01840 { 01841 x = T (v.x); 01842 y = T (v.y); 01843 z = T (v.z); 01844 w = T (1); 01845 } 01846 01847 template <class T> 01848 template <class S> 01849 inline bool 01850 Vec4<T>::operator == (const Vec4<S> &v) const 01851 { 01852 return x == v.x && y == v.y && z == v.z && w == v.w; 01853 } 01854 01855 template <class T> 01856 template <class S> 01857 inline bool 01858 Vec4<T>::operator != (const Vec4<S> &v) const 01859 { 01860 return x != v.x || y != v.y || z != v.z || w != v.w; 01861 } 01862 01863 template <class T> 01864 bool 01865 Vec4<T>::equalWithAbsError (const Vec4<T> &v, T e) const 01866 { 01867 for (int i = 0; i < 4; i++) 01868 if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) 01869 return false; 01870 01871 return true; 01872 } 01873 01874 template <class T> 01875 bool 01876 Vec4<T>::equalWithRelError (const Vec4<T> &v, T e) const 01877 { 01878 for (int i = 0; i < 4; i++) 01879 if (!Imath::equalWithRelError ((*this)[i], v[i], e)) 01880 return false; 01881 01882 return true; 01883 } 01884 01885 template <class T> 01886 inline T 01887 Vec4<T>::dot (const Vec4 &v) const 01888 { 01889 return x * v.x + y * v.y + z * v.z + w * v.w; 01890 } 01891 01892 template <class T> 01893 inline T 01894 Vec4<T>::operator ^ (const Vec4 &v) const 01895 { 01896 return dot (v); 01897 } 01898 01899 01900 template <class T> 01901 inline const Vec4<T> & 01902 Vec4<T>::operator += (const Vec4 &v) 01903 { 01904 x += v.x; 01905 y += v.y; 01906 z += v.z; 01907 w += v.w; 01908 return *this; 01909 } 01910 01911 template <class T> 01912 inline Vec4<T> 01913 Vec4<T>::operator + (const Vec4 &v) const 01914 { 01915 return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w); 01916 } 01917 01918 template <class T> 01919 inline const Vec4<T> & 01920 Vec4<T>::operator -= (const Vec4 &v) 01921 { 01922 x -= v.x; 01923 y -= v.y; 01924 z -= v.z; 01925 w -= v.w; 01926 return *this; 01927 } 01928 01929 template <class T> 01930 inline Vec4<T> 01931 Vec4<T>::operator - (const Vec4 &v) const 01932 { 01933 return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w); 01934 } 01935 01936 template <class T> 01937 inline Vec4<T> 01938 Vec4<T>::operator - () const 01939 { 01940 return Vec4 (-x, -y, -z, -w); 01941 } 01942 01943 template <class T> 01944 inline const Vec4<T> & 01945 Vec4<T>::negate () 01946 { 01947 x = -x; 01948 y = -y; 01949 z = -z; 01950 w = -w; 01951 return *this; 01952 } 01953 01954 template <class T> 01955 inline const Vec4<T> & 01956 Vec4<T>::operator *= (const Vec4 &v) 01957 { 01958 x *= v.x; 01959 y *= v.y; 01960 z *= v.z; 01961 w *= v.w; 01962 return *this; 01963 } 01964 01965 template <class T> 01966 inline const Vec4<T> & 01967 Vec4<T>::operator *= (T a) 01968 { 01969 x *= a; 01970 y *= a; 01971 z *= a; 01972 w *= a; 01973 return *this; 01974 } 01975 01976 template <class T> 01977 inline Vec4<T> 01978 Vec4<T>::operator * (const Vec4 &v) const 01979 { 01980 return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w); 01981 } 01982 01983 template <class T> 01984 inline Vec4<T> 01985 Vec4<T>::operator * (T a) const 01986 { 01987 return Vec4 (x * a, y * a, z * a, w * a); 01988 } 01989 01990 template <class T> 01991 inline const Vec4<T> & 01992 Vec4<T>::operator /= (const Vec4 &v) 01993 { 01994 x /= v.x; 01995 y /= v.y; 01996 z /= v.z; 01997 w /= v.w; 01998 return *this; 01999 } 02000 02001 template <class T> 02002 inline const Vec4<T> & 02003 Vec4<T>::operator /= (T a) 02004 { 02005 x /= a; 02006 y /= a; 02007 z /= a; 02008 w /= a; 02009 return *this; 02010 } 02011 02012 template <class T> 02013 inline Vec4<T> 02014 Vec4<T>::operator / (const Vec4 &v) const 02015 { 02016 return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w); 02017 } 02018 02019 template <class T> 02020 inline Vec4<T> 02021 Vec4<T>::operator / (T a) const 02022 { 02023 return Vec4 (x / a, y / a, z / a, w / a); 02024 } 02025 02026 template <class T> 02027 T 02028 Vec4<T>::lengthTiny () const 02029 { 02030 T absX = (x >= 0)? x: -x; 02031 T absY = (y >= 0)? y: -y; 02032 T absZ = (z >= 0)? z: -z; 02033 T absW = (w >= 0)? w: -w; 02034 02035 T max = absX; 02036 02037 if (max < absY) 02038 max = absY; 02039 02040 if (max < absZ) 02041 max = absZ; 02042 02043 if (max < absW) 02044 max = absW; 02045 02046 if (max == 0) 02047 return 0; 02048 02049 // 02050 // Do not replace the divisions by max with multiplications by 1/max. 02051 // Computing 1/max can overflow but the divisions below will always 02052 // produce results less than or equal to 1. 02053 // 02054 02055 absX /= max; 02056 absY /= max; 02057 absZ /= max; 02058 absW /= max; 02059 02060 return max * 02061 Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW); 02062 } 02063 02064 template <class T> 02065 inline T 02066 Vec4<T>::length () const 02067 { 02068 T length2 = dot (*this); 02069 02070 if (length2 < 2 * limits<T>::smallest()) 02071 return lengthTiny(); 02072 02073 return Math<T>::sqrt (length2); 02074 } 02075 02076 template <class T> 02077 inline T 02078 Vec4<T>::length2 () const 02079 { 02080 return dot (*this); 02081 } 02082 02083 template <class T> 02084 const Vec4<T> & 02085 Vec4<T>::normalize () 02086 { 02087 T l = length(); 02088 02089 if (l != 0) 02090 { 02091 // 02092 // Do not replace the divisions by l with multiplications by 1/l. 02093 // Computing 1/l can overflow but the divisions below will always 02094 // produce results less than or equal to 1. 02095 // 02096 02097 x /= l; 02098 y /= l; 02099 z /= l; 02100 w /= l; 02101 } 02102 02103 return *this; 02104 } 02105 02106 template <class T> 02107 const Vec4<T> & 02108 Vec4<T>::normalizeExc () throw (Iex::MathExc) 02109 { 02110 T l = length(); 02111 02112 if (l == 0) 02113 throw NullVecExc ("Cannot normalize null vector."); 02114 02115 x /= l; 02116 y /= l; 02117 z /= l; 02118 w /= l; 02119 return *this; 02120 } 02121 02122 template <class T> 02123 inline 02124 const Vec4<T> & 02125 Vec4<T>::normalizeNonNull () 02126 { 02127 T l = length(); 02128 x /= l; 02129 y /= l; 02130 z /= l; 02131 w /= l; 02132 return *this; 02133 } 02134 02135 template <class T> 02136 Vec4<T> 02137 Vec4<T>::normalized () const 02138 { 02139 T l = length(); 02140 02141 if (l == 0) 02142 return Vec4 (T (0)); 02143 02144 return Vec4 (x / l, y / l, z / l, w / l); 02145 } 02146 02147 template <class T> 02148 Vec4<T> 02149 Vec4<T>::normalizedExc () const throw (Iex::MathExc) 02150 { 02151 T l = length(); 02152 02153 if (l == 0) 02154 throw NullVecExc ("Cannot normalize null vector."); 02155 02156 return Vec4 (x / l, y / l, z / l, w / l); 02157 } 02158 02159 template <class T> 02160 inline 02161 Vec4<T> 02162 Vec4<T>::normalizedNonNull () const 02163 { 02164 T l = length(); 02165 return Vec4 (x / l, y / l, z / l, w / l); 02166 } 02167 02168 //----------------------------- 02169 // Stream output implementation 02170 //----------------------------- 02171 02172 template <class T> 02173 std::ostream & 02174 operator << (std::ostream &s, const Vec2<T> &v) 02175 { 02176 return s << '(' << v.x << ' ' << v.y << ')'; 02177 } 02178 02179 template <class T> 02180 std::ostream & 02181 operator << (std::ostream &s, const Vec3<T> &v) 02182 { 02183 return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')'; 02184 } 02185 02186 template <class T> 02187 std::ostream & 02188 operator << (std::ostream &s, const Vec4<T> &v) 02189 { 02190 return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w << ')'; 02191 } 02192 02193 02194 //----------------------------------------- 02195 // Implementation of reverse multiplication 02196 //----------------------------------------- 02197 02198 template <class T> 02199 inline Vec2<T> 02200 operator * (T a, const Vec2<T> &v) 02201 { 02202 return Vec2<T> (a * v.x, a * v.y); 02203 } 02204 02205 template <class T> 02206 inline Vec3<T> 02207 operator * (T a, const Vec3<T> &v) 02208 { 02209 return Vec3<T> (a * v.x, a * v.y, a * v.z); 02210 } 02211 02212 template <class T> 02213 inline Vec4<T> 02214 operator * (T a, const Vec4<T> &v) 02215 { 02216 return Vec4<T> (a * v.x, a * v.y, a * v.z, a * v.w); 02217 } 02218 02219 02220 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER 02221 #pragma warning(pop) 02222 #endif 02223 02224 } // namespace Imath 02225 02226 #endif