1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas 4 // Digital Ltd. LLC 5 // 6 // All rights reserved. 7 // 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions are 10 // met: 11 // * Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // * Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following disclaimer 15 // in the documentation and/or other materials provided with the 16 // distribution. 17 // * Neither the name of Industrial Light & Magic nor the names of 18 // its contributors may be used to endorse or promote products derived 19 // from this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 // 33 /////////////////////////////////////////////////////////////////////////// 34 35 36 37 #ifndef INCLUDED_IMATHVEC_H 38 #define INCLUDED_IMATHVEC_H 39 40 //---------------------------------------------------- 41 // 42 // 2D, 3D and 4D point/vector class templates 43 // 44 //---------------------------------------------------- 45 46 #include "ImathExc.h" 47 #include "ImathLimits.h" 48 #include "ImathMath.h" 49 50 #include <iostream> 51 52 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER 53 // suppress exception specification warnings 54 #pragma warning(push) 55 #pragma warning(disable:4290) 56 #endif 57 58 59 namespace Imath { 60 61 template <class T> class Vec2; 62 template <class T> class Vec3; 63 template <class T> class Vec4; 64 65 enum InfException {INF_EXCEPTION}; 66 67 68 template <class T> class Vec2 69 { 70 public: 71 72 //------------------- 73 // Access to elements 74 //------------------- 75 76 T x, y; 77 78 T & operator [] (int i); 79 const T & operator [] (int i) const; 80 81 82 //------------- 83 // Constructors 84 //------------- 85 86 Vec2 (); // no initialization 87 explicit Vec2 (T a); // (a a) 88 Vec2 (T a, T b); // (a b) 89 90 91 //--------------------------------- 92 // Copy constructors and assignment 93 //--------------------------------- 94 95 Vec2 (const Vec2 &v); 96 template <class S> Vec2 (const Vec2<S> &v); 97 98 const Vec2 & operator = (const Vec2 &v); 99 100 101 //---------------------- 102 // Compatibility with Sb 103 //---------------------- 104 105 template <class S> 106 void setValue (S a, S b); 107 108 template <class S> 109 void setValue (const Vec2<S> &v); 110 111 template <class S> 112 void getValue (S &a, S &b) const; 113 114 template <class S> 115 void getValue (Vec2<S> &v) const; 116 117 T * getValue (); 118 const T * getValue () const; 119 120 121 //--------- 122 // Equality 123 //--------- 124 125 template <class S> 126 bool operator == (const Vec2<S> &v) const; 127 128 template <class S> 129 bool operator != (const Vec2<S> &v) const; 130 131 132 //----------------------------------------------------------------------- 133 // Compare two vectors and test if they are "approximately equal": 134 // 135 // equalWithAbsError (v, e) 136 // 137 // Returns true if the coefficients of this and v are the same with 138 // an absolute error of no more than e, i.e., for all i 139 // 140 // abs (this[i] - v[i]) <= e 141 // 142 // equalWithRelError (v, e) 143 // 144 // Returns true if the coefficients of this and v are the same with 145 // a relative error of no more than e, i.e., for all i 146 // 147 // abs (this[i] - v[i]) <= e * abs (this[i]) 148 //----------------------------------------------------------------------- 149 150 bool equalWithAbsError (const Vec2<T> &v, T e) const; 151 bool equalWithRelError (const Vec2<T> &v, T e) const; 152 153 //------------ 154 // Dot product 155 //------------ 156 157 T dot (const Vec2 &v) const; 158 T operator ^ (const Vec2 &v) const; 159 160 161 //------------------------------------------------ 162 // Right-handed cross product, i.e. z component of 163 // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0) 164 //------------------------------------------------ 165 166 T cross (const Vec2 &v) const; 167 T operator % (const Vec2 &v) const; 168 169 170 //------------------------ 171 // Component-wise addition 172 //------------------------ 173 174 const Vec2 & operator += (const Vec2 &v); 175 Vec2 operator + (const Vec2 &v) const; 176 177 178 //--------------------------- 179 // Component-wise subtraction 180 //--------------------------- 181 182 const Vec2 & operator -= (const Vec2 &v); 183 Vec2 operator - (const Vec2 &v) const; 184 185 186 //------------------------------------ 187 // Component-wise multiplication by -1 188 //------------------------------------ 189 190 Vec2 operator - () const; 191 const Vec2 & negate (); 192 193 194 //------------------------------ 195 // Component-wise multiplication 196 //------------------------------ 197 198 const Vec2 & operator *= (const Vec2 &v); 199 const Vec2 & operator *= (T a); 200 Vec2 operator * (const Vec2 &v) const; 201 Vec2 operator * (T a) const; 202 203 204 //------------------------ 205 // Component-wise division 206 //------------------------ 207 208 const Vec2 & operator /= (const Vec2 &v); 209 const Vec2 & operator /= (T a); 210 Vec2 operator / (const Vec2 &v) const; 211 Vec2 operator / (T a) const; 212 213 214 //---------------------------------------------------------------- 215 // Length and normalization: If v.length() is 0.0, v.normalize() 216 // and v.normalized() produce a null vector; v.normalizeExc() and 217 // v.normalizedExc() throw a NullVecExc. 218 // v.normalizeNonNull() and v.normalizedNonNull() are slightly 219 // faster than the other normalization routines, but if v.length() 220 // is 0.0, the result is undefined. 221 //---------------------------------------------------------------- 222 223 T length () const; 224 T length2 () const; 225 226 const Vec2 & normalize (); // modifies *this 227 const Vec2 & normalizeExc () throw (Iex::MathExc); 228 const Vec2 & normalizeNonNull (); 229 230 Vec2<T> normalized () const; // does not modify *this 231 Vec2<T> normalizedExc () const throw (Iex::MathExc); 232 Vec2<T> normalizedNonNull () const; 233 234 235 //-------------------------------------------------------- 236 // Number of dimensions, i.e. number of elements in a Vec2 237 //-------------------------------------------------------- 238 239 static unsigned int dimensions() {return 2;} 240 241 242 //------------------------------------------------- 243 // Limitations of type T (see also class limits<T>) 244 //------------------------------------------------- 245 246 static T baseTypeMin() {return limits<T>::min();} 247 static T baseTypeMax() {return limits<T>::max();} 248 static T baseTypeSmallest() {return limits<T>::smallest();} 249 static T baseTypeEpsilon() {return limits<T>::epsilon();} 250 251 252 //-------------------------------------------------------------- 253 // Base type -- in templates, which accept a parameter, V, which 254 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 255 // refer to T as V::BaseType 256 //-------------------------------------------------------------- 257 258 typedef T BaseType; 259 260 private: 261 262 T lengthTiny () const; 263 }; 264 265 266 template <class T> class Vec3 267 { 268 public: 269 270 //------------------- 271 // Access to elements 272 //------------------- 273 274 T x, y, z; 275 276 T & operator [] (int i); 277 const T & operator [] (int i) const; 278 279 280 //------------- 281 // Constructors 282 //------------- 283 284 Vec3 (); // no initialization 285 explicit Vec3 (T a); // (a a a) 286 Vec3 (T a, T b, T c); // (a b c) 287 288 289 //--------------------------------- 290 // Copy constructors and assignment 291 //--------------------------------- 292 293 Vec3 (const Vec3 &v); 294 template <class S> Vec3 (const Vec3<S> &v); 295 296 const Vec3 & operator = (const Vec3 &v); 297 298 299 //--------------------------------------------------------- 300 // Vec4 to Vec3 conversion, divides x, y and z by w: 301 // 302 // The one-argument conversion function divides by w even 303 // if w is zero. The result depends on how the environment 304 // handles floating-point exceptions. 305 // 306 // The two-argument version thows an InfPointExc exception 307 // if w is zero or if division by w would overflow. 308 //--------------------------------------------------------- 309 310 template <class S> explicit Vec3 (const Vec4<S> &v); 311 template <class S> explicit Vec3 (const Vec4<S> &v, InfException); 312 313 314 //---------------------- 315 // Compatibility with Sb 316 //---------------------- 317 318 template <class S> 319 void setValue (S a, S b, S c); 320 321 template <class S> 322 void setValue (const Vec3<S> &v); 323 324 template <class S> 325 void getValue (S &a, S &b, S &c) const; 326 327 template <class S> 328 void getValue (Vec3<S> &v) const; 329 330 T * getValue(); 331 const T * getValue() const; 332 333 334 //--------- 335 // Equality 336 //--------- 337 338 template <class S> 339 bool operator == (const Vec3<S> &v) const; 340 341 template <class S> 342 bool operator != (const Vec3<S> &v) const; 343 344 //----------------------------------------------------------------------- 345 // Compare two vectors and test if they are "approximately equal": 346 // 347 // equalWithAbsError (v, e) 348 // 349 // Returns true if the coefficients of this and v are the same with 350 // an absolute error of no more than e, i.e., for all i 351 // 352 // abs (this[i] - v[i]) <= e 353 // 354 // equalWithRelError (v, e) 355 // 356 // Returns true if the coefficients of this and v are the same with 357 // a relative error of no more than e, i.e., for all i 358 // 359 // abs (this[i] - v[i]) <= e * abs (this[i]) 360 //----------------------------------------------------------------------- 361 362 bool equalWithAbsError (const Vec3<T> &v, T e) const; 363 bool equalWithRelError (const Vec3<T> &v, T e) const; 364 365 //------------ 366 // Dot product 367 //------------ 368 369 T dot (const Vec3 &v) const; 370 T operator ^ (const Vec3 &v) const; 371 372 373 //--------------------------- 374 // Right-handed cross product 375 //--------------------------- 376 377 Vec3 cross (const Vec3 &v) const; 378 const Vec3 & operator %= (const Vec3 &v); 379 Vec3 operator % (const Vec3 &v) const; 380 381 382 //------------------------ 383 // Component-wise addition 384 //------------------------ 385 386 const Vec3 & operator += (const Vec3 &v); 387 Vec3 operator + (const Vec3 &v) const; 388 389 390 //--------------------------- 391 // Component-wise subtraction 392 //--------------------------- 393 394 const Vec3 & operator -= (const Vec3 &v); 395 Vec3 operator - (const Vec3 &v) const; 396 397 398 //------------------------------------ 399 // Component-wise multiplication by -1 400 //------------------------------------ 401 402 Vec3 operator - () const; 403 const Vec3 & negate (); 404 405 406 //------------------------------ 407 // Component-wise multiplication 408 //------------------------------ 409 410 const Vec3 & operator *= (const Vec3 &v); 411 const Vec3 & operator *= (T a); 412 Vec3 operator * (const Vec3 &v) const; 413 Vec3 operator * (T a) const; 414 415 416 //------------------------ 417 // Component-wise division 418 //------------------------ 419 420 const Vec3 & operator /= (const Vec3 &v); 421 const Vec3 & operator /= (T a); 422 Vec3 operator / (const Vec3 &v) const; 423 Vec3 operator / (T a) const; 424 425 426 //---------------------------------------------------------------- 427 // Length and normalization: If v.length() is 0.0, v.normalize() 428 // and v.normalized() produce a null vector; v.normalizeExc() and 429 // v.normalizedExc() throw a NullVecExc. 430 // v.normalizeNonNull() and v.normalizedNonNull() are slightly 431 // faster than the other normalization routines, but if v.length() 432 // is 0.0, the result is undefined. 433 //---------------------------------------------------------------- 434 435 T length () const; 436 T length2 () const; 437 438 const Vec3 & normalize (); // modifies *this 439 const Vec3 & normalizeExc () throw (Iex::MathExc); 440 const Vec3 & normalizeNonNull (); 441 442 Vec3<T> normalized () const; // does not modify *this 443 Vec3<T> normalizedExc () const throw (Iex::MathExc); 444 Vec3<T> normalizedNonNull () const; 445 446 447 //-------------------------------------------------------- 448 // Number of dimensions, i.e. number of elements in a Vec3 449 //-------------------------------------------------------- 450 451 static unsigned int dimensions() {return 3;} 452 453 454 //------------------------------------------------- 455 // Limitations of type T (see also class limits<T>) 456 //------------------------------------------------- 457 458 static T baseTypeMin() {return limits<T>::min();} 459 static T baseTypeMax() {return limits<T>::max();} 460 static T baseTypeSmallest() {return limits<T>::smallest();} 461 static T baseTypeEpsilon() {return limits<T>::epsilon();} 462 463 464 //-------------------------------------------------------------- 465 // Base type -- in templates, which accept a parameter, V, which 466 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 467 // refer to T as V::BaseType 468 //-------------------------------------------------------------- 469 470 typedef T BaseType; 471 472 private: 473 474 T lengthTiny () const; 475 }; 476 477 478 479 template <class T> class Vec4 480 { 481 public: 482 483 //------------------- 484 // Access to elements 485 //------------------- 486 487 T x, y, z, w; 488 489 T & operator [] (int i); 490 const T & operator [] (int i) const; 491 492 493 //------------- 494 // Constructors 495 //------------- 496 497 Vec4 (); // no initialization 498 explicit Vec4 (T a); // (a a a a) 499 Vec4 (T a, T b, T c, T d); // (a b c d) 500 501 502 //--------------------------------- 503 // Copy constructors and assignment 504 //--------------------------------- 505 506 Vec4 (const Vec4 &v); 507 template <class S> Vec4 (const Vec4<S> &v); 508 509 const Vec4 & operator = (const Vec4 &v); 510 511 512 //------------------------------------- 513 // Vec3 to Vec4 conversion, sets w to 1 514 //------------------------------------- 515 516 template <class S> explicit Vec4 (const Vec3<S> &v); 517 518 519 //--------- 520 // Equality 521 //--------- 522 523 template <class S> 524 bool operator == (const Vec4<S> &v) const; 525 526 template <class S> 527 bool operator != (const Vec4<S> &v) const; 528 529 530 //----------------------------------------------------------------------- 531 // Compare two vectors and test if they are "approximately equal": 532 // 533 // equalWithAbsError (v, e) 534 // 535 // Returns true if the coefficients of this and v are the same with 536 // an absolute error of no more than e, i.e., for all i 537 // 538 // abs (this[i] - v[i]) <= e 539 // 540 // equalWithRelError (v, e) 541 // 542 // Returns true if the coefficients of this and v are the same with 543 // a relative error of no more than e, i.e., for all i 544 // 545 // abs (this[i] - v[i]) <= e * abs (this[i]) 546 //----------------------------------------------------------------------- 547 548 bool equalWithAbsError (const Vec4<T> &v, T e) const; 549 bool equalWithRelError (const Vec4<T> &v, T e) const; 550 551 552 //------------ 553 // Dot product 554 //------------ 555 556 T dot (const Vec4 &v) const; 557 T operator ^ (const Vec4 &v) const; 558 559 560 //----------------------------------- 561 // Cross product is not defined in 4D 562 //----------------------------------- 563 564 //------------------------ 565 // Component-wise addition 566 //------------------------ 567 568 const Vec4 & operator += (const Vec4 &v); 569 Vec4 operator + (const Vec4 &v) const; 570 571 572 //--------------------------- 573 // Component-wise subtraction 574 //--------------------------- 575 576 const Vec4 & operator -= (const Vec4 &v); 577 Vec4 operator - (const Vec4 &v) const; 578 579 580 //------------------------------------ 581 // Component-wise multiplication by -1 582 //------------------------------------ 583 584 Vec4 operator - () const; 585 const Vec4 & negate (); 586 587 588 //------------------------------ 589 // Component-wise multiplication 590 //------------------------------ 591 592 const Vec4 & operator *= (const Vec4 &v); 593 const Vec4 & operator *= (T a); 594 Vec4 operator * (const Vec4 &v) const; 595 Vec4 operator * (T a) const; 596 597 598 //------------------------ 599 // Component-wise division 600 //------------------------ 601 602 const Vec4 & operator /= (const Vec4 &v); 603 const Vec4 & operator /= (T a); 604 Vec4 operator / (const Vec4 &v) const; 605 Vec4 operator / (T a) const; 606 607 608 //---------------------------------------------------------------- 609 // Length and normalization: If v.length() is 0.0, v.normalize() 610 // and v.normalized() produce a null vector; v.normalizeExc() and 611 // v.normalizedExc() throw a NullVecExc. 612 // v.normalizeNonNull() and v.normalizedNonNull() are slightly 613 // faster than the other normalization routines, but if v.length() 614 // is 0.0, the result is undefined. 615 //---------------------------------------------------------------- 616 617 T length () const; 618 T length2 () const; 619 620 const Vec4 & normalize (); // modifies *this 621 const Vec4 & normalizeExc () throw (Iex::MathExc); 622 const Vec4 & normalizeNonNull (); 623 624 Vec4<T> normalized () const; // does not modify *this 625 Vec4<T> normalizedExc () const throw (Iex::MathExc); 626 Vec4<T> normalizedNonNull () const; 627 628 629 //-------------------------------------------------------- 630 // Number of dimensions, i.e. number of elements in a Vec4 631 //-------------------------------------------------------- 632 633 static unsigned int dimensions() {return 4;} 634 635 636 //------------------------------------------------- 637 // Limitations of type T (see also class limits<T>) 638 //------------------------------------------------- 639 640 static T baseTypeMin() {return limits<T>::min();} 641 static T baseTypeMax() {return limits<T>::max();} 642 static T baseTypeSmallest() {return limits<T>::smallest();} 643 static T baseTypeEpsilon() {return limits<T>::epsilon();} 644 645 646 //-------------------------------------------------------------- 647 // Base type -- in templates, which accept a parameter, V, which 648 // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 649 // refer to T as V::BaseType 650 //-------------------------------------------------------------- 651 652 typedef T BaseType; 653 654 private: 655 656 T lengthTiny () const; 657 }; 658 659 660 //-------------- 661 // Stream output 662 //-------------- 663 664 template <class T> 665 std::ostream & operator << (std::ostream &s, const Vec2<T> &v); 666 667 template <class T> 668 std::ostream & operator << (std::ostream &s, const Vec3<T> &v); 669 670 template <class T> 671 std::ostream & operator << (std::ostream &s, const Vec4<T> &v); 672 673 //---------------------------------------------------- 674 // Reverse multiplication: S * Vec2<T> and S * Vec3<T> 675 //---------------------------------------------------- 676 677 template <class T> Vec2<T> operator * (T a, const Vec2<T> &v); 678 template <class T> Vec3<T> operator * (T a, const Vec3<T> &v); 679 template <class T> Vec4<T> operator * (T a, const Vec4<T> &v); 680 681 682 //------------------------- 683 // Typedefs for convenience 684 //------------------------- 685 686 typedef Vec2 <short> V2s; 687 typedef Vec2 <int> V2i; 688 typedef Vec2 <float> V2f; 689 typedef Vec2 <double> V2d; 690 typedef Vec3 <short> V3s; 691 typedef Vec3 <int> V3i; 692 typedef Vec3 <float> V3f; 693 typedef Vec3 <double> V3d; 694 typedef Vec4 <short> V4s; 695 typedef Vec4 <int> V4i; 696 typedef Vec4 <float> V4f; 697 typedef Vec4 <double> V4d; 698 699 700 //------------------------------------------- 701 // Specializations for VecN<short>, VecN<int> 702 //------------------------------------------- 703 704 // Vec2<short> 705 706 template <> short 707 Vec2<short>::length () const; 708 709 template <> const Vec2<short> & 710 Vec2<short>::normalize (); 711 712 template <> const Vec2<short> & 713 Vec2<short>::normalizeExc () throw (Iex::MathExc); 714 715 template <> const Vec2<short> & 716 Vec2<short>::normalizeNonNull (); 717 718 template <> Vec2<short> 719 Vec2<short>::normalized () const; 720 721 template <> Vec2<short> 722 Vec2<short>::normalizedExc () const throw (Iex::MathExc); 723 724 template <> Vec2<short> 725 Vec2<short>::normalizedNonNull () const; 726 727 728 // Vec2<int> 729 730 template <> int 731 Vec2<int>::length () const; 732 733 template <> const Vec2<int> & 734 Vec2<int>::normalize (); 735 736 template <> const Vec2<int> & 737 Vec2<int>::normalizeExc () throw (Iex::MathExc); 738 739 template <> const Vec2<int> & 740 Vec2<int>::normalizeNonNull (); 741 742 template <> Vec2<int> 743 Vec2<int>::normalized () const; 744 745 template <> Vec2<int> 746 Vec2<int>::normalizedExc () const throw (Iex::MathExc); 747 748 template <> Vec2<int> 749 Vec2<int>::normalizedNonNull () const; 750 751 752 // Vec3<short> 753 754 template <> short 755 Vec3<short>::length () const; 756 757 template <> const Vec3<short> & 758 Vec3<short>::normalize (); 759 760 template <> const Vec3<short> & 761 Vec3<short>::normalizeExc () throw (Iex::MathExc); 762 763 template <> const Vec3<short> & 764 Vec3<short>::normalizeNonNull (); 765 766 template <> Vec3<short> 767 Vec3<short>::normalized () const; 768 769 template <> Vec3<short> 770 Vec3<short>::normalizedExc () const throw (Iex::MathExc); 771 772 template <> Vec3<short> 773 Vec3<short>::normalizedNonNull () const; 774 775 776 // Vec3<int> 777 778 template <> int 779 Vec3<int>::length () const; 780 781 template <> const Vec3<int> & 782 Vec3<int>::normalize (); 783 784 template <> const Vec3<int> & 785 Vec3<int>::normalizeExc () throw (Iex::MathExc); 786 787 template <> const Vec3<int> & 788 Vec3<int>::normalizeNonNull (); 789 790 template <> Vec3<int> 791 Vec3<int>::normalized () const; 792 793 template <> Vec3<int> 794 Vec3<int>::normalizedExc () const throw (Iex::MathExc); 795 796 template <> Vec3<int> 797 Vec3<int>::normalizedNonNull () const; 798 799 // Vec4<short> 800 801 template <> short 802 Vec4<short>::length () const; 803 804 template <> const Vec4<short> & 805 Vec4<short>::normalize (); 806 807 template <> const Vec4<short> & 808 Vec4<short>::normalizeExc () throw (Iex::MathExc); 809 810 template <> const Vec4<short> & 811 Vec4<short>::normalizeNonNull (); 812 813 template <> Vec4<short> 814 Vec4<short>::normalized () const; 815 816 template <> Vec4<short> 817 Vec4<short>::normalizedExc () const throw (Iex::MathExc); 818 819 template <> Vec4<short> 820 Vec4<short>::normalizedNonNull () const; 821 822 823 // Vec4<int> 824 825 template <> int 826 Vec4<int>::length () const; 827 828 template <> const Vec4<int> & 829 Vec4<int>::normalize (); 830 831 template <> const Vec4<int> & 832 Vec4<int>::normalizeExc () throw (Iex::MathExc); 833 834 template <> const Vec4<int> & 835 Vec4<int>::normalizeNonNull (); 836 837 template <> Vec4<int> 838 Vec4<int>::normalized () const; 839 840 template <> Vec4<int> 841 Vec4<int>::normalizedExc () const throw (Iex::MathExc); 842 843 template <> Vec4<int> 844 Vec4<int>::normalizedNonNull () const; 845 846 847 //------------------------ 848 // Implementation of Vec2: 849 //------------------------ 850 851 template <class T> 852 inline T & 853 Vec2<T>::operator [] (int i) 854 { 855 return (&x)[i]; 856 } 857 858 template <class T> 859 inline const T & 860 Vec2<T>::operator [] (int i) const 861 { 862 return (&x)[i]; 863 } 864 865 template <class T> 866 inline 867 Vec2<T>::Vec2 () 868 { 869 // empty 870 } 871 872 template <class T> 873 inline 874 Vec2<T>::Vec2 (T a) 875 { 876 x = y = a; 877 } 878 879 template <class T> 880 inline 881 Vec2<T>::Vec2 (T a, T b) 882 { 883 x = a; 884 y = b; 885 } 886 887 template <class T> 888 inline 889 Vec2<T>::Vec2 (const Vec2 &v) 890 { 891 x = v.x; 892 y = v.y; 893 } 894 895 template <class T> 896 template <class S> 897 inline 898 Vec2<T>::Vec2 (const Vec2<S> &v) 899 { 900 x = T (v.x); 901 y = T (v.y); 902 } 903 904 template <class T> 905 inline const Vec2<T> & 906 Vec2<T>::operator = (const Vec2 &v) 907 { 908 x = v.x; 909 y = v.y; 910 return *this; 911 } 912 913 template <class T> 914 template <class S> 915 inline void 916 Vec2<T>::setValue (S a, S b) 917 { 918 x = T (a); 919 y = T (b); 920 } 921 922 template <class T> 923 template <class S> 924 inline void 925 Vec2<T>::setValue (const Vec2<S> &v) 926 { 927 x = T (v.x); 928 y = T (v.y); 929 } 930 931 template <class T> 932 template <class S> 933 inline void 934 Vec2<T>::getValue (S &a, S &b) const 935 { 936 a = S (x); 937 b = S (y); 938 } 939 940 template <class T> 941 template <class S> 942 inline void 943 Vec2<T>::getValue (Vec2<S> &v) const 944 { 945 v.x = S (x); 946 v.y = S (y); 947 } 948 949 template <class T> 950 inline T * 951 Vec2<T>::getValue() 952 { 953 return (T *) &x; 954 } 955 956 template <class T> 957 inline const T * 958 Vec2<T>::getValue() const 959 { 960 return (const T *) &x; 961 } 962 963 template <class T> 964 template <class S> 965 inline bool 966 Vec2<T>::operator == (const Vec2<S> &v) const 967 { 968 return x == v.x && y == v.y; 969 } 970 971 template <class T> 972 template <class S> 973 inline bool 974 Vec2<T>::operator != (const Vec2<S> &v) const 975 { 976 return x != v.x || y != v.y; 977 } 978 979 template <class T> 980 bool 981 Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const 982 { 983 for (int i = 0; i < 2; i++) 984 if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) 985 return false; 986 987 return true; 988 } 989 990 template <class T> 991 bool 992 Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const 993 { 994 for (int i = 0; i < 2; i++) 995 if (!Imath::equalWithRelError ((*this)[i], v[i], e)) 996 return false; 997 998 return true; 999 } 1000 1001 template <class T> 1002 inline T 1003 Vec2<T>::dot (const Vec2 &v) const 1004 { 1005 return x * v.x + y * v.y; 1006 } 1007 1008 template <class T> 1009 inline T 1010 Vec2<T>::operator ^ (const Vec2 &v) const 1011 { 1012 return dot (v); 1013 } 1014 1015 template <class T> 1016 inline T 1017 Vec2<T>::cross (const Vec2 &v) const 1018 { 1019 return x * v.y - y * v.x; 1020 1021 } 1022 1023 template <class T> 1024 inline T 1025 Vec2<T>::operator % (const Vec2 &v) const 1026 { 1027 return x * v.y - y * v.x; 1028 } 1029 1030 template <class T> 1031 inline const Vec2<T> & 1032 Vec2<T>::operator += (const Vec2 &v) 1033 { 1034 x += v.x; 1035 y += v.y; 1036 return *this; 1037 } 1038 1039 template <class T> 1040 inline Vec2<T> 1041 Vec2<T>::operator + (const Vec2 &v) const 1042 { 1043 return Vec2 (x + v.x, y + v.y); 1044 } 1045 1046 template <class T> 1047 inline const Vec2<T> & 1048 Vec2<T>::operator -= (const Vec2 &v) 1049 { 1050 x -= v.x; 1051 y -= v.y; 1052 return *this; 1053 } 1054 1055 template <class T> 1056 inline Vec2<T> 1057 Vec2<T>::operator - (const Vec2 &v) const 1058 { 1059 return Vec2 (x - v.x, y - v.y); 1060 } 1061 1062 template <class T> 1063 inline Vec2<T> 1064 Vec2<T>::operator - () const 1065 { 1066 return Vec2 (-x, -y); 1067 } 1068 1069 template <class T> 1070 inline const Vec2<T> & 1071 Vec2<T>::negate () 1072 { 1073 x = -x; 1074 y = -y; 1075 return *this; 1076 } 1077 1078 template <class T> 1079 inline const Vec2<T> & 1080 Vec2<T>::operator *= (const Vec2 &v) 1081 { 1082 x *= v.x; 1083 y *= v.y; 1084 return *this; 1085 } 1086 1087 template <class T> 1088 inline const Vec2<T> & 1089 Vec2<T>::operator *= (T a) 1090 { 1091 x *= a; 1092 y *= a; 1093 return *this; 1094 } 1095 1096 template <class T> 1097 inline Vec2<T> 1098 Vec2<T>::operator * (const Vec2 &v) const 1099 { 1100 return Vec2 (x * v.x, y * v.y); 1101 } 1102 1103 template <class T> 1104 inline Vec2<T> 1105 Vec2<T>::operator * (T a) const 1106 { 1107 return Vec2 (x * a, y * a); 1108 } 1109 1110 template <class T> 1111 inline const Vec2<T> & 1112 Vec2<T>::operator /= (const Vec2 &v) 1113 { 1114 x /= v.x; 1115 y /= v.y; 1116 return *this; 1117 } 1118 1119 template <class T> 1120 inline const Vec2<T> & 1121 Vec2<T>::operator /= (T a) 1122 { 1123 x /= a; 1124 y /= a; 1125 return *this; 1126 } 1127 1128 template <class T> 1129 inline Vec2<T> 1130 Vec2<T>::operator / (const Vec2 &v) const 1131 { 1132 return Vec2 (x / v.x, y / v.y); 1133 } 1134 1135 template <class T> 1136 inline Vec2<T> 1137 Vec2<T>::operator / (T a) const 1138 { 1139 return Vec2 (x / a, y / a); 1140 } 1141 1142 template <class T> 1143 T 1144 Vec2<T>::lengthTiny () const 1145 { 1146 T absX = (x >= T (0))? x: -x; 1147 T absY = (y >= T (0))? y: -y; 1148 1149 T max = absX; 1150 1151 if (max < absY) 1152 max = absY; 1153 1154 if (max == T (0)) 1155 return T (0); 1156 1157 // 1158 // Do not replace the divisions by max with multiplications by 1/max. 1159 // Computing 1/max can overflow but the divisions below will always 1160 // produce results less than or equal to 1. 1161 // 1162 1163 absX /= max; 1164 absY /= max; 1165 1166 return max * Math<T>::sqrt (absX * absX + absY * absY); 1167 } 1168 1169 template <class T> 1170 inline T 1171 Vec2<T>::length () const 1172 { 1173 T length2 = dot (*this); 1174 1175 if (length2 < T (2) * limits<T>::smallest()) 1176 return lengthTiny(); 1177 1178 return Math<T>::sqrt (length2); 1179 } 1180 1181 template <class T> 1182 inline T 1183 Vec2<T>::length2 () const 1184 { 1185 return dot (*this); 1186 } 1187 1188 template <class T> 1189 const Vec2<T> & 1190 Vec2<T>::normalize () 1191 { 1192 T l = length(); 1193 1194 if (l != T (0)) 1195 { 1196 // 1197 // Do not replace the divisions by l with multiplications by 1/l. 1198 // Computing 1/l can overflow but the divisions below will always 1199 // produce results less than or equal to 1. 1200 // 1201 1202 x /= l; 1203 y /= l; 1204 } 1205 1206 return *this; 1207 } 1208 1209 template <class T> 1210 const Vec2<T> & 1211 Vec2<T>::normalizeExc () throw (Iex::MathExc) 1212 { 1213 T l = length(); 1214 1215 if (l == T (0)) 1216 throw NullVecExc ("Cannot normalize null vector."); 1217 1218 x /= l; 1219 y /= l; 1220 return *this; 1221 } 1222 1223 template <class T> 1224 inline 1225 const Vec2<T> & 1226 Vec2<T>::normalizeNonNull () 1227 { 1228 T l = length(); 1229 x /= l; 1230 y /= l; 1231 return *this; 1232 } 1233 1234 template <class T> 1235 Vec2<T> 1236 Vec2<T>::normalized () const 1237 { 1238 T l = length(); 1239 1240 if (l == T (0)) 1241 return Vec2 (T (0)); 1242 1243 return Vec2 (x / l, y / l); 1244 } 1245 1246 template <class T> 1247 Vec2<T> 1248 Vec2<T>::normalizedExc () const throw (Iex::MathExc) 1249 { 1250 T l = length(); 1251 1252 if (l == T (0)) 1253 throw NullVecExc ("Cannot normalize null vector."); 1254 1255 return Vec2 (x / l, y / l); 1256 } 1257 1258 template <class T> 1259 inline 1260 Vec2<T> 1261 Vec2<T>::normalizedNonNull () const 1262 { 1263 T l = length(); 1264 return Vec2 (x / l, y / l); 1265 } 1266 1267 1268 //----------------------- 1269 // Implementation of Vec3 1270 //----------------------- 1271 1272 template <class T> 1273 inline T & 1274 Vec3<T>::operator [] (int i) 1275 { 1276 return (&x)[i]; 1277 } 1278 1279 template <class T> 1280 inline const T & 1281 Vec3<T>::operator [] (int i) const 1282 { 1283 return (&x)[i]; 1284 } 1285 1286 template <class T> 1287 inline 1288 Vec3<T>::Vec3 () 1289 { 1290 // empty 1291 } 1292 1293 template <class T> 1294 inline 1295 Vec3<T>::Vec3 (T a) 1296 { 1297 x = y = z = a; 1298 } 1299 1300 template <class T> 1301 inline 1302 Vec3<T>::Vec3 (T a, T b, T c) 1303 { 1304 x = a; 1305 y = b; 1306 z = c; 1307 } 1308 1309 template <class T> 1310 inline 1311 Vec3<T>::Vec3 (const Vec3 &v) 1312 { 1313 x = v.x; 1314 y = v.y; 1315 z = v.z; 1316 } 1317 1318 template <class T> 1319 template <class S> 1320 inline 1321 Vec3<T>::Vec3 (const Vec3<S> &v) 1322 { 1323 x = T (v.x); 1324 y = T (v.y); 1325 z = T (v.z); 1326 } 1327 1328 template <class T> 1329 inline const Vec3<T> & 1330 Vec3<T>::operator = (const Vec3 &v) 1331 { 1332 x = v.x; 1333 y = v.y; 1334 z = v.z; 1335 return *this; 1336 } 1337 1338 template <class T> 1339 template <class S> 1340 inline 1341 Vec3<T>::Vec3 (const Vec4<S> &v) 1342 { 1343 x = T (v.x / v.w); 1344 y = T (v.y / v.w); 1345 z = T (v.z / v.w); 1346 } 1347 1348 template <class T> 1349 template <class S> 1350 Vec3<T>::Vec3 (const Vec4<S> &v, InfException) 1351 { 1352 T vx = T (v.x); 1353 T vy = T (v.y); 1354 T vz = T (v.z); 1355 T vw = T (v.w); 1356 1357 T absW = (vw >= T (0))? vw: -vw; 1358 1359 if (absW < 1) 1360 { 1361 T m = baseTypeMax() * absW; 1362 1363 if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m) 1364 throw InfPointExc ("Cannot normalize point at infinity."); 1365 } 1366 1367 x = vx / vw; 1368 y = vy / vw; 1369 z = vz / vw; 1370 } 1371 1372 template <class T> 1373 template <class S> 1374 inline void 1375 Vec3<T>::setValue (S a, S b, S c) 1376 { 1377 x = T (a); 1378 y = T (b); 1379 z = T (c); 1380 } 1381 1382 template <class T> 1383 template <class S> 1384 inline void 1385 Vec3<T>::setValue (const Vec3<S> &v) 1386 { 1387 x = T (v.x); 1388 y = T (v.y); 1389 z = T (v.z); 1390 } 1391 1392 template <class T> 1393 template <class S> 1394 inline void 1395 Vec3<T>::getValue (S &a, S &b, S &c) const 1396 { 1397 a = S (x); 1398 b = S (y); 1399 c = S (z); 1400 } 1401 1402 template <class T> 1403 template <class S> 1404 inline void 1405 Vec3<T>::getValue (Vec3<S> &v) const 1406 { 1407 v.x = S (x); 1408 v.y = S (y); 1409 v.z = S (z); 1410 } 1411 1412 template <class T> 1413 inline T * 1414 Vec3<T>::getValue() 1415 { 1416 return (T *) &x; 1417 } 1418 1419 template <class T> 1420 inline const T * 1421 Vec3<T>::getValue() const 1422 { 1423 return (const T *) &x; 1424 } 1425 1426 template <class T> 1427 template <class S> 1428 inline bool 1429 Vec3<T>::operator == (const Vec3<S> &v) const 1430 { 1431 return x == v.x && y == v.y && z == v.z; 1432 } 1433 1434 template <class T> 1435 template <class S> 1436 inline bool 1437 Vec3<T>::operator != (const Vec3<S> &v) const 1438 { 1439 return x != v.x || y != v.y || z != v.z; 1440 } 1441 1442 template <class T> 1443 bool 1444 Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const 1445 { 1446 for (int i = 0; i < 3; i++) 1447 if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) 1448 return false; 1449 1450 return true; 1451 } 1452 1453 template <class T> 1454 bool 1455 Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const 1456 { 1457 for (int i = 0; i < 3; i++) 1458 if (!Imath::equalWithRelError ((*this)[i], v[i], e)) 1459 return false; 1460 1461 return true; 1462 } 1463 1464 template <class T> 1465 inline T 1466 Vec3<T>::dot (const Vec3 &v) const 1467 { 1468 return x * v.x + y * v.y + z * v.z; 1469 } 1470 1471 template <class T> 1472 inline T 1473 Vec3<T>::operator ^ (const Vec3 &v) const 1474 { 1475 return dot (v); 1476 } 1477 1478 template <class T> 1479 inline Vec3<T> 1480 Vec3<T>::cross (const Vec3 &v) const 1481 { 1482 return Vec3 (y * v.z - z * v.y, 1483 z * v.x - x * v.z, 1484 x * v.y - y * v.x); 1485 } 1486 1487 template <class T> 1488 inline const Vec3<T> & 1489 Vec3<T>::operator %= (const Vec3 &v) 1490 { 1491 T a = y * v.z - z * v.y; 1492 T b = z * v.x - x * v.z; 1493 T c = x * v.y - y * v.x; 1494 x = a; 1495 y = b; 1496 z = c; 1497 return *this; 1498 } 1499 1500 template <class T> 1501 inline Vec3<T> 1502 Vec3<T>::operator % (const Vec3 &v) const 1503 { 1504 return Vec3 (y * v.z - z * v.y, 1505 z * v.x - x * v.z, 1506 x * v.y - y * v.x); 1507 } 1508 1509 template <class T> 1510 inline const Vec3<T> & 1511 Vec3<T>::operator += (const Vec3 &v) 1512 { 1513 x += v.x; 1514 y += v.y; 1515 z += v.z; 1516 return *this; 1517 } 1518 1519 template <class T> 1520 inline Vec3<T> 1521 Vec3<T>::operator + (const Vec3 &v) const 1522 { 1523 return Vec3 (x + v.x, y + v.y, z + v.z); 1524 } 1525 1526 template <class T> 1527 inline const Vec3<T> & 1528 Vec3<T>::operator -= (const Vec3 &v) 1529 { 1530 x -= v.x; 1531 y -= v.y; 1532 z -= v.z; 1533 return *this; 1534 } 1535 1536 template <class T> 1537 inline Vec3<T> 1538 Vec3<T>::operator - (const Vec3 &v) const 1539 { 1540 return Vec3 (x - v.x, y - v.y, z - v.z); 1541 } 1542 1543 template <class T> 1544 inline Vec3<T> 1545 Vec3<T>::operator - () const 1546 { 1547 return Vec3 (-x, -y, -z); 1548 } 1549 1550 template <class T> 1551 inline const Vec3<T> & 1552 Vec3<T>::negate () 1553 { 1554 x = -x; 1555 y = -y; 1556 z = -z; 1557 return *this; 1558 } 1559 1560 template <class T> 1561 inline const Vec3<T> & 1562 Vec3<T>::operator *= (const Vec3 &v) 1563 { 1564 x *= v.x; 1565 y *= v.y; 1566 z *= v.z; 1567 return *this; 1568 } 1569 1570 template <class T> 1571 inline const Vec3<T> & 1572 Vec3<T>::operator *= (T a) 1573 { 1574 x *= a; 1575 y *= a; 1576 z *= a; 1577 return *this; 1578 } 1579 1580 template <class T> 1581 inline Vec3<T> 1582 Vec3<T>::operator * (const Vec3 &v) const 1583 { 1584 return Vec3 (x * v.x, y * v.y, z * v.z); 1585 } 1586 1587 template <class T> 1588 inline Vec3<T> 1589 Vec3<T>::operator * (T a) const 1590 { 1591 return Vec3 (x * a, y * a, z * a); 1592 } 1593 1594 template <class T> 1595 inline const Vec3<T> & 1596 Vec3<T>::operator /= (const Vec3 &v) 1597 { 1598 x /= v.x; 1599 y /= v.y; 1600 z /= v.z; 1601 return *this; 1602 } 1603 1604 template <class T> 1605 inline const Vec3<T> & 1606 Vec3<T>::operator /= (T a) 1607 { 1608 x /= a; 1609 y /= a; 1610 z /= a; 1611 return *this; 1612 } 1613 1614 template <class T> 1615 inline Vec3<T> 1616 Vec3<T>::operator / (const Vec3 &v) const 1617 { 1618 return Vec3 (x / v.x, y / v.y, z / v.z); 1619 } 1620 1621 template <class T> 1622 inline Vec3<T> 1623 Vec3<T>::operator / (T a) const 1624 { 1625 return Vec3 (x / a, y / a, z / a); 1626 } 1627 1628 template <class T> 1629 T 1630 Vec3<T>::lengthTiny () const 1631 { 1632 T absX = (x >= T (0))? x: -x; 1633 T absY = (y >= T (0))? y: -y; 1634 T absZ = (z >= T (0))? z: -z; 1635 1636 T max = absX; 1637 1638 if (max < absY) 1639 max = absY; 1640 1641 if (max < absZ) 1642 max = absZ; 1643 1644 if (max == T (0)) 1645 return T (0); 1646 1647 // 1648 // Do not replace the divisions by max with multiplications by 1/max. 1649 // Computing 1/max can overflow but the divisions below will always 1650 // produce results less than or equal to 1. 1651 // 1652 1653 absX /= max; 1654 absY /= max; 1655 absZ /= max; 1656 1657 return max * Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ); 1658 } 1659 1660 template <class T> 1661 inline T 1662 Vec3<T>::length () const 1663 { 1664 T length2 = dot (*this); 1665 1666 if (length2 < T (2) * limits<T>::smallest()) 1667 return lengthTiny(); 1668 1669 return Math<T>::sqrt (length2); 1670 } 1671 1672 template <class T> 1673 inline T 1674 Vec3<T>::length2 () const 1675 { 1676 return dot (*this); 1677 } 1678 1679 template <class T> 1680 const Vec3<T> & 1681 Vec3<T>::normalize () 1682 { 1683 T l = length(); 1684 1685 if (l != T (0)) 1686 { 1687 // 1688 // Do not replace the divisions by l with multiplications by 1/l. 1689 // Computing 1/l can overflow but the divisions below will always 1690 // produce results less than or equal to 1. 1691 // 1692 1693 x /= l; 1694 y /= l; 1695 z /= l; 1696 } 1697 1698 return *this; 1699 } 1700 1701 template <class T> 1702 const Vec3<T> & 1703 Vec3<T>::normalizeExc () throw (Iex::MathExc) 1704 { 1705 T l = length(); 1706 1707 if (l == T (0)) 1708 throw NullVecExc ("Cannot normalize null vector."); 1709 1710 x /= l; 1711 y /= l; 1712 z /= l; 1713 return *this; 1714 } 1715 1716 template <class T> 1717 inline 1718 const Vec3<T> & 1719 Vec3<T>::normalizeNonNull () 1720 { 1721 T l = length(); 1722 x /= l; 1723 y /= l; 1724 z /= l; 1725 return *this; 1726 } 1727 1728 template <class T> 1729 Vec3<T> 1730 Vec3<T>::normalized () const 1731 { 1732 T l = length(); 1733 1734 if (l == T (0)) 1735 return Vec3 (T (0)); 1736 1737 return Vec3 (x / l, y / l, z / l); 1738 } 1739 1740 template <class T> 1741 Vec3<T> 1742 Vec3<T>::normalizedExc () const throw (Iex::MathExc) 1743 { 1744 T l = length(); 1745 1746 if (l == T (0)) 1747 throw NullVecExc ("Cannot normalize null vector."); 1748 1749 return Vec3 (x / l, y / l, z / l); 1750 } 1751 1752 template <class T> 1753 inline 1754 Vec3<T> 1755 Vec3<T>::normalizedNonNull () const 1756 { 1757 T l = length(); 1758 return Vec3 (x / l, y / l, z / l); 1759 } 1760 1761 1762 //----------------------- 1763 // Implementation of Vec4 1764 //----------------------- 1765 1766 template <class T> 1767 inline T & 1768 Vec4<T>::operator [] (int i) 1769 { 1770 return (&x)[i]; 1771 } 1772 1773 template <class T> 1774 inline const T & 1775 Vec4<T>::operator [] (int i) const 1776 { 1777 return (&x)[i]; 1778 } 1779 1780 template <class T> 1781 inline 1782 Vec4<T>::Vec4 () 1783 { 1784 // empty 1785 } 1786 1787 template <class T> 1788 inline 1789 Vec4<T>::Vec4 (T a) 1790 { 1791 x = y = z = w = a; 1792 } 1793 1794 template <class T> 1795 inline 1796 Vec4<T>::Vec4 (T a, T b, T c, T d) 1797 { 1798 x = a; 1799 y = b; 1800 z = c; 1801 w = d; 1802 } 1803 1804 template <class T> 1805 inline 1806 Vec4<T>::Vec4 (const Vec4 &v) 1807 { 1808 x = v.x; 1809 y = v.y; 1810 z = v.z; 1811 w = v.w; 1812 } 1813 1814 template <class T> 1815 template <class S> 1816 inline 1817 Vec4<T>::Vec4 (const Vec4<S> &v) 1818 { 1819 x = T (v.x); 1820 y = T (v.y); 1821 z = T (v.z); 1822 w = T (v.w); 1823 } 1824 1825 template <class T> 1826 inline const Vec4<T> & 1827 Vec4<T>::operator = (const Vec4 &v) 1828 { 1829 x = v.x; 1830 y = v.y; 1831 z = v.z; 1832 w = v.w; 1833 return *this; 1834 } 1835 1836 template <class T> 1837 template <class S> 1838 inline 1839 Vec4<T>::Vec4 (const Vec3<S> &v) 1840 { 1841 x = T (v.x); 1842 y = T (v.y); 1843 z = T (v.z); 1844 w = T (1); 1845 } 1846 1847 template <class T> 1848 template <class S> 1849 inline bool 1850 Vec4<T>::operator == (const Vec4<S> &v) const 1851 { 1852 return x == v.x && y == v.y && z == v.z && w == v.w; 1853 } 1854 1855 template <class T> 1856 template <class S> 1857 inline bool 1858 Vec4<T>::operator != (const Vec4<S> &v) const 1859 { 1860 return x != v.x || y != v.y || z != v.z || w != v.w; 1861 } 1862 1863 template <class T> 1864 bool 1865 Vec4<T>::equalWithAbsError (const Vec4<T> &v, T e) const 1866 { 1867 for (int i = 0; i < 4; i++) 1868 if (!Imath::equalWithAbsError ((*this)[i], v[i], e)) 1869 return false; 1870 1871 return true; 1872 } 1873 1874 template <class T> 1875 bool 1876 Vec4<T>::equalWithRelError (const Vec4<T> &v, T e) const 1877 { 1878 for (int i = 0; i < 4; i++) 1879 if (!Imath::equalWithRelError ((*this)[i], v[i], e)) 1880 return false; 1881 1882 return true; 1883 } 1884 1885 template <class T> 1886 inline T 1887 Vec4<T>::dot (const Vec4 &v) const 1888 { 1889 return x * v.x + y * v.y + z * v.z + w * v.w; 1890 } 1891 1892 template <class T> 1893 inline T 1894 Vec4<T>::operator ^ (const Vec4 &v) const 1895 { 1896 return dot (v); 1897 } 1898 1899 1900 template <class T> 1901 inline const Vec4<T> & 1902 Vec4<T>::operator += (const Vec4 &v) 1903 { 1904 x += v.x; 1905 y += v.y; 1906 z += v.z; 1907 w += v.w; 1908 return *this; 1909 } 1910 1911 template <class T> 1912 inline Vec4<T> 1913 Vec4<T>::operator + (const Vec4 &v) const 1914 { 1915 return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w); 1916 } 1917 1918 template <class T> 1919 inline const Vec4<T> & 1920 Vec4<T>::operator -= (const Vec4 &v) 1921 { 1922 x -= v.x; 1923 y -= v.y; 1924 z -= v.z; 1925 w -= v.w; 1926 return *this; 1927 } 1928 1929 template <class T> 1930 inline Vec4<T> 1931 Vec4<T>::operator - (const Vec4 &v) const 1932 { 1933 return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w); 1934 } 1935 1936 template <class T> 1937 inline Vec4<T> 1938 Vec4<T>::operator - () const 1939 { 1940 return Vec4 (-x, -y, -z, -w); 1941 } 1942 1943 template <class T> 1944 inline const Vec4<T> & 1945 Vec4<T>::negate () 1946 { 1947 x = -x; 1948 y = -y; 1949 z = -z; 1950 w = -w; 1951 return *this; 1952 } 1953 1954 template <class T> 1955 inline const Vec4<T> & 1956 Vec4<T>::operator *= (const Vec4 &v) 1957 { 1958 x *= v.x; 1959 y *= v.y; 1960 z *= v.z; 1961 w *= v.w; 1962 return *this; 1963 } 1964 1965 template <class T> 1966 inline const Vec4<T> & 1967 Vec4<T>::operator *= (T a) 1968 { 1969 x *= a; 1970 y *= a; 1971 z *= a; 1972 w *= a; 1973 return *this; 1974 } 1975 1976 template <class T> 1977 inline Vec4<T> 1978 Vec4<T>::operator * (const Vec4 &v) const 1979 { 1980 return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w); 1981 } 1982 1983 template <class T> 1984 inline Vec4<T> 1985 Vec4<T>::operator * (T a) const 1986 { 1987 return Vec4 (x * a, y * a, z * a, w * a); 1988 } 1989 1990 template <class T> 1991 inline const Vec4<T> & 1992 Vec4<T>::operator /= (const Vec4 &v) 1993 { 1994 x /= v.x; 1995 y /= v.y; 1996 z /= v.z; 1997 w /= v.w; 1998 return *this; 1999 } 2000 2001 template <class T> 2002 inline const Vec4<T> & 2003 Vec4<T>::operator /= (T a) 2004 { 2005 x /= a; 2006 y /= a; 2007 z /= a; 2008 w /= a; 2009 return *this; 2010 } 2011 2012 template <class T> 2013 inline Vec4<T> 2014 Vec4<T>::operator / (const Vec4 &v) const 2015 { 2016 return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w); 2017 } 2018 2019 template <class T> 2020 inline Vec4<T> 2021 Vec4<T>::operator / (T a) const 2022 { 2023 return Vec4 (x / a, y / a, z / a, w / a); 2024 } 2025 2026 template <class T> 2027 T 2028 Vec4<T>::lengthTiny () const 2029 { 2030 T absX = (x >= T (0))? x: -x; 2031 T absY = (y >= T (0))? y: -y; 2032 T absZ = (z >= T (0))? z: -z; 2033 T absW = (w >= T (0))? w: -w; 2034 2035 T max = absX; 2036 2037 if (max < absY) 2038 max = absY; 2039 2040 if (max < absZ) 2041 max = absZ; 2042 2043 if (max < absW) 2044 max = absW; 2045 2046 if (max == T (0)) 2047 return T (0); 2048 2049 // 2050 // Do not replace the divisions by max with multiplications by 1/max. 2051 // Computing 1/max can overflow but the divisions below will always 2052 // produce results less than or equal to 1. 2053 // 2054 2055 absX /= max; 2056 absY /= max; 2057 absZ /= max; 2058 absW /= max; 2059 2060 return max * 2061 Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW); 2062 } 2063 2064 template <class T> 2065 inline T 2066 Vec4<T>::length () const 2067 { 2068 T length2 = dot (*this); 2069 2070 if (length2 < T (2) * limits<T>::smallest()) 2071 return lengthTiny(); 2072 2073 return Math<T>::sqrt (length2); 2074 } 2075 2076 template <class T> 2077 inline T 2078 Vec4<T>::length2 () const 2079 { 2080 return dot (*this); 2081 } 2082 2083 template <class T> 2084 const Vec4<T> & 2085 Vec4<T>::normalize () 2086 { 2087 T l = length(); 2088 2089 if (l != T (0)) 2090 { 2091 // 2092 // Do not replace the divisions by l with multiplications by 1/l. 2093 // Computing 1/l can overflow but the divisions below will always 2094 // produce results less than or equal to 1. 2095 // 2096 2097 x /= l; 2098 y /= l; 2099 z /= l; 2100 w /= l; 2101 } 2102 2103 return *this; 2104 } 2105 2106 template <class T> 2107 const Vec4<T> & 2108 Vec4<T>::normalizeExc () throw (Iex::MathExc) 2109 { 2110 T l = length(); 2111 2112 if (l == T (0)) 2113 throw NullVecExc ("Cannot normalize null vector."); 2114 2115 x /= l; 2116 y /= l; 2117 z /= l; 2118 w /= l; 2119 return *this; 2120 } 2121 2122 template <class T> 2123 inline 2124 const Vec4<T> & 2125 Vec4<T>::normalizeNonNull () 2126 { 2127 T l = length(); 2128 x /= l; 2129 y /= l; 2130 z /= l; 2131 w /= l; 2132 return *this; 2133 } 2134 2135 template <class T> 2136 Vec4<T> 2137 Vec4<T>::normalized () const 2138 { 2139 T l = length(); 2140 2141 if (l == T (0)) 2142 return Vec4 (T (0)); 2143 2144 return Vec4 (x / l, y / l, z / l, w / l); 2145 } 2146 2147 template <class T> 2148 Vec4<T> 2149 Vec4<T>::normalizedExc () const throw (Iex::MathExc) 2150 { 2151 T l = length(); 2152 2153 if (l == T (0)) 2154 throw NullVecExc ("Cannot normalize null vector."); 2155 2156 return Vec4 (x / l, y / l, z / l, w / l); 2157 } 2158 2159 template <class T> 2160 inline 2161 Vec4<T> 2162 Vec4<T>::normalizedNonNull () const 2163 { 2164 T l = length(); 2165 return Vec4 (x / l, y / l, z / l, w / l); 2166 } 2167 2168 //----------------------------- 2169 // Stream output implementation 2170 //----------------------------- 2171 2172 template <class T> 2173 std::ostream & 2174 operator << (std::ostream &s, const Vec2<T> &v) 2175 { 2176 return s << '(' << v.x << ' ' << v.y << ')'; 2177 } 2178 2179 template <class T> 2180 std::ostream & 2181 operator << (std::ostream &s, const Vec3<T> &v) 2182 { 2183 return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')'; 2184 } 2185 2186 template <class T> 2187 std::ostream & 2188 operator << (std::ostream &s, const Vec4<T> &v) 2189 { 2190 return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w << ')'; 2191 } 2192 2193 2194 //----------------------------------------- 2195 // Implementation of reverse multiplication 2196 //----------------------------------------- 2197 2198 template <class T> 2199 inline Vec2<T> 2200 operator * (T a, const Vec2<T> &v) 2201 { 2202 return Vec2<T> (a * v.x, a * v.y); 2203 } 2204 2205 template <class T> 2206 inline Vec3<T> 2207 operator * (T a, const Vec3<T> &v) 2208 { 2209 return Vec3<T> (a * v.x, a * v.y, a * v.z); 2210 } 2211 2212 template <class T> 2213 inline Vec4<T> 2214 operator * (T a, const Vec4<T> &v) 2215 { 2216 return Vec4<T> (a * v.x, a * v.y, a * v.z, a * v.w); 2217 } 2218 2219 2220 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER 2221 #pragma warning(pop) 2222 #endif 2223 2224 } // namespace Imath 2225 2226 #endif 2227