gltl.h
上传用户:sesekoo
上传日期:2020-07-18
资源大小:21543k
文件大小:46k
源码类别:

界面编程

开发平台:

Visual C++

  1. #if (!defined __GLTL_H)
  2. #define __GLTL_H
  3. // disable warning C4201
  4. #pragma warning( push )
  5. #pragma warning( disable : 4201 )
  6. namespace gltl
  7. {
  8. template < class _num >
  9. class ntraits;
  10. template < class _num, class _ntr >
  11. class vector3;
  12. template < class _num, class _ntr >
  13. class vector4;
  14. template < class _num, class _ntr >
  15. class matrix;
  16. #include <math.h>
  17. #if (defined _DEBUG)
  18. #if (defined ASSERT)
  19. #define __gltl_assert__(__x__) ASSERT(__x__)
  20. #elif (defined ATLASSERT)
  21. #define __gltl_assert__(__x__) ATLASSERT(__x__)
  22. #else
  23. #include <assert.h>
  24. #define __gltl_assert__(__x__) assert(__x__)
  25. #endif
  26. #else
  27. #define __gltl_assert__(__x__)
  28. #endif // _DEBUG
  29. template < class _num >
  30. class ntraits
  31. {
  32. public:
  33. typedef const _num _numc;
  34. typedef _num & _numr;
  35. typedef const _num & _numrc;
  36. typedef _num * _nump;
  37. typedef const _num * _numpc;
  38. static _num adjust_angle_d(
  39. _numc _angle_degrees,
  40. long _l_adjust_prec = 1000L
  41. )
  42. {
  43. long _ang = long( _angle_degrees * ((_num)(_l_adjust_prec)) );
  44. long _modx360 = 360L * _l_adjust_prec;
  45. // long _modx180 = _modx360 >> 1; // _modx360/2
  46. _ang %= _modx360;
  47. if( _ang < 0L )
  48. _ang = _modx360 + _ang;
  49. __gltl_assert__( _ang >= 0L );
  50. // if( _ang > _modx180 )
  51. // _ang = _ang%_modx180 - _modx180;
  52. _num _ret_val = (_num)(_ang);
  53. _ret_val /= (_num)(_l_adjust_prec);
  54. return _ret_val;
  55. }
  56. static _numc get_pi()
  57. {
  58. return ((_num)(3.1415926535897932384626433832795));
  59. }
  60. static _numc get_safe_min()
  61. {
  62. return ((_num)(0.000001));
  63. }
  64. static _numc get_def_epsilon()
  65. {
  66. return ((_num)(0.0001));
  67. }
  68. static _num r2d( _numc _angle_radians )
  69. {
  70. return
  71. adjust_angle_d( 
  72. ( _angle_radians * ((_num)180.0) )
  73. / get_pi()
  74. );
  75. }
  76. static _num d2r( _numc _angle_degrees )
  77. {
  78. return
  79. ( adjust_angle_d(_angle_degrees) * get_pi() )
  80. / ((_num)180.0)
  81. ;
  82. }
  83. static _num abs( _numc _val )
  84. {
  85. return (_val >= (_num)(0.0)) ? _val : (-_val);
  86. }
  87. static _num sin( _numc _val )
  88. {
  89. return ( (_num) ::sin(_val) );
  90. }
  91. static _num cos( _numc _val )
  92. {
  93. return ( (_num) ::cos(_val) );
  94. }
  95. static _num tan( _numc _val )
  96. {
  97. return ( (_num) ::tan(_val) );
  98. }
  99. static _num asin( _numc _val )
  100. {
  101. return ( (_num) ::asin(_val) );
  102. }
  103. static _num acos( _numc _val )
  104. {
  105. return ( (_num) ::acos(_val) );
  106. }
  107. static _num atan( _numc _val )
  108. {
  109. return ( (_num) ::atan(_val) );
  110. }
  111. static _num atan2( _numc _y, _numc _x )
  112. {
  113. return ( (_num) ::atan2( _y, _x ) );
  114. }
  115. static _num sqrt( _numc _val )
  116. {
  117. return ( (_num) ::sqrt(_val) );
  118. }
  119. };
  120. template < class _num, class _ntr >
  121. class vector3
  122. {
  123. public:
  124. typedef const _num _numc;
  125. typedef _num & _numr;
  126. typedef const _num & _numrc;
  127. typedef _num * _nump;
  128. typedef const _num * _numpc;
  129. typedef vector3<_num,_ntr> _v3t;
  130. typedef vector3<_num,_ntr> & _v3rt;
  131. typedef const vector3<_num,_ntr> & _v3rct;
  132. typedef vector4<_num,_ntr> _v4t;
  133. typedef vector4<_num,_ntr> & _v4rt;
  134. typedef const vector4<_num,_ntr> & _v4rct;
  135. typedef matrix<_num,_ntr> _mt;
  136. typedef matrix<_num,_ntr> & _mrt;
  137. typedef const matrix<_num,_ntr> & _mrct;
  138. union 
  139. {
  140. struct { _num x, y, z; };
  141. struct { _num a, b, c; };
  142. _num arr[3];
  143. };
  144. vector3(
  145. _numc _x = ((_num)0.0),
  146. _numc _y = ((_num)0.0),
  147. _numc _z = ((_num)0.0)
  148. )
  149. : x( _x )
  150. , y( _y )
  151. , z( _z )
  152. {
  153. }
  154. void load_vector(
  155. _num _x = ((_num)0.0),
  156. _num _y = ((_num)0.0),
  157. _num _z = ((_num)0.0)
  158. )
  159. {
  160. x = _x;
  161. y = _y;
  162. z = _z;
  163. }
  164. void translate(
  165. _num _x = ((_num)0.0),
  166. _num _y = ((_num)0.0),
  167. _num _z = ((_num)0.0)
  168. )
  169. {
  170. x += _x;
  171. y += _y;
  172. z += _z;
  173. }
  174. void scale(
  175. _num _x = ((_num)1.0),
  176. _num _y = ((_num)1.0),
  177. _num _z = ((_num)1.0)
  178. )
  179. {
  180. x *= _x;
  181. y *= _y;
  182. z *= _z;
  183. }
  184. _num get_length_sq() const
  185. {
  186. return ( (_num) (x*x + y*y + z*z) );
  187. }
  188. _num get_length() const
  189. {
  190. return _ntr::sqrt( get_length_sq() );
  191. }
  192. _mt get_as_scale() const;
  193. _mt get_as_translation() const;
  194. _mt get_as_rotation_xyz() const;
  195. _mt get_as_rotation_quaternion() const;
  196. _v3rt normalize() 
  197. {
  198. _num _len = get_length();
  199. if( ( _len < _ntr::get_safe_min() ) && ( _len > (- _ntr::get_safe_min()) ) )
  200. _len = 1;
  201. x /= _len;
  202. y /= _len;
  203. z /= _len;
  204. return (*this);
  205. }
  206. static inline void stat_multiplication(
  207. _mrct _mtx,
  208. _v3rct _v,
  209. _v3rt _ret_val
  210. );
  211. static inline _v3t stat_multiplication(
  212. _mrct _mtx,
  213. _v3rct _v
  214. );
  215. _numr operator () ( int _i )
  216. {
  217. __gltl_assert__( ( 0 <= _i ) && ( _i <= 3 ) );
  218. return *(((_nump)&x) + _i);
  219. }
  220. _numr operator [] ( int _i ) 
  221. {
  222. __gltl_assert__( ( 0 <= _i ) && ( _i <= 2 ) );
  223. return *(((_nump)&x) + _i);
  224. }
  225. _numrc operator [] ( int _i ) const
  226. {
  227. __gltl_assert__( ( 0 <= _i ) && ( _i <= 2 ) );
  228. return *(((_nump)&x) + _i);
  229. }
  230. bool operator == ( _v3rct _v ) const
  231. {
  232. return ( x==_v.x && y==_v.y && z==_v.z ) ? true : false;
  233. }
  234. bool operator != ( _v3rct _v ) const
  235. {
  236. return ( x==_v.x && y==_v.y && z==_v.z ) ? false : true;
  237. }
  238. _v3rt operator = ( _v3rct _v )
  239. {
  240. x = _v.x;
  241. y = _v.y;
  242. z = _v.z;
  243. return (*this);
  244. }
  245. _v3rt operator = ( _v4rct );
  246. _v3rt operator *= ( _numc _s ) 
  247. {
  248. x *= _s;
  249. y *= _s;
  250. z *= _s;
  251. return (*this);
  252. }
  253. _v3rt operator *= ( _mrct _mtx ) 
  254. {
  255. stat_multiplication( _mtx, *this, *this );
  256. return (*this);
  257. }
  258. _v3rt operator += ( _v3rct _v ) 
  259. {
  260. x += _v.x;
  261. y += _v.y;
  262. z += _v.z;
  263. return (*this);
  264. }
  265. _v3rt operator -= ( _v3rct _v ) 
  266. {
  267. x -= _v.x;
  268. y -= _v.y;
  269. z -= _v.z;
  270. return (*this);
  271. }
  272. };
  273. template < class _num, class _ntr >
  274. inline vector3<_num,_ntr> operator * (
  275. const vector3<_num,_ntr> & _v,
  276. const _num _s
  277. {
  278. vector3<_num,_ntr> _ret_val;
  279. _ret_val.x = _v.x * _s;
  280. _ret_val.y = _v.y * _s;
  281. _ret_val.z = _v.z * _s;
  282. return _ret_val;
  283. }
  284. template < class _num, class _ntr >
  285. inline vector3<_num,_ntr> operator * (
  286. const _num _s,
  287. const vector3<_num,_ntr> & _v
  288. {
  289. vector3<_num,_ntr> _ret_val;
  290. _ret_val.x = _v.x * _s;
  291. _ret_val.y = _v.y * _s;
  292. _ret_val.z = _v.z * _s;
  293. return _ret_val;
  294. }
  295. template < class _num, class _ntr >
  296. inline _num operator * (
  297. const vector3<_num,_ntr> & _v1,
  298. const vector3<_num,_ntr> & _v2
  299. {
  300. return ( _v1.x*_v2.x + _v1.y*_v2.y + _v1.z*_v2.z );
  301. }
  302. template < class _num, class _ntr >
  303. inline vector3<_num,_ntr> operator ^ (
  304. const vector3<_num,_ntr> & _v1,
  305. const vector3<_num,_ntr> & _v2
  306. {
  307. vector3<_num,_ntr> _ret_val;
  308. _ret_val.x = _v1.y*_v2.z - _v1.z*_v2.y;
  309. _ret_val.y = _v1.z*_v2.x - _v1.x*_v2.z;
  310. _ret_val.z = _v1.x*_v2.y - _v1.y*_v2.x;
  311. return _ret_val;
  312. }
  313. template < class _num, class _ntr >
  314. inline vector3<_num,_ntr> operator + (
  315. const vector3<_num,_ntr> & _v1,
  316. const vector3<_num,_ntr> & _v2
  317. {
  318. vector3<_num,_ntr> _ret_val;
  319. _ret_val.x = _v1.x + _v2.x;
  320. _ret_val.y = _v1.y + _v2.y;
  321. _ret_val.z = _v1.z + _v2.z;
  322. return _ret_val;
  323. }
  324. template < class _num, class _ntr >
  325. inline vector3<_num,_ntr> operator - (
  326. const vector3<_num,_ntr> & _v1,
  327. const vector3<_num,_ntr> & _v2
  328. {
  329. vector3<_num,_ntr> _ret_val;
  330. _ret_val.x = _v1.x - _v2.x;
  331. _ret_val.y = _v1.y - _v2.y;
  332. _ret_val.z = _v1.z - _v2.z;
  333. return _ret_val;
  334. }
  335. template < class _num, class _ntr >
  336. inline vector3<_num,_ntr> operator - (
  337. const vector3<_num,_ntr> & _v
  338. {
  339. vector3<_num,_ntr> _ret_val;
  340. _ret_val.x = - _v.x;
  341. _ret_val.y = - _v.y;
  342. _ret_val.z = - _v.z;
  343. return _ret_val;
  344. }
  345. template < class _num, class _ntr >
  346. inline vector3<_num,_ntr> operator + (
  347. const vector3<_num,_ntr> & _v
  348. {
  349. return _v;
  350. }
  351. template < class _num, class _ntr >
  352. inline vector3<_num,_ntr> operator ~ (
  353. const vector3<_num,_ntr> & _v
  354. {
  355. _num _len = _v.get_length();
  356. vector3<_num,_ntr> _ret_val;
  357. _ret_val.x = _v.x / _len;
  358. _ret_val.y = _v.y / _len;
  359. _ret_val.z = _v.z / _len;
  360. return _ret_val;
  361. }
  362. template < class _num, class _ntr >
  363. class vector4
  364. {
  365. public:
  366. typedef const _num _numc;
  367. typedef _num & _numr;
  368. typedef const _num & _numrc;
  369. typedef _num * _nump;
  370. typedef const _num * _numpc;
  371. typedef vector3<_num,_ntr> _v3t;
  372. typedef vector3<_num,_ntr> & _v3rt;
  373. typedef const vector3<_num,_ntr> & _v3rct;
  374. typedef vector4<_num,_ntr> _v4t;
  375. typedef vector4<_num,_ntr> & _v4rt;
  376. typedef const vector4<_num,_ntr> & _v4rct;
  377. typedef matrix<_num,_ntr> _mt;
  378. typedef matrix<_num,_ntr> & _mrt;
  379. typedef const matrix<_num,_ntr> & _mrct;
  380. union 
  381. {
  382. struct { _num x, y, z, w; };
  383. struct { _num a, b, c, d; };
  384. _num arr[4];
  385. };
  386. vector4(
  387. _numc _x = ((_num)0.0),
  388. _numc _y = ((_num)0.0),
  389. _numc _z = ((_num)0.0),
  390. _numc _w = ((_num)0.0)
  391. )
  392. : x( _x )
  393. , y( _y )
  394. , z( _z )
  395. , w( _w )
  396. {
  397. }
  398. void load_vector(
  399. _num _x = ((_num)0.0),
  400. _num _y = ((_num)0.0),
  401. _num _z = ((_num)0.0),
  402. _num _w = ((_num)0.0)
  403. )
  404. {
  405. x = _x;
  406. y = _y;
  407. z = _z;
  408. w = _w;
  409. }
  410. void translate(
  411. _num _x = ((_num)0.0),
  412. _num _y = ((_num)0.0),
  413. _num _z = ((_num)0.0),
  414. _num _w = ((_num)0.0)
  415. )
  416. {
  417. x += _x;
  418. y += _y;
  419. z += _z;
  420. w += _w;
  421. }
  422. void scale(
  423. _num _x = ((_num)1.0),
  424. _num _y = ((_num)1.0),
  425. _num _z = ((_num)1.0),
  426. _num _w = ((_num)1.0)
  427. )
  428. {
  429. x *= _x;
  430. y *= _y;
  431. z *= _z;
  432. w *= _w;
  433. }
  434. _num get_length_sq() const
  435. {
  436. return ( (_num) (x*x + y*y + z*z + w*w) );
  437. }
  438. _num get_length() const
  439. {
  440. return _ntr::sqrt( get_length_sq() );
  441. }
  442. _v4rt normalize() 
  443. {
  444. _num _len = get_length();
  445. if( ( _len < _ntr::get_safe_min() ) && ( _len > (- _ntr::get_safe_min()) ) )
  446. _len = 1;
  447. x /= _len;
  448. y /= _len;
  449. z /= _len;
  450. w /= _len;
  451. return (*this);
  452. }
  453. static inline _v4t stat_multiplication(
  454. _mrct _mtx,
  455. _v4rct _v
  456. );
  457. static inline void stat_multiplication(
  458. _mrct _mtx,
  459. _v4rct _v,
  460. _v4rt _ret_val
  461. );
  462. _numr operator () ( int _i )
  463. {
  464. __gltl_assert__( ( 0 <= _i ) && ( _i <= 3 ) );
  465. return *(((_nump)&x) + _i);
  466. }
  467. _numr operator [] ( int _i ) 
  468. {
  469. __gltl_assert__( ( 0 <= _i ) && ( _i <= 3 ) );
  470. return *(((_nump)&x) + _i);
  471. }
  472. _numrc operator [] ( int _i ) const
  473. {
  474. __gltl_assert__( ( 0 <= _i ) && ( _i <= 3 ) );
  475. return *(((_nump)&x) + _i);
  476. }
  477. bool operator == ( _v4rct _v ) const
  478. {
  479. return ( x==_v.x && y==_v.y && z==_v.z && w==_v.w ) ? true : false;
  480. }
  481. bool operator != ( _v4rct _v ) const
  482. {
  483. return ( x==_v.x && y==_v.y && z==_v.z && w==_v.w ) ? false : true;
  484. }
  485. _v4rt operator = ( _v4rct _v )
  486. {
  487. x = _v.x;
  488. y = _v.y;
  489. z = _v.z;
  490. w = _v.w;
  491. return (*this);
  492. }
  493. _v4rt operator = ( _v3rct _v )
  494. {
  495. x = _v.x;
  496. y = _v.y;
  497. z = _v.z;
  498. w = ((_num)0.0);
  499. return (*this);
  500. }
  501. _v4rt operator *= ( _numc _s ) 
  502. {
  503.  x *= _s;
  504.  y *= _s;
  505.  z *= _s;
  506.  w *= _s;
  507. return (*this);
  508. }
  509. _v4rt operator *= ( _mrct _mtx ) 
  510. {
  511. stat_multiplication( _mtx, *this, *this );
  512. return (*this);
  513. }
  514. _v4rt operator += ( _v4rct _v ) 
  515. {
  516. x += _v.x;
  517. y += _v.y;
  518. z += _v.z;
  519. w += _v.w;
  520. return (*this);
  521. }
  522. _v4rt operator -= ( _v4rct _v ) 
  523. {
  524. x -= _v.x;
  525. y -= _v.y;
  526. z -= _v.z;
  527. w -= _v.w;
  528. return (*this);
  529. }
  530. };
  531. template < class _num, class _ntr >
  532. inline vector4<_num,_ntr> operator * (
  533. const vector4<_num,_ntr> & _v,
  534. const _num _s
  535. {
  536. vector4<_num,_ntr> _ret_val;
  537. _ret_val.x = _v.x * _s;
  538. _ret_val.y = _v.y * _s;
  539. _ret_val.z = _v.z * _s;
  540. _ret_val.w = _v.w * _s;
  541. return _ret_val;
  542. }
  543. template < class _num, class _ntr >
  544. inline vector4<_num,_ntr> operator * (
  545. const _num _s,
  546. const vector4<_num,_ntr> & _v
  547. {
  548. vector4<_num,_ntr> _ret_val;
  549. _ret_val.x = _v.x * _s;
  550. _ret_val.y = _v.y * _s;
  551. _ret_val.z = _v.z * _s;
  552. _ret_val.w = _v.w * _s;
  553. return _ret_val;
  554. }
  555. template < class _num, class _ntr >
  556. inline _num operator * (
  557. const vector4<_num,_ntr> & _v1,
  558. const vector4<_num,_ntr> & _v2
  559. {
  560. return ( _v1.x*_v2.x + _v1.y*_v2.y + _v1.z*_v2.z + _v1.w*_v2.w );
  561. }
  562. template < class _num, class _ntr >
  563. inline vector4<_num,_ntr> operator + (
  564. const vector4<_num,_ntr> & _v1,
  565. const vector4<_num,_ntr> & _v2
  566. {
  567. vector4<_num,_ntr> _ret_val;
  568. _ret_val.x = _v1.x + _v2.x;
  569. _ret_val.y = _v1.y + _v2.y;
  570. _ret_val.z = _v1.z + _v2.z;
  571. _ret_val.w = _v1.w + _v2.w;
  572. return _ret_val;
  573. }
  574. template < class _num, class _ntr >
  575. inline vector4<_num,_ntr> operator - (
  576. const vector4<_num,_ntr> & _v1,
  577. const vector4<_num,_ntr> & _v2
  578. {
  579. vector4<_num,_ntr> _ret_val;
  580. _ret_val.x = _v1.x - _v2.x;
  581. _ret_val.y = _v1.y - _v2.y;
  582. _ret_val.z = _v1.z - _v2.z;
  583. _ret_val.w = _v1.w - _v2.w;
  584. return _ret_val;
  585. }
  586. template < class _num, class _ntr >
  587. inline vector4<_num,_ntr> operator - (
  588. const vector4<_num,_ntr> & _v
  589. {
  590. vector4<_num,_ntr> _ret_val;
  591. _ret_val.x = - _v.x;
  592. _ret_val.y = - _v.y;
  593. _ret_val.z = - _v.z;
  594. _ret_val.w = - _v.w;
  595. return _ret_val;
  596. }
  597. template < class _num, class _ntr >
  598. inline vector4<_num,_ntr> operator + (
  599. const vector4<_num,_ntr> & _v
  600. {
  601. return _v;
  602. }
  603. template < class _num, class _ntr >
  604. inline vector4<_num,_ntr> operator ~ (
  605. const vector4<_num,_ntr> & _v
  606. {
  607. _num _len = _v.get_length();
  608. vector4<_num,_ntr> _ret_val;
  609. _ret_val.x = _v.x / _len;
  610. _ret_val.y = _v.y / _len;
  611. _ret_val.z = _v.z / _len;
  612. _ret_val.w = _v.w / _len;
  613. return _ret_val;
  614. }
  615. template < class _num, class _ntr >
  616. inline vector4<_num,_ntr> operator ^ (
  617. const vector4<_num,_ntr> & _v1,
  618. const vector4<_num,_ntr> & _v2
  619. {
  620. vector4<_num,_ntr> _ret_val;
  621. _ret_val.x = _v1.y*_v2.z - _v1.z*_v2.y;
  622. _ret_val.y = _v1.z*_v2.x - _v1.x*_v2.z;
  623. _ret_val.z = _v1.x*_v2.y - _v1.y*_v2.x;
  624. _ret_val.w = ((_num)0.0);
  625. return _ret_val;
  626. }
  627. template < class _num, class _ntr >
  628. inline vector3<_num,_ntr> & vector3<_num,_ntr>::operator = (
  629. const vector4<_num,_ntr> & _v
  630. )
  631. {
  632. x = _v.x;
  633. y = _v.y;
  634. z = _v.z;
  635. return (*this);
  636. }
  637. template < class _num, class _ntr >
  638. class quaternion : public vector4<_num,_ntr>
  639. {
  640. public:
  641. typedef quaternion<_num,_ntr> _q4t;
  642. typedef quaternion<_num,_ntr> & _q4rt;
  643. typedef const quaternion<_num,_ntr> & _q4rct;
  644. quaternion()
  645. {
  646. load_quaternion();
  647. }
  648. quaternion( _q4rct _q )
  649. {
  650. set_quaternion( _q );
  651. }
  652. quaternion( _numc _x, _numc _y, _numc _z )
  653. {
  654. set_quaternion( _x, _y, _z );
  655. }
  656. quaternion( _v3rct _v )
  657. {
  658. set_quaternion( _v );
  659. }
  660. quaternion( _numc _angle, _numc _x, _numc _y, _numc _z )
  661. {
  662. set_quaternion( _angle, _x, _y, _z );
  663. }
  664. quaternion( _numc _mtx[3][3] )
  665. {
  666. _num _tr, _s, _q[4];
  667. int _i, _j, _k, _nxt_val[3] = {1, 2, 0};
  668. _tr = _mtx[0][0] + _mtx[1][1] + _mtx[2][2];
  669. if( _tr > 0.0 ) 
  670. {
  671. _s = _ntr::sqrt( _tr + ((_num)1.0) );
  672. w  = _s / ((_num)2.0);
  673. _s = ((_num)0.5) / _s;
  674. x  = (_mtx[1][2] - _mtx[2][1]) * _s;
  675. y  = (_mtx[2][0] - _mtx[0][2]) * _s;
  676. z  = (_mtx[0][1] - _mtx[1][0]) * _s;
  677. else 
  678. {
  679.      _i = 0;
  680. if( _mtx[1][1] > _mtx[0][0] )
  681. _i = 1;
  682. if( _mtx[2][2] > _mtx[_i][_i] )
  683. _i = 2;
  684. _j = _nxt_val[_i];
  685. _k = _nxt_val[_j];
  686. _s =
  687. _ntr::sqrt(
  688. ( _mtx[_i][_i] - ( _mtx[_j][_j] + _mtx[_k][_k] ) )
  689. + 1.0
  690. );
  691. _q[_i] = _s * ((_num)0.5);
  692. if( _s != ((_num)0.0) )
  693. _s = ((_num)0.5) / _s;
  694. _q[3]  = (_mtx[_j][_k] - _mtx[_k][_j]) * _s;
  695. _q[_j] = (_mtx[_i][_j] + _mtx[_j][_i]) * _s;
  696. _q[_k] = (_mtx[_i][_k] + _mtx[_k][_i]) * _s;
  697. x = _q[0];
  698. y = _q[1];
  699. z = _q[2];
  700. w = _q[3];
  701. }
  702. }
  703. quaternion( _mrt _mtx );
  704. void load_quaternion(
  705. _numc _x = ((_num)0.0),
  706. _numc _y = ((_num)0.0),
  707. _numc _z = ((_num)0.0),
  708. _numc _w = ((_num)1.0)
  709. )
  710. {
  711. x = _x;
  712. y = _y;
  713. z = _z;
  714. w = _w;
  715. }
  716. void set_quaternion( _num _angle, _num _x, _num _y, _num _z )
  717. {
  718. _numc _fct = _x*_x+_y*_y+_z*_z;
  719. __gltl_assert__( _fct != 0 );
  720. _numc _scale_by( ((_num)1.0) / _ntr::sqrt(_fct) );
  721. _x = _x * _scale_by;
  722. _y = _y * _scale_by;
  723. _z = _z * _scale_by;
  724. w = _ntr::cos( _angle / ((_num)2.0) );
  725. _numc _sin_half( _ntr::sin( _angle / ((_num)2.0) ) );
  726. x = _x * _sin_half;
  727. y = _y * _sin_half;
  728. z = _z * _sin_half;
  729. }
  730. void set_quaternion( _numc _x, _numc _y, _numc _z )
  731. {
  732. _q4t _x_q( _x, ((_num)1.0), ((_num)0.0), ((_num)0.0) );
  733. _q4t _y_q( _y, ((_num)0.0), ((_num)1.0), ((_num)0.0) );
  734. _q4t _z_q( _z, ((_num)0.0), ((_num)0.0), ((_num)1.0) );
  735. set_quaternion( _x_q );
  736. (*this) *= _y_q;
  737. (*this) *= _z_q;
  738. }
  739. void set_quaternion( _v3rct _v )
  740. {
  741. set_quaternion( _v.x, _v.y, _v.z );
  742. }
  743. void set_quaternion( _q4rct _q )
  744. {
  745. x = _q.x;
  746. y = _q.y;
  747. z = _q.z;
  748. w = _q.w;
  749. }
  750. void normalize()
  751. {
  752. _num _fct = get_length_sq();
  753. __gltl_assert__( _fct != 0 );
  754. _num _scale_by( ((_num)1.0) / _ntr::sqrt(_fct) );
  755. x = x * _scale_by;
  756. y = y * _scale_by;
  757. z = z * _scale_by;
  758. w = w * _scale_by;
  759. }
  760. void get_as_matrix( _mrt _mtx );
  761. _mt get_as_matrix() const;
  762. void get_axis_angle( _numr axis_x, _numr axis_y, _numr axis_z, _numr _rot_angle ) const
  763. {
  764. _numc _vec_len2 = x*x + y*y + z*z;
  765. if( _vec_len2 < _ntr::get_def_epsilon() )
  766. {
  767. axis_x = ((_num)1.0);
  768. axis_y = ((_num)0.0);
  769. axis_z = ((_num)0.0);
  770. _rot_angle = ((_num)0.0);
  771. }
  772. else
  773. {
  774. _numc _len_inv = ((_num)1.0) / _ntr::sqrt(_vec_len2);
  775. axis_x = x * _len_inv;
  776. axis_y = y * _len_inv;
  777. axis_z = z * _len_inv;
  778. _rot_angle = ((_num)2.0) * _ntr::acos(w);
  779. }
  780. }
  781. void get_axis_angle( _v3rt _v, _numr _rot_angle ) const
  782. {
  783. get_axis_angle( _v.x, _v.y, _v.z, _rot_angle );
  784. }
  785. void get_lt_ln( _numr _angle_lat, _numr _angle_long ) const
  786. {
  787. _num _x, _y, _z;
  788. get_direction_vector( _x, _y, _z );
  789. _angle_lat = _ntr::asin( _y );
  790. if( _ntr::abs(_y) > ( ((_num)1.0) - _ntr::get_def_epsilon() ) )
  791. _angle_long = ((_num)0.0);
  792. else
  793. {
  794. if( _ntr::abs(_z) < _ntr::get_def_epsilon() )
  795. _angle_long = _x > ((_num)0.0)
  796. ? ( _ntr::get_pi() / ((_num)2.0) )
  797. : ( _ntr::get_pi() * ((_num)3.0) / ((_num)2.0) )
  798. ;
  799. else
  800. {
  801. if( _z >= ((_num)0.0) )
  802. _angle_long = _ntr::atan( _x / _z );
  803. else
  804. _angle_long = _ntr::get_pi() + _ntr::atan( _x / _z );
  805. if( _angle_long < ((_num)0.0) )
  806. _angle_long += _ntr::get_pi() * ((_num)2.0);
  807. }
  808. }
  809. }
  810. void get_direction_vector( _numr _x, _numr _y, _numr _z )
  811. {
  812. normalize();
  813. _x = ((_num)2.0) * ( x * z - w * y );
  814. _y = ((_num)2.0) * ( y * z + w * x );
  815. _z = ((_num)1.0) - ((_num)2.0) * ( x * x + y * y );
  816. }
  817. void get_direction_vector( _v3rt _v )
  818. {
  819. get_direction_vector( _v.x, _v.y, _v.z );
  820. }
  821. static _q4t stat_multiplication( _q4rct _q1, _q4rct _q2 )
  822. {
  823. _q4t _q;
  824. _q.x =
  825.   _q2.w*_q1.x
  826. + _q2.x*_q1.w
  827. + _q2.y*_q1.z
  828. - _q2.z*_q1.y;
  829. _q.y =
  830.   _q2.w*_q1.y
  831. - _q2.x*_q1.z
  832. + _q2.y*_q1.w
  833. + _q2.z*_q1.x;
  834. _q.z =
  835.   _q2.w*_q1.z
  836. + _q2.x*_q1.y
  837. - _q2.y*_q1.x
  838. + _q2.z*_q1.w;
  839. _q.w =
  840.   _q2.w*_q1.w
  841. - _q2.x*_q1.x
  842. - _q2.y*_q1.y
  843. - _q2.z*_q1.z;
  844. return _q;
  845. }
  846. _q4rt operator *= ( _q4rct _q2 )
  847. {
  848. _q4t _holder( *this );
  849. (*this) = stat_multiplication( _holder, _q2 );
  850. return (*this);
  851. }
  852. };
  853. template < class _num, class _ntr >
  854. class matrix
  855. {
  856. public:
  857. typedef const _num _numc;
  858. typedef _num & _numr;
  859. typedef const _num & _numrc;
  860. typedef _num * _nump;
  861. typedef const _num * _numpc;
  862. typedef vector3<_num,_ntr> _v3t;
  863. typedef vector3<_num,_ntr> & _v3rt;
  864. typedef const vector3<_num,_ntr> & _v3rct;
  865. typedef vector4<_num,_ntr> _v4t;
  866. typedef vector4<_num,_ntr> & _v4rt;
  867. typedef const vector4<_num,_ntr> & _v4rct;
  868. typedef quaternion<_num,_ntr> _q4t;
  869. typedef quaternion<_num,_ntr> & _q4rt;
  870. typedef const quaternion<_num,_ntr> & _q4rct;
  871. typedef matrix<_num,_ntr> _mt;
  872. typedef matrix<_num,_ntr> & _mrt;
  873. typedef const matrix<_num,_ntr> & _mrct;
  874. union
  875. {
  876. struct
  877. {
  878. _num
  879. m11, m21, m31, m41,
  880. m12, m22, m32, m42,
  881. m13, m23, m33, m43,
  882. m14, m24, m34, m44;
  883. };
  884. _num arr[16];
  885. _num _xx[4][4];
  886. };
  887. matrix(
  888. _num src11 = ((_num)1.0), _num src21 = ((_num)0.0), _num src31 = ((_num)0.0), _num src41 = ((_num)0.0),
  889. _num src12 = ((_num)0.0), _num src22 = ((_num)1.0), _num src32 = ((_num)0.0), _num src42 = ((_num)0.0),
  890. _num src13 = ((_num)0.0), _num src23 = ((_num)0.0), _num src33 = ((_num)1.0), _num src43 = ((_num)0.0),
  891. _num src14 = ((_num)0.0), _num src24 = ((_num)0.0), _num src34 = ((_num)0.0), _num src44 = ((_num)1.0)
  892. )
  893. : m14(src14), m13(src13), m12(src12), m11(src11)
  894. , m24(src24), m23(src23), m22(src22), m21(src21)
  895. , m34(src34), m33(src33), m32(src32), m31(src31)
  896. , m44(src44), m43(src43), m42(src42), m41(src41)
  897. {
  898. }
  899. matrix( _nump p_src )
  900. : m14(p_src[ 3]), m13(p_src[ 2]), m12(p_src[ 1]), m11(p_src[ 0])
  901. , m24(p_src[ 7]), m23(p_src[ 6]), m22(p_src[ 5]), m21(p_src[ 4])
  902. , m34(p_src[11]), m33(p_src[10]), m32(p_src[ 9]), m31(p_src[ 8])
  903. , m44(p_src[15]), m43(p_src[14]), m42(p_src[13]), m41(p_src[12])
  904. {
  905. }
  906. matrix( _num _mtx[3][3] )
  907. : m14(_mtx[0][0]),  m13(_mtx[0][1]),  m12(_mtx[0][2]),  m11(((_num)0.0))
  908. , m24(_mtx[1][0]),  m23(_mtx[1][1]),  m22(_mtx[1][2]),  m21(((_num)0.0))
  909. , m34(_mtx[2][0]),  m33(_mtx[2][1]),  m32(_mtx[2][2]),  m31(((_num)0.0))
  910. , m44(((_num)0.0)), m43(((_num)0.0)), m42(((_num)0.0)), m41(((_num)1.0))
  911. {
  912. }
  913. _numr get_item_ref_xy( int _i = 0, int _j = 0 )
  914. {
  915. __gltl_assert__( (0<=_i) && (_i<=3) && (0<=_j) && (_j<=3) );
  916. return *(((_nump)&m11) + (_j<<2)+_i);
  917. }
  918. _numrc get_item_ref_xy( int _i = 0, int _j = 0 ) const
  919. {
  920. __gltl_assert__( (0<=_i) && (_i<=3) && (0<=_j) && (_j<=3) );
  921. return *(((_nump)&m11) + (_j<<2)+_i);
  922. }
  923. _nump get_item_ptr_xy( int _i = 0, int _j = 0 )
  924. {
  925. __gltl_assert__( (0<=_i) && (_i<=3) && (0<=_j) && (_j<=3) );
  926. return (((_nump)&m11) + (_j<<2)+_i);
  927. }
  928. _numpc get_item_ptr_xy( int _i = 0, int _j = 0 ) const
  929. {
  930. __gltl_assert__( (0<=_i) && (_i<=3) && (0<=_j) && (_j<=3) );
  931. return (((_nump)&m11) + (_j<<2)+_i);
  932. }
  933. _numr operator () ( int _i, int _j )
  934. {
  935. return get_item_ref_xy( _i, _j );
  936. }
  937. _numrc operator () ( int _i, int _j ) const
  938. {
  939. return get_item_ref_xy( _i, _j );
  940. }
  941. _numr get_item_ref_yx( int _i = 0, int _j = 0 )
  942. {
  943. return get_item_ref_xy( _j, _i );
  944. }
  945. _numrc get_item_ref_yx( int _i = 0, int _j = 0 ) const
  946. {
  947. return get_item_ref_xy( _j, _i );
  948. }
  949. _nump get_item_ptr_yx( int _i = 0, int _j = 0 )
  950. {
  951. return get_item_ptr_xy( _j, _i );
  952. }
  953. _numpc get_item_ptr_yx( int _i = 0, int _j = 0 ) const
  954. {
  955. return get_item_ptr_xy( _j, _i );
  956. }
  957. bool operator == ( _mrct _mtx ) const
  958. {
  959. return (
  960.    m11 == _mtx.m11 && m12 == _mtx.m12 && m13 == _mtx.m13 && m14 == _mtx.m14
  961. && m21 == _mtx.m21 && m22 == _mtx.m22 && m23 == _mtx.m23 && m24 == _mtx.m24
  962. && m31 == _mtx.m31 && m32 == _mtx.m32 && m33 == _mtx.m33 && m34 == _mtx.m34
  963. && m41 == _mtx.m41 && m42 == _mtx.m42 && m43 == _mtx.m43 && m44 == _mtx.m44
  964. ) ? true : false;
  965. }
  966. bool operator != ( _mrct _mtx ) const
  967. {
  968. return (
  969.    m11 == _mtx.m11 && m12 == _mtx.m12 && m13 == _mtx.m13 && m14 == _mtx.m14
  970. && m21 == _mtx.m21 && m22 == _mtx.m22 && m23 == _mtx.m23 && m24 == _mtx.m24
  971. && m31 == _mtx.m31 && m32 == _mtx.m32 && m33 == _mtx.m33 && m34 == _mtx.m34
  972. && m41 == _mtx.m41 && m42 == _mtx.m42 && m43 == _mtx.m43 && m44 == _mtx.m44
  973. ) ? false : true;
  974. }
  975. _mrt operator = ( _mrct _mtx ) 
  976. {
  977. m11 = _mtx.m11; m12 = _mtx.m12; m13 = _mtx.m13; m14 = _mtx.m14;
  978. m21 = _mtx.m21; m22 = _mtx.m22; m23 = _mtx.m23; m24 = _mtx.m24;
  979. m31 = _mtx.m31; m32 = _mtx.m32; m33 = _mtx.m33; m34 = _mtx.m34;
  980. m41 = _mtx.m41; m42 = _mtx.m42; m43 = _mtx.m43; m44 = _mtx.m44;
  981. return (*this);
  982. }
  983. static void stat_multiplication(
  984. _mrct _mtx1,
  985. _mrct _mtx2,
  986. _mrt _ret_val
  987. {
  988. _mt _ret_val_prep;
  989. _ret_val_prep.m11 = _mtx1.m11*_mtx2.m11 + _mtx1.m12*_mtx2.m21 + _mtx1.m13*_mtx2.m31 + _mtx1.m14*_mtx2.m41;
  990. _ret_val_prep.m12 = _mtx1.m11*_mtx2.m12 + _mtx1.m12*_mtx2.m22 + _mtx1.m13*_mtx2.m32 + _mtx1.m14*_mtx2.m42;
  991. _ret_val_prep.m13 = _mtx1.m11*_mtx2.m13 + _mtx1.m12*_mtx2.m23 + _mtx1.m13*_mtx2.m33 + _mtx1.m14*_mtx2.m43;
  992. _ret_val_prep.m14 = _mtx1.m11*_mtx2.m14 + _mtx1.m12*_mtx2.m24 + _mtx1.m13*_mtx2.m34 + _mtx1.m14*_mtx2.m44;
  993. _ret_val_prep.m21 = _mtx1.m21*_mtx2.m11 + _mtx1.m22*_mtx2.m21 + _mtx1.m23*_mtx2.m31 + _mtx1.m24*_mtx2.m41;
  994. _ret_val_prep.m22 = _mtx1.m21*_mtx2.m12 + _mtx1.m22*_mtx2.m22 + _mtx1.m23*_mtx2.m32 + _mtx1.m24*_mtx2.m42;
  995. _ret_val_prep.m23 = _mtx1.m21*_mtx2.m13 + _mtx1.m22*_mtx2.m23 + _mtx1.m23*_mtx2.m33 + _mtx1.m24*_mtx2.m43;
  996. _ret_val_prep.m24 = _mtx1.m21*_mtx2.m14 + _mtx1.m22*_mtx2.m24 + _mtx1.m23*_mtx2.m34 + _mtx1.m24*_mtx2.m44;
  997. _ret_val_prep.m31 = _mtx1.m31*_mtx2.m11 + _mtx1.m32*_mtx2.m21 + _mtx1.m33*_mtx2.m31 + _mtx1.m34*_mtx2.m41;
  998. _ret_val_prep.m32 = _mtx1.m31*_mtx2.m12 + _mtx1.m32*_mtx2.m22 + _mtx1.m33*_mtx2.m32 + _mtx1.m34*_mtx2.m42;
  999. _ret_val_prep.m33 = _mtx1.m31*_mtx2.m13 + _mtx1.m32*_mtx2.m23 + _mtx1.m33*_mtx2.m33 + _mtx1.m34*_mtx2.m43;
  1000. _ret_val_prep.m34 = _mtx1.m31*_mtx2.m14 + _mtx1.m32*_mtx2.m24 + _mtx1.m33*_mtx2.m34 + _mtx1.m34*_mtx2.m44;
  1001. _ret_val_prep.m41 = _mtx1.m41*_mtx2.m11 + _mtx1.m42*_mtx2.m21 + _mtx1.m43*_mtx2.m31 + _mtx1.m44*_mtx2.m41;
  1002. _ret_val_prep.m42 = _mtx1.m41*_mtx2.m12 + _mtx1.m42*_mtx2.m22 + _mtx1.m43*_mtx2.m32 + _mtx1.m44*_mtx2.m42;
  1003. _ret_val_prep.m43 = _mtx1.m41*_mtx2.m13 + _mtx1.m42*_mtx2.m23 + _mtx1.m43*_mtx2.m33 + _mtx1.m44*_mtx2.m43;
  1004. _ret_val_prep.m44 = _mtx1.m41*_mtx2.m14 + _mtx1.m42*_mtx2.m24 + _mtx1.m43*_mtx2.m34 + _mtx1.m44*_mtx2.m44;
  1005. // for( int _i = 0; _i < 4; _i++ )
  1006. // {
  1007. // for( int _j = 0; _j < 4; _j++ )
  1008. // {
  1009. // _ret_val_prep._xx[_i][_j] = 0;
  1010. // for( int _k = 0; _k < 4; _k++ )
  1011. // {
  1012. // _ret_val_prep._xx[_i][_j] +=
  1013. // _mtx2._xx[_i][_k] * _mtx1._xx[_k][_j];
  1014. // }
  1015. // }
  1016. // }
  1017. _ret_val = _ret_val_prep;
  1018. }
  1019. static _mt stat_multiplication(
  1020. _mrct _mtx1,
  1021. _mrct _mtx2
  1022. {
  1023. _mt _ret_val;
  1024. _ret_val.m11 = _mtx1.m11*_mtx2.m11 + _mtx1.m12*_mtx2.m21 + _mtx1.m13*_mtx2.m31 + _mtx1.m14*_mtx2.m41;
  1025. _ret_val.m12 = _mtx1.m11*_mtx2.m12 + _mtx1.m12*_mtx2.m22 + _mtx1.m13*_mtx2.m32 + _mtx1.m14*_mtx2.m42;
  1026. _ret_val.m13 = _mtx1.m11*_mtx2.m13 + _mtx1.m12*_mtx2.m23 + _mtx1.m13*_mtx2.m33 + _mtx1.m14*_mtx2.m43;
  1027. _ret_val.m14 = _mtx1.m11*_mtx2.m14 + _mtx1.m12*_mtx2.m24 + _mtx1.m13*_mtx2.m34 + _mtx1.m14*_mtx2.m44;
  1028. _ret_val.m21 = _mtx1.m21*_mtx2.m11 + _mtx1.m22*_mtx2.m21 + _mtx1.m23*_mtx2.m31 + _mtx1.m24*_mtx2.m41;
  1029. _ret_val.m22 = _mtx1.m21*_mtx2.m12 + _mtx1.m22*_mtx2.m22 + _mtx1.m23*_mtx2.m32 + _mtx1.m24*_mtx2.m42;
  1030. _ret_val.m23 = _mtx1.m21*_mtx2.m13 + _mtx1.m22*_mtx2.m23 + _mtx1.m23*_mtx2.m33 + _mtx1.m24*_mtx2.m43;
  1031. _ret_val.m24 = _mtx1.m21*_mtx2.m14 + _mtx1.m22*_mtx2.m24 + _mtx1.m23*_mtx2.m34 + _mtx1.m24*_mtx2.m44;
  1032. _ret_val.m31 = _mtx1.m31*_mtx2.m11 + _mtx1.m32*_mtx2.m21 + _mtx1.m33*_mtx2.m31 + _mtx1.m34*_mtx2.m41;
  1033. _ret_val.m32 = _mtx1.m31*_mtx2.m12 + _mtx1.m32*_mtx2.m22 + _mtx1.m33*_mtx2.m32 + _mtx1.m34*_mtx2.m42;
  1034. _ret_val.m33 = _mtx1.m31*_mtx2.m13 + _mtx1.m32*_mtx2.m23 + _mtx1.m33*_mtx2.m33 + _mtx1.m34*_mtx2.m43;
  1035. _ret_val.m34 = _mtx1.m31*_mtx2.m14 + _mtx1.m32*_mtx2.m24 + _mtx1.m33*_mtx2.m34 + _mtx1.m34*_mtx2.m44;
  1036. _ret_val.m41 = _mtx1.m41*_mtx2.m11 + _mtx1.m42*_mtx2.m21 + _mtx1.m43*_mtx2.m31 + _mtx1.m44*_mtx2.m41;
  1037. _ret_val.m42 = _mtx1.m41*_mtx2.m12 + _mtx1.m42*_mtx2.m22 + _mtx1.m43*_mtx2.m32 + _mtx1.m44*_mtx2.m42;
  1038. _ret_val.m43 = _mtx1.m41*_mtx2.m13 + _mtx1.m42*_mtx2.m23 + _mtx1.m43*_mtx2.m33 + _mtx1.m44*_mtx2.m43;
  1039. _ret_val.m44 = _mtx1.m41*_mtx2.m14 + _mtx1.m42*_mtx2.m24 + _mtx1.m43*_mtx2.m34 + _mtx1.m44*_mtx2.m44;
  1040. // for( int _i = 0; _i < 4; _i++ )
  1041. // {
  1042. // for( int _j = 0; _j < 4; _j++ )
  1043. // {
  1044. // _ret_val._xx[_i][_j] = 0;
  1045. // for( int _k = 0; _k < 4; _k++ )
  1046. // {
  1047. // _ret_val._xx[_i][_j] +=
  1048. // _mtx2._xx[_i][_k] * _mtx1._xx[_k][_j];
  1049. // }
  1050. // }
  1051. // }
  1052. return _ret_val;
  1053. }
  1054. _mrt operator *= ( _q4rct _q ); 
  1055. _mrt operator *= ( _mrct _mtx ) 
  1056. {
  1057. stat_multiplication( *this, _mtx, *this );
  1058. return (*this);
  1059. }
  1060. _mrt operator *= ( _numc _v ) 
  1061. {
  1062. for( int _i = 0; _i < 16; _i++ )
  1063. *(((_num*)&m11)+_i) = *(((_num*)&m11)+_i) * _v;
  1064. return (*this);
  1065. }
  1066. _mrt operator += ( _mrct _mtx )
  1067. {
  1068. for( int _i = 0; _i < 16; _i++ )
  1069. *(((_num*)&m11)+_i) = *(((_num*)&m11)+_i) + *(((_num*)&_mtx.m11)+_i);
  1070. return (*this);
  1071. }
  1072. _mrt operator -= ( _mrct _mtx ) 
  1073. {
  1074. for( int _i = 0; _i < 16; _i++ )
  1075. *(((_num*)&m11)+_i) = *(((_num*)&m11)+_i) - *(((_num*)&_mtx.m11)+_i);
  1076. return (*this);
  1077. }
  1078. void load_transposition() 
  1079. {
  1080. _num _swap_val;
  1081. _swap_val = m12; m12 = m21; m21 = _swap_val;
  1082. _swap_val = m13; m13 = m31; m31 = _swap_val;
  1083. _swap_val = m14; m14 = m41; m41 = _swap_val;
  1084. _swap_val = m23; m23 = m32; m32 = _swap_val;
  1085. _swap_val = m24; m24 = m42; m42 = _swap_val;
  1086. _swap_val = m34; m34 = m43; m43 = _swap_val;
  1087. }
  1088. _num load_inversion()
  1089. {
  1090. _num _dest[16], _swap[12], _src[16];
  1091. for( int _i = 0; _i < 4; _i++ ) 
  1092. {
  1093. _src[_i]      = *(((_nump)&m11) + (_i<<2));
  1094. _src[_i +  4] = *(((_nump)&m11) + (_i<<2) + 1);
  1095. _src[_i +  8] = *(((_nump)&m11) + (_i<<2) + 2);
  1096. _src[_i + 12] = *(((_nump)&m11) + (_i<<2) + 3);
  1097. }
  1098. _swap[ 0] = _src[10] * _src[15];
  1099. _swap[ 1] = _src[11] * _src[14];
  1100. _swap[ 2] = _src[ 9] * _src[15];
  1101. _swap[ 3] = _src[11] * _src[13];
  1102. _swap[ 4] = _src[ 9] * _src[14];
  1103. _swap[ 5] = _src[10] * _src[13];
  1104. _swap[ 6] = _src[ 8] * _src[15];
  1105. _swap[ 7] = _src[11] * _src[12];
  1106. _swap[ 8] = _src[ 8] * _src[14];
  1107. _swap[ 9] = _src[10] * _src[12];
  1108. _swap[10] = _src[ 8] * _src[13];
  1109. _swap[11] = _src[ 9] * _src[12];
  1110. _dest[ 0] = _swap[0]*_src[5] + _swap[3]*_src[6] + _swap[ 4]*_src[7];
  1111. _dest[ 0]-= _swap[1]*_src[5] + _swap[2]*_src[6] + _swap[ 5]*_src[7];
  1112. _dest[ 1] = _swap[1]*_src[4] + _swap[6]*_src[6] + _swap[ 9]*_src[7];
  1113. _dest[ 1]-= _swap[0]*_src[4] + _swap[7]*_src[6] + _swap[ 8]*_src[7];
  1114. _dest[ 2] = _swap[2]*_src[4] + _swap[7]*_src[5] + _swap[10]*_src[7];
  1115. _dest[ 2]-= _swap[3]*_src[4] + _swap[6]*_src[5] + _swap[11]*_src[7];
  1116. _dest[ 3] = _swap[5]*_src[4] + _swap[8]*_src[5] + _swap[11]*_src[6];
  1117. _dest[ 3]-= _swap[4]*_src[4] + _swap[9]*_src[5] + _swap[10]*_src[6];
  1118. _dest[ 4] = _swap[1]*_src[1] + _swap[2]*_src[2] + _swap[ 5]*_src[3];
  1119. _dest[ 4]-= _swap[0]*_src[1] + _swap[3]*_src[2] + _swap[ 4]*_src[3];
  1120. _dest[ 5] = _swap[0]*_src[0] + _swap[7]*_src[2] + _swap[ 8]*_src[3];
  1121. _dest[ 5]-= _swap[1]*_src[0] + _swap[6]*_src[2] + _swap[ 9]*_src[3];
  1122. _dest[ 6] = _swap[3]*_src[0] + _swap[6]*_src[1] + _swap[11]*_src[3];
  1123. _dest[ 6]-= _swap[2]*_src[0] + _swap[7]*_src[1] + _swap[10]*_src[3];
  1124. _dest[ 7] = _swap[4]*_src[0] + _swap[9]*_src[1] + _swap[10]*_src[2];
  1125. _dest[ 7]-= _swap[5]*_src[0] + _swap[8]*_src[1] + _swap[11]*_src[2];
  1126. _swap[ 0] = _src[2]*_src[7];
  1127. _swap[ 1] = _src[3]*_src[6];
  1128. _swap[ 2] = _src[1]*_src[7];
  1129. _swap[ 3] = _src[3]*_src[5];
  1130. _swap[ 4] = _src[1]*_src[6];
  1131. _swap[ 5] = _src[2]*_src[5];
  1132. _swap[ 6] = _src[0]*_src[7];
  1133. _swap[ 7] = _src[3]*_src[4];
  1134. _swap[ 8] = _src[0]*_src[6];
  1135. _swap[ 9] = _src[2]*_src[4];
  1136. _swap[10] = _src[0]*_src[5];
  1137. _swap[11] = _src[1]*_src[4];
  1138. _dest[ 8] = _swap[ 0]*_src[13] + _swap[ 3]*_src[14] + _swap[ 4]*_src[15];
  1139. _dest[ 8]-= _swap[ 1]*_src[13] + _swap[ 2]*_src[14] + _swap[ 5]*_src[15];
  1140. _dest[ 9] = _swap[ 1]*_src[12] + _swap[ 6]*_src[14] + _swap[ 9]*_src[15];
  1141. _dest[ 9]-= _swap[ 0]*_src[12] + _swap[ 7]*_src[14] + _swap[ 8]*_src[15];
  1142. _dest[10] = _swap[ 2]*_src[12] + _swap[ 7]*_src[13] + _swap[10]*_src[15];
  1143. _dest[10]-= _swap[ 3]*_src[12] + _swap[ 6]*_src[13] + _swap[11]*_src[15];
  1144. _dest[11] = _swap[ 5]*_src[12] + _swap[ 8]*_src[13] + _swap[11]*_src[14];
  1145. _dest[11]-= _swap[ 4]*_src[12] + _swap[ 9]*_src[13] + _swap[10]*_src[14];
  1146. _dest[12] = _swap[ 2]*_src[10] + _swap[ 5]*_src[11] + _swap[ 1]*_src[ 9];
  1147. _dest[12]-= _swap[ 4]*_src[11] + _swap[ 0]*_src[ 9] + _swap[ 3]*_src[10];
  1148. _dest[13] = _swap[ 8]*_src[11] + _swap[ 0]*_src[ 8] + _swap[ 7]*_src[10];
  1149. _dest[13]-= _swap[ 6]*_src[10] + _swap[ 9]*_src[11] + _swap[ 1]*_src[ 8];
  1150. _dest[14] = _swap[ 6]*_src[ 9] + _swap[11]*_src[11] + _swap[ 3]*_src[ 8];
  1151. _dest[14]-= _swap[10]*_src[11] + _swap[ 2]*_src[ 8] + _swap[ 7]*_src[ 9];
  1152. _dest[15] = _swap[10]*_src[10] + _swap[ 4]*_src[ 8] + _swap[ 9]*_src[ 9];
  1153. _dest[15]-= _swap[ 8]*_src[ 9] + _swap[11]*_src[10] + _swap[ 5]*_src[ 8];
  1154. _num _det1 =
  1155.   _src[0]*_dest[0]
  1156. + _src[1]*_dest[1]
  1157. + _src[2]*_dest[2]
  1158. + _src[3]*_dest[3];
  1159. _num _det2 = ((_num)1.0) / _det1;
  1160. for( int _j = 0; _j < 16; _j++ )
  1161. {
  1162. _dest[_j] *= _det2;
  1163. *(((_nump)&m11) + _j) = _dest[_j];
  1164. }
  1165. return _det1;
  1166. }
  1167. _num get_determinant() 
  1168. {
  1169. _num _src[16], _swap[12], _dest[4];
  1170. for( int _i = 0; _i < 16; _i++ )
  1171. _src[_i] = *(((_nump)&m11) + _i);
  1172. _swap[ 0] = _src[10] * _src[15];
  1173. _swap[ 1] = _src[11] * _src[14];
  1174. _swap[ 2] = _src[ 9] * _src[15];
  1175. _swap[ 3] = _src[11] * _src[13];
  1176. _swap[ 4] = _src[ 9] * _src[14];
  1177. _swap[ 5] = _src[10] * _src[13];
  1178. _swap[ 6] = _src[ 8] * _src[15];
  1179. _swap[ 7] = _src[11] * _src[12];
  1180. _swap[ 8] = _src[ 8] * _src[14];
  1181. _swap[ 9] = _src[10] * _src[12];
  1182. _swap[10] = _src[ 8] * _src[13];
  1183. _swap[11] = _src[ 9] * _src[12];
  1184. _dest[ 0] = _swap[0]*_src[5] + _swap[3]*_src[6] + _swap[ 4]*_src[7];
  1185. _dest[ 0]-= _swap[1]*_src[5] + _swap[2]*_src[6] + _swap[ 5]*_src[7];
  1186. _dest[ 1] = _swap[1]*_src[4] + _swap[6]*_src[6] + _swap[ 9]*_src[7];
  1187. _dest[ 1]-= _swap[0]*_src[4] + _swap[7]*_src[6] + _swap[ 8]*_src[7];
  1188. _dest[ 2] = _swap[2]*_src[4] + _swap[7]*_src[5] + _swap[10]*_src[7];
  1189. _dest[ 2]-= _swap[3]*_src[4] + _swap[6]*_src[5] + _swap[11]*_src[7];
  1190. _dest[ 3] = _swap[5]*_src[4] + _swap[8]*_src[5] + _swap[11]*_src[6];
  1191. _dest[ 3]-= _swap[4]*_src[4] + _swap[9]*_src[5] + _swap[10]*_src[6];
  1192. _num _det =
  1193.   _src[0]*_dest[0]
  1194. + _src[1]*_dest[1]
  1195. + _src[2]*_dest[2]
  1196. + _src[3]*_dest[3];
  1197. return _det;
  1198. }
  1199. _v3t get_angles()
  1200. {
  1201. _num yy, xx, zz, _k, rd;
  1202. rd = _ntr::sqrt( m13*m13 + m23*m23 + m33*m33 );
  1203. _k = ( ((_num)1.0) - _ntr::get_safe_min() ) * rd;
  1204. if( m23 > _k )
  1205. {
  1206. zz = ((_num)0.0);
  1207. xx = - _ntr::get_pi() / ((_num)2.0);
  1208. yy = _ntr::atan2( -m12, m11 );
  1209. }
  1210. else if( m23 < (-_k) )
  1211. {
  1212. zz = ((_num)0.0);
  1213. xx = _ntr::get_pi() / ((_num)2.0);
  1214. yy = _ntr::atan2( m12, m11 );
  1215. }
  1216. else
  1217. {
  1218. if( rd == 0)
  1219. yy = xx = zz = ((_num)0.0);
  1220. else
  1221. {
  1222. xx =  - _ntr::asin( m23 / rd );
  1223. yy =    _ntr::atan2( m13, m33 );
  1224. zz =    _ntr::atan2( m21, m22 );
  1225. }
  1226. }
  1227. return _v3t( xx, yy, zz );
  1228. }
  1229. _v3t get_position()
  1230. {
  1231. return _v3t( m14, m24, m34 );
  1232. }
  1233. void load_zero()
  1234. {
  1235.   m11 = m12 = m13 = m14
  1236. = m21 = m22 = m23 = m24
  1237. = m31 = m32 = m33 = m34
  1238. = m41 = m42 = m43 = m44
  1239. = ((_num)0.0);
  1240. }
  1241. void load_identity()
  1242. {
  1243. load_zero();
  1244. m11 = m22 = m33 = m44 = ((_num)1.0);
  1245. }
  1246. void load_translation(
  1247. _numc dx,
  1248. _numc dy,
  1249. _numc dz
  1250. )
  1251. {
  1252. load_identity();
  1253. m14 = dx;
  1254. m24 = dy;
  1255. m34 = dz;
  1256. }
  1257. void load_translation( _v3rct _v )
  1258. {
  1259. load_identity();
  1260. m14 = _v.x;
  1261. m24 = _v.y;
  1262. m34 = _v.z;
  1263. }
  1264. void load_rotation_x( _numc _angle_radians )
  1265. {
  1266. _num _c = _ntr::cos(_angle_radians), _s = _ntr::sin(_angle_radians);
  1267. load_identity();
  1268. m22 = + _c;
  1269. m23 = - _s;
  1270. m32 = + _s;
  1271. m33 = + _c;
  1272. }
  1273. void load_rotation_y( _numc _angle_radians )
  1274. {
  1275. _num _c = _ntr::cos(_angle_radians), _s = _ntr::sin(_angle_radians);
  1276. load_identity();
  1277. m11 = + _c;
  1278. m13 = + _s;
  1279. m31 = - _s;
  1280. m33 = + _c;
  1281. }
  1282. void load_rotation_z( _numc _angle_radians )
  1283. {
  1284. _num _c = _ntr::cos(_angle_radians), _s = _ntr::sin(_angle_radians);
  1285. load_identity();
  1286. m11 = + _c;
  1287. m12 = - _s;
  1288. m21 = + _s;
  1289. m22 = + _c;
  1290. }
  1291. void load_rotation_xyz( _numc _x, _numc _y, _numc _z )
  1292. {
  1293. _mt mtx_rotation_x, mtx_rotation_y, mtx_rotation_z;
  1294. mtx_rotation_x.load_rotation_x(_x);
  1295. mtx_rotation_y.load_rotation_y(_y);
  1296. mtx_rotation_z.load_rotation_z(_z);
  1297. (*this) = mtx_rotation_x * mtx_rotation_y * mtx_rotation_z;
  1298. }
  1299. void load_rotation_xyz( _v3rct _v )
  1300. {
  1301. load_rotation_xyz( _v.x, _v.y, _v.z );
  1302. }
  1303. void load_scale( _numc _x, _numc _y, _numc _z )
  1304. {
  1305. load_identity();
  1306. m11 = _x;
  1307. m22 = _y;
  1308. m33 = _z;
  1309. void load_scale( _v3rct _v )
  1310. {
  1311. load_identity();
  1312. m11 = _v.x;
  1313. m22 = _v.y;
  1314. m33 = _v.z;
  1315. void load_scale( _numc _val )
  1316. {
  1317. load_identity();
  1318. m11 = m22 = m33 = _val;
  1319. }
  1320. void load_perspective(
  1321. _num fovy,
  1322. _num aspect,
  1323. _num znear,
  1324. _num zfar
  1325. )
  1326. {
  1327. load_identity();
  1328. _num _ctan_fov =
  1329. ((_num)1.0)
  1330. /
  1331. ( _ntr::tan( fovy / ((_num)2.0)) );
  1332. m11 =   _ctan_fov / aspect;
  1333. m22 =   _ctan_fov;
  1334. m33 = - (zfar + znear) / (zfar - znear);
  1335. m34 = - ((_num)2.0) * (zfar * znear) / ( zfar - znear );
  1336. m43 = - ((_num)1.0);
  1337. m44 =   ((_num)0.0);
  1338. }
  1339. void load_rotation_about_vector(
  1340. _numc _angle,
  1341. _v3rct _vec
  1342. )
  1343. {
  1344. _v3t _v( _vec );
  1345. _v.normalize();
  1346. _num _x = _v._x, _y = _v._y, _z = _v._z;
  1347. _num _c = _ntr::cos(_angle);
  1348. _num _s = _ntr::sin(_angle);
  1349. _num xx = _x * _x;
  1350. _num xy = _y * _x;
  1351. _num xz = _z * _x;
  1352. _num yy = _y * _y;
  1353. _num yz = _y * _z;
  1354. _num zz = _z * _z;
  1355. _num xs = _x * _s;
  1356. _num ys = _y * _s;
  1357. _num zs = _z * _s;
  1358. _num _1c = 1 - _c;
  1359. m11 = xx*_1c+_c;
  1360. m12 = xy*_1c+zs;
  1361. m13 = xz*_1c-ys;
  1362. m14 = 0;
  1363. m21 = xy*_1c-zs;
  1364. m22 = yy*_1c+_c;
  1365. m23 = yz*_1c+xs;
  1366. m24 = 0;
  1367. m31 = xz*_1c+ys;
  1368. m32 = yz*_1c-xs;
  1369. m33 = zz*_1c+_c;
  1370. m34 = 0;
  1371. m41 = 0;
  1372. m42 = 0;
  1373. m43 = 0;
  1374. m44 = 1;
  1375. }
  1376. void load_rotation_about_vector(
  1377. _numc _angle,
  1378. _numc _x,
  1379. _numc _y,
  1380. _numc _z
  1381. )
  1382. {
  1383. load_rotation_about_vector(
  1384. _angle,
  1385. _v3t( _x, _y, _z )
  1386. );
  1387. }
  1388. void load_rotation_about_vector(
  1389. _numc _angle,
  1390. _v4rct _vec
  1391. )
  1392. {
  1393. load_rotation_about_vector(
  1394. _angle,
  1395. _v3t(_vec.x,_vec.y,_vec.z)
  1396. );
  1397. }
  1398. void load_reflection(
  1399. _numc _a,
  1400. _numc _b,
  1401. _numc _c,
  1402. _numc _d
  1403. )
  1404. {
  1405. get_item_ref_yx( 0, 0 ) = _numc(1.0) - _numc(2.0) * _a * _a;
  1406. get_item_ref_yx( 1, 0 ) =            - _numc(2.0) * _a * _b;
  1407. get_item_ref_yx( 2, 0 ) =            - _numc(2.0) * _a * _c;
  1408. get_item_ref_yx( 3, 0 ) =            - _numc(2.0) * _d * _a;
  1409. get_item_ref_yx( 0, 1 ) =            - _numc(2.0) * _b * _a;
  1410. get_item_ref_yx( 1, 1 ) = _numc(1.0) - _numc(2.0) * _b * _b;
  1411. get_item_ref_yx( 2, 1 ) =            - _numc(2.0) * _b * _c;
  1412. get_item_ref_yx( 3, 1 ) =            - _numc(2.0) * _d * _b;
  1413. get_item_ref_yx( 0, 2 ) =            - _numc(2.0) * _c * _a;
  1414. get_item_ref_yx( 1, 2 ) =            - _numc(2.0) * _c * _b;
  1415. get_item_ref_yx( 2, 2 ) = _numc(1.0) - _numc(2.0) * _c * _c;
  1416. get_item_ref_yx( 3, 2 ) =            - _numc(2.0) * _d * _c;
  1417. get_item_ref_yx( 0, 3 ) = _numc(0.0);
  1418. get_item_ref_yx( 1, 3 ) = _numc(0.0);
  1419. get_item_ref_yx( 2, 3 ) = _numc(0.0);
  1420. get_item_ref_yx( 3, 3 ) = _numc(1.0);
  1421. }
  1422. void load_reflection( _v4rct plane )
  1423. {
  1424. load_reflection( plane.a, plane.b, plane.c, plane.d );
  1425. }
  1426. };
  1427. template < class _num, class _ntr >
  1428. inline matrix<_num,_ntr> operator * (
  1429. const matrix<_num,_ntr> &_mtx,
  1430. const _num _v
  1431. {
  1432. matrix<_num,_ntr> _ret_val;
  1433. for( int _i = 0; _i < 16; _i++ )
  1434. *(((_num*)&_ret_val.m11)+_i) = *(((_num*)&_mtx.m11)+_i) * _v;
  1435. return _ret_val;
  1436. }
  1437. template < class _num, class _ntr >
  1438. inline matrix<_num,_ntr> operator * (
  1439. const _num _v,
  1440. const matrix<_num,_ntr> & _mtx
  1441. {
  1442. matrix<_num,_ntr> _ret_val;
  1443. for( int _i = 0; _i < 16; _i++ )
  1444. *(((_num*)&_ret_val.m11)+_i) = *(((_num*)&_mtx.m11)+_i) * _v;
  1445. return _ret_val;
  1446. }
  1447. template < class _num, class _ntr >
  1448. inline matrix<_num,_ntr> operator * (
  1449. const matrix<_num,_ntr> & _mtx1,
  1450. const matrix<_num,_ntr> & _mtx2
  1451. {
  1452. return matrix<_num,_ntr>::stat_multiplication( _mtx1, _mtx2 );
  1453. }
  1454. template < class _num, class _ntr >
  1455. inline matrix<_num,_ntr> operator + (
  1456. const matrix<_num,_ntr> & _mtx1,
  1457. const matrix<_num,_ntr> & _mtx2
  1458. {
  1459. matrix<_num,_ntr> _ret_val;
  1460. for( int _i = 0; _i < 16; _i++ )
  1461. *(((_num*)&_ret_val.m11)+_i) = *(((_num*)&_mtx1.m11)+_i) + *(((_num*)&_mtx2.m11)+_i);
  1462. return _ret_val;
  1463. }
  1464. template < class _num, class _ntr >
  1465. inline matrix<_num,_ntr> operator - (
  1466. const matrix<_num,_ntr> & _mtx1,
  1467. const matrix<_num,_ntr> & _mtx2
  1468. )
  1469. {
  1470. matrix<_num,_ntr> _ret_val;
  1471. for( int _i = 0; _i < 16; _i++ )
  1472. *(((_num*)&_ret_val.m11)+_i) = *(((_num*)&_mtx1.m11)+_i) - *(((_num*)&_mtx2.m11)+_i);
  1473. return _ret_val;
  1474. }
  1475. template < class _num, class _ntr >
  1476. inline matrix<_num,_ntr> operator - ( const matrix<_num,_ntr> & _mtx ) 
  1477. {
  1478. matrix<_num,_ntr> _ret_val;
  1479. for( int _i = 0; _i < 16; _i++ )
  1480. *(((_num*)&_ret_val.m11)+_i) = - *(((_num*)&_mtx.m11)+_i);
  1481. return _ret_val;
  1482. }
  1483. template < class _num, class _ntr >
  1484. inline matrix<_num,_ntr> operator + ( const matrix<_num,_ntr> & _mtx ) 
  1485. {
  1486. return _mtx;
  1487. }
  1488. template < class _num, class _ntr >
  1489. void inline vector3<_num,_ntr>::stat_multiplication(
  1490. const matrix<_num,_ntr> & _mtx,
  1491. const vector3<_num,_ntr> & _v,
  1492. vector3<_num,_ntr> & _ret_val
  1493. )
  1494. {
  1495. vector3<_num,_ntr> _ret_val_prep;
  1496. _ret_val_prep.x = _mtx.m11*_v.x + _mtx.m12*_v.y + _mtx.m13*_v.z + _mtx.m14;
  1497. _ret_val_prep.y = _mtx.m21*_v.x + _mtx.m22*_v.y + _mtx.m23*_v.z + _mtx.m24;
  1498. _ret_val_prep.z = _mtx.m31*_v.x + _mtx.m32*_v.y + _mtx.m33*_v.z + _mtx.m34;
  1499. _ret_val.x = _ret_val_prep.x;
  1500. _ret_val.y = _ret_val_prep.y;
  1501. _ret_val.z = _ret_val_prep.z;
  1502. }
  1503. template < class _num, class _ntr >
  1504. inline vector3<_num,_ntr> vector3<_num,_ntr>::stat_multiplication(
  1505. const matrix<_num,_ntr> & _mtx,
  1506. const vector3<_num,_ntr> & _v
  1507. )
  1508. {
  1509. vector3<_num,_ntr> _ret_val;
  1510. _ret_val.x = _mtx.m11*_v.x + _mtx.m12*_v.y + _mtx.m13*_v.z + _mtx.m14;
  1511. _ret_val.y = _mtx.m21*_v.x + _mtx.m22*_v.y + _mtx.m23*_v.z + _mtx.m24;
  1512. _ret_val.z = _mtx.m31*_v.x + _mtx.m32*_v.y + _mtx.m33*_v.z + _mtx.m34;
  1513. return _ret_val;
  1514. }
  1515. template < class _num, class _ntr >
  1516. inline vector3<_num,_ntr> operator * (
  1517. const matrix<_num,_ntr> & _mtx,
  1518. const vector3<_num,_ntr> & _v
  1519. )
  1520. {
  1521. return vector3<_num,_ntr>::stat_multiplication( _mtx, _v );
  1522. }
  1523. template < class _num, class _ntr >
  1524. inline void vector4<_num,_ntr>::stat_multiplication(
  1525. const matrix<_num,_ntr> & _mtx,
  1526. _v4rct _v,
  1527. _v4rt _ret_val
  1528. )
  1529. {
  1530. vector4<_num,_ntr> _ret_val_prep;
  1531. _ret_val_prep.x = _mtx.m11*_v.x + _mtx.m12*_v.y + _mtx.m13*_v.z + _mtx.m14*_v.w;
  1532. _ret_val_prep.y = _mtx.m21*_v.x + _mtx.m22*_v.y + _mtx.m23*_v.z + _mtx.m24*_v.w;
  1533. _ret_val_prep.z = _mtx.m31*_v.x + _mtx.m32*_v.y + _mtx.m33*_v.z + _mtx.m34*_v.w;
  1534. _ret_val_prep.w = _mtx.m41*_v.x + _mtx.m42*_v.y + _mtx.m43*_v.z + _mtx.m44*_v.w;
  1535. _ret_val.x = _ret_val_prep.x;
  1536. _ret_val.y = _ret_val_prep.y;
  1537. _ret_val.z = _ret_val_prep.z;
  1538. _ret_val.w = _ret_val_prep.w;
  1539. }
  1540. template < class _num, class _ntr >
  1541. inline vector4<_num,_ntr> vector4<_num,_ntr>::stat_multiplication(
  1542. const matrix<_num,_ntr> & _mtx,
  1543. _v4rct _v
  1544. )
  1545. {
  1546. vector4<_num,_ntr> _ret_val;
  1547. _ret_val.x = _mtx.m11*_v.x + _mtx.m12*_v.y + _mtx.m13*_v.z + _mtx.m14*_v.w;
  1548. _ret_val.y = _mtx.m21*_v.x + _mtx.m22*_v.y + _mtx.m23*_v.z + _mtx.m24*_v.w;
  1549. _ret_val.z = _mtx.m31*_v.x + _mtx.m32*_v.y + _mtx.m33*_v.z + _mtx.m34*_v.w;
  1550. _ret_val.w = _mtx.m41*_v.x + _mtx.m42*_v.y + _mtx.m43*_v.z + _mtx.m44*_v.w;
  1551. return _ret_val;
  1552. }
  1553. template < class _num, class _ntr >
  1554. inline vector4<_num,_ntr> operator * (
  1555. const matrix<_num,_ntr> & _mtx,
  1556. const vector4<_num,_ntr> & _v
  1557. )
  1558. {
  1559. return vector4<_num,_ntr>::stat_multiplication( _mtx, _v );
  1560. }
  1561. template < class _num, class _ntr >
  1562. inline quaternion<_num,_ntr>::quaternion(
  1563. matrix<_num,_ntr> & _mtx
  1564. )
  1565. {
  1566. _num _tr, _s, _q[4];
  1567. int _i, _j, _k;
  1568. int _nxt_val[3] = { 1, 2, 0 };
  1569. _tr = _mtx.m11 + _mtx.m22 + _mtx.m33;
  1570. if( _tr > ((_num)0.0) ) 
  1571. {
  1572. _s = _ntr::sqrt( _tr + ((_num)1.0) );
  1573. w  = _s / ((_num)2.0);
  1574. _s = ((_num)0.5) / _s;
  1575. x  = (_mtx.m23 - _mtx.m32) * _s;
  1576. y  = (_mtx.m31 - _mtx.m13) * _s;
  1577. z  = (_mtx.m12 - _mtx.m21) * _s;
  1578. else 
  1579. {
  1580.      _i = 0;
  1581. if( _mtx.m22 > _mtx.m11 )
  1582. _i = 1;
  1583. if( _mtx.m33 > _mtx.arr[4*_i+_i] )
  1584. _i = 2;
  1585. _j = _nxt_val[_i];
  1586. _k = _nxt_val[_j];
  1587. _s =
  1588. _ntr::sqrt(
  1589. ( _mtx.arr[4*_i+_i] -
  1590. ( _mtx.arr[4*_j+_j] + _mtx.arr[4*_k+_k] )
  1591. ) + ((_num)1.0)
  1592. );
  1593. _q[_i] = _s * ((_num)0.5);
  1594. if( _s != ((_num)0.0) )
  1595. _s = ((_num)0.5) / _s;
  1596. _q[3]  = (_mtx.arr[4*_j+_k] - _mtx.arr[4*_k+_j] ) * _s;
  1597. _q[_j] = (_mtx.arr[4*_i+_j] + _mtx.arr[4*_j+_i] ) * _s;
  1598. _q[_k] = (_mtx.arr[4*_i+_k] + _mtx.arr[4*_k+_i] ) * _s;
  1599. x = _q[0];
  1600. y = _q[1];
  1601. z = _q[2];
  1602. w = _q[3];
  1603. }
  1604. }
  1605. template < class _num, class _ntr >
  1606. inline void quaternion<_num,_ntr>::get_as_matrix(
  1607. matrix<_num,_ntr> & _mtx
  1608. )
  1609. {
  1610. normalize();
  1611. _num xx = x * x;
  1612. _num yy = y * y;
  1613. _num zz = z * z;
  1614. _mtx.get_item_ref_yx( 0, 0 ) = ((_num)1.0) - ((_num)2.0) * ( yy + zz );
  1615. _mtx.get_item_ref_yx( 1, 0 ) = ((_num)2.0) * ( x * y + w * z );
  1616. _mtx.get_item_ref_yx( 2, 0 ) = ((_num)2.0) * ( x * z - w * y );
  1617. _mtx.get_item_ref_yx( 3, 0 ) = ((_num)0.0);
  1618. _mtx.get_item_ref_yx( 0, 1 ) = ((_num)2.0) * ( x * y - w * z );
  1619. _mtx.get_item_ref_yx( 1, 1 ) = ((_num)1.0) - ((_num)2.0) * ( xx + zz );
  1620. _mtx.get_item_ref_yx( 2, 1 ) = ((_num)2.0) * ( y * z + w * x );
  1621. _mtx.get_item_ref_yx( 3, 1 ) = ((_num)0.0);
  1622. _mtx.get_item_ref_yx( 0, 2 ) = ((_num)2.0) * ( x * z + w * y );
  1623. _mtx.get_item_ref_yx( 1, 2 ) = ((_num)2.0) * ( y * z - w * x );
  1624. _mtx.get_item_ref_yx( 2, 2 ) = ((_num)1.0) - ((_num)2.0) * ( xx + yy );
  1625. _mtx.get_item_ref_yx( 3, 2 ) = ((_num)0.0);
  1626. _mtx.get_item_ref_yx( 0, 3 ) = ((_num)0.0);
  1627. _mtx.get_item_ref_yx( 1, 3 ) = ((_num)0.0);
  1628. _mtx.get_item_ref_yx( 2, 3 ) = ((_num)0.0);
  1629. _mtx.get_item_ref_yx( 3, 3 ) = ((_num)1.0);
  1630. }
  1631. template < class _num, class _ntr >
  1632. inline matrix<_num,_ntr> quaternion<_num,_ntr>::
  1633. get_as_matrix() const
  1634. {
  1635. _q4t _q = (*this);
  1636. _mt _mtx;
  1637. _q.get_as_matrix( _mtx );
  1638. return _mtx;
  1639. }
  1640. template < class _num, class _ntr >
  1641. inline matrix<_num,_ntr> &
  1642. matrix<_num,_ntr>::operator *= (
  1643. const quaternion<_num,_ntr> & _q
  1644. )
  1645. {
  1646. (*this) *= _q.get_as_matrix();
  1647. return (*this);
  1648. }
  1649. template < class _num, class _ntr >
  1650. inline matrix<_num,_ntr> operator * (
  1651. const matrix<_num,_ntr> & _mtx,
  1652. const quaternion<_num,_ntr> & _q
  1653. )
  1654. {
  1655. matrix<_num,_ntr> _ret_val = _mtx;
  1656. _ret_val *= _q;
  1657. return _ret_val;
  1658. }
  1659. template < class _num, class _ntr >
  1660. inline matrix<_num,_ntr>
  1661. vector3<_num,_ntr>::get_as_scale() const
  1662. {
  1663. _mt _mtx;
  1664. _mtx.load_scale( *this );
  1665. return _mtx;
  1666. }
  1667. template < class _num, class _ntr >
  1668. inline matrix<_num,_ntr>
  1669. vector3<_num,_ntr>::get_as_translation() const
  1670. {
  1671. _mt _mtx;
  1672. _mtx.load_translation( *this );
  1673. return _mtx;
  1674. }
  1675. template < class _num, class _ntr >
  1676. inline matrix<_num,_ntr>
  1677. vector3<_num,_ntr>::get_as_rotation_xyz() const
  1678. {
  1679. _mt _mtx;
  1680. _mtx.load_rotation_xyz( *this );
  1681. return _mtx;
  1682. }
  1683. template < class _num, class _ntr >
  1684. inline matrix<_num,_ntr>
  1685. vector3<_num,_ntr>::get_as_rotation_quaternion() const
  1686. {
  1687. quaternion<_num,_ntr> _q( *this );
  1688. return _q.get_as_matrix();
  1689. }
  1690. }; // namespace gltl
  1691. // rollback warning C4201
  1692. #pragma warning( pop )
  1693. #endif // __GLTL_H