Matrixf 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2004 Robert Osfield
  2. *
  3. * This library is open source and may be redistributed and/or modified under
  4. * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
  5. * (at your option) any later version. The full license is in LICENSE file
  6. * included with this distribution, and on the openscenegraph.org website.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * OpenSceneGraph Public License for more details.
  12. */
  13. #ifndef OSG_MATRIXF
  14. #define OSG_MATRIXF 1
  15. #include <osg/Object>
  16. #include <osg/Vec3d>
  17. #include <osg/Vec4d>
  18. #include <osg/Quat>
  19. namespace osg {
  20. class Matrixf;
  21. class OSG_EXPORT Matrixf
  22. {
  23. public:
  24. typedef float value_type;
  25. typedef double other_value_type;
  26. inline Matrixf() { makeIdentity(); }
  27. inline Matrixf( const Matrixf& mat) { set(mat.ptr()); }
  28. Matrixf( const Matrixd& mat );
  29. inline explicit Matrixf( float const * const ptr ) { set(ptr); }
  30. inline explicit Matrixf( double const * const ptr ) { set(ptr); }
  31. inline explicit Matrixf( const Quat& quat ) { makeRotate(quat); }
  32. Matrixf( value_type a00, value_type a01, value_type a02, value_type a03,
  33. value_type a10, value_type a11, value_type a12, value_type a13,
  34. value_type a20, value_type a21, value_type a22, value_type a23,
  35. value_type a30, value_type a31, value_type a32, value_type a33);
  36. ~Matrixf() {}
  37. int compare(const Matrixf& m) const;
  38. bool operator < (const Matrixf& m) const { return compare(m)<0; }
  39. bool operator == (const Matrixf& m) const { return compare(m)==0; }
  40. bool operator != (const Matrixf& m) const { return compare(m)!=0; }
  41. inline value_type& operator()(int row, int col) { return _mat[row][col]; }
  42. inline value_type operator()(int row, int col) const { return _mat[row][col]; }
  43. inline bool valid() const { return !isNaN(); }
  44. inline bool isNaN() const { return osg::isNaN(_mat[0][0]) || osg::isNaN(_mat[0][1]) || osg::isNaN(_mat[0][2]) || osg::isNaN(_mat[0][3]) ||
  45. osg::isNaN(_mat[1][0]) || osg::isNaN(_mat[1][1]) || osg::isNaN(_mat[1][2]) || osg::isNaN(_mat[1][3]) ||
  46. osg::isNaN(_mat[2][0]) || osg::isNaN(_mat[2][1]) || osg::isNaN(_mat[2][2]) || osg::isNaN(_mat[2][3]) ||
  47. osg::isNaN(_mat[3][0]) || osg::isNaN(_mat[3][1]) || osg::isNaN(_mat[3][2]) || osg::isNaN(_mat[3][3]); }
  48. inline Matrixf& operator = (const Matrixf& rhs)
  49. {
  50. if( &rhs == this ) return *this;
  51. set(rhs.ptr());
  52. return *this;
  53. }
  54. Matrixf& operator = (const Matrixd& other);
  55. inline void set(const Matrixf& rhs) { set(rhs.ptr()); }
  56. void set(const Matrixd& rhs);
  57. inline void set(float const * const ptr)
  58. {
  59. value_type* local_ptr = (value_type*)_mat;
  60. for(int i=0;i<16;++i) local_ptr[i]=(value_type)ptr[i];
  61. }
  62. inline void set(double const * const ptr)
  63. {
  64. value_type* local_ptr = (value_type*)_mat;
  65. for(int i=0;i<16;++i) local_ptr[i]=(value_type)ptr[i];
  66. }
  67. void set(value_type a00, value_type a01, value_type a02,value_type a03,
  68. value_type a10, value_type a11, value_type a12,value_type a13,
  69. value_type a20, value_type a21, value_type a22,value_type a23,
  70. value_type a30, value_type a31, value_type a32,value_type a33);
  71. value_type * ptr() { return (value_type*)_mat; }
  72. const value_type * ptr() const { return (const value_type *)_mat; }
  73. bool isIdentity() const
  74. {
  75. return _mat[0][0]==1.0f && _mat[0][1]==0.0f && _mat[0][2]==0.0f && _mat[0][3]==0.0f &&
  76. _mat[1][0]==0.0f && _mat[1][1]==1.0f && _mat[1][2]==0.0f && _mat[1][3]==0.0f &&
  77. _mat[2][0]==0.0f && _mat[2][1]==0.0f && _mat[2][2]==1.0f && _mat[2][3]==0.0f &&
  78. _mat[3][0]==0.0f && _mat[3][1]==0.0f && _mat[3][2]==0.0f && _mat[3][3]==1.0f;
  79. }
  80. void makeIdentity();
  81. void makeScale( const Vec3f& );
  82. void makeScale( const Vec3d& );
  83. void makeScale( value_type, value_type, value_type );
  84. void makeTranslate( const Vec3f& );
  85. void makeTranslate( const Vec3d& );
  86. void makeTranslate( value_type, value_type, value_type );
  87. void makeRotate( const Vec3f& from, const Vec3f& to );
  88. void makeRotate( const Vec3d& from, const Vec3d& to );
  89. void makeRotate( value_type angle, const Vec3f& axis );
  90. void makeRotate( value_type angle, const Vec3d& axis );
  91. void makeRotate( value_type angle, value_type x, value_type y, value_type z );
  92. void makeRotate( const Quat& );
  93. void makeRotate( value_type angle1, const Vec3f& axis1,
  94. value_type angle2, const Vec3f& axis2,
  95. value_type angle3, const Vec3f& axis3);
  96. void makeRotate( value_type angle1, const Vec3d& axis1,
  97. value_type angle2, const Vec3d& axis2,
  98. value_type angle3, const Vec3d& axis3);
  99. /** decompose the matrix into translation, rotation, scale and scale orientation.*/
  100. void decompose( osg::Vec3f& translation,
  101. osg::Quat& rotation,
  102. osg::Vec3f& scale,
  103. osg::Quat& so ) const;
  104. /** decompose the matrix into translation, rotation, scale and scale orientation.*/
  105. void decompose( osg::Vec3d& translation,
  106. osg::Quat& rotation,
  107. osg::Vec3d& scale,
  108. osg::Quat& so ) const;
  109. /** Set to an orthographic projection.
  110. * See glOrtho for further details.
  111. */
  112. void makeOrtho(double left, double right,
  113. double bottom, double top,
  114. double zNear, double zFar);
  115. /** Get the orthographic settings of the orthographic projection matrix.
  116. * Note, if matrix is not an orthographic matrix then invalid values
  117. * will be returned.
  118. */
  119. bool getOrtho(double& left, double& right,
  120. double& bottom, double& top,
  121. double& zNear, double& zFar) const;
  122. /** float version of getOrtho(..) */
  123. bool getOrtho(float& left, float& right,
  124. float& bottom, float& top,
  125. float& zNear, float& zFar) const;
  126. /** Set to a 2D orthographic projection.
  127. * See glOrtho2D for further details.
  128. */
  129. inline void makeOrtho2D(double left, double right,
  130. double bottom, double top)
  131. {
  132. makeOrtho(left,right,bottom,top,-1.0,1.0);
  133. }
  134. /** Set to a perspective projection.
  135. * See glFrustum for further details.
  136. */
  137. void makeFrustum(double left, double right,
  138. double bottom, double top,
  139. double zNear, double zFar);
  140. /** Get the frustum settings of a perspective projection matrix.
  141. * Note, if matrix is not a perspective matrix then invalid values
  142. * will be returned.
  143. */
  144. bool getFrustum(double& left, double& right,
  145. double& bottom, double& top,
  146. double& zNear, double& zFar) const;
  147. /** float version of getFrustum(..) */
  148. bool getFrustum(float& left, float& right,
  149. float& bottom, float& top,
  150. float& zNear, float& zFar) const;
  151. /** Set to a symmetrical perspective projection.
  152. * See gluPerspective for further details.
  153. * Aspect ratio is defined as width/height.
  154. */
  155. void makePerspective(double fovy, double aspectRatio,
  156. double zNear, double zFar);
  157. /** Get the frustum settings of a symmetric perspective projection
  158. * matrix.
  159. * Return false if matrix is not a perspective matrix,
  160. * where parameter values are undefined.
  161. * Note, if matrix is not a symmetric perspective matrix then the
  162. * shear will be lost.
  163. * Asymmetric matrices occur when stereo, power walls, caves and
  164. * reality center display are used.
  165. * In these configuration one should use the AsFrustum method instead.
  166. */
  167. bool getPerspective(double& fovy, double& aspectRatio,
  168. double& zNear, double& zFar) const;
  169. /** float version of getPerspective(..) */
  170. bool getPerspective(float& fovy, float& aspectRatio,
  171. float& zNear, float& zFar) const;
  172. /** Set the position and orientation to be a view matrix,
  173. * using the same convention as gluLookAt.
  174. */
  175. void makeLookAt(const Vec3d& eye,const Vec3d& center,const Vec3d& up);
  176. /** Get to the position and orientation of a modelview matrix,
  177. * using the same convention as gluLookAt.
  178. */
  179. void getLookAt(Vec3f& eye,Vec3f& center,Vec3f& up,
  180. value_type lookDistance=1.0f) const;
  181. /** Get to the position and orientation of a modelview matrix,
  182. * using the same convention as gluLookAt.
  183. */
  184. void getLookAt(Vec3d& eye,Vec3d& center,Vec3d& up,
  185. value_type lookDistance=1.0f) const;
  186. /** invert the matrix rhs, automatically select invert_4x3 or invert_4x4. */
  187. inline bool invert( const Matrixf& rhs)
  188. {
  189. bool is_4x3 = (rhs._mat[0][3]==0.0f && rhs._mat[1][3]==0.0f && rhs._mat[2][3]==0.0f && rhs._mat[3][3]==1.0f);
  190. return is_4x3 ? invert_4x3(rhs) : invert_4x4(rhs);
  191. }
  192. /** 4x3 matrix invert, not right hand column is assumed to be 0,0,0,1. */
  193. bool invert_4x3( const Matrixf& rhs);
  194. /** full 4x4 matrix invert. */
  195. bool invert_4x4( const Matrixf& rhs);
  196. /** transpose matrix **/
  197. bool transpose(const Matrixf&rhs);
  198. /** transpose orthogonal part of the matrix **/
  199. bool transpose3x3(const Matrixf&rhs);
  200. /** ortho-normalize the 3x3 rotation & scale matrix */
  201. void orthoNormalize(const Matrixf& rhs);
  202. //basic utility functions to create new matrices
  203. inline static Matrixf identity( void );
  204. inline static Matrixf scale( const Vec3f& sv);
  205. inline static Matrixf scale( const Vec3d& sv);
  206. inline static Matrixf scale( value_type sx, value_type sy, value_type sz);
  207. inline static Matrixf translate( const Vec3f& dv);
  208. inline static Matrixf translate( const Vec3d& dv);
  209. inline static Matrixf translate( value_type x, value_type y, value_type z);
  210. inline static Matrixf rotate( const Vec3f& from, const Vec3f& to);
  211. inline static Matrixf rotate( const Vec3d& from, const Vec3d& to);
  212. inline static Matrixf rotate( value_type angle, value_type x, value_type y, value_type z);
  213. inline static Matrixf rotate( value_type angle, const Vec3f& axis);
  214. inline static Matrixf rotate( value_type angle, const Vec3d& axis);
  215. inline static Matrixf rotate( value_type angle1, const Vec3f& axis1,
  216. value_type angle2, const Vec3f& axis2,
  217. value_type angle3, const Vec3f& axis3);
  218. inline static Matrixf rotate( value_type angle1, const Vec3d& axis1,
  219. value_type angle2, const Vec3d& axis2,
  220. value_type angle3, const Vec3d& axis3);
  221. inline static Matrixf rotate( const Quat& quat);
  222. inline static Matrixf inverse( const Matrixf& matrix);
  223. inline static Matrixf orthoNormal(const Matrixf& matrix);
  224. /** Create an orthographic projection matrix.
  225. * See glOrtho for further details.
  226. */
  227. inline static Matrixf ortho(double left, double right,
  228. double bottom, double top,
  229. double zNear, double zFar);
  230. /** Create a 2D orthographic projection.
  231. * See glOrtho for further details.
  232. */
  233. inline static Matrixf ortho2D(double left, double right,
  234. double bottom, double top);
  235. /** Create a perspective projection.
  236. * See glFrustum for further details.
  237. */
  238. inline static Matrixf frustum(double left, double right,
  239. double bottom, double top,
  240. double zNear, double zFar);
  241. /** Create a symmetrical perspective projection.
  242. * See gluPerspective for further details.
  243. * Aspect ratio is defined as width/height.
  244. */
  245. inline static Matrixf perspective(double fovy, double aspectRatio,
  246. double zNear, double zFar);
  247. /** Create the position and orientation as per a camera,
  248. * using the same convention as gluLookAt.
  249. */
  250. inline static Matrixf lookAt(const Vec3f& eye,
  251. const Vec3f& center,
  252. const Vec3f& up);
  253. /** Create the position and orientation as per a camera,
  254. * using the same convention as gluLookAt.
  255. */
  256. inline static Matrixf lookAt(const Vec3d& eye,
  257. const Vec3d& center,
  258. const Vec3d& up);
  259. inline Vec3f preMult( const Vec3f& v ) const;
  260. inline Vec3d preMult( const Vec3d& v ) const;
  261. inline Vec3f postMult( const Vec3f& v ) const;
  262. inline Vec3d postMult( const Vec3d& v ) const;
  263. inline Vec3f operator* ( const Vec3f& v ) const;
  264. inline Vec3d operator* ( const Vec3d& v ) const;
  265. inline Vec4f preMult( const Vec4f& v ) const;
  266. inline Vec4d preMult( const Vec4d& v ) const;
  267. inline Vec4f postMult( const Vec4f& v ) const;
  268. inline Vec4d postMult( const Vec4d& v ) const;
  269. inline Vec4f operator* ( const Vec4f& v ) const;
  270. inline Vec4d operator* ( const Vec4d& v ) const;
  271. #ifdef OSG_USE_DEPRECATED_API
  272. inline void set(const Quat& q) { makeRotate(q); }
  273. inline void get(Quat& q) const { q = getRotate(); }
  274. #endif
  275. void setRotate(const Quat& q);
  276. /** Get the matrix rotation as a Quat. Note that this function
  277. * assumes a non-scaled matrix and will return incorrect results
  278. * for scaled matrixces. Consider decompose() instead.
  279. */
  280. Quat getRotate() const;
  281. void setTrans( value_type tx, value_type ty, value_type tz );
  282. void setTrans( const Vec3f& v );
  283. void setTrans( const Vec3d& v );
  284. inline Vec3d getTrans() const { return Vec3d(_mat[3][0],_mat[3][1],_mat[3][2]); }
  285. inline Vec3d getScale() const {
  286. Vec3d x_vec(_mat[0][0],_mat[1][0],_mat[2][0]);
  287. Vec3d y_vec(_mat[0][1],_mat[1][1],_mat[2][1]);
  288. Vec3d z_vec(_mat[0][2],_mat[1][2],_mat[2][2]);
  289. return Vec3d(x_vec.length(), y_vec.length(), z_vec.length());
  290. }
  291. /** apply a 3x3 transform of v*M[0..2,0..2]. */
  292. inline static Vec3f transform3x3(const Vec3f& v,const Matrixf& m);
  293. /** apply a 3x3 transform of v*M[0..2,0..2]. */
  294. inline static Vec3d transform3x3(const Vec3d& v,const Matrixf& m);
  295. /** apply a 3x3 transform of M[0..2,0..2]*v. */
  296. inline static Vec3f transform3x3(const Matrixf& m,const Vec3f& v);
  297. /** apply a 3x3 transform of M[0..2,0..2]*v. */
  298. inline static Vec3d transform3x3(const Matrixf& m,const Vec3d& v);
  299. // basic Matrixf multiplication, our workhorse methods.
  300. void mult( const Matrixf&, const Matrixf& );
  301. void preMult( const Matrixf& );
  302. void postMult( const Matrixf& );
  303. /** Optimized version of preMult(translate(v)); */
  304. inline void preMultTranslate( const Vec3d& v );
  305. inline void preMultTranslate( const Vec3f& v );
  306. /** Optimized version of postMult(translate(v)); */
  307. inline void postMultTranslate( const Vec3d& v );
  308. inline void postMultTranslate( const Vec3f& v );
  309. /** Optimized version of preMult(scale(v)); */
  310. inline void preMultScale( const Vec3d& v );
  311. inline void preMultScale( const Vec3f& v );
  312. /** Optimized version of postMult(scale(v)); */
  313. inline void postMultScale( const Vec3d& v );
  314. inline void postMultScale( const Vec3f& v );
  315. /** Optimized version of preMult(rotate(q)); */
  316. inline void preMultRotate( const Quat& q );
  317. /** Optimized version of postMult(rotate(q)); */
  318. inline void postMultRotate( const Quat& q );
  319. inline void operator *= ( const Matrixf& other )
  320. { if( this == &other ) {
  321. Matrixf temp(other);
  322. postMult( temp );
  323. }
  324. else postMult( other );
  325. }
  326. inline Matrixf operator * ( const Matrixf &m ) const
  327. {
  328. osg::Matrixf r;
  329. r.mult(*this,m);
  330. return r;
  331. }
  332. /** Multiply by scalar. */
  333. inline Matrixf operator * (value_type rhs) const
  334. {
  335. return Matrixf(
  336. _mat[0][0]*rhs, _mat[0][1]*rhs, _mat[0][2]*rhs, _mat[0][3]*rhs,
  337. _mat[1][0]*rhs, _mat[1][1]*rhs, _mat[1][2]*rhs, _mat[1][3]*rhs,
  338. _mat[2][0]*rhs, _mat[2][1]*rhs, _mat[2][2]*rhs, _mat[2][3]*rhs,
  339. _mat[3][0]*rhs, _mat[3][1]*rhs, _mat[3][2]*rhs, _mat[3][3]*rhs);
  340. }
  341. /** Unary multiply by scalar. */
  342. inline Matrixf& operator *= (value_type rhs)
  343. {
  344. _mat[0][0]*=rhs;
  345. _mat[0][1]*=rhs;
  346. _mat[0][2]*=rhs;
  347. _mat[0][3]*=rhs;
  348. _mat[1][0]*=rhs;
  349. _mat[1][1]*=rhs;
  350. _mat[1][2]*=rhs;
  351. _mat[1][3]*=rhs;
  352. _mat[2][0]*=rhs;
  353. _mat[2][1]*=rhs;
  354. _mat[2][2]*=rhs;
  355. _mat[2][3]*=rhs;
  356. _mat[3][0]*=rhs;
  357. _mat[3][1]*=rhs;
  358. _mat[3][2]*=rhs;
  359. _mat[3][3]*=rhs;
  360. return *this;
  361. }
  362. /** Divide by scalar. */
  363. inline Matrixf operator / (value_type rhs) const
  364. {
  365. return Matrixf(
  366. _mat[0][0]/rhs, _mat[0][1]/rhs, _mat[0][2]/rhs, _mat[0][3]/rhs,
  367. _mat[1][0]/rhs, _mat[1][1]/rhs, _mat[1][2]/rhs, _mat[1][3]/rhs,
  368. _mat[2][0]/rhs, _mat[2][1]/rhs, _mat[2][2]/rhs, _mat[2][3]/rhs,
  369. _mat[3][0]/rhs, _mat[3][1]/rhs, _mat[3][2]/rhs, _mat[3][3]/rhs);
  370. }
  371. /** Unary divide by scalar. */
  372. inline Matrixf& operator /= (value_type rhs)
  373. {
  374. _mat[0][0]/=rhs;
  375. _mat[0][1]/=rhs;
  376. _mat[0][2]/=rhs;
  377. _mat[0][3]/=rhs;
  378. _mat[1][0]/=rhs;
  379. _mat[1][1]/=rhs;
  380. _mat[1][2]/=rhs;
  381. _mat[1][3]/=rhs;
  382. _mat[2][0]/=rhs;
  383. _mat[2][1]/=rhs;
  384. _mat[2][2]/=rhs;
  385. _mat[2][3]/=rhs;
  386. _mat[3][0]/=rhs;
  387. _mat[3][1]/=rhs;
  388. _mat[3][2]/=rhs;
  389. _mat[3][3]/=rhs;
  390. return *this;
  391. }
  392. /** Binary vector add. */
  393. inline Matrixf operator + (const Matrixf& rhs) const
  394. {
  395. return Matrixf(
  396. _mat[0][0] + rhs._mat[0][0],
  397. _mat[0][1] + rhs._mat[0][1],
  398. _mat[0][2] + rhs._mat[0][2],
  399. _mat[0][3] + rhs._mat[0][3],
  400. _mat[1][0] + rhs._mat[1][0],
  401. _mat[1][1] + rhs._mat[1][1],
  402. _mat[1][2] + rhs._mat[1][2],
  403. _mat[1][3] + rhs._mat[1][3],
  404. _mat[2][0] + rhs._mat[2][0],
  405. _mat[2][1] + rhs._mat[2][1],
  406. _mat[2][2] + rhs._mat[2][2],
  407. _mat[2][3] + rhs._mat[2][3],
  408. _mat[3][0] + rhs._mat[3][0],
  409. _mat[3][1] + rhs._mat[3][1],
  410. _mat[3][2] + rhs._mat[3][2],
  411. _mat[3][3] + rhs._mat[3][3]);
  412. }
  413. /** Unary vector add. Slightly more efficient because no temporary
  414. * intermediate object.
  415. */
  416. inline Matrixf& operator += (const Matrixf& rhs)
  417. {
  418. _mat[0][0] += rhs._mat[0][0];
  419. _mat[0][1] += rhs._mat[0][1];
  420. _mat[0][2] += rhs._mat[0][2];
  421. _mat[0][3] += rhs._mat[0][3];
  422. _mat[1][0] += rhs._mat[1][0];
  423. _mat[1][1] += rhs._mat[1][1];
  424. _mat[1][2] += rhs._mat[1][2];
  425. _mat[1][3] += rhs._mat[1][3];
  426. _mat[2][0] += rhs._mat[2][0];
  427. _mat[2][1] += rhs._mat[2][1];
  428. _mat[2][2] += rhs._mat[2][2];
  429. _mat[2][3] += rhs._mat[2][3];
  430. _mat[3][0] += rhs._mat[3][0];
  431. _mat[3][1] += rhs._mat[3][1];
  432. _mat[3][2] += rhs._mat[3][2];
  433. _mat[3][3] += rhs._mat[3][3];
  434. return *this;
  435. }
  436. protected:
  437. value_type _mat[4][4];
  438. };
  439. class RefMatrixf : public Object, public Matrixf
  440. {
  441. public:
  442. RefMatrixf():Object(false), Matrixf() {}
  443. RefMatrixf( const Matrixf& other) : Object(false), Matrixf(other) {}
  444. RefMatrixf( const Matrixd& other) : Object(false), Matrixf(other) {}
  445. RefMatrixf( const RefMatrixf& other) : Object(other), Matrixf(other) {}
  446. explicit RefMatrixf( Matrixf::value_type const * const def ):Object(false), Matrixf(def) {}
  447. RefMatrixf( Matrixf::value_type a00, Matrixf::value_type a01, Matrixf::value_type a02, Matrixf::value_type a03,
  448. Matrixf::value_type a10, Matrixf::value_type a11, Matrixf::value_type a12, Matrixf::value_type a13,
  449. Matrixf::value_type a20, Matrixf::value_type a21, Matrixf::value_type a22, Matrixf::value_type a23,
  450. Matrixf::value_type a30, Matrixf::value_type a31, Matrixf::value_type a32, Matrixf::value_type a33):
  451. Object(false),
  452. Matrixf(a00, a01, a02, a03,
  453. a10, a11, a12, a13,
  454. a20, a21, a22, a23,
  455. a30, a31, a32, a33) {}
  456. virtual Object* cloneType() const { return new RefMatrixf(); }
  457. virtual Object* clone(const CopyOp&) const { return new RefMatrixf(*this); }
  458. virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const RefMatrixf*>(obj)!=NULL; }
  459. virtual const char* libraryName() const { return "osg"; }
  460. virtual const char* className() const { return "Matrix"; }
  461. protected:
  462. virtual ~RefMatrixf() {}
  463. };
  464. //static utility methods
  465. inline Matrixf Matrixf::identity(void)
  466. {
  467. Matrixf m;
  468. m.makeIdentity();
  469. return m;
  470. }
  471. inline Matrixf Matrixf::scale(value_type sx, value_type sy, value_type sz)
  472. {
  473. Matrixf m;
  474. m.makeScale(sx,sy,sz);
  475. return m;
  476. }
  477. inline Matrixf Matrixf::scale(const Vec3f& v )
  478. {
  479. return scale(v.x(), v.y(), v.z() );
  480. }
  481. inline Matrixf Matrixf::scale(const Vec3d& v )
  482. {
  483. return scale(v.x(), v.y(), v.z() );
  484. }
  485. inline Matrixf Matrixf::translate(value_type tx, value_type ty, value_type tz)
  486. {
  487. Matrixf m;
  488. m.makeTranslate(tx,ty,tz);
  489. return m;
  490. }
  491. inline Matrixf Matrixf::translate(const Vec3f& v )
  492. {
  493. return translate(v.x(), v.y(), v.z() );
  494. }
  495. inline Matrixf Matrixf::translate(const Vec3d& v )
  496. {
  497. return translate(v.x(), v.y(), v.z() );
  498. }
  499. inline Matrixf Matrixf::rotate( const Quat& q )
  500. {
  501. return Matrixf(q);
  502. }
  503. inline Matrixf Matrixf::rotate(value_type angle, value_type x, value_type y, value_type z )
  504. {
  505. Matrixf m;
  506. m.makeRotate(angle,x,y,z);
  507. return m;
  508. }
  509. inline Matrixf Matrixf::rotate(value_type angle, const Vec3f& axis )
  510. {
  511. Matrixf m;
  512. m.makeRotate(angle,axis);
  513. return m;
  514. }
  515. inline Matrixf Matrixf::rotate(value_type angle, const Vec3d& axis )
  516. {
  517. Matrixf m;
  518. m.makeRotate(angle,axis);
  519. return m;
  520. }
  521. inline Matrixf Matrixf::rotate( value_type angle1, const Vec3f& axis1,
  522. value_type angle2, const Vec3f& axis2,
  523. value_type angle3, const Vec3f& axis3)
  524. {
  525. Matrixf m;
  526. m.makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
  527. return m;
  528. }
  529. inline Matrixf Matrixf::rotate( value_type angle1, const Vec3d& axis1,
  530. value_type angle2, const Vec3d& axis2,
  531. value_type angle3, const Vec3d& axis3)
  532. {
  533. Matrixf m;
  534. m.makeRotate(angle1,axis1,angle2,axis2,angle3,axis3);
  535. return m;
  536. }
  537. inline Matrixf Matrixf::rotate(const Vec3f& from, const Vec3f& to )
  538. {
  539. Matrixf m;
  540. m.makeRotate(from,to);
  541. return m;
  542. }
  543. inline Matrixf Matrixf::rotate(const Vec3d& from, const Vec3d& to )
  544. {
  545. Matrixf m;
  546. m.makeRotate(from,to);
  547. return m;
  548. }
  549. inline Matrixf Matrixf::inverse( const Matrixf& matrix)
  550. {
  551. Matrixf m;
  552. m.invert(matrix);
  553. return m;
  554. }
  555. inline Matrixf Matrixf::orthoNormal(const Matrixf& matrix)
  556. {
  557. Matrixf m;
  558. m.orthoNormalize(matrix);
  559. return m;
  560. }
  561. inline Matrixf Matrixf::ortho(double left, double right,
  562. double bottom, double top,
  563. double zNear, double zFar)
  564. {
  565. Matrixf m;
  566. m.makeOrtho(left,right,bottom,top,zNear,zFar);
  567. return m;
  568. }
  569. inline Matrixf Matrixf::ortho2D(double left, double right,
  570. double bottom, double top)
  571. {
  572. Matrixf m;
  573. m.makeOrtho2D(left,right,bottom,top);
  574. return m;
  575. }
  576. inline Matrixf Matrixf::frustum(double left, double right,
  577. double bottom, double top,
  578. double zNear, double zFar)
  579. {
  580. Matrixf m;
  581. m.makeFrustum(left,right,bottom,top,zNear,zFar);
  582. return m;
  583. }
  584. inline Matrixf Matrixf::perspective(double fovy,double aspectRatio,
  585. double zNear, double zFar)
  586. {
  587. Matrixf m;
  588. m.makePerspective(fovy,aspectRatio,zNear,zFar);
  589. return m;
  590. }
  591. inline Matrixf Matrixf::lookAt(const Vec3f& eye,const Vec3f& center,const Vec3f& up)
  592. {
  593. Matrixf m;
  594. m.makeLookAt(eye,center,up);
  595. return m;
  596. }
  597. inline Matrixf Matrixf::lookAt(const Vec3d& eye,const Vec3d& center,const Vec3d& up)
  598. {
  599. Matrixf m;
  600. m.makeLookAt(eye,center,up);
  601. return m;
  602. }
  603. inline Vec3f Matrixf::postMult( const Vec3f& v ) const
  604. {
  605. value_type d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;
  606. return Vec3f( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d,
  607. (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d,
  608. (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ;
  609. }
  610. inline Vec3d Matrixf::postMult( const Vec3d& v ) const
  611. {
  612. value_type d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;
  613. return Vec3d( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3])*d,
  614. (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3])*d,
  615. (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3])*d) ;
  616. }
  617. inline Vec3f Matrixf::preMult( const Vec3f& v ) const
  618. {
  619. value_type d = 1.0f/(_mat[0][3]*v.x()+_mat[1][3]*v.y()+_mat[2][3]*v.z()+_mat[3][3]) ;
  620. return Vec3f( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0])*d,
  621. (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1])*d,
  622. (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2])*d);
  623. }
  624. inline Vec3d Matrixf::preMult( const Vec3d& v ) const
  625. {
  626. value_type d = 1.0f/(_mat[0][3]*v.x()+_mat[1][3]*v.y()+_mat[2][3]*v.z()+_mat[3][3]) ;
  627. return Vec3d( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0])*d,
  628. (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1])*d,
  629. (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2])*d);
  630. }
  631. inline Vec4f Matrixf::postMult( const Vec4f& v ) const
  632. {
  633. return Vec4f( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()),
  634. (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()),
  635. (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()),
  636. (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ;
  637. }
  638. inline Vec4d Matrixf::postMult( const Vec4d& v ) const
  639. {
  640. return Vec4d( (_mat[0][0]*v.x() + _mat[0][1]*v.y() + _mat[0][2]*v.z() + _mat[0][3]*v.w()),
  641. (_mat[1][0]*v.x() + _mat[1][1]*v.y() + _mat[1][2]*v.z() + _mat[1][3]*v.w()),
  642. (_mat[2][0]*v.x() + _mat[2][1]*v.y() + _mat[2][2]*v.z() + _mat[2][3]*v.w()),
  643. (_mat[3][0]*v.x() + _mat[3][1]*v.y() + _mat[3][2]*v.z() + _mat[3][3]*v.w())) ;
  644. }
  645. inline Vec4f Matrixf::preMult( const Vec4f& v ) const
  646. {
  647. return Vec4f( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0]*v.w()),
  648. (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1]*v.w()),
  649. (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2]*v.w()),
  650. (_mat[0][3]*v.x() + _mat[1][3]*v.y() + _mat[2][3]*v.z() + _mat[3][3]*v.w()));
  651. }
  652. inline Vec4d Matrixf::preMult( const Vec4d& v ) const
  653. {
  654. return Vec4d( (_mat[0][0]*v.x() + _mat[1][0]*v.y() + _mat[2][0]*v.z() + _mat[3][0]*v.w()),
  655. (_mat[0][1]*v.x() + _mat[1][1]*v.y() + _mat[2][1]*v.z() + _mat[3][1]*v.w()),
  656. (_mat[0][2]*v.x() + _mat[1][2]*v.y() + _mat[2][2]*v.z() + _mat[3][2]*v.w()),
  657. (_mat[0][3]*v.x() + _mat[1][3]*v.y() + _mat[2][3]*v.z() + _mat[3][3]*v.w()));
  658. }
  659. inline Vec3f Matrixf::transform3x3(const Vec3f& v,const Matrixf& m)
  660. {
  661. return Vec3f( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()),
  662. (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()),
  663. (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z()));
  664. }
  665. inline Vec3d Matrixf::transform3x3(const Vec3d& v,const Matrixf& m)
  666. {
  667. return Vec3d( (m._mat[0][0]*v.x() + m._mat[1][0]*v.y() + m._mat[2][0]*v.z()),
  668. (m._mat[0][1]*v.x() + m._mat[1][1]*v.y() + m._mat[2][1]*v.z()),
  669. (m._mat[0][2]*v.x() + m._mat[1][2]*v.y() + m._mat[2][2]*v.z()));
  670. }
  671. inline Vec3f Matrixf::transform3x3(const Matrixf& m,const Vec3f& v)
  672. {
  673. return Vec3f( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()),
  674. (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()),
  675. (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ;
  676. }
  677. inline Vec3d Matrixf::transform3x3(const Matrixf& m,const Vec3d& v)
  678. {
  679. return Vec3d( (m._mat[0][0]*v.x() + m._mat[0][1]*v.y() + m._mat[0][2]*v.z()),
  680. (m._mat[1][0]*v.x() + m._mat[1][1]*v.y() + m._mat[1][2]*v.z()),
  681. (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ;
  682. }
  683. inline void Matrixf::preMultTranslate( const Vec3d& v )
  684. {
  685. for (unsigned i = 0; i < 3; ++i)
  686. {
  687. double tmp = v[i];
  688. if (tmp == 0)
  689. continue;
  690. _mat[3][0] += tmp*_mat[i][0];
  691. _mat[3][1] += tmp*_mat[i][1];
  692. _mat[3][2] += tmp*_mat[i][2];
  693. _mat[3][3] += tmp*_mat[i][3];
  694. }
  695. }
  696. inline void Matrixf::preMultTranslate( const Vec3f& v )
  697. {
  698. for (unsigned i = 0; i < 3; ++i)
  699. {
  700. float tmp = v[i];
  701. if (tmp == 0)
  702. continue;
  703. _mat[3][0] += tmp*_mat[i][0];
  704. _mat[3][1] += tmp*_mat[i][1];
  705. _mat[3][2] += tmp*_mat[i][2];
  706. _mat[3][3] += tmp*_mat[i][3];
  707. }
  708. }
  709. inline void Matrixf::postMultTranslate( const Vec3d& v )
  710. {
  711. for (unsigned i = 0; i < 3; ++i)
  712. {
  713. double tmp = v[i];
  714. if (tmp == 0)
  715. continue;
  716. _mat[0][i] += tmp*_mat[0][3];
  717. _mat[1][i] += tmp*_mat[1][3];
  718. _mat[2][i] += tmp*_mat[2][3];
  719. _mat[3][i] += tmp*_mat[3][3];
  720. }
  721. }
  722. inline void Matrixf::postMultTranslate( const Vec3f& v )
  723. {
  724. for (unsigned i = 0; i < 3; ++i)
  725. {
  726. float tmp = v[i];
  727. if (tmp == 0)
  728. continue;
  729. _mat[0][i] += tmp*_mat[0][3];
  730. _mat[1][i] += tmp*_mat[1][3];
  731. _mat[2][i] += tmp*_mat[2][3];
  732. _mat[3][i] += tmp*_mat[3][3];
  733. }
  734. }
  735. inline void Matrixf::preMultScale( const Vec3d& v )
  736. {
  737. _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0];
  738. _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1];
  739. _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2];
  740. }
  741. inline void Matrixf::preMultScale( const Vec3f& v )
  742. {
  743. _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0];
  744. _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1];
  745. _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2];
  746. }
  747. inline void Matrixf::postMultScale( const Vec3d& v )
  748. {
  749. _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0];
  750. _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1];
  751. _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2];
  752. }
  753. inline void Matrixf::postMultScale( const Vec3f& v )
  754. {
  755. _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0];
  756. _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1];
  757. _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2];
  758. }
  759. inline void Matrixf::preMultRotate( const Quat& q )
  760. {
  761. if (q.zeroRotation())
  762. return;
  763. Matrixf r;
  764. r.setRotate(q);
  765. preMult(r);
  766. }
  767. inline void Matrixf::postMultRotate( const Quat& q )
  768. {
  769. if (q.zeroRotation())
  770. return;
  771. Matrixf r;
  772. r.setRotate(q);
  773. postMult(r);
  774. }
  775. inline Vec3f operator* (const Vec3f& v, const Matrixf& m )
  776. {
  777. return m.preMult(v);
  778. }
  779. inline Vec3d operator* (const Vec3d& v, const Matrixf& m )
  780. {
  781. return m.preMult(v);
  782. }
  783. inline Vec4f operator* (const Vec4f& v, const Matrixf& m )
  784. {
  785. return m.preMult(v);
  786. }
  787. inline Vec4d operator* (const Vec4d& v, const Matrixf& m )
  788. {
  789. return m.preMult(v);
  790. }
  791. inline Vec3f Matrixf::operator* (const Vec3f& v) const
  792. {
  793. return postMult(v);
  794. }
  795. inline Vec3d Matrixf::operator* (const Vec3d& v) const
  796. {
  797. return postMult(v);
  798. }
  799. inline Vec4f Matrixf::operator* (const Vec4f& v) const
  800. {
  801. return postMult(v);
  802. }
  803. inline Vec4d Matrixf::operator* (const Vec4d& v) const
  804. {
  805. return postMult(v);
  806. }
  807. } //namespace osg
  808. #endif