1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2002, 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_IMATHMATRIX_H 38 #define INCLUDED_IMATHMATRIX_H 39 40 //---------------------------------------------------------------- 41 // 42 // 2D (3x3) and 3D (4x4) transformation matrix templates. 43 // 44 //---------------------------------------------------------------- 45 46 #include "ImathPlatform.h" 47 #include "ImathFun.h" 48 #include "ImathExc.h" 49 #include "ImathVec.h" 50 #include "ImathShear.h" 51 52 #include <cstring> 53 #include <iostream> 54 #include <iomanip> 55 #include <string.h> 56 57 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER 58 // suppress exception specification warnings 59 #pragma warning(disable:4290) 60 #endif 61 62 63 namespace Imath { 64 65 enum Uninitialized {UNINITIALIZED}; 66 67 68 template <class T> class Matrix33 69 { 70 public: 71 72 //------------------- 73 // Access to elements 74 //------------------- 75 76 T x[3][3]; 77 78 T * operator [] (int i); 79 const T * operator [] (int i) const; 80 81 82 //------------- 83 // Constructors 84 //------------- 85 Matrix33(Uninitialized)86 Matrix33 (Uninitialized) {} 87 88 Matrix33 (); 89 // 1 0 0 90 // 0 1 0 91 // 0 0 1 92 93 Matrix33 (T a); 94 // a a a 95 // a a a 96 // a a a 97 98 Matrix33 (const T a[3][3]); 99 // a[0][0] a[0][1] a[0][2] 100 // a[1][0] a[1][1] a[1][2] 101 // a[2][0] a[2][1] a[2][2] 102 103 Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i); 104 105 // a b c 106 // d e f 107 // g h i 108 109 110 //-------------------------------- 111 // Copy constructor and assignment 112 //-------------------------------- 113 114 Matrix33 (const Matrix33 &v); 115 template <class S> explicit Matrix33 (const Matrix33<S> &v); 116 117 const Matrix33 & operator = (const Matrix33 &v); 118 const Matrix33 & operator = (T a); 119 120 121 //---------------------- 122 // Compatibility with Sb 123 //---------------------- 124 125 T * getValue (); 126 const T * getValue () const; 127 128 template <class S> 129 void getValue (Matrix33<S> &v) const; 130 template <class S> 131 Matrix33 & setValue (const Matrix33<S> &v); 132 133 template <class S> 134 Matrix33 & setTheMatrix (const Matrix33<S> &v); 135 136 137 //--------- 138 // Identity 139 //--------- 140 141 void makeIdentity(); 142 143 144 //--------- 145 // Equality 146 //--------- 147 148 bool operator == (const Matrix33 &v) const; 149 bool operator != (const Matrix33 &v) const; 150 151 //----------------------------------------------------------------------- 152 // Compare two matrices and test if they are "approximately equal": 153 // 154 // equalWithAbsError (m, e) 155 // 156 // Returns true if the coefficients of this and m are the same with 157 // an absolute error of no more than e, i.e., for all i, j 158 // 159 // abs (this[i][j] - m[i][j]) <= e 160 // 161 // equalWithRelError (m, e) 162 // 163 // Returns true if the coefficients of this and m are the same with 164 // a relative error of no more than e, i.e., for all i, j 165 // 166 // abs (this[i] - v[i][j]) <= e * abs (this[i][j]) 167 //----------------------------------------------------------------------- 168 169 bool equalWithAbsError (const Matrix33<T> &v, T e) const; 170 bool equalWithRelError (const Matrix33<T> &v, T e) const; 171 172 173 //------------------------ 174 // Component-wise addition 175 //------------------------ 176 177 const Matrix33 & operator += (const Matrix33 &v); 178 const Matrix33 & operator += (T a); 179 Matrix33 operator + (const Matrix33 &v) const; 180 181 182 //--------------------------- 183 // Component-wise subtraction 184 //--------------------------- 185 186 const Matrix33 & operator -= (const Matrix33 &v); 187 const Matrix33 & operator -= (T a); 188 Matrix33 operator - (const Matrix33 &v) const; 189 190 191 //------------------------------------ 192 // Component-wise multiplication by -1 193 //------------------------------------ 194 195 Matrix33 operator - () const; 196 const Matrix33 & negate (); 197 198 199 //------------------------------ 200 // Component-wise multiplication 201 //------------------------------ 202 203 const Matrix33 & operator *= (T a); 204 Matrix33 operator * (T a) const; 205 206 207 //----------------------------------- 208 // Matrix-times-matrix multiplication 209 //----------------------------------- 210 211 const Matrix33 & operator *= (const Matrix33 &v); 212 Matrix33 operator * (const Matrix33 &v) const; 213 214 215 //----------------------------------------------------------------- 216 // Vector-times-matrix multiplication; see also the "operator *" 217 // functions defined below. 218 // 219 // m.multVecMatrix(src,dst) implements a homogeneous transformation 220 // by computing Vec3 (src.x, src.y, 1) * m and dividing by the 221 // result's third element. 222 // 223 // m.multDirMatrix(src,dst) multiplies src by the upper left 2x2 224 // submatrix, ignoring the rest of matrix m. 225 //----------------------------------------------------------------- 226 227 template <class S> 228 void multVecMatrix(const Vec2<S> &src, Vec2<S> &dst) const; 229 230 template <class S> 231 void multDirMatrix(const Vec2<S> &src, Vec2<S> &dst) const; 232 233 234 //------------------------ 235 // Component-wise division 236 //------------------------ 237 238 const Matrix33 & operator /= (T a); 239 Matrix33 operator / (T a) const; 240 241 242 //------------------ 243 // Transposed matrix 244 //------------------ 245 246 const Matrix33 & transpose (); 247 Matrix33 transposed () const; 248 249 250 //------------------------------------------------------------ 251 // Inverse matrix: If singExc is false, inverting a singular 252 // matrix produces an identity matrix. If singExc is true, 253 // inverting a singular matrix throws a SingMatrixExc. 254 // 255 // inverse() and invert() invert matrices using determinants; 256 // gjInverse() and gjInvert() use the Gauss-Jordan method. 257 // 258 // inverse() and invert() are significantly faster than 259 // gjInverse() and gjInvert(), but the results may be slightly 260 // less accurate. 261 // 262 //------------------------------------------------------------ 263 264 const Matrix33 & invert (bool singExc = false) 265 throw (Iex::MathExc); 266 267 Matrix33<T> inverse (bool singExc = false) const 268 throw (Iex::MathExc); 269 270 const Matrix33 & gjInvert (bool singExc = false) 271 throw (Iex::MathExc); 272 273 Matrix33<T> gjInverse (bool singExc = false) const 274 throw (Iex::MathExc); 275 276 277 //------------------------------------------------ 278 // Calculate the matrix minor of the (r,c) element 279 //------------------------------------------------ 280 281 T minorOf (const int r, const int c) const; 282 283 //--------------------------------------------------- 284 // Build a minor using the specified rows and columns 285 //--------------------------------------------------- 286 287 T fastMinor (const int r0, const int r1, 288 const int c0, const int c1) const; 289 290 //------------ 291 // Determinant 292 //------------ 293 294 T determinant() const; 295 296 //----------------------------------------- 297 // Set matrix to rotation by r (in radians) 298 //----------------------------------------- 299 300 template <class S> 301 const Matrix33 & setRotation (S r); 302 303 304 //----------------------------- 305 // Rotate the given matrix by r 306 //----------------------------- 307 308 template <class S> 309 const Matrix33 & rotate (S r); 310 311 312 //-------------------------------------------- 313 // Set matrix to scale by given uniform factor 314 //-------------------------------------------- 315 316 const Matrix33 & setScale (T s); 317 318 319 //------------------------------------ 320 // Set matrix to scale by given vector 321 //------------------------------------ 322 323 template <class S> 324 const Matrix33 & setScale (const Vec2<S> &s); 325 326 327 //---------------------- 328 // Scale the matrix by s 329 //---------------------- 330 331 template <class S> 332 const Matrix33 & scale (const Vec2<S> &s); 333 334 335 //------------------------------------------ 336 // Set matrix to translation by given vector 337 //------------------------------------------ 338 339 template <class S> 340 const Matrix33 & setTranslation (const Vec2<S> &t); 341 342 343 //----------------------------- 344 // Return translation component 345 //----------------------------- 346 347 Vec2<T> translation () const; 348 349 350 //-------------------------- 351 // Translate the matrix by t 352 //-------------------------- 353 354 template <class S> 355 const Matrix33 & translate (const Vec2<S> &t); 356 357 358 //----------------------------------------------------------- 359 // Set matrix to shear x for each y coord. by given factor xy 360 //----------------------------------------------------------- 361 362 template <class S> 363 const Matrix33 & setShear (const S &h); 364 365 366 //------------------------------------------------------------- 367 // Set matrix to shear x for each y coord. by given factor h[0] 368 // and to shear y for each x coord. by given factor h[1] 369 //------------------------------------------------------------- 370 371 template <class S> 372 const Matrix33 & setShear (const Vec2<S> &h); 373 374 375 //----------------------------------------------------------- 376 // Shear the matrix in x for each y coord. by given factor xy 377 //----------------------------------------------------------- 378 379 template <class S> 380 const Matrix33 & shear (const S &xy); 381 382 383 //----------------------------------------------------------- 384 // Shear the matrix in x for each y coord. by given factor xy 385 // and shear y for each x coord. by given factor yx 386 //----------------------------------------------------------- 387 388 template <class S> 389 const Matrix33 & shear (const Vec2<S> &h); 390 391 392 //-------------------------------------------------------- 393 // Number of the row and column dimensions, since 394 // Matrix33 is a square matrix. 395 //-------------------------------------------------------- 396 dimensions()397 static unsigned int dimensions() {return 3;} 398 399 400 //------------------------------------------------- 401 // Limitations of type T (see also class limits<T>) 402 //------------------------------------------------- 403 baseTypeMin()404 static T baseTypeMin() {return limits<T>::min();} baseTypeMax()405 static T baseTypeMax() {return limits<T>::max();} baseTypeSmallest()406 static T baseTypeSmallest() {return limits<T>::smallest();} baseTypeEpsilon()407 static T baseTypeEpsilon() {return limits<T>::epsilon();} 408 409 typedef T BaseType; 410 typedef Vec3<T> BaseVecType; 411 412 private: 413 414 template <typename R, typename S> 415 struct isSameType 416 { 417 enum {value = 0}; 418 }; 419 420 template <typename R> 421 struct isSameType<R, R> 422 { 423 enum {value = 1}; 424 }; 425 }; 426 427 428 template <class T> class Matrix44 429 { 430 public: 431 432 //------------------- 433 // Access to elements 434 //------------------- 435 436 T x[4][4]; 437 438 T * operator [] (int i); 439 const T * operator [] (int i) const; 440 441 442 //------------- 443 // Constructors 444 //------------- 445 446 Matrix44 (Uninitialized) {} 447 448 Matrix44 (); 449 // 1 0 0 0 450 // 0 1 0 0 451 // 0 0 1 0 452 // 0 0 0 1 453 454 Matrix44 (T a); 455 // a a a a 456 // a a a a 457 // a a a a 458 // a a a a 459 460 Matrix44 (const T a[4][4]) ; 461 // a[0][0] a[0][1] a[0][2] a[0][3] 462 // a[1][0] a[1][1] a[1][2] a[1][3] 463 // a[2][0] a[2][1] a[2][2] a[2][3] 464 // a[3][0] a[3][1] a[3][2] a[3][3] 465 466 Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h, 467 T i, T j, T k, T l, T m, T n, T o, T p); 468 469 // a b c d 470 // e f g h 471 // i j k l 472 // m n o p 473 474 Matrix44 (Matrix33<T> r, Vec3<T> t); 475 // r r r 0 476 // r r r 0 477 // r r r 0 478 // t t t 1 479 480 481 //-------------------------------- 482 // Copy constructor and assignment 483 //-------------------------------- 484 485 Matrix44 (const Matrix44 &v); 486 template <class S> explicit Matrix44 (const Matrix44<S> &v); 487 488 const Matrix44 & operator = (const Matrix44 &v); 489 const Matrix44 & operator = (T a); 490 491 492 //---------------------- 493 // Compatibility with Sb 494 //---------------------- 495 496 T * getValue (); 497 const T * getValue () const; 498 499 template <class S> 500 void getValue (Matrix44<S> &v) const; 501 template <class S> 502 Matrix44 & setValue (const Matrix44<S> &v); 503 504 template <class S> 505 Matrix44 & setTheMatrix (const Matrix44<S> &v); 506 507 //--------- 508 // Identity 509 //--------- 510 511 void makeIdentity(); 512 513 514 //--------- 515 // Equality 516 //--------- 517 518 bool operator == (const Matrix44 &v) const; 519 bool operator != (const Matrix44 &v) const; 520 521 //----------------------------------------------------------------------- 522 // Compare two matrices and test if they are "approximately equal": 523 // 524 // equalWithAbsError (m, e) 525 // 526 // Returns true if the coefficients of this and m are the same with 527 // an absolute error of no more than e, i.e., for all i, j 528 // 529 // abs (this[i][j] - m[i][j]) <= e 530 // 531 // equalWithRelError (m, e) 532 // 533 // Returns true if the coefficients of this and m are the same with 534 // a relative error of no more than e, i.e., for all i, j 535 // 536 // abs (this[i] - v[i][j]) <= e * abs (this[i][j]) 537 //----------------------------------------------------------------------- 538 539 bool equalWithAbsError (const Matrix44<T> &v, T e) const; 540 bool equalWithRelError (const Matrix44<T> &v, T e) const; 541 542 543 //------------------------ 544 // Component-wise addition 545 //------------------------ 546 547 const Matrix44 & operator += (const Matrix44 &v); 548 const Matrix44 & operator += (T a); 549 Matrix44 operator + (const Matrix44 &v) const; 550 551 552 //--------------------------- 553 // Component-wise subtraction 554 //--------------------------- 555 556 const Matrix44 & operator -= (const Matrix44 &v); 557 const Matrix44 & operator -= (T a); 558 Matrix44 operator - (const Matrix44 &v) const; 559 560 561 //------------------------------------ 562 // Component-wise multiplication by -1 563 //------------------------------------ 564 565 Matrix44 operator - () const; 566 const Matrix44 & negate (); 567 568 569 //------------------------------ 570 // Component-wise multiplication 571 //------------------------------ 572 573 const Matrix44 & operator *= (T a); 574 Matrix44 operator * (T a) const; 575 576 577 //----------------------------------- 578 // Matrix-times-matrix multiplication 579 //----------------------------------- 580 581 const Matrix44 & operator *= (const Matrix44 &v); 582 Matrix44 operator * (const Matrix44 &v) const; 583 584 static void multiply (const Matrix44 &a, // assumes that 585 const Matrix44 &b, // &a != &c and 586 Matrix44 &c); // &b != &c. 587 588 589 //----------------------------------------------------------------- 590 // Vector-times-matrix multiplication; see also the "operator *" 591 // functions defined below. 592 // 593 // m.multVecMatrix(src,dst) implements a homogeneous transformation 594 // by computing Vec4 (src.x, src.y, src.z, 1) * m and dividing by 595 // the result's third element. 596 // 597 // m.multDirMatrix(src,dst) multiplies src by the upper left 3x3 598 // submatrix, ignoring the rest of matrix m. 599 //----------------------------------------------------------------- 600 601 template <class S> 602 void multVecMatrix(const Vec3<S> &src, Vec3<S> &dst) const; 603 604 template <class S> 605 void multDirMatrix(const Vec3<S> &src, Vec3<S> &dst) const; 606 607 608 //------------------------ 609 // Component-wise division 610 //------------------------ 611 612 const Matrix44 & operator /= (T a); 613 Matrix44 operator / (T a) const; 614 615 616 //------------------ 617 // Transposed matrix 618 //------------------ 619 620 const Matrix44 & transpose (); 621 Matrix44 transposed () const; 622 623 624 //------------------------------------------------------------ 625 // Inverse matrix: If singExc is false, inverting a singular 626 // matrix produces an identity matrix. If singExc is true, 627 // inverting a singular matrix throws a SingMatrixExc. 628 // 629 // inverse() and invert() invert matrices using determinants; 630 // gjInverse() and gjInvert() use the Gauss-Jordan method. 631 // 632 // inverse() and invert() are significantly faster than 633 // gjInverse() and gjInvert(), but the results may be slightly 634 // less accurate. 635 // 636 //------------------------------------------------------------ 637 638 const Matrix44 & invert (bool singExc = false) 639 throw (Iex::MathExc); 640 641 Matrix44<T> inverse (bool singExc = false) const 642 throw (Iex::MathExc); 643 644 const Matrix44 & gjInvert (bool singExc = false) 645 throw (Iex::MathExc); 646 647 Matrix44<T> gjInverse (bool singExc = false) const 648 throw (Iex::MathExc); 649 650 651 //------------------------------------------------ 652 // Calculate the matrix minor of the (r,c) element 653 //------------------------------------------------ 654 655 T minorOf (const int r, const int c) const; 656 657 //--------------------------------------------------- 658 // Build a minor using the specified rows and columns 659 //--------------------------------------------------- 660 661 T fastMinor (const int r0, const int r1, const int r2, 662 const int c0, const int c1, const int c2) const; 663 664 //------------ 665 // Determinant 666 //------------ 667 668 T determinant() const; 669 670 //-------------------------------------------------------- 671 // Set matrix to rotation by XYZ euler angles (in radians) 672 //-------------------------------------------------------- 673 674 template <class S> 675 const Matrix44 & setEulerAngles (const Vec3<S>& r); 676 677 678 //-------------------------------------------------------- 679 // Set matrix to rotation around given axis by given angle 680 //-------------------------------------------------------- 681 682 template <class S> 683 const Matrix44 & setAxisAngle (const Vec3<S>& ax, S ang); 684 685 686 //------------------------------------------- 687 // Rotate the matrix by XYZ euler angles in r 688 //------------------------------------------- 689 690 template <class S> 691 const Matrix44 & rotate (const Vec3<S> &r); 692 693 694 //-------------------------------------------- 695 // Set matrix to scale by given uniform factor 696 //-------------------------------------------- 697 698 const Matrix44 & setScale (T s); 699 700 701 //------------------------------------ 702 // Set matrix to scale by given vector 703 //------------------------------------ 704 705 template <class S> 706 const Matrix44 & setScale (const Vec3<S> &s); 707 708 709 //---------------------- 710 // Scale the matrix by s 711 //---------------------- 712 713 template <class S> 714 const Matrix44 & scale (const Vec3<S> &s); 715 716 717 //------------------------------------------ 718 // Set matrix to translation by given vector 719 //------------------------------------------ 720 721 template <class S> 722 const Matrix44 & setTranslation (const Vec3<S> &t); 723 724 725 //----------------------------- 726 // Return translation component 727 //----------------------------- 728 729 const Vec3<T> translation () const; 730 731 732 //-------------------------- 733 // Translate the matrix by t 734 //-------------------------- 735 736 template <class S> 737 const Matrix44 & translate (const Vec3<S> &t); 738 739 740 //------------------------------------------------------------- 741 // Set matrix to shear by given vector h. The resulting matrix 742 // will shear x for each y coord. by a factor of h[0] ; 743 // will shear x for each z coord. by a factor of h[1] ; 744 // will shear y for each z coord. by a factor of h[2] . 745 //------------------------------------------------------------- 746 747 template <class S> 748 const Matrix44 & setShear (const Vec3<S> &h); 749 750 751 //------------------------------------------------------------ 752 // Set matrix to shear by given factors. The resulting matrix 753 // will shear x for each y coord. by a factor of h.xy ; 754 // will shear x for each z coord. by a factor of h.xz ; 755 // will shear y for each z coord. by a factor of h.yz ; 756 // will shear y for each x coord. by a factor of h.yx ; 757 // will shear z for each x coord. by a factor of h.zx ; 758 // will shear z for each y coord. by a factor of h.zy . 759 //------------------------------------------------------------ 760 761 template <class S> 762 const Matrix44 & setShear (const Shear6<S> &h); 763 764 765 //-------------------------------------------------------- 766 // Shear the matrix by given vector. The composed matrix 767 // will be <shear> * <this>, where the shear matrix ... 768 // will shear x for each y coord. by a factor of h[0] ; 769 // will shear x for each z coord. by a factor of h[1] ; 770 // will shear y for each z coord. by a factor of h[2] . 771 //-------------------------------------------------------- 772 773 template <class S> 774 const Matrix44 & shear (const Vec3<S> &h); 775 776 //-------------------------------------------------------- 777 // Number of the row and column dimensions, since 778 // Matrix44 is a square matrix. 779 //-------------------------------------------------------- 780 781 static unsigned int dimensions() {return 4;} 782 783 784 //------------------------------------------------------------ 785 // Shear the matrix by the given factors. The composed matrix 786 // will be <shear> * <this>, where the shear matrix ... 787 // will shear x for each y coord. by a factor of h.xy ; 788 // will shear x for each z coord. by a factor of h.xz ; 789 // will shear y for each z coord. by a factor of h.yz ; 790 // will shear y for each x coord. by a factor of h.yx ; 791 // will shear z for each x coord. by a factor of h.zx ; 792 // will shear z for each y coord. by a factor of h.zy . 793 //------------------------------------------------------------ 794 795 template <class S> 796 const Matrix44 & shear (const Shear6<S> &h); 797 798 799 //------------------------------------------------- 800 // Limitations of type T (see also class limits<T>) 801 //------------------------------------------------- 802 803 static T baseTypeMin() {return limits<T>::min();} 804 static T baseTypeMax() {return limits<T>::max();} 805 static T baseTypeSmallest() {return limits<T>::smallest();} 806 static T baseTypeEpsilon() {return limits<T>::epsilon();} 807 808 typedef T BaseType; 809 typedef Vec4<T> BaseVecType; 810 811 private: 812 813 template <typename R, typename S> 814 struct isSameType 815 { 816 enum {value = 0}; 817 }; 818 819 template <typename R> 820 struct isSameType<R, R> 821 { 822 enum {value = 1}; 823 }; 824 }; 825 826 827 //-------------- 828 // Stream output 829 //-------------- 830 831 template <class T> 832 std::ostream & operator << (std::ostream & s, const Matrix33<T> &m); 833 834 template <class T> 835 std::ostream & operator << (std::ostream & s, const Matrix44<T> &m); 836 837 838 //--------------------------------------------- 839 // Vector-times-matrix multiplication operators 840 //--------------------------------------------- 841 842 template <class S, class T> 843 const Vec2<S> & operator *= (Vec2<S> &v, const Matrix33<T> &m); 844 845 template <class S, class T> 846 Vec2<S> operator * (const Vec2<S> &v, const Matrix33<T> &m); 847 848 template <class S, class T> 849 const Vec3<S> & operator *= (Vec3<S> &v, const Matrix33<T> &m); 850 851 template <class S, class T> 852 Vec3<S> operator * (const Vec3<S> &v, const Matrix33<T> &m); 853 854 template <class S, class T> 855 const Vec3<S> & operator *= (Vec3<S> &v, const Matrix44<T> &m); 856 857 template <class S, class T> 858 Vec3<S> operator * (const Vec3<S> &v, const Matrix44<T> &m); 859 860 template <class S, class T> 861 const Vec4<S> & operator *= (Vec4<S> &v, const Matrix44<T> &m); 862 863 template <class S, class T> 864 Vec4<S> operator * (const Vec4<S> &v, const Matrix44<T> &m); 865 866 //------------------------- 867 // Typedefs for convenience 868 //------------------------- 869 870 typedef Matrix33 <float> M33f; 871 typedef Matrix33 <double> M33d; 872 typedef Matrix44 <float> M44f; 873 typedef Matrix44 <double> M44d; 874 875 876 //--------------------------- 877 // Implementation of Matrix33 878 //--------------------------- 879 880 template <class T> 881 inline T * 882 Matrix33<T>::operator [] (int i) 883 { 884 return x[i]; 885 } 886 887 template <class T> 888 inline const T * 889 Matrix33<T>::operator [] (int i) const 890 { 891 return x[i]; 892 } 893 894 template <class T> 895 inline 896 Matrix33<T>::Matrix33 () 897 { 898 memset (x, 0, sizeof (x)); 899 x[0][0] = 1; 900 x[1][1] = 1; 901 x[2][2] = 1; 902 } 903 904 template <class T> 905 inline 906 Matrix33<T>::Matrix33 (T a) 907 { 908 x[0][0] = a; 909 x[0][1] = a; 910 x[0][2] = a; 911 x[1][0] = a; 912 x[1][1] = a; 913 x[1][2] = a; 914 x[2][0] = a; 915 x[2][1] = a; 916 x[2][2] = a; 917 } 918 919 template <class T> 920 inline 921 Matrix33<T>::Matrix33 (const T a[3][3]) 922 { 923 memcpy (x, a, sizeof (x)); 924 } 925 926 template <class T> 927 inline 928 Matrix33<T>::Matrix33 (T a, T b, T c, T d, T e, T f, T g, T h, T i) 929 { 930 x[0][0] = a; 931 x[0][1] = b; 932 x[0][2] = c; 933 x[1][0] = d; 934 x[1][1] = e; 935 x[1][2] = f; 936 x[2][0] = g; 937 x[2][1] = h; 938 x[2][2] = i; 939 } 940 941 template <class T> 942 inline 943 Matrix33<T>::Matrix33 (const Matrix33 &v) 944 { 945 memcpy (x, v.x, sizeof (x)); 946 } 947 948 template <class T> 949 template <class S> 950 inline 951 Matrix33<T>::Matrix33 (const Matrix33<S> &v) 952 { 953 x[0][0] = T (v.x[0][0]); 954 x[0][1] = T (v.x[0][1]); 955 x[0][2] = T (v.x[0][2]); 956 x[1][0] = T (v.x[1][0]); 957 x[1][1] = T (v.x[1][1]); 958 x[1][2] = T (v.x[1][2]); 959 x[2][0] = T (v.x[2][0]); 960 x[2][1] = T (v.x[2][1]); 961 x[2][2] = T (v.x[2][2]); 962 } 963 964 template <class T> 965 inline const Matrix33<T> & 966 Matrix33<T>::operator = (const Matrix33 &v) 967 { 968 memcpy (x, v.x, sizeof (x)); 969 return *this; 970 } 971 972 template <class T> 973 inline const Matrix33<T> & 974 Matrix33<T>::operator = (T a) 975 { 976 x[0][0] = a; 977 x[0][1] = a; 978 x[0][2] = a; 979 x[1][0] = a; 980 x[1][1] = a; 981 x[1][2] = a; 982 x[2][0] = a; 983 x[2][1] = a; 984 x[2][2] = a; 985 return *this; 986 } 987 988 template <class T> 989 inline T * 990 Matrix33<T>::getValue () 991 { 992 return (T *) &x[0][0]; 993 } 994 995 template <class T> 996 inline const T * 997 Matrix33<T>::getValue () const 998 { 999 return (const T *) &x[0][0]; 1000 } 1001 1002 template <class T> 1003 template <class S> 1004 inline void 1005 Matrix33<T>::getValue (Matrix33<S> &v) const 1006 { 1007 if (isSameType<S,T>::value) 1008 { 1009 memcpy (v.x, x, sizeof (x)); 1010 } 1011 else 1012 { 1013 v.x[0][0] = x[0][0]; 1014 v.x[0][1] = x[0][1]; 1015 v.x[0][2] = x[0][2]; 1016 v.x[1][0] = x[1][0]; 1017 v.x[1][1] = x[1][1]; 1018 v.x[1][2] = x[1][2]; 1019 v.x[2][0] = x[2][0]; 1020 v.x[2][1] = x[2][1]; 1021 v.x[2][2] = x[2][2]; 1022 } 1023 } 1024 1025 template <class T> 1026 template <class S> 1027 inline Matrix33<T> & 1028 Matrix33<T>::setValue (const Matrix33<S> &v) 1029 { 1030 if (isSameType<S,T>::value) 1031 { 1032 memcpy (x, v.x, sizeof (x)); 1033 } 1034 else 1035 { 1036 x[0][0] = v.x[0][0]; 1037 x[0][1] = v.x[0][1]; 1038 x[0][2] = v.x[0][2]; 1039 x[1][0] = v.x[1][0]; 1040 x[1][1] = v.x[1][1]; 1041 x[1][2] = v.x[1][2]; 1042 x[2][0] = v.x[2][0]; 1043 x[2][1] = v.x[2][1]; 1044 x[2][2] = v.x[2][2]; 1045 } 1046 1047 return *this; 1048 } 1049 1050 template <class T> 1051 template <class S> 1052 inline Matrix33<T> & 1053 Matrix33<T>::setTheMatrix (const Matrix33<S> &v) 1054 { 1055 if (isSameType<S,T>::value) 1056 { 1057 memcpy (x, v.x, sizeof (x)); 1058 } 1059 else 1060 { 1061 x[0][0] = v.x[0][0]; 1062 x[0][1] = v.x[0][1]; 1063 x[0][2] = v.x[0][2]; 1064 x[1][0] = v.x[1][0]; 1065 x[1][1] = v.x[1][1]; 1066 x[1][2] = v.x[1][2]; 1067 x[2][0] = v.x[2][0]; 1068 x[2][1] = v.x[2][1]; 1069 x[2][2] = v.x[2][2]; 1070 } 1071 1072 return *this; 1073 } 1074 1075 template <class T> 1076 inline void 1077 Matrix33<T>::makeIdentity() 1078 { 1079 memset (x, 0, sizeof (x)); 1080 x[0][0] = 1; 1081 x[1][1] = 1; 1082 x[2][2] = 1; 1083 } 1084 1085 template <class T> 1086 bool 1087 Matrix33<T>::operator == (const Matrix33 &v) const 1088 { 1089 return x[0][0] == v.x[0][0] && 1090 x[0][1] == v.x[0][1] && 1091 x[0][2] == v.x[0][2] && 1092 x[1][0] == v.x[1][0] && 1093 x[1][1] == v.x[1][1] && 1094 x[1][2] == v.x[1][2] && 1095 x[2][0] == v.x[2][0] && 1096 x[2][1] == v.x[2][1] && 1097 x[2][2] == v.x[2][2]; 1098 } 1099 1100 template <class T> 1101 bool 1102 Matrix33<T>::operator != (const Matrix33 &v) const 1103 { 1104 return x[0][0] != v.x[0][0] || 1105 x[0][1] != v.x[0][1] || 1106 x[0][2] != v.x[0][2] || 1107 x[1][0] != v.x[1][0] || 1108 x[1][1] != v.x[1][1] || 1109 x[1][2] != v.x[1][2] || 1110 x[2][0] != v.x[2][0] || 1111 x[2][1] != v.x[2][1] || 1112 x[2][2] != v.x[2][2]; 1113 } 1114 1115 template <class T> 1116 bool 1117 Matrix33<T>::equalWithAbsError (const Matrix33<T> &m, T e) const 1118 { 1119 for (int i = 0; i < 3; i++) 1120 for (int j = 0; j < 3; j++) 1121 if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e)) 1122 return false; 1123 1124 return true; 1125 } 1126 1127 template <class T> 1128 bool 1129 Matrix33<T>::equalWithRelError (const Matrix33<T> &m, T e) const 1130 { 1131 for (int i = 0; i < 3; i++) 1132 for (int j = 0; j < 3; j++) 1133 if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e)) 1134 return false; 1135 1136 return true; 1137 } 1138 1139 template <class T> 1140 const Matrix33<T> & 1141 Matrix33<T>::operator += (const Matrix33<T> &v) 1142 { 1143 x[0][0] += v.x[0][0]; 1144 x[0][1] += v.x[0][1]; 1145 x[0][2] += v.x[0][2]; 1146 x[1][0] += v.x[1][0]; 1147 x[1][1] += v.x[1][1]; 1148 x[1][2] += v.x[1][2]; 1149 x[2][0] += v.x[2][0]; 1150 x[2][1] += v.x[2][1]; 1151 x[2][2] += v.x[2][2]; 1152 1153 return *this; 1154 } 1155 1156 template <class T> 1157 const Matrix33<T> & 1158 Matrix33<T>::operator += (T a) 1159 { 1160 x[0][0] += a; 1161 x[0][1] += a; 1162 x[0][2] += a; 1163 x[1][0] += a; 1164 x[1][1] += a; 1165 x[1][2] += a; 1166 x[2][0] += a; 1167 x[2][1] += a; 1168 x[2][2] += a; 1169 1170 return *this; 1171 } 1172 1173 template <class T> 1174 Matrix33<T> 1175 Matrix33<T>::operator + (const Matrix33<T> &v) const 1176 { 1177 return Matrix33 (x[0][0] + v.x[0][0], 1178 x[0][1] + v.x[0][1], 1179 x[0][2] + v.x[0][2], 1180 x[1][0] + v.x[1][0], 1181 x[1][1] + v.x[1][1], 1182 x[1][2] + v.x[1][2], 1183 x[2][0] + v.x[2][0], 1184 x[2][1] + v.x[2][1], 1185 x[2][2] + v.x[2][2]); 1186 } 1187 1188 template <class T> 1189 const Matrix33<T> & 1190 Matrix33<T>::operator -= (const Matrix33<T> &v) 1191 { 1192 x[0][0] -= v.x[0][0]; 1193 x[0][1] -= v.x[0][1]; 1194 x[0][2] -= v.x[0][2]; 1195 x[1][0] -= v.x[1][0]; 1196 x[1][1] -= v.x[1][1]; 1197 x[1][2] -= v.x[1][2]; 1198 x[2][0] -= v.x[2][0]; 1199 x[2][1] -= v.x[2][1]; 1200 x[2][2] -= v.x[2][2]; 1201 1202 return *this; 1203 } 1204 1205 template <class T> 1206 const Matrix33<T> & 1207 Matrix33<T>::operator -= (T a) 1208 { 1209 x[0][0] -= a; 1210 x[0][1] -= a; 1211 x[0][2] -= a; 1212 x[1][0] -= a; 1213 x[1][1] -= a; 1214 x[1][2] -= a; 1215 x[2][0] -= a; 1216 x[2][1] -= a; 1217 x[2][2] -= a; 1218 1219 return *this; 1220 } 1221 1222 template <class T> 1223 Matrix33<T> 1224 Matrix33<T>::operator - (const Matrix33<T> &v) const 1225 { 1226 return Matrix33 (x[0][0] - v.x[0][0], 1227 x[0][1] - v.x[0][1], 1228 x[0][2] - v.x[0][2], 1229 x[1][0] - v.x[1][0], 1230 x[1][1] - v.x[1][1], 1231 x[1][2] - v.x[1][2], 1232 x[2][0] - v.x[2][0], 1233 x[2][1] - v.x[2][1], 1234 x[2][2] - v.x[2][2]); 1235 } 1236 1237 template <class T> 1238 Matrix33<T> 1239 Matrix33<T>::operator - () const 1240 { 1241 return Matrix33 (-x[0][0], 1242 -x[0][1], 1243 -x[0][2], 1244 -x[1][0], 1245 -x[1][1], 1246 -x[1][2], 1247 -x[2][0], 1248 -x[2][1], 1249 -x[2][2]); 1250 } 1251 1252 template <class T> 1253 const Matrix33<T> & 1254 Matrix33<T>::negate () 1255 { 1256 x[0][0] = -x[0][0]; 1257 x[0][1] = -x[0][1]; 1258 x[0][2] = -x[0][2]; 1259 x[1][0] = -x[1][0]; 1260 x[1][1] = -x[1][1]; 1261 x[1][2] = -x[1][2]; 1262 x[2][0] = -x[2][0]; 1263 x[2][1] = -x[2][1]; 1264 x[2][2] = -x[2][2]; 1265 1266 return *this; 1267 } 1268 1269 template <class T> 1270 const Matrix33<T> & 1271 Matrix33<T>::operator *= (T a) 1272 { 1273 x[0][0] *= a; 1274 x[0][1] *= a; 1275 x[0][2] *= a; 1276 x[1][0] *= a; 1277 x[1][1] *= a; 1278 x[1][2] *= a; 1279 x[2][0] *= a; 1280 x[2][1] *= a; 1281 x[2][2] *= a; 1282 1283 return *this; 1284 } 1285 1286 template <class T> 1287 Matrix33<T> 1288 Matrix33<T>::operator * (T a) const 1289 { 1290 return Matrix33 (x[0][0] * a, 1291 x[0][1] * a, 1292 x[0][2] * a, 1293 x[1][0] * a, 1294 x[1][1] * a, 1295 x[1][2] * a, 1296 x[2][0] * a, 1297 x[2][1] * a, 1298 x[2][2] * a); 1299 } 1300 1301 template <class T> 1302 inline Matrix33<T> 1303 operator * (T a, const Matrix33<T> &v) 1304 { 1305 return v * a; 1306 } 1307 1308 template <class T> 1309 const Matrix33<T> & 1310 Matrix33<T>::operator *= (const Matrix33<T> &v) 1311 { 1312 Matrix33 tmp (T (0)); 1313 1314 for (int i = 0; i < 3; i++) 1315 for (int j = 0; j < 3; j++) 1316 for (int k = 0; k < 3; k++) 1317 tmp.x[i][j] += x[i][k] * v.x[k][j]; 1318 1319 *this = tmp; 1320 return *this; 1321 } 1322 1323 template <class T> 1324 Matrix33<T> 1325 Matrix33<T>::operator * (const Matrix33<T> &v) const 1326 { 1327 Matrix33 tmp (T (0)); 1328 1329 for (int i = 0; i < 3; i++) 1330 for (int j = 0; j < 3; j++) 1331 for (int k = 0; k < 3; k++) 1332 tmp.x[i][j] += x[i][k] * v.x[k][j]; 1333 1334 return tmp; 1335 } 1336 1337 template <class T> 1338 template <class S> 1339 void 1340 Matrix33<T>::multVecMatrix(const Vec2<S> &src, Vec2<S> &dst) const 1341 { 1342 S a, b, w; 1343 1344 a = src[0] * x[0][0] + src[1] * x[1][0] + x[2][0]; 1345 b = src[0] * x[0][1] + src[1] * x[1][1] + x[2][1]; 1346 w = src[0] * x[0][2] + src[1] * x[1][2] + x[2][2]; 1347 1348 dst.x = a / w; 1349 dst.y = b / w; 1350 } 1351 1352 template <class T> 1353 template <class S> 1354 void 1355 Matrix33<T>::multDirMatrix(const Vec2<S> &src, Vec2<S> &dst) const 1356 { 1357 S a, b; 1358 1359 a = src[0] * x[0][0] + src[1] * x[1][0]; 1360 b = src[0] * x[0][1] + src[1] * x[1][1]; 1361 1362 dst.x = a; 1363 dst.y = b; 1364 } 1365 1366 template <class T> 1367 const Matrix33<T> & 1368 Matrix33<T>::operator /= (T a) 1369 { 1370 x[0][0] /= a; 1371 x[0][1] /= a; 1372 x[0][2] /= a; 1373 x[1][0] /= a; 1374 x[1][1] /= a; 1375 x[1][2] /= a; 1376 x[2][0] /= a; 1377 x[2][1] /= a; 1378 x[2][2] /= a; 1379 1380 return *this; 1381 } 1382 1383 template <class T> 1384 Matrix33<T> 1385 Matrix33<T>::operator / (T a) const 1386 { 1387 return Matrix33 (x[0][0] / a, 1388 x[0][1] / a, 1389 x[0][2] / a, 1390 x[1][0] / a, 1391 x[1][1] / a, 1392 x[1][2] / a, 1393 x[2][0] / a, 1394 x[2][1] / a, 1395 x[2][2] / a); 1396 } 1397 1398 template <class T> 1399 const Matrix33<T> & 1400 Matrix33<T>::transpose () 1401 { 1402 Matrix33 tmp (x[0][0], 1403 x[1][0], 1404 x[2][0], 1405 x[0][1], 1406 x[1][1], 1407 x[2][1], 1408 x[0][2], 1409 x[1][2], 1410 x[2][2]); 1411 *this = tmp; 1412 return *this; 1413 } 1414 1415 template <class T> 1416 Matrix33<T> 1417 Matrix33<T>::transposed () const 1418 { 1419 return Matrix33 (x[0][0], 1420 x[1][0], 1421 x[2][0], 1422 x[0][1], 1423 x[1][1], 1424 x[2][1], 1425 x[0][2], 1426 x[1][2], 1427 x[2][2]); 1428 } 1429 1430 template <class T> 1431 const Matrix33<T> & 1432 Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc) 1433 { 1434 *this = gjInverse (singExc); 1435 return *this; 1436 } 1437 1438 template <class T> 1439 Matrix33<T> 1440 Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc) 1441 { 1442 int i, j, k; 1443 Matrix33 s; 1444 Matrix33 t (*this); 1445 1446 // Forward elimination 1447 1448 for (i = 0; i < 2 ; i++) 1449 { 1450 int pivot = i; 1451 1452 T pivotsize = t[i][i]; 1453 1454 if (pivotsize < 0) 1455 pivotsize = -pivotsize; 1456 1457 for (j = i + 1; j < 3; j++) 1458 { 1459 T tmp = t[j][i]; 1460 1461 if (tmp < 0) 1462 tmp = -tmp; 1463 1464 if (tmp > pivotsize) 1465 { 1466 pivot = j; 1467 pivotsize = tmp; 1468 } 1469 } 1470 1471 if (pivotsize == 0) 1472 { 1473 if (singExc) 1474 throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); 1475 1476 return Matrix33(); 1477 } 1478 1479 if (pivot != i) 1480 { 1481 for (j = 0; j < 3; j++) 1482 { 1483 T tmp; 1484 1485 tmp = t[i][j]; 1486 t[i][j] = t[pivot][j]; 1487 t[pivot][j] = tmp; 1488 1489 tmp = s[i][j]; 1490 s[i][j] = s[pivot][j]; 1491 s[pivot][j] = tmp; 1492 } 1493 } 1494 1495 for (j = i + 1; j < 3; j++) 1496 { 1497 T f = t[j][i] / t[i][i]; 1498 1499 for (k = 0; k < 3; k++) 1500 { 1501 t[j][k] -= f * t[i][k]; 1502 s[j][k] -= f * s[i][k]; 1503 } 1504 } 1505 } 1506 1507 // Backward substitution 1508 1509 for (i = 2; i >= 0; --i) 1510 { 1511 T f; 1512 1513 if ((f = t[i][i]) == 0) 1514 { 1515 if (singExc) 1516 throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); 1517 1518 return Matrix33(); 1519 } 1520 1521 for (j = 0; j < 3; j++) 1522 { 1523 t[i][j] /= f; 1524 s[i][j] /= f; 1525 } 1526 1527 for (j = 0; j < i; j++) 1528 { 1529 f = t[j][i]; 1530 1531 for (k = 0; k < 3; k++) 1532 { 1533 t[j][k] -= f * t[i][k]; 1534 s[j][k] -= f * s[i][k]; 1535 } 1536 } 1537 } 1538 1539 return s; 1540 } 1541 1542 template <class T> 1543 const Matrix33<T> & 1544 Matrix33<T>::invert (bool singExc) throw (Iex::MathExc) 1545 { 1546 *this = inverse (singExc); 1547 return *this; 1548 } 1549 1550 template <class T> 1551 Matrix33<T> 1552 Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc) 1553 { 1554 if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1) 1555 { 1556 Matrix33 s (x[1][1] * x[2][2] - x[2][1] * x[1][2], 1557 x[2][1] * x[0][2] - x[0][1] * x[2][2], 1558 x[0][1] * x[1][2] - x[1][1] * x[0][2], 1559 1560 x[2][0] * x[1][2] - x[1][0] * x[2][2], 1561 x[0][0] * x[2][2] - x[2][0] * x[0][2], 1562 x[1][0] * x[0][2] - x[0][0] * x[1][2], 1563 1564 x[1][0] * x[2][1] - x[2][0] * x[1][1], 1565 x[2][0] * x[0][1] - x[0][0] * x[2][1], 1566 x[0][0] * x[1][1] - x[1][0] * x[0][1]); 1567 1568 T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0]; 1569 1570 if (Imath::abs (r) >= 1) 1571 { 1572 for (int i = 0; i < 3; ++i) 1573 { 1574 for (int j = 0; j < 3; ++j) 1575 { 1576 s[i][j] /= r; 1577 } 1578 } 1579 } 1580 else 1581 { 1582 T mr = Imath::abs (r) / limits<T>::smallest(); 1583 1584 for (int i = 0; i < 3; ++i) 1585 { 1586 for (int j = 0; j < 3; ++j) 1587 { 1588 if (mr > Imath::abs (s[i][j])) 1589 { 1590 s[i][j] /= r; 1591 } 1592 else 1593 { 1594 if (singExc) 1595 throw SingMatrixExc ("Cannot invert " 1596 "singular matrix."); 1597 return Matrix33(); 1598 } 1599 } 1600 } 1601 } 1602 1603 return s; 1604 } 1605 else 1606 { 1607 Matrix33 s ( x[1][1], 1608 -x[0][1], 1609 0, 1610 1611 -x[1][0], 1612 x[0][0], 1613 0, 1614 1615 0, 1616 0, 1617 1); 1618 1619 T r = x[0][0] * x[1][1] - x[1][0] * x[0][1]; 1620 1621 if (Imath::abs (r) >= 1) 1622 { 1623 for (int i = 0; i < 2; ++i) 1624 { 1625 for (int j = 0; j < 2; ++j) 1626 { 1627 s[i][j] /= r; 1628 } 1629 } 1630 } 1631 else 1632 { 1633 T mr = Imath::abs (r) / limits<T>::smallest(); 1634 1635 for (int i = 0; i < 2; ++i) 1636 { 1637 for (int j = 0; j < 2; ++j) 1638 { 1639 if (mr > Imath::abs (s[i][j])) 1640 { 1641 s[i][j] /= r; 1642 } 1643 else 1644 { 1645 if (singExc) 1646 throw SingMatrixExc ("Cannot invert " 1647 "singular matrix."); 1648 return Matrix33(); 1649 } 1650 } 1651 } 1652 } 1653 1654 s[2][0] = -x[2][0] * s[0][0] - x[2][1] * s[1][0]; 1655 s[2][1] = -x[2][0] * s[0][1] - x[2][1] * s[1][1]; 1656 1657 return s; 1658 } 1659 } 1660 1661 template <class T> 1662 inline T 1663 Matrix33<T>::minorOf (const int r, const int c) const 1664 { 1665 int r0 = 0 + (r < 1 ? 1 : 0); 1666 int r1 = 1 + (r < 2 ? 1 : 0); 1667 int c0 = 0 + (c < 1 ? 1 : 0); 1668 int c1 = 1 + (c < 2 ? 1 : 0); 1669 1670 return x[r0][c0]*x[r1][c1] - x[r1][c0]*x[r0][c1]; 1671 } 1672 1673 template <class T> 1674 inline T 1675 Matrix33<T>::fastMinor( const int r0, const int r1, 1676 const int c0, const int c1) const 1677 { 1678 return x[r0][c0]*x[r1][c1] - x[r0][c1]*x[r1][c0]; 1679 } 1680 1681 template <class T> 1682 inline T 1683 Matrix33<T>::determinant () const 1684 { 1685 return x[0][0]*(x[1][1]*x[2][2] - x[1][2]*x[2][1]) + 1686 x[0][1]*(x[1][2]*x[2][0] - x[1][0]*x[2][2]) + 1687 x[0][2]*(x[1][0]*x[2][1] - x[1][1]*x[2][0]); 1688 } 1689 1690 template <class T> 1691 template <class S> 1692 const Matrix33<T> & 1693 Matrix33<T>::setRotation (S r) 1694 { 1695 S cos_r, sin_r; 1696 1697 cos_r = Math<T>::cos (r); 1698 sin_r = Math<T>::sin (r); 1699 1700 x[0][0] = cos_r; 1701 x[0][1] = sin_r; 1702 x[0][2] = 0; 1703 1704 x[1][0] = -sin_r; 1705 x[1][1] = cos_r; 1706 x[1][2] = 0; 1707 1708 x[2][0] = 0; 1709 x[2][1] = 0; 1710 x[2][2] = 1; 1711 1712 return *this; 1713 } 1714 1715 template <class T> 1716 template <class S> 1717 const Matrix33<T> & 1718 Matrix33<T>::rotate (S r) 1719 { 1720 *this *= Matrix33<T>().setRotation (r); 1721 return *this; 1722 } 1723 1724 template <class T> 1725 const Matrix33<T> & 1726 Matrix33<T>::setScale (T s) 1727 { 1728 memset (x, 0, sizeof (x)); 1729 x[0][0] = s; 1730 x[1][1] = s; 1731 x[2][2] = 1; 1732 1733 return *this; 1734 } 1735 1736 template <class T> 1737 template <class S> 1738 const Matrix33<T> & 1739 Matrix33<T>::setScale (const Vec2<S> &s) 1740 { 1741 memset (x, 0, sizeof (x)); 1742 x[0][0] = s[0]; 1743 x[1][1] = s[1]; 1744 x[2][2] = 1; 1745 1746 return *this; 1747 } 1748 1749 template <class T> 1750 template <class S> 1751 const Matrix33<T> & 1752 Matrix33<T>::scale (const Vec2<S> &s) 1753 { 1754 x[0][0] *= s[0]; 1755 x[0][1] *= s[0]; 1756 x[0][2] *= s[0]; 1757 1758 x[1][0] *= s[1]; 1759 x[1][1] *= s[1]; 1760 x[1][2] *= s[1]; 1761 1762 return *this; 1763 } 1764 1765 template <class T> 1766 template <class S> 1767 const Matrix33<T> & 1768 Matrix33<T>::setTranslation (const Vec2<S> &t) 1769 { 1770 x[0][0] = 1; 1771 x[0][1] = 0; 1772 x[0][2] = 0; 1773 1774 x[1][0] = 0; 1775 x[1][1] = 1; 1776 x[1][2] = 0; 1777 1778 x[2][0] = t[0]; 1779 x[2][1] = t[1]; 1780 x[2][2] = 1; 1781 1782 return *this; 1783 } 1784 1785 template <class T> 1786 inline Vec2<T> 1787 Matrix33<T>::translation () const 1788 { 1789 return Vec2<T> (x[2][0], x[2][1]); 1790 } 1791 1792 template <class T> 1793 template <class S> 1794 const Matrix33<T> & 1795 Matrix33<T>::translate (const Vec2<S> &t) 1796 { 1797 x[2][0] += t[0] * x[0][0] + t[1] * x[1][0]; 1798 x[2][1] += t[0] * x[0][1] + t[1] * x[1][1]; 1799 x[2][2] += t[0] * x[0][2] + t[1] * x[1][2]; 1800 1801 return *this; 1802 } 1803 1804 template <class T> 1805 template <class S> 1806 const Matrix33<T> & 1807 Matrix33<T>::setShear (const S &xy) 1808 { 1809 x[0][0] = 1; 1810 x[0][1] = 0; 1811 x[0][2] = 0; 1812 1813 x[1][0] = xy; 1814 x[1][1] = 1; 1815 x[1][2] = 0; 1816 1817 x[2][0] = 0; 1818 x[2][1] = 0; 1819 x[2][2] = 1; 1820 1821 return *this; 1822 } 1823 1824 template <class T> 1825 template <class S> 1826 const Matrix33<T> & 1827 Matrix33<T>::setShear (const Vec2<S> &h) 1828 { 1829 x[0][0] = 1; 1830 x[0][1] = h[1]; 1831 x[0][2] = 0; 1832 1833 x[1][0] = h[0]; 1834 x[1][1] = 1; 1835 x[1][2] = 0; 1836 1837 x[2][0] = 0; 1838 x[2][1] = 0; 1839 x[2][2] = 1; 1840 1841 return *this; 1842 } 1843 1844 template <class T> 1845 template <class S> 1846 const Matrix33<T> & 1847 Matrix33<T>::shear (const S &xy) 1848 { 1849 // 1850 // In this case, we don't need a temp. copy of the matrix 1851 // because we never use a value on the RHS after we've 1852 // changed it on the LHS. 1853 // 1854 1855 x[1][0] += xy * x[0][0]; 1856 x[1][1] += xy * x[0][1]; 1857 x[1][2] += xy * x[0][2]; 1858 1859 return *this; 1860 } 1861 1862 template <class T> 1863 template <class S> 1864 const Matrix33<T> & 1865 Matrix33<T>::shear (const Vec2<S> &h) 1866 { 1867 Matrix33<T> P (*this); 1868 1869 x[0][0] = P[0][0] + h[1] * P[1][0]; 1870 x[0][1] = P[0][1] + h[1] * P[1][1]; 1871 x[0][2] = P[0][2] + h[1] * P[1][2]; 1872 1873 x[1][0] = P[1][0] + h[0] * P[0][0]; 1874 x[1][1] = P[1][1] + h[0] * P[0][1]; 1875 x[1][2] = P[1][2] + h[0] * P[0][2]; 1876 1877 return *this; 1878 } 1879 1880 1881 //--------------------------- 1882 // Implementation of Matrix44 1883 //--------------------------- 1884 1885 template <class T> 1886 inline T * 1887 Matrix44<T>::operator [] (int i) 1888 { 1889 return x[i]; 1890 } 1891 1892 template <class T> 1893 inline const T * 1894 Matrix44<T>::operator [] (int i) const 1895 { 1896 return x[i]; 1897 } 1898 1899 template <class T> 1900 inline 1901 Matrix44<T>::Matrix44 () 1902 { 1903 memset (x, 0, sizeof (x)); 1904 x[0][0] = 1; 1905 x[1][1] = 1; 1906 x[2][2] = 1; 1907 x[3][3] = 1; 1908 } 1909 1910 template <class T> 1911 inline 1912 Matrix44<T>::Matrix44 (T a) 1913 { 1914 x[0][0] = a; 1915 x[0][1] = a; 1916 x[0][2] = a; 1917 x[0][3] = a; 1918 x[1][0] = a; 1919 x[1][1] = a; 1920 x[1][2] = a; 1921 x[1][3] = a; 1922 x[2][0] = a; 1923 x[2][1] = a; 1924 x[2][2] = a; 1925 x[2][3] = a; 1926 x[3][0] = a; 1927 x[3][1] = a; 1928 x[3][2] = a; 1929 x[3][3] = a; 1930 } 1931 1932 template <class T> 1933 inline 1934 Matrix44<T>::Matrix44 (const T a[4][4]) 1935 { 1936 memcpy (x, a, sizeof (x)); 1937 } 1938 1939 template <class T> 1940 inline 1941 Matrix44<T>::Matrix44 (T a, T b, T c, T d, T e, T f, T g, T h, 1942 T i, T j, T k, T l, T m, T n, T o, T p) 1943 { 1944 x[0][0] = a; 1945 x[0][1] = b; 1946 x[0][2] = c; 1947 x[0][3] = d; 1948 x[1][0] = e; 1949 x[1][1] = f; 1950 x[1][2] = g; 1951 x[1][3] = h; 1952 x[2][0] = i; 1953 x[2][1] = j; 1954 x[2][2] = k; 1955 x[2][3] = l; 1956 x[3][0] = m; 1957 x[3][1] = n; 1958 x[3][2] = o; 1959 x[3][3] = p; 1960 } 1961 1962 1963 template <class T> 1964 inline 1965 Matrix44<T>::Matrix44 (Matrix33<T> r, Vec3<T> t) 1966 { 1967 x[0][0] = r[0][0]; 1968 x[0][1] = r[0][1]; 1969 x[0][2] = r[0][2]; 1970 x[0][3] = 0; 1971 x[1][0] = r[1][0]; 1972 x[1][1] = r[1][1]; 1973 x[1][2] = r[1][2]; 1974 x[1][3] = 0; 1975 x[2][0] = r[2][0]; 1976 x[2][1] = r[2][1]; 1977 x[2][2] = r[2][2]; 1978 x[2][3] = 0; 1979 x[3][0] = t[0]; 1980 x[3][1] = t[1]; 1981 x[3][2] = t[2]; 1982 x[3][3] = 1; 1983 } 1984 1985 template <class T> 1986 inline 1987 Matrix44<T>::Matrix44 (const Matrix44 &v) 1988 { 1989 x[0][0] = v.x[0][0]; 1990 x[0][1] = v.x[0][1]; 1991 x[0][2] = v.x[0][2]; 1992 x[0][3] = v.x[0][3]; 1993 x[1][0] = v.x[1][0]; 1994 x[1][1] = v.x[1][1]; 1995 x[1][2] = v.x[1][2]; 1996 x[1][3] = v.x[1][3]; 1997 x[2][0] = v.x[2][0]; 1998 x[2][1] = v.x[2][1]; 1999 x[2][2] = v.x[2][2]; 2000 x[2][3] = v.x[2][3]; 2001 x[3][0] = v.x[3][0]; 2002 x[3][1] = v.x[3][1]; 2003 x[3][2] = v.x[3][2]; 2004 x[3][3] = v.x[3][3]; 2005 } 2006 2007 template <class T> 2008 template <class S> 2009 inline 2010 Matrix44<T>::Matrix44 (const Matrix44<S> &v) 2011 { 2012 x[0][0] = T (v.x[0][0]); 2013 x[0][1] = T (v.x[0][1]); 2014 x[0][2] = T (v.x[0][2]); 2015 x[0][3] = T (v.x[0][3]); 2016 x[1][0] = T (v.x[1][0]); 2017 x[1][1] = T (v.x[1][1]); 2018 x[1][2] = T (v.x[1][2]); 2019 x[1][3] = T (v.x[1][3]); 2020 x[2][0] = T (v.x[2][0]); 2021 x[2][1] = T (v.x[2][1]); 2022 x[2][2] = T (v.x[2][2]); 2023 x[2][3] = T (v.x[2][3]); 2024 x[3][0] = T (v.x[3][0]); 2025 x[3][1] = T (v.x[3][1]); 2026 x[3][2] = T (v.x[3][2]); 2027 x[3][3] = T (v.x[3][3]); 2028 } 2029 2030 template <class T> 2031 inline const Matrix44<T> & 2032 Matrix44<T>::operator = (const Matrix44 &v) 2033 { 2034 x[0][0] = v.x[0][0]; 2035 x[0][1] = v.x[0][1]; 2036 x[0][2] = v.x[0][2]; 2037 x[0][3] = v.x[0][3]; 2038 x[1][0] = v.x[1][0]; 2039 x[1][1] = v.x[1][1]; 2040 x[1][2] = v.x[1][2]; 2041 x[1][3] = v.x[1][3]; 2042 x[2][0] = v.x[2][0]; 2043 x[2][1] = v.x[2][1]; 2044 x[2][2] = v.x[2][2]; 2045 x[2][3] = v.x[2][3]; 2046 x[3][0] = v.x[3][0]; 2047 x[3][1] = v.x[3][1]; 2048 x[3][2] = v.x[3][2]; 2049 x[3][3] = v.x[3][3]; 2050 return *this; 2051 } 2052 2053 template <class T> 2054 inline const Matrix44<T> & 2055 Matrix44<T>::operator = (T a) 2056 { 2057 x[0][0] = a; 2058 x[0][1] = a; 2059 x[0][2] = a; 2060 x[0][3] = a; 2061 x[1][0] = a; 2062 x[1][1] = a; 2063 x[1][2] = a; 2064 x[1][3] = a; 2065 x[2][0] = a; 2066 x[2][1] = a; 2067 x[2][2] = a; 2068 x[2][3] = a; 2069 x[3][0] = a; 2070 x[3][1] = a; 2071 x[3][2] = a; 2072 x[3][3] = a; 2073 return *this; 2074 } 2075 2076 template <class T> 2077 inline T * 2078 Matrix44<T>::getValue () 2079 { 2080 return (T *) &x[0][0]; 2081 } 2082 2083 template <class T> 2084 inline const T * 2085 Matrix44<T>::getValue () const 2086 { 2087 return (const T *) &x[0][0]; 2088 } 2089 2090 template <class T> 2091 template <class S> 2092 inline void 2093 Matrix44<T>::getValue (Matrix44<S> &v) const 2094 { 2095 if (isSameType<S,T>::value) 2096 { 2097 memcpy (v.x, x, sizeof (x)); 2098 } 2099 else 2100 { 2101 v.x[0][0] = x[0][0]; 2102 v.x[0][1] = x[0][1]; 2103 v.x[0][2] = x[0][2]; 2104 v.x[0][3] = x[0][3]; 2105 v.x[1][0] = x[1][0]; 2106 v.x[1][1] = x[1][1]; 2107 v.x[1][2] = x[1][2]; 2108 v.x[1][3] = x[1][3]; 2109 v.x[2][0] = x[2][0]; 2110 v.x[2][1] = x[2][1]; 2111 v.x[2][2] = x[2][2]; 2112 v.x[2][3] = x[2][3]; 2113 v.x[3][0] = x[3][0]; 2114 v.x[3][1] = x[3][1]; 2115 v.x[3][2] = x[3][2]; 2116 v.x[3][3] = x[3][3]; 2117 } 2118 } 2119 2120 template <class T> 2121 template <class S> 2122 inline Matrix44<T> & 2123 Matrix44<T>::setValue (const Matrix44<S> &v) 2124 { 2125 if (isSameType<S,T>::value) 2126 { 2127 memcpy (x, v.x, sizeof (x)); 2128 } 2129 else 2130 { 2131 x[0][0] = v.x[0][0]; 2132 x[0][1] = v.x[0][1]; 2133 x[0][2] = v.x[0][2]; 2134 x[0][3] = v.x[0][3]; 2135 x[1][0] = v.x[1][0]; 2136 x[1][1] = v.x[1][1]; 2137 x[1][2] = v.x[1][2]; 2138 x[1][3] = v.x[1][3]; 2139 x[2][0] = v.x[2][0]; 2140 x[2][1] = v.x[2][1]; 2141 x[2][2] = v.x[2][2]; 2142 x[2][3] = v.x[2][3]; 2143 x[3][0] = v.x[3][0]; 2144 x[3][1] = v.x[3][1]; 2145 x[3][2] = v.x[3][2]; 2146 x[3][3] = v.x[3][3]; 2147 } 2148 2149 return *this; 2150 } 2151 2152 template <class T> 2153 template <class S> 2154 inline Matrix44<T> & 2155 Matrix44<T>::setTheMatrix (const Matrix44<S> &v) 2156 { 2157 if (isSameType<S,T>::value) 2158 { 2159 memcpy (x, v.x, sizeof (x)); 2160 } 2161 else 2162 { 2163 x[0][0] = v.x[0][0]; 2164 x[0][1] = v.x[0][1]; 2165 x[0][2] = v.x[0][2]; 2166 x[0][3] = v.x[0][3]; 2167 x[1][0] = v.x[1][0]; 2168 x[1][1] = v.x[1][1]; 2169 x[1][2] = v.x[1][2]; 2170 x[1][3] = v.x[1][3]; 2171 x[2][0] = v.x[2][0]; 2172 x[2][1] = v.x[2][1]; 2173 x[2][2] = v.x[2][2]; 2174 x[2][3] = v.x[2][3]; 2175 x[3][0] = v.x[3][0]; 2176 x[3][1] = v.x[3][1]; 2177 x[3][2] = v.x[3][2]; 2178 x[3][3] = v.x[3][3]; 2179 } 2180 2181 return *this; 2182 } 2183 2184 template <class T> 2185 inline void 2186 Matrix44<T>::makeIdentity() 2187 { 2188 memset (x, 0, sizeof (x)); 2189 x[0][0] = 1; 2190 x[1][1] = 1; 2191 x[2][2] = 1; 2192 x[3][3] = 1; 2193 } 2194 2195 template <class T> 2196 bool 2197 Matrix44<T>::operator == (const Matrix44 &v) const 2198 { 2199 return x[0][0] == v.x[0][0] && 2200 x[0][1] == v.x[0][1] && 2201 x[0][2] == v.x[0][2] && 2202 x[0][3] == v.x[0][3] && 2203 x[1][0] == v.x[1][0] && 2204 x[1][1] == v.x[1][1] && 2205 x[1][2] == v.x[1][2] && 2206 x[1][3] == v.x[1][3] && 2207 x[2][0] == v.x[2][0] && 2208 x[2][1] == v.x[2][1] && 2209 x[2][2] == v.x[2][2] && 2210 x[2][3] == v.x[2][3] && 2211 x[3][0] == v.x[3][0] && 2212 x[3][1] == v.x[3][1] && 2213 x[3][2] == v.x[3][2] && 2214 x[3][3] == v.x[3][3]; 2215 } 2216 2217 template <class T> 2218 bool 2219 Matrix44<T>::operator != (const Matrix44 &v) const 2220 { 2221 return x[0][0] != v.x[0][0] || 2222 x[0][1] != v.x[0][1] || 2223 x[0][2] != v.x[0][2] || 2224 x[0][3] != v.x[0][3] || 2225 x[1][0] != v.x[1][0] || 2226 x[1][1] != v.x[1][1] || 2227 x[1][2] != v.x[1][2] || 2228 x[1][3] != v.x[1][3] || 2229 x[2][0] != v.x[2][0] || 2230 x[2][1] != v.x[2][1] || 2231 x[2][2] != v.x[2][2] || 2232 x[2][3] != v.x[2][3] || 2233 x[3][0] != v.x[3][0] || 2234 x[3][1] != v.x[3][1] || 2235 x[3][2] != v.x[3][2] || 2236 x[3][3] != v.x[3][3]; 2237 } 2238 2239 template <class T> 2240 bool 2241 Matrix44<T>::equalWithAbsError (const Matrix44<T> &m, T e) const 2242 { 2243 for (int i = 0; i < 4; i++) 2244 for (int j = 0; j < 4; j++) 2245 if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e)) 2246 return false; 2247 2248 return true; 2249 } 2250 2251 template <class T> 2252 bool 2253 Matrix44<T>::equalWithRelError (const Matrix44<T> &m, T e) const 2254 { 2255 for (int i = 0; i < 4; i++) 2256 for (int j = 0; j < 4; j++) 2257 if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e)) 2258 return false; 2259 2260 return true; 2261 } 2262 2263 template <class T> 2264 const Matrix44<T> & 2265 Matrix44<T>::operator += (const Matrix44<T> &v) 2266 { 2267 x[0][0] += v.x[0][0]; 2268 x[0][1] += v.x[0][1]; 2269 x[0][2] += v.x[0][2]; 2270 x[0][3] += v.x[0][3]; 2271 x[1][0] += v.x[1][0]; 2272 x[1][1] += v.x[1][1]; 2273 x[1][2] += v.x[1][2]; 2274 x[1][3] += v.x[1][3]; 2275 x[2][0] += v.x[2][0]; 2276 x[2][1] += v.x[2][1]; 2277 x[2][2] += v.x[2][2]; 2278 x[2][3] += v.x[2][3]; 2279 x[3][0] += v.x[3][0]; 2280 x[3][1] += v.x[3][1]; 2281 x[3][2] += v.x[3][2]; 2282 x[3][3] += v.x[3][3]; 2283 2284 return *this; 2285 } 2286 2287 template <class T> 2288 const Matrix44<T> & 2289 Matrix44<T>::operator += (T a) 2290 { 2291 x[0][0] += a; 2292 x[0][1] += a; 2293 x[0][2] += a; 2294 x[0][3] += a; 2295 x[1][0] += a; 2296 x[1][1] += a; 2297 x[1][2] += a; 2298 x[1][3] += a; 2299 x[2][0] += a; 2300 x[2][1] += a; 2301 x[2][2] += a; 2302 x[2][3] += a; 2303 x[3][0] += a; 2304 x[3][1] += a; 2305 x[3][2] += a; 2306 x[3][3] += a; 2307 2308 return *this; 2309 } 2310 2311 template <class T> 2312 Matrix44<T> 2313 Matrix44<T>::operator + (const Matrix44<T> &v) const 2314 { 2315 return Matrix44 (x[0][0] + v.x[0][0], 2316 x[0][1] + v.x[0][1], 2317 x[0][2] + v.x[0][2], 2318 x[0][3] + v.x[0][3], 2319 x[1][0] + v.x[1][0], 2320 x[1][1] + v.x[1][1], 2321 x[1][2] + v.x[1][2], 2322 x[1][3] + v.x[1][3], 2323 x[2][0] + v.x[2][0], 2324 x[2][1] + v.x[2][1], 2325 x[2][2] + v.x[2][2], 2326 x[2][3] + v.x[2][3], 2327 x[3][0] + v.x[3][0], 2328 x[3][1] + v.x[3][1], 2329 x[3][2] + v.x[3][2], 2330 x[3][3] + v.x[3][3]); 2331 } 2332 2333 template <class T> 2334 const Matrix44<T> & 2335 Matrix44<T>::operator -= (const Matrix44<T> &v) 2336 { 2337 x[0][0] -= v.x[0][0]; 2338 x[0][1] -= v.x[0][1]; 2339 x[0][2] -= v.x[0][2]; 2340 x[0][3] -= v.x[0][3]; 2341 x[1][0] -= v.x[1][0]; 2342 x[1][1] -= v.x[1][1]; 2343 x[1][2] -= v.x[1][2]; 2344 x[1][3] -= v.x[1][3]; 2345 x[2][0] -= v.x[2][0]; 2346 x[2][1] -= v.x[2][1]; 2347 x[2][2] -= v.x[2][2]; 2348 x[2][3] -= v.x[2][3]; 2349 x[3][0] -= v.x[3][0]; 2350 x[3][1] -= v.x[3][1]; 2351 x[3][2] -= v.x[3][2]; 2352 x[3][3] -= v.x[3][3]; 2353 2354 return *this; 2355 } 2356 2357 template <class T> 2358 const Matrix44<T> & 2359 Matrix44<T>::operator -= (T a) 2360 { 2361 x[0][0] -= a; 2362 x[0][1] -= a; 2363 x[0][2] -= a; 2364 x[0][3] -= a; 2365 x[1][0] -= a; 2366 x[1][1] -= a; 2367 x[1][2] -= a; 2368 x[1][3] -= a; 2369 x[2][0] -= a; 2370 x[2][1] -= a; 2371 x[2][2] -= a; 2372 x[2][3] -= a; 2373 x[3][0] -= a; 2374 x[3][1] -= a; 2375 x[3][2] -= a; 2376 x[3][3] -= a; 2377 2378 return *this; 2379 } 2380 2381 template <class T> 2382 Matrix44<T> 2383 Matrix44<T>::operator - (const Matrix44<T> &v) const 2384 { 2385 return Matrix44 (x[0][0] - v.x[0][0], 2386 x[0][1] - v.x[0][1], 2387 x[0][2] - v.x[0][2], 2388 x[0][3] - v.x[0][3], 2389 x[1][0] - v.x[1][0], 2390 x[1][1] - v.x[1][1], 2391 x[1][2] - v.x[1][2], 2392 x[1][3] - v.x[1][3], 2393 x[2][0] - v.x[2][0], 2394 x[2][1] - v.x[2][1], 2395 x[2][2] - v.x[2][2], 2396 x[2][3] - v.x[2][3], 2397 x[3][0] - v.x[3][0], 2398 x[3][1] - v.x[3][1], 2399 x[3][2] - v.x[3][2], 2400 x[3][3] - v.x[3][3]); 2401 } 2402 2403 template <class T> 2404 Matrix44<T> 2405 Matrix44<T>::operator - () const 2406 { 2407 return Matrix44 (-x[0][0], 2408 -x[0][1], 2409 -x[0][2], 2410 -x[0][3], 2411 -x[1][0], 2412 -x[1][1], 2413 -x[1][2], 2414 -x[1][3], 2415 -x[2][0], 2416 -x[2][1], 2417 -x[2][2], 2418 -x[2][3], 2419 -x[3][0], 2420 -x[3][1], 2421 -x[3][2], 2422 -x[3][3]); 2423 } 2424 2425 template <class T> 2426 const Matrix44<T> & 2427 Matrix44<T>::negate () 2428 { 2429 x[0][0] = -x[0][0]; 2430 x[0][1] = -x[0][1]; 2431 x[0][2] = -x[0][2]; 2432 x[0][3] = -x[0][3]; 2433 x[1][0] = -x[1][0]; 2434 x[1][1] = -x[1][1]; 2435 x[1][2] = -x[1][2]; 2436 x[1][3] = -x[1][3]; 2437 x[2][0] = -x[2][0]; 2438 x[2][1] = -x[2][1]; 2439 x[2][2] = -x[2][2]; 2440 x[2][3] = -x[2][3]; 2441 x[3][0] = -x[3][0]; 2442 x[3][1] = -x[3][1]; 2443 x[3][2] = -x[3][2]; 2444 x[3][3] = -x[3][3]; 2445 2446 return *this; 2447 } 2448 2449 template <class T> 2450 const Matrix44<T> & 2451 Matrix44<T>::operator *= (T a) 2452 { 2453 x[0][0] *= a; 2454 x[0][1] *= a; 2455 x[0][2] *= a; 2456 x[0][3] *= a; 2457 x[1][0] *= a; 2458 x[1][1] *= a; 2459 x[1][2] *= a; 2460 x[1][3] *= a; 2461 x[2][0] *= a; 2462 x[2][1] *= a; 2463 x[2][2] *= a; 2464 x[2][3] *= a; 2465 x[3][0] *= a; 2466 x[3][1] *= a; 2467 x[3][2] *= a; 2468 x[3][3] *= a; 2469 2470 return *this; 2471 } 2472 2473 template <class T> 2474 Matrix44<T> 2475 Matrix44<T>::operator * (T a) const 2476 { 2477 return Matrix44 (x[0][0] * a, 2478 x[0][1] * a, 2479 x[0][2] * a, 2480 x[0][3] * a, 2481 x[1][0] * a, 2482 x[1][1] * a, 2483 x[1][2] * a, 2484 x[1][3] * a, 2485 x[2][0] * a, 2486 x[2][1] * a, 2487 x[2][2] * a, 2488 x[2][3] * a, 2489 x[3][0] * a, 2490 x[3][1] * a, 2491 x[3][2] * a, 2492 x[3][3] * a); 2493 } 2494 2495 template <class T> 2496 inline Matrix44<T> 2497 operator * (T a, const Matrix44<T> &v) 2498 { 2499 return v * a; 2500 } 2501 2502 template <class T> 2503 inline const Matrix44<T> & 2504 Matrix44<T>::operator *= (const Matrix44<T> &v) 2505 { 2506 Matrix44 tmp (T (0)); 2507 2508 multiply (*this, v, tmp); 2509 *this = tmp; 2510 return *this; 2511 } 2512 2513 template <class T> 2514 inline Matrix44<T> 2515 Matrix44<T>::operator * (const Matrix44<T> &v) const 2516 { 2517 Matrix44 tmp (T (0)); 2518 2519 multiply (*this, v, tmp); 2520 return tmp; 2521 } 2522 2523 template <class T> 2524 void 2525 Matrix44<T>::multiply (const Matrix44<T> &a, 2526 const Matrix44<T> &b, 2527 Matrix44<T> &c) 2528 { 2529 register const T * IMATH_RESTRICT ap = &a.x[0][0]; 2530 register const T * IMATH_RESTRICT bp = &b.x[0][0]; 2531 register T * IMATH_RESTRICT cp = &c.x[0][0]; 2532 2533 register T a0, a1, a2, a3; 2534 2535 a0 = ap[0]; 2536 a1 = ap[1]; 2537 a2 = ap[2]; 2538 a3 = ap[3]; 2539 2540 cp[0] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; 2541 cp[1] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; 2542 cp[2] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; 2543 cp[3] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; 2544 2545 a0 = ap[4]; 2546 a1 = ap[5]; 2547 a2 = ap[6]; 2548 a3 = ap[7]; 2549 2550 cp[4] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; 2551 cp[5] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; 2552 cp[6] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; 2553 cp[7] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; 2554 2555 a0 = ap[8]; 2556 a1 = ap[9]; 2557 a2 = ap[10]; 2558 a3 = ap[11]; 2559 2560 cp[8] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; 2561 cp[9] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; 2562 cp[10] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; 2563 cp[11] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; 2564 2565 a0 = ap[12]; 2566 a1 = ap[13]; 2567 a2 = ap[14]; 2568 a3 = ap[15]; 2569 2570 cp[12] = a0 * bp[0] + a1 * bp[4] + a2 * bp[8] + a3 * bp[12]; 2571 cp[13] = a0 * bp[1] + a1 * bp[5] + a2 * bp[9] + a3 * bp[13]; 2572 cp[14] = a0 * bp[2] + a1 * bp[6] + a2 * bp[10] + a3 * bp[14]; 2573 cp[15] = a0 * bp[3] + a1 * bp[7] + a2 * bp[11] + a3 * bp[15]; 2574 } 2575 2576 template <class T> template <class S> 2577 void 2578 Matrix44<T>::multVecMatrix(const Vec3<S> &src, Vec3<S> &dst) const 2579 { 2580 S a, b, c, w; 2581 2582 a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0] + x[3][0]; 2583 b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1] + x[3][1]; 2584 c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2] + x[3][2]; 2585 w = src[0] * x[0][3] + src[1] * x[1][3] + src[2] * x[2][3] + x[3][3]; 2586 2587 dst.x = a / w; 2588 dst.y = b / w; 2589 dst.z = c / w; 2590 } 2591 2592 template <class T> template <class S> 2593 void 2594 Matrix44<T>::multDirMatrix(const Vec3<S> &src, Vec3<S> &dst) const 2595 { 2596 S a, b, c; 2597 2598 a = src[0] * x[0][0] + src[1] * x[1][0] + src[2] * x[2][0]; 2599 b = src[0] * x[0][1] + src[1] * x[1][1] + src[2] * x[2][1]; 2600 c = src[0] * x[0][2] + src[1] * x[1][2] + src[2] * x[2][2]; 2601 2602 dst.x = a; 2603 dst.y = b; 2604 dst.z = c; 2605 } 2606 2607 template <class T> 2608 const Matrix44<T> & 2609 Matrix44<T>::operator /= (T a) 2610 { 2611 x[0][0] /= a; 2612 x[0][1] /= a; 2613 x[0][2] /= a; 2614 x[0][3] /= a; 2615 x[1][0] /= a; 2616 x[1][1] /= a; 2617 x[1][2] /= a; 2618 x[1][3] /= a; 2619 x[2][0] /= a; 2620 x[2][1] /= a; 2621 x[2][2] /= a; 2622 x[2][3] /= a; 2623 x[3][0] /= a; 2624 x[3][1] /= a; 2625 x[3][2] /= a; 2626 x[3][3] /= a; 2627 2628 return *this; 2629 } 2630 2631 template <class T> 2632 Matrix44<T> 2633 Matrix44<T>::operator / (T a) const 2634 { 2635 return Matrix44 (x[0][0] / a, 2636 x[0][1] / a, 2637 x[0][2] / a, 2638 x[0][3] / a, 2639 x[1][0] / a, 2640 x[1][1] / a, 2641 x[1][2] / a, 2642 x[1][3] / a, 2643 x[2][0] / a, 2644 x[2][1] / a, 2645 x[2][2] / a, 2646 x[2][3] / a, 2647 x[3][0] / a, 2648 x[3][1] / a, 2649 x[3][2] / a, 2650 x[3][3] / a); 2651 } 2652 2653 template <class T> 2654 const Matrix44<T> & 2655 Matrix44<T>::transpose () 2656 { 2657 Matrix44 tmp (x[0][0], 2658 x[1][0], 2659 x[2][0], 2660 x[3][0], 2661 x[0][1], 2662 x[1][1], 2663 x[2][1], 2664 x[3][1], 2665 x[0][2], 2666 x[1][2], 2667 x[2][2], 2668 x[3][2], 2669 x[0][3], 2670 x[1][3], 2671 x[2][3], 2672 x[3][3]); 2673 *this = tmp; 2674 return *this; 2675 } 2676 2677 template <class T> 2678 Matrix44<T> 2679 Matrix44<T>::transposed () const 2680 { 2681 return Matrix44 (x[0][0], 2682 x[1][0], 2683 x[2][0], 2684 x[3][0], 2685 x[0][1], 2686 x[1][1], 2687 x[2][1], 2688 x[3][1], 2689 x[0][2], 2690 x[1][2], 2691 x[2][2], 2692 x[3][2], 2693 x[0][3], 2694 x[1][3], 2695 x[2][3], 2696 x[3][3]); 2697 } 2698 2699 template <class T> 2700 const Matrix44<T> & 2701 Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc) 2702 { 2703 *this = gjInverse (singExc); 2704 return *this; 2705 } 2706 2707 template <class T> 2708 Matrix44<T> 2709 Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc) 2710 { 2711 int i, j, k; 2712 Matrix44 s; 2713 Matrix44 t (*this); 2714 2715 // Forward elimination 2716 2717 for (i = 0; i < 3 ; i++) 2718 { 2719 int pivot = i; 2720 2721 T pivotsize = t[i][i]; 2722 2723 if (pivotsize < 0) 2724 pivotsize = -pivotsize; 2725 2726 for (j = i + 1; j < 4; j++) 2727 { 2728 T tmp = t[j][i]; 2729 2730 if (tmp < 0) 2731 tmp = -tmp; 2732 2733 if (tmp > pivotsize) 2734 { 2735 pivot = j; 2736 pivotsize = tmp; 2737 } 2738 } 2739 2740 if (pivotsize == 0) 2741 { 2742 if (singExc) 2743 throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); 2744 2745 return Matrix44(); 2746 } 2747 2748 if (pivot != i) 2749 { 2750 for (j = 0; j < 4; j++) 2751 { 2752 T tmp; 2753 2754 tmp = t[i][j]; 2755 t[i][j] = t[pivot][j]; 2756 t[pivot][j] = tmp; 2757 2758 tmp = s[i][j]; 2759 s[i][j] = s[pivot][j]; 2760 s[pivot][j] = tmp; 2761 } 2762 } 2763 2764 for (j = i + 1; j < 4; j++) 2765 { 2766 T f = t[j][i] / t[i][i]; 2767 2768 for (k = 0; k < 4; k++) 2769 { 2770 t[j][k] -= f * t[i][k]; 2771 s[j][k] -= f * s[i][k]; 2772 } 2773 } 2774 } 2775 2776 // Backward substitution 2777 2778 for (i = 3; i >= 0; --i) 2779 { 2780 T f; 2781 2782 if ((f = t[i][i]) == 0) 2783 { 2784 if (singExc) 2785 throw ::Imath::SingMatrixExc ("Cannot invert singular matrix."); 2786 2787 return Matrix44(); 2788 } 2789 2790 for (j = 0; j < 4; j++) 2791 { 2792 t[i][j] /= f; 2793 s[i][j] /= f; 2794 } 2795 2796 for (j = 0; j < i; j++) 2797 { 2798 f = t[j][i]; 2799 2800 for (k = 0; k < 4; k++) 2801 { 2802 t[j][k] -= f * t[i][k]; 2803 s[j][k] -= f * s[i][k]; 2804 } 2805 } 2806 } 2807 2808 return s; 2809 } 2810 2811 template <class T> 2812 const Matrix44<T> & 2813 Matrix44<T>::invert (bool singExc) throw (Iex::MathExc) 2814 { 2815 *this = inverse (singExc); 2816 return *this; 2817 } 2818 2819 template <class T> 2820 Matrix44<T> 2821 Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc) 2822 { 2823 if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1) 2824 return gjInverse(singExc); 2825 2826 Matrix44 s (x[1][1] * x[2][2] - x[2][1] * x[1][2], 2827 x[2][1] * x[0][2] - x[0][1] * x[2][2], 2828 x[0][1] * x[1][2] - x[1][1] * x[0][2], 2829 0, 2830 2831 x[2][0] * x[1][2] - x[1][0] * x[2][2], 2832 x[0][0] * x[2][2] - x[2][0] * x[0][2], 2833 x[1][0] * x[0][2] - x[0][0] * x[1][2], 2834 0, 2835 2836 x[1][0] * x[2][1] - x[2][0] * x[1][1], 2837 x[2][0] * x[0][1] - x[0][0] * x[2][1], 2838 x[0][0] * x[1][1] - x[1][0] * x[0][1], 2839 0, 2840 2841 0, 2842 0, 2843 0, 2844 1); 2845 2846 T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0]; 2847 2848 if (Imath::abs (r) >= 1) 2849 { 2850 for (int i = 0; i < 3; ++i) 2851 { 2852 for (int j = 0; j < 3; ++j) 2853 { 2854 s[i][j] /= r; 2855 } 2856 } 2857 } 2858 else 2859 { 2860 T mr = Imath::abs (r) / limits<T>::smallest(); 2861 2862 for (int i = 0; i < 3; ++i) 2863 { 2864 for (int j = 0; j < 3; ++j) 2865 { 2866 if (mr > Imath::abs (s[i][j])) 2867 { 2868 s[i][j] /= r; 2869 } 2870 else 2871 { 2872 if (singExc) 2873 throw SingMatrixExc ("Cannot invert singular matrix."); 2874 2875 return Matrix44(); 2876 } 2877 } 2878 } 2879 } 2880 2881 s[3][0] = -x[3][0] * s[0][0] - x[3][1] * s[1][0] - x[3][2] * s[2][0]; 2882 s[3][1] = -x[3][0] * s[0][1] - x[3][1] * s[1][1] - x[3][2] * s[2][1]; 2883 s[3][2] = -x[3][0] * s[0][2] - x[3][1] * s[1][2] - x[3][2] * s[2][2]; 2884 2885 return s; 2886 } 2887 2888 template <class T> 2889 inline T 2890 Matrix44<T>::fastMinor( const int r0, const int r1, const int r2, 2891 const int c0, const int c1, const int c2) const 2892 { 2893 return x[r0][c0] * (x[r1][c1]*x[r2][c2] - x[r1][c2]*x[r2][c1]) 2894 + x[r0][c1] * (x[r1][c2]*x[r2][c0] - x[r1][c0]*x[r2][c2]) 2895 + x[r0][c2] * (x[r1][c0]*x[r2][c1] - x[r1][c1]*x[r2][c0]); 2896 } 2897 2898 template <class T> 2899 inline T 2900 Matrix44<T>::minorOf (const int r, const int c) const 2901 { 2902 int r0 = 0 + (r < 1 ? 1 : 0); 2903 int r1 = 1 + (r < 2 ? 1 : 0); 2904 int r2 = 2 + (r < 3 ? 1 : 0); 2905 int c0 = 0 + (c < 1 ? 1 : 0); 2906 int c1 = 1 + (c < 2 ? 1 : 0); 2907 int c2 = 2 + (c < 3 ? 1 : 0); 2908 2909 Matrix33<T> working (x[r0][c0],x[r1][c0],x[r2][c0], 2910 x[r0][c1],x[r1][c1],x[r2][c1], 2911 x[r0][c2],x[r1][c2],x[r2][c2]); 2912 2913 return working.determinant(); 2914 } 2915 2916 template <class T> 2917 inline T 2918 Matrix44<T>::determinant () const 2919 { 2920 T sum = (T)0; 2921 2922 if (x[0][3] != 0.) sum -= x[0][3] * fastMinor(1,2,3,0,1,2); 2923 if (x[1][3] != 0.) sum += x[1][3] * fastMinor(0,2,3,0,1,2); 2924 if (x[2][3] != 0.) sum -= x[2][3] * fastMinor(0,1,3,0,1,2); 2925 if (x[3][3] != 0.) sum += x[3][3] * fastMinor(0,1,2,0,1,2); 2926 2927 return sum; 2928 } 2929 2930 template <class T> 2931 template <class S> 2932 const Matrix44<T> & 2933 Matrix44<T>::setEulerAngles (const Vec3<S>& r) 2934 { 2935 S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx; 2936 2937 cos_rz = Math<T>::cos (r[2]); 2938 cos_ry = Math<T>::cos (r[1]); 2939 cos_rx = Math<T>::cos (r[0]); 2940 2941 sin_rz = Math<T>::sin (r[2]); 2942 sin_ry = Math<T>::sin (r[1]); 2943 sin_rx = Math<T>::sin (r[0]); 2944 2945 x[0][0] = cos_rz * cos_ry; 2946 x[0][1] = sin_rz * cos_ry; 2947 x[0][2] = -sin_ry; 2948 x[0][3] = 0; 2949 2950 x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx; 2951 x[1][1] = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx; 2952 x[1][2] = cos_ry * sin_rx; 2953 x[1][3] = 0; 2954 2955 x[2][0] = sin_rz * sin_rx + cos_rz * sin_ry * cos_rx; 2956 x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx; 2957 x[2][2] = cos_ry * cos_rx; 2958 x[2][3] = 0; 2959 2960 x[3][0] = 0; 2961 x[3][1] = 0; 2962 x[3][2] = 0; 2963 x[3][3] = 1; 2964 2965 return *this; 2966 } 2967 2968 template <class T> 2969 template <class S> 2970 const Matrix44<T> & 2971 Matrix44<T>::setAxisAngle (const Vec3<S>& axis, S angle) 2972 { 2973 Vec3<S> unit (axis.normalized()); 2974 S sine = Math<T>::sin (angle); 2975 S cosine = Math<T>::cos (angle); 2976 2977 x[0][0] = unit[0] * unit[0] * (1 - cosine) + cosine; 2978 x[0][1] = unit[0] * unit[1] * (1 - cosine) + unit[2] * sine; 2979 x[0][2] = unit[0] * unit[2] * (1 - cosine) - unit[1] * sine; 2980 x[0][3] = 0; 2981 2982 x[1][0] = unit[0] * unit[1] * (1 - cosine) - unit[2] * sine; 2983 x[1][1] = unit[1] * unit[1] * (1 - cosine) + cosine; 2984 x[1][2] = unit[1] * unit[2] * (1 - cosine) + unit[0] * sine; 2985 x[1][3] = 0; 2986 2987 x[2][0] = unit[0] * unit[2] * (1 - cosine) + unit[1] * sine; 2988 x[2][1] = unit[1] * unit[2] * (1 - cosine) - unit[0] * sine; 2989 x[2][2] = unit[2] * unit[2] * (1 - cosine) + cosine; 2990 x[2][3] = 0; 2991 2992 x[3][0] = 0; 2993 x[3][1] = 0; 2994 x[3][2] = 0; 2995 x[3][3] = 1; 2996 2997 return *this; 2998 } 2999 3000 template <class T> 3001 template <class S> 3002 const Matrix44<T> & 3003 Matrix44<T>::rotate (const Vec3<S> &r) 3004 { 3005 S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx; 3006 S m00, m01, m02; 3007 S m10, m11, m12; 3008 S m20, m21, m22; 3009 3010 cos_rz = Math<S>::cos (r[2]); 3011 cos_ry = Math<S>::cos (r[1]); 3012 cos_rx = Math<S>::cos (r[0]); 3013 3014 sin_rz = Math<S>::sin (r[2]); 3015 sin_ry = Math<S>::sin (r[1]); 3016 sin_rx = Math<S>::sin (r[0]); 3017 3018 m00 = cos_rz * cos_ry; 3019 m01 = sin_rz * cos_ry; 3020 m02 = -sin_ry; 3021 m10 = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx; 3022 m11 = cos_rz * cos_rx + sin_rz * sin_ry * sin_rx; 3023 m12 = cos_ry * sin_rx; 3024 m20 = -sin_rz * -sin_rx + cos_rz * sin_ry * cos_rx; 3025 m21 = cos_rz * -sin_rx + sin_rz * sin_ry * cos_rx; 3026 m22 = cos_ry * cos_rx; 3027 3028 Matrix44<T> P (*this); 3029 3030 x[0][0] = P[0][0] * m00 + P[1][0] * m01 + P[2][0] * m02; 3031 x[0][1] = P[0][1] * m00 + P[1][1] * m01 + P[2][1] * m02; 3032 x[0][2] = P[0][2] * m00 + P[1][2] * m01 + P[2][2] * m02; 3033 x[0][3] = P[0][3] * m00 + P[1][3] * m01 + P[2][3] * m02; 3034 3035 x[1][0] = P[0][0] * m10 + P[1][0] * m11 + P[2][0] * m12; 3036 x[1][1] = P[0][1] * m10 + P[1][1] * m11 + P[2][1] * m12; 3037 x[1][2] = P[0][2] * m10 + P[1][2] * m11 + P[2][2] * m12; 3038 x[1][3] = P[0][3] * m10 + P[1][3] * m11 + P[2][3] * m12; 3039 3040 x[2][0] = P[0][0] * m20 + P[1][0] * m21 + P[2][0] * m22; 3041 x[2][1] = P[0][1] * m20 + P[1][1] * m21 + P[2][1] * m22; 3042 x[2][2] = P[0][2] * m20 + P[1][2] * m21 + P[2][2] * m22; 3043 x[2][3] = P[0][3] * m20 + P[1][3] * m21 + P[2][3] * m22; 3044 3045 return *this; 3046 } 3047 3048 template <class T> 3049 const Matrix44<T> & 3050 Matrix44<T>::setScale (T s) 3051 { 3052 memset (x, 0, sizeof (x)); 3053 x[0][0] = s; 3054 x[1][1] = s; 3055 x[2][2] = s; 3056 x[3][3] = 1; 3057 3058 return *this; 3059 } 3060 3061 template <class T> 3062 template <class S> 3063 const Matrix44<T> & 3064 Matrix44<T>::setScale (const Vec3<S> &s) 3065 { 3066 memset (x, 0, sizeof (x)); 3067 x[0][0] = s[0]; 3068 x[1][1] = s[1]; 3069 x[2][2] = s[2]; 3070 x[3][3] = 1; 3071 3072 return *this; 3073 } 3074 3075 template <class T> 3076 template <class S> 3077 const Matrix44<T> & 3078 Matrix44<T>::scale (const Vec3<S> &s) 3079 { 3080 x[0][0] *= s[0]; 3081 x[0][1] *= s[0]; 3082 x[0][2] *= s[0]; 3083 x[0][3] *= s[0]; 3084 3085 x[1][0] *= s[1]; 3086 x[1][1] *= s[1]; 3087 x[1][2] *= s[1]; 3088 x[1][3] *= s[1]; 3089 3090 x[2][0] *= s[2]; 3091 x[2][1] *= s[2]; 3092 x[2][2] *= s[2]; 3093 x[2][3] *= s[2]; 3094 3095 return *this; 3096 } 3097 3098 template <class T> 3099 template <class S> 3100 const Matrix44<T> & 3101 Matrix44<T>::setTranslation (const Vec3<S> &t) 3102 { 3103 x[0][0] = 1; 3104 x[0][1] = 0; 3105 x[0][2] = 0; 3106 x[0][3] = 0; 3107 3108 x[1][0] = 0; 3109 x[1][1] = 1; 3110 x[1][2] = 0; 3111 x[1][3] = 0; 3112 3113 x[2][0] = 0; 3114 x[2][1] = 0; 3115 x[2][2] = 1; 3116 x[2][3] = 0; 3117 3118 x[3][0] = t[0]; 3119 x[3][1] = t[1]; 3120 x[3][2] = t[2]; 3121 x[3][3] = 1; 3122 3123 return *this; 3124 } 3125 3126 template <class T> 3127 inline const Vec3<T> 3128 Matrix44<T>::translation () const 3129 { 3130 return Vec3<T> (x[3][0], x[3][1], x[3][2]); 3131 } 3132 3133 template <class T> 3134 template <class S> 3135 const Matrix44<T> & 3136 Matrix44<T>::translate (const Vec3<S> &t) 3137 { 3138 x[3][0] += t[0] * x[0][0] + t[1] * x[1][0] + t[2] * x[2][0]; 3139 x[3][1] += t[0] * x[0][1] + t[1] * x[1][1] + t[2] * x[2][1]; 3140 x[3][2] += t[0] * x[0][2] + t[1] * x[1][2] + t[2] * x[2][2]; 3141 x[3][3] += t[0] * x[0][3] + t[1] * x[1][3] + t[2] * x[2][3]; 3142 3143 return *this; 3144 } 3145 3146 template <class T> 3147 template <class S> 3148 const Matrix44<T> & 3149 Matrix44<T>::setShear (const Vec3<S> &h) 3150 { 3151 x[0][0] = 1; 3152 x[0][1] = 0; 3153 x[0][2] = 0; 3154 x[0][3] = 0; 3155 3156 x[1][0] = h[0]; 3157 x[1][1] = 1; 3158 x[1][2] = 0; 3159 x[1][3] = 0; 3160 3161 x[2][0] = h[1]; 3162 x[2][1] = h[2]; 3163 x[2][2] = 1; 3164 x[2][3] = 0; 3165 3166 x[3][0] = 0; 3167 x[3][1] = 0; 3168 x[3][2] = 0; 3169 x[3][3] = 1; 3170 3171 return *this; 3172 } 3173 3174 template <class T> 3175 template <class S> 3176 const Matrix44<T> & 3177 Matrix44<T>::setShear (const Shear6<S> &h) 3178 { 3179 x[0][0] = 1; 3180 x[0][1] = h.yx; 3181 x[0][2] = h.zx; 3182 x[0][3] = 0; 3183 3184 x[1][0] = h.xy; 3185 x[1][1] = 1; 3186 x[1][2] = h.zy; 3187 x[1][3] = 0; 3188 3189 x[2][0] = h.xz; 3190 x[2][1] = h.yz; 3191 x[2][2] = 1; 3192 x[2][3] = 0; 3193 3194 x[3][0] = 0; 3195 x[3][1] = 0; 3196 x[3][2] = 0; 3197 x[3][3] = 1; 3198 3199 return *this; 3200 } 3201 3202 template <class T> 3203 template <class S> 3204 const Matrix44<T> & 3205 Matrix44<T>::shear (const Vec3<S> &h) 3206 { 3207 // 3208 // In this case, we don't need a temp. copy of the matrix 3209 // because we never use a value on the RHS after we've 3210 // changed it on the LHS. 3211 // 3212 3213 for (int i=0; i < 4; i++) 3214 { 3215 x[2][i] += h[1] * x[0][i] + h[2] * x[1][i]; 3216 x[1][i] += h[0] * x[0][i]; 3217 } 3218 3219 return *this; 3220 } 3221 3222 template <class T> 3223 template <class S> 3224 const Matrix44<T> & 3225 Matrix44<T>::shear (const Shear6<S> &h) 3226 { 3227 Matrix44<T> P (*this); 3228 3229 for (int i=0; i < 4; i++) 3230 { 3231 x[0][i] = P[0][i] + h.yx * P[1][i] + h.zx * P[2][i]; 3232 x[1][i] = h.xy * P[0][i] + P[1][i] + h.zy * P[2][i]; 3233 x[2][i] = h.xz * P[0][i] + h.yz * P[1][i] + P[2][i]; 3234 } 3235 3236 return *this; 3237 } 3238 3239 3240 //-------------------------------- 3241 // Implementation of stream output 3242 //-------------------------------- 3243 3244 template <class T> 3245 std::ostream & 3246 operator << (std::ostream &s, const Matrix33<T> &m) 3247 { 3248 std::ios_base::fmtflags oldFlags = s.flags(); 3249 int width; 3250 3251 if (s.flags() & std::ios_base::fixed) 3252 { 3253 s.setf (std::ios_base::showpoint); 3254 width = s.precision() + 5; 3255 } 3256 else 3257 { 3258 s.setf (std::ios_base::scientific); 3259 s.setf (std::ios_base::showpoint); 3260 width = s.precision() + 8; 3261 } 3262 3263 s << "(" << std::setw (width) << m[0][0] << 3264 " " << std::setw (width) << m[0][1] << 3265 " " << std::setw (width) << m[0][2] << "\n" << 3266 3267 " " << std::setw (width) << m[1][0] << 3268 " " << std::setw (width) << m[1][1] << 3269 " " << std::setw (width) << m[1][2] << "\n" << 3270 3271 " " << std::setw (width) << m[2][0] << 3272 " " << std::setw (width) << m[2][1] << 3273 " " << std::setw (width) << m[2][2] << ")\n"; 3274 3275 s.flags (oldFlags); 3276 return s; 3277 } 3278 3279 template <class T> 3280 std::ostream & 3281 operator << (std::ostream &s, const Matrix44<T> &m) 3282 { 3283 std::ios_base::fmtflags oldFlags = s.flags(); 3284 int width; 3285 3286 if (s.flags() & std::ios_base::fixed) 3287 { 3288 s.setf (std::ios_base::showpoint); 3289 width = s.precision() + 5; 3290 } 3291 else 3292 { 3293 s.setf (std::ios_base::scientific); 3294 s.setf (std::ios_base::showpoint); 3295 width = s.precision() + 8; 3296 } 3297 3298 s << "(" << std::setw (width) << m[0][0] << 3299 " " << std::setw (width) << m[0][1] << 3300 " " << std::setw (width) << m[0][2] << 3301 " " << std::setw (width) << m[0][3] << "\n" << 3302 3303 " " << std::setw (width) << m[1][0] << 3304 " " << std::setw (width) << m[1][1] << 3305 " " << std::setw (width) << m[1][2] << 3306 " " << std::setw (width) << m[1][3] << "\n" << 3307 3308 " " << std::setw (width) << m[2][0] << 3309 " " << std::setw (width) << m[2][1] << 3310 " " << std::setw (width) << m[2][2] << 3311 " " << std::setw (width) << m[2][3] << "\n" << 3312 3313 " " << std::setw (width) << m[3][0] << 3314 " " << std::setw (width) << m[3][1] << 3315 " " << std::setw (width) << m[3][2] << 3316 " " << std::setw (width) << m[3][3] << ")\n"; 3317 3318 s.flags (oldFlags); 3319 return s; 3320 } 3321 3322 3323 //--------------------------------------------------------------- 3324 // Implementation of vector-times-matrix multiplication operators 3325 //--------------------------------------------------------------- 3326 3327 template <class S, class T> 3328 inline const Vec2<S> & 3329 operator *= (Vec2<S> &v, const Matrix33<T> &m) 3330 { 3331 S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]); 3332 S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]); 3333 S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]); 3334 3335 v.x = x / w; 3336 v.y = y / w; 3337 3338 return v; 3339 } 3340 3341 template <class S, class T> 3342 inline Vec2<S> 3343 operator * (const Vec2<S> &v, const Matrix33<T> &m) 3344 { 3345 S x = S(v.x * m[0][0] + v.y * m[1][0] + m[2][0]); 3346 S y = S(v.x * m[0][1] + v.y * m[1][1] + m[2][1]); 3347 S w = S(v.x * m[0][2] + v.y * m[1][2] + m[2][2]); 3348 3349 return Vec2<S> (x / w, y / w); 3350 } 3351 3352 3353 template <class S, class T> 3354 inline const Vec3<S> & 3355 operator *= (Vec3<S> &v, const Matrix33<T> &m) 3356 { 3357 S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]); 3358 S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]); 3359 S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]); 3360 3361 v.x = x; 3362 v.y = y; 3363 v.z = z; 3364 3365 return v; 3366 } 3367 3368 template <class S, class T> 3369 inline Vec3<S> 3370 operator * (const Vec3<S> &v, const Matrix33<T> &m) 3371 { 3372 S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0]); 3373 S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1]); 3374 S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]); 3375 3376 return Vec3<S> (x, y, z); 3377 } 3378 3379 3380 template <class S, class T> 3381 inline const Vec3<S> & 3382 operator *= (Vec3<S> &v, const Matrix44<T> &m) 3383 { 3384 S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]); 3385 S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]); 3386 S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]); 3387 S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]); 3388 3389 v.x = x / w; 3390 v.y = y / w; 3391 v.z = z / w; 3392 3393 return v; 3394 } 3395 3396 template <class S, class T> 3397 inline Vec3<S> 3398 operator * (const Vec3<S> &v, const Matrix44<T> &m) 3399 { 3400 S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]); 3401 S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]); 3402 S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]); 3403 S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + m[3][3]); 3404 3405 return Vec3<S> (x / w, y / w, z / w); 3406 } 3407 3408 3409 template <class S, class T> 3410 inline const Vec4<S> & 3411 operator *= (Vec4<S> &v, const Matrix44<T> &m) 3412 { 3413 S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]); 3414 S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]); 3415 S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]); 3416 S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]); 3417 3418 v.x = x; 3419 v.y = y; 3420 v.z = z; 3421 v.w = w; 3422 3423 return v; 3424 } 3425 3426 template <class S, class T> 3427 inline Vec4<S> 3428 operator * (const Vec4<S> &v, const Matrix44<T> &m) 3429 { 3430 S x = S(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]); 3431 S y = S(v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]); 3432 S z = S(v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]); 3433 S w = S(v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]); 3434 3435 return Vec4<S> (x, y, z, w); 3436 } 3437 3438 } // namespace Imath 3439 3440 3441 3442 #endif 3443