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