PageRenderTime 71ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/FreeImage/Source/OpenEXR/Imath/ImathMatrix.h

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