/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

Large files are truncated click here to view the full file

  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];