fork download
  1. #ifndef FURROVINERMATRIX4_H
  2. #define FURROVINERMATRIX4_H
  3.  
  4. #include <Furrovine++/Core.h>
  5. #include <Furrovine++/Quaternion.h>
  6.  
  7. namespace Furrovine {
  8.  
  9. template <typename T> struct RMatrix4 {
  10. public:
  11.  
  12. union {
  13.  
  14. struct {
  15. #ifdef FURROVINEMATRIX_ROWMAJOR
  16. T m11, m12, m13, m14,
  17. m21, m22, m23, m24,
  18. m31, m32, m33, m34,
  19. m41, m42, m43, m44;
  20. #else
  21. T m11, m21, m31, m41,
  22. m12, m22, m32, m42,
  23. m13, m23, m33, m43,
  24. m14, m24, m34, m44;
  25. #endif /* FURROVINEMATRIX_ROWMAJOR */
  26. };
  27.  
  28. T m[16];
  29.  
  30. struct {
  31. typename MatrixTraits<T>::TApi4 api;
  32. };
  33.  
  34. RVector4<T> rows[4];
  35. };
  36.  
  37. RMatrix4<T>& Set ( T x11 = T(1), T x21 = T(0), T x31 = T(0), T x41 = T(0),
  38. T x12 = T(0), T x22 = T(1), T x32 = T(0), T x42 = T(0),
  39. T x13 = T(0), T x23 = T(0), T x33 = T(1), T x43 = T(0),
  40. T x14 = T(0), T x24 = T(0), T x34 = T(0), T x44 = T(1) ) {
  41. m11 = x11;
  42. m12 = x12;
  43. m13 = x13;
  44. m14 = x14;
  45. m21 = x21;
  46. m22 = x22;
  47. m23 = x23;
  48. m24 = x24;
  49. m31 = x31;
  50. m32 = x32;
  51. m33 = x33;
  52. m34 = x34;
  53. m41 = x41;
  54. m42 = x42;
  55. m43 = x43;
  56. m44 = x44;
  57. return *this;
  58. }
  59.  
  60. RMatrix4<T>& Set ( bool memorder,
  61. T x01, T x02, T x03, T x04,
  62. T x05, T x06, T x07, T x08,
  63. T x09, T x10, T x11, T x12,
  64. T x13, T x14, T x15, T x16 ) {
  65. m[0] = x01;
  66. m[1] = x02;
  67. m[2] = x03;
  68. m[3] = x04;
  69. m[4] = x05;
  70. m[5] = x06;
  71. m[6] = x07;
  72. m[7] = x08;
  73. m[8] = x09;
  74. m[9] = x10;
  75. m[10] = x11;
  76. m[11] = x12;
  77. m[12] = x13;
  78. m[13] = x14;
  79. m[14] = x15;
  80. m[15] = x16;
  81. return *this;
  82. }
  83.  
  84. void Identify () {
  85. m12 = m13 = m14 = m21 = m23 = m24 = m31 = m32 = m34 = m41 = m42 = m43 = 0;
  86. m11 = m22 = m33 = m44 = (T)1;
  87. }
  88.  
  89. RMatrix4<T> Clone () {
  90. RMatrix4<T> r;
  91. memcpy(m, r.m, sizeof(T) * 16);
  92. return r;
  93. }
  94.  
  95. RMatrix4<T>& Clone (const RMatrix4<T>& obj) {
  96. memcpy(m, obj.m, sizeof(T) * 16);
  97. return *this;
  98. }
  99.  
  100. RMatrix4<T>& Transpose () {
  101. Mem::Swap<T>(m12, m21);
  102. Mem::Swap<T>(m13, m31);
  103. Mem::Swap<T>(m14, m41);
  104.  
  105. Mem::Swap<T>(m32, m23);
  106. Mem::Swap<T>(m34, m43);
  107.  
  108. Mem::Swap<T>(m42, m24);
  109.  
  110. return *this;
  111. }
  112.  
  113. TVector3<T> Transform (const TVector3<T>& source) {
  114. return *this * source;
  115. }
  116.  
  117. TVector4<T> Transform (const TVector4<T>& source) {
  118. return *this * source;
  119. }
  120.  
  121. void Transform (const TVector3<T>& source, TVector3<T>& out) {
  122. T w = m[4 * 1 - 1] * source.x +
  123. m[4 * 2 - 1] * source.y +
  124. m[4 * 3 - 1] * source.z +
  125. m[4 * 4 - 1];
  126.  
  127. out.x = m[1 * 1 - 1] * source.x +
  128. m[1 * 2 - 1] * source.y +
  129. m[1 * 3 - 1] * source.z +
  130. m[1 * 4 - 1];
  131. out.y = m[2 * 1 - 1] * source.x +
  132. m[2 * 2 - 1] * source.y +
  133. m[2 * 3 - 1] * source.z +
  134. m[2 * 4 - 1];
  135. out.z = m[3 * 1 - 1] * source.x +
  136. m[3 * 2 - 1] * source.y +
  137. m[3 * 3 - 1] * source.z +
  138. m[3 * 4 - 1];
  139.  
  140. out /= w;
  141. }
  142.  
  143. void Transform (const TVector4<T>& source, TVector4<T>& out) {
  144. out.x = m[1 * 1 - 1] * source.x +
  145. m[1 * 2 - 1] * source.y +
  146. m[1 * 3 - 1] * source.z +
  147. m[1 * 4 - 1] * source.w;
  148. out.y = m[2 * 1 - 1] * source.x +
  149. m[2 * 2 - 1] * source.y +
  150. m[2 * 3 - 1] * source.z +
  151. m[2 * 4 - 1] * source.w;
  152. out.z = m[3 * 1 - 1] * source.x +
  153. m[3 * 2 - 1] * source.y +
  154. m[3 * 3 - 1] * source.z +
  155. m[3 * 4 - 1] * source.w;
  156. out.w = m[4 * 1 - 1] * source.x +
  157. m[4 * 2 - 1] * source.y +
  158. m[4 * 3 - 1] * source.z +
  159. m[4 * 4 - 1] * source.w;
  160. }
  161.  
  162. void Transform (const TVector4<T>& source, TVector3<T>& out) {
  163. T w = m[4 * 1 - 1] * source.x +
  164. m[4 * 2 - 1] * source.y +
  165. m[4 * 3 - 1] * source.z +
  166. m[4 * 4 - 1] * source.w;
  167.  
  168. out.x = m[1 * 1 - 1] * source.x +
  169. m[1 * 2 - 1] * source.y +
  170. m[1 * 3 - 1] * source.z +
  171. m[1 * 4 - 1] * source.w;
  172. out.y = m[2 * 1 - 1] * source.x +
  173. m[2 * 2 - 1] * source.y +
  174. m[2 * 3 - 1] * source.z +
  175. m[2 * 4 - 1] * source.w;
  176. out.z = m[3 * 1 - 1] * source.x +
  177. m[3 * 2 - 1] * source.y +
  178. m[3 * 3 - 1] * source.z +
  179. m[3 * 4 - 1] * source.w;
  180.  
  181. out /= w;
  182. }
  183.  
  184. TVector3<T> Transform (const TVector3<T>& source) const {
  185. return *this * source;
  186. }
  187.  
  188. TVector4<T> Transform (const TVector4<T>& source) const {
  189. return *this * source;
  190. }
  191.  
  192. void Transform (const TVector3<T>& source, TVector3<T>& out) const {
  193. T w = m[4 * 1 - 1] * source.x +
  194. m[4 * 2 - 1] * source.y +
  195. m[4 * 3 - 1] * source.z +
  196. m[4 * 4 - 1];
  197.  
  198. out.x = m[1 * 1 - 1] * source.x +
  199. m[1 * 2 - 1] * source.y +
  200. m[1 * 3 - 1] * source.z +
  201. m[1 * 4 - 1];
  202. out.y = m[2 * 1 - 1] * source.x +
  203. m[2 * 2 - 1] * source.y +
  204. m[2 * 3 - 1] * source.z +
  205. m[2 * 4 - 1];
  206. out.z = m[3 * 1 - 1] * source.x +
  207. m[3 * 2 - 1] * source.y +
  208. m[3 * 3 - 1] * source.z +
  209. m[3 * 4 - 1];
  210.  
  211. out /= w;
  212. }
  213.  
  214. void Transform (const TVector4<T>& source, TVector4<T>& out) const {
  215. out.x = m[1 * 1 - 1] * source.x +
  216. m[1 * 2 - 1] * source.y +
  217. m[1 * 3 - 1] * source.z +
  218. m[1 * 4 - 1] * source.w;
  219. out.y = m[2 * 1 - 1] * source.x +
  220. m[2 * 2 - 1] * source.y +
  221. m[2 * 3 - 1] * source.z +
  222. m[2 * 4 - 1] * source.w;
  223. out.z = m[3 * 1 - 1] * source.x +
  224. m[3 * 2 - 1] * source.y +
  225. m[3 * 3 - 1] * source.z +
  226. m[3 * 4 - 1] * source.w;
  227. out.w = m[4 * 1 - 1] * source.x +
  228. m[4 * 2 - 1] * source.y +
  229. m[4 * 3 - 1] * source.z +
  230. m[4 * 4 - 1] * source.w;
  231. }
  232.  
  233. void Transform (const TVector4<T>& source, TVector3<T>& out) const {
  234. T w = m[4 * 1 - 1] * source.x +
  235. m[4 * 2 - 1] * source.y +
  236. m[4 * 3 - 1] * source.z +
  237. m[4 * 4 - 1] * source.w;
  238.  
  239. out.x = m[1 * 1 - 1] * source.x +
  240. m[1 * 2 - 1] * source.y +
  241. m[1 * 3 - 1] * source.z +
  242. m[1 * 4 - 1] * source.w;
  243. out.y = m[2 * 1 - 1] * source.x +
  244. m[2 * 2 - 1] * source.y +
  245. m[2 * 3 - 1] * source.z +
  246. m[2 * 4 - 1] * source.w;
  247. out.z = m[3 * 1 - 1] * source.x +
  248. m[3 * 2 - 1] * source.y +
  249. m[3 * 3 - 1] * source.z +
  250. m[3 * 4 - 1] * source.w;
  251.  
  252. out /= w;
  253. }
  254.  
  255. T Determinant () {
  256. T a0 = m[0] * m[5] - m[1] * m[4];
  257. T a1 = m[0] * m[6] - m[2] * m[4];
  258. T a2 = m[0] * m[7] - m[3] * m[4];
  259. T a3 = m[1] * m[6] - m[2] * m[5];
  260. T a4 = m[1] * m[7] - m[3] * m[5];
  261. T a5 = m[2] * m[7] - m[3] * m[6];
  262. T b0 = m[8] * m[13] - m[9] * m[12];
  263. T b1 = m[8] * m[14] - m[10] * m[12];
  264. T b2 = m[8] * m[15] - m[11] * m[12];
  265. T b3 = m[9] * m[14] - m[10] * m[13];
  266. T b4 = m[9] * m[15] - m[11] * m[13];
  267. T b5 = m[10] * m[15] - m[11] * m[14];
  268.  
  269. T det = a0*b5 - a1*b4 + a2*b3 + a3*b2 - a4*b1 + a5*b0;
  270.  
  271. return det;
  272. }
  273.  
  274. RMatrix4<T> Inverse () {
  275. T a0 = m[0] * m[5] - m[1] * m[4];
  276. T a1 = m[0] * m[6] - m[2] * m[4];
  277. T a2 = m[0] * m[7] - m[3] * m[4];
  278. T a3 = m[1] * m[6] - m[2] * m[5];
  279. T a4 = m[1] * m[7] - m[3] * m[5];
  280. T a5 = m[2] * m[7] - m[3] * m[6];
  281. T b0 = m[8] * m[13] - m[9] * m[12];
  282. T b1 = m[8] * m[14] - m[10] * m[12];
  283. T b2 = m[8] * m[15] - m[11] * m[12];
  284. T b3 = m[9] * m[14] - m[10] * m[13];
  285. T b4 = m[9] * m[15] - m[11] * m[13];
  286. T b5 = m[10] * m[15] - m[11] * m[14];
  287.  
  288. T det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
  289. RMatrix4<T> inverse;
  290. if (Mathema<T>::Abs(det) > T(0)) {
  291. inverse.m[0] = + m[5] * b5 - m[6] * b4 + m[7] * b3;
  292. inverse.m[4] = - m[4] * b5 + m[6] * b2 - m[7] * b1;
  293. inverse.m[8] = + m[4] * b4 - m[5] * b2 + m[7] * b0;
  294. inverse.m[12] = - m[4] * b3 + m[5] * b1 - m[6] * b0;
  295. inverse.m[1] = - m[1] * b5 + m[2] * b4 - m[3] * b3;
  296. inverse.m[5] = + m[0] * b5 - m[2] * b2 + m[3] * b1;
  297. inverse.m[9] = - m[0] * b4 + m[1] * b2 - m[3] * b0;
  298. inverse.m[13] = + m[0] * b3 - m[1] * b1 + m[2] * b0;
  299. inverse.m[2] = + m[13] * a5 - m[14] * a4 + m[15] * a3;
  300. inverse.m[6] = - m[12] * a5 + m[14] * a2 - m[15] * a1;
  301. inverse.m[10] = + m[12] * a4 - m[13] * a2 + m[15] * a0;
  302. inverse.m[14] = - m[12] * a3 + m[13] * a1 - m[14] * a0;
  303. inverse.m[3] = - m[9] * a5 + m[10] * a4 - m[11] * a3;
  304. inverse.m[7] = + m[8] * a5 - m[10] * a2 + m[11] * a1;
  305. inverse.m[11] = - m[8] * a4 + m[9] * a2 - m[11] * a0;
  306. inverse.m[15] = + m[8] * a3 - m[9] * a1 + m[10] * a0;
  307.  
  308. T invDet = (T(1)) / det;
  309. inverse.m[0] *= invDet;
  310. inverse.m[1] *= invDet;
  311. inverse.m[2] *= invDet;
  312. inverse.m[3] *= invDet;
  313. inverse.m[4] *= invDet;
  314. inverse.m[5] *= invDet;
  315. inverse.m[6] *= invDet;
  316. inverse.m[7] *= invDet;
  317. inverse.m[8] *= invDet;
  318. inverse.m[9] *= invDet;
  319. inverse.m[10] *= invDet;
  320. inverse.m[11] *= invDet;
  321. inverse.m[12] *= invDet;
  322. inverse.m[13] *= invDet;
  323. inverse.m[14] *= invDet;
  324. inverse.m[15] *= invDet;
  325.  
  326. return inverse;
  327. }
  328. inverse.Identify();
  329. return inverse;
  330. }
  331.  
  332. bool Invert () {
  333. T a0 = m[0] * m[5] - m[1] * m[4];
  334. T a1 = m[0] * m[6] - m[2] * m[4];
  335. T a2 = m[0] * m[7] - m[3] * m[4];
  336. T a3 = m[1] * m[6] - m[2] * m[5];
  337. T a4 = m[1] * m[7] - m[3] * m[5];
  338. T a5 = m[2] * m[7] - m[3] * m[6];
  339. T b0 = m[8] * m[13] - m[9] * m[12];
  340. T b1 = m[8] * m[14] - m[10] * m[12];
  341. T b2 = m[8] * m[15] - m[11] * m[12];
  342. T b3 = m[9] * m[14] - m[10] * m[13];
  343. T b4 = m[9] * m[15] - m[11] * m[13];
  344. T b5 = m[10] * m[15] - m[11] * m[14];
  345.  
  346. T det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
  347. if (Mathema<T>::Abs(det) > T(0)) {
  348. RMatrix4<T> inverse;
  349. inverse.m[0] = + m[5] * b5 - m[6] * b4 + m[7] * b3;
  350. inverse.m[4] = - m[4] * b5 + m[6] * b2 - m[7] * b1;
  351. inverse.m[8] = + m[4] * b4 - m[5] * b2 + m[7] * b0;
  352. inverse.m[12] = - m[4] * b3 + m[5] * b1 - m[6] * b0;
  353. inverse.m[1] = - m[1] * b5 + m[2] * b4 - m[3] * b3;
  354. inverse.m[5] = + m[0] * b5 - m[2] * b2 + m[3] * b1;
  355. inverse.m[9] = - m[0] * b4 + m[1] * b2 - m[3] * b0;
  356. inverse.m[13] = + m[0] * b3 - m[1] * b1 + m[2] * b0;
  357. inverse.m[2] = + m[13] * a5 - m[14] * a4 + m[15] * a3;
  358. inverse.m[6] = - m[12] * a5 + m[14] * a2 - m[15] * a1;
  359. inverse.m[10] = + m[12] * a4 - m[13] * a2 + m[15] * a0;
  360. inverse.m[14] = - m[12] * a3 + m[13] * a1 - m[14] * a0;
  361. inverse.m[3] = - m[9] * a5 + m[10] * a4 - m[11] * a3;
  362. inverse.m[7] = + m[8] * a5 - m[10] * a2 + m[11] * a1;
  363. inverse.m[11] = - m[8] * a4 + m[9] * a2 - m[11] * a0;
  364. inverse.m[15] = + m[8] * a3 - m[9] * a1 + m[10] * a0;
  365.  
  366. T invDet = (T(1)) / det;
  367. inverse.m[0] *= invDet;
  368. inverse.m[1] *= invDet;
  369. inverse.m[2] *= invDet;
  370. inverse.m[3] *= invDet;
  371. inverse.m[4] *= invDet;
  372. inverse.m[5] *= invDet;
  373. inverse.m[6] *= invDet;
  374. inverse.m[7] *= invDet;
  375. inverse.m[8] *= invDet;
  376. inverse.m[9] *= invDet;
  377. inverse.m[10] *= invDet;
  378. inverse.m[11] *= invDet;
  379. inverse.m[12] *= invDet;
  380. inverse.m[13] *= invDet;
  381. inverse.m[14] *= invDet;
  382. inverse.m[15] *= invDet;
  383.  
  384. Clone(inverse);
  385.  
  386. return true;
  387. }
  388.  
  389. return false;
  390. }
  391.  
  392. void Decompose (TVector3<T>& outscale, TQuaternion<T>& outrotate, TVector3<T>& outtranslation) {
  393. T mdiag = Mathema<T>::Sqrt(m[0] + m[5] + m[10] + m[15]);
  394. T mdiag2 = 2 * mdiag;
  395. #ifdef FURROVINEMATRIX_ROWMAJOR
  396. outscale.x = Mathema<T>::Sqrt(m11 * m11 + m21 * m21 * m31 * m31);
  397. outscale.y = Mathema<T>::Sqrt(m12 * m12 + m22 * m22 * m32 * m32);
  398. outscale.z = Mathema<T>::Sqrt(m13 * m13 + m23 * m23 * m33 * m33);
  399. outtranslation.x = m14;
  400. outtranslation.y = m24;
  401. outtranslation.z = m34;
  402. outrotate.x = (m[6] - m[9]) / mdiag2;
  403. outrotate.y = (m[8] - m[2]) / mdiag2;
  404. outrotate.z = (m[1] - m[4]) / mdiag2;
  405. outrotate.w = mdiag / 2;
  406. #else
  407. outtranslation.x = m[3];
  408. outtranslation.y = m[7];
  409. outtranslation.z = m[11];
  410. outscale.x = Mathema<T>::Sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
  411. outscale.y = Mathema<T>::Sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
  412. outscale.z = Mathema<T>::Sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
  413. outrotate.x = (m[6] - m[9]) / mdiag2;
  414. outrotate.y = (m[8] - m[2]) / mdiag2;
  415. outrotate.z = (m[1] - m[4]) / mdiag2;
  416. outrotate.w = mdiag / 2;
  417. #endif
  418. }
  419.  
  420. void Decompose (TVector3<T>& outscale, TVector3<T>& outrotate, TVector3<T>& ouTranslate) {
  421. #ifdef FURROVINEMATRIX_ROWMAJOR
  422. outscale.x = Mathema<T>::Sqrt(m11 * m11 + m21 * m21 * m31 * m31);
  423. outscale.y = Mathema<T>::Sqrt(m12 * m12 + m22 * m22 * m32 * m32);
  424. outscale.z = Mathema<T>::Sqrt(m13 * m13 + m23 * m23 * m33 * m33);
  425. ouTranslate.x = m14;
  426. ouTranslate.y = m24;
  427. ouTranslate.z = m34;
  428. outrotate.x = (m[6] - m[9]) / mdiag2;
  429. outrotate.y = (m[8] - m[2]) / mdiag2;
  430. outrotate.z = (m[1] - m[4]) / mdiag2;
  431. outrotate.w = mdiag / 2;
  432. #else
  433. ouTranslate.x = m[3];
  434. ouTranslate.y = m[7];
  435. ouTranslate.z = m[11];
  436. outscale.x = Mathema<T>::Sqrt(m[0] * m[0] + m[1] * m[1] + m[2] * m[2]);
  437. outscale.y = Mathema<T>::Sqrt(m[4] * m[4] + m[5] * m[5] + m[6] * m[6]);
  438. outscale.z = Mathema<T>::Sqrt(m[8] * m[8] + m[9] * m[9] + m[10] * m[10]);
  439. outrotate.y = Mathema<T>::Asin(-m[8]);
  440. T theta = Mathema<T>::Cos(outrotate.y);
  441. outrotate.x = Mathema<T>::Asin(Mathema<T>::Mod(m[9] / theta, T(1)) );
  442. outrotate.z = Mathema<T>::Asin(Mathema<T>::Mod(m[4] / theta, T(1)) );
  443. #endif
  444. }
  445.  
  446. RMatrix4<T> operator+ (const RMatrix4<T>& right) const {
  447. RMatrix4<T> r = {
  448. m[0] + right.m[0],
  449. m[1] + right.m[1],
  450. m[2] + right.m[2],
  451. m[3] + right.m[3],
  452. m[4] + right.m[4],
  453. m[5] + right.m[5],
  454. m[6] + right.m[6],
  455. m[7] + right.m[7],
  456. m[8] + right.m[8],
  457. m[9] + right.m[9],
  458. m[10] + right.m[10],
  459. m[11] + right.m[11],
  460. m[12] + right.m[12],
  461. m[13] + right.m[13],
  462. m[14] + right.m[14],
  463. m[15] + right.m[15]
  464. };
  465. return r;
  466. }
  467.  
  468. RMatrix4<T> operator- (const RMatrix4<T>& right) const {
  469. RMatrix4<T> r = {
  470. m[0] - right.m[0],
  471. m[1] - right.m[1],
  472. m[2] - right.m[2],
  473. m[3] - right.m[3],
  474. m[4] - right.m[4],
  475. m[5] - right.m[5],
  476. m[6] - right.m[6],
  477. m[7] - right.m[7],
  478. m[8] - right.m[8],
  479. m[9] - right.m[9],
  480. m[10] - right.m[10],
  481. m[11] - right.m[11],
  482. m[12] - right.m[12],
  483. m[13] - right.m[13],
  484. m[14] - right.m[14],
  485. m[15] - right.m[15]
  486. };
  487. return r;
  488. }
  489.  
  490. RMatrix4<T> operator* (const T& right) const {
  491. RMatrix4<T> r = {
  492. m[0] * right,
  493. m[1] * right,
  494. m[2] * right,
  495. m[3] * right,
  496. m[4] * right,
  497. m[5] * right,
  498. m[6] * right,
  499. m[7] * right,
  500. m[8] * right,
  501. m[9] * right,
  502. m[10] * right,
  503. m[11] * right,
  504. m[12] * right,
  505. m[13] * right,
  506. m[14] * right,
  507. m[15] * right
  508. };
  509. return r;
  510. }
  511.  
  512. RMatrix4<T> operator/ (const T& right) const {
  513. if (right == T(0)) {
  514. RMatrix4<T> z = { 0 };
  515. return z;
  516. }
  517. T invright = (T(1)) / right;
  518. RMatrix4<T> r = {
  519. m[0] * invright,
  520. m[1] * invright,
  521. m[2] * invright,
  522. m[3] * invright,
  523. m[4] * invright,
  524. m[5] * invright,
  525. m[6] * invright,
  526. m[7] * invright,
  527. m[8] * invright,
  528. m[9] * invright,
  529. m[10] * invright,
  530. m[11] * invright,
  531. m[12] * invright,
  532. m[13] * invright,
  533. m[14] * invright,
  534. m[15] * invright };
  535.  
  536. return r;
  537. }
  538.  
  539. RMatrix4<T>& operator+= (const RMatrix4<T>& right) {
  540. m[0] += right.m[0];
  541. m[1] += right.m[1];
  542. m[2] += right.m[2];
  543. m[3] += right.m[3];
  544. m[4] += right.m[4];
  545. m[5] += right.m[5];
  546. m[6] += right.m[6];
  547. m[7] += right.m[7];
  548. m[8] += right.m[8];
  549. m[9] += right.m[9];
  550. m[10] += right.m[10];
  551. m[11] += right.m[11];
  552. m[12] += right.m[12];
  553. m[13] += right.m[13];
  554. m[14] += right.m[14];
  555. m[15] += right.m[15];
  556.  
  557. return *this;
  558. }
  559.  
  560. RMatrix4<T>& operator-= (const RMatrix4<T>& right) {
  561. m[0] -= right.m[0];
  562. m[1] -= right.m[1];
  563. m[2] -= right.m[2];
  564. m[3] -= right.m[3];
  565. m[4] -= right.m[4];
  566. m[5] -= right.m[5];
  567. m[6] -= right.m[6];
  568. m[7] -= right.m[7];
  569. m[8] -= right.m[8];
  570. m[9] -= right.m[9];
  571. m[10] -= right.m[10];
  572. m[11] -= right.m[11];
  573. m[12] -= right.m[12];
  574. m[13] -= right.m[13];
  575. m[14] -= right.m[14];
  576. m[15] -= right.m[15];
  577.  
  578. return *this;
  579. }
  580.  
  581. RMatrix4<T>& operator*= (const T& right) {
  582. m[0] *= right;
  583. m[1] *= right;
  584. m[2] *= right;
  585. m[3] *= right;
  586. m[4] *= right;
  587. m[5] *= right;
  588. m[6] *= right;
  589. m[7] *= right;
  590. m[8] *= right;
  591. m[9] *= right;
  592. m[10] *= right;
  593. m[11] *= right;
  594. m[12] *= right;
  595. m[13] *= right;
  596. m[14] *= right;
  597. m[15] *= right;
  598.  
  599. return *this;
  600. }
  601.  
  602. RMatrix4<T>& operator/= (const T& right) {
  603. if (right == T(0))
  604. return *this;
  605.  
  606. T invright = (T(1)) / right;
  607. m[0] *= invright;
  608. m[1] *= invright;
  609. m[2] *= invright;
  610. m[3] *= invright;
  611. m[4] *= invright;
  612. m[5] *= invright;
  613. m[6] *= invright;
  614. m[7] *= invright;
  615. m[8] *= invright;
  616. m[9] *= invright;
  617. m[10] *= invright;
  618. m[11] *= invright;
  619. m[12] *= invright;
  620. m[13] *= invright;
  621. m[14] *= invright;
  622. m[15] *= invright;
  623.  
  624. return *this;
  625. }
  626.  
  627. TVector4<T> operator* ( const TVector4<T>& right ) {
  628. return TVector4<T>(
  629. m[1 * 1 - 1] * right.x +
  630. m[1 * 2 - 1] * right.y +
  631. m[1 * 3 - 1] * right.z +
  632. m[1 * 4 - 1] * right.w,
  633.  
  634. m[2 * 1 - 1] * right.x +
  635. m[2 * 2 - 1] * right.y +
  636. m[2 * 3 - 1] * right.z +
  637. m[2 * 4 - 1] * right.w,
  638.  
  639. m[3 * 1 - 1] * right.x +
  640. m[3 * 2 - 1] * right.y +
  641. m[3 * 3 - 1] * right.z +
  642. m[3 * 4 - 1] * right.w,
  643.  
  644. m[4 * 1 - 1] * right.x +
  645. m[4 * 2 - 1] * right.y +
  646. m[4 * 3 - 1] * right.z +
  647. m[4 * 4 - 1] * right.w
  648. );
  649. }
  650.  
  651. TVector3<T> operator* ( const TVector3<T>& right ) {
  652. return TVector3<T> (
  653. m[1 * 1 - 1] * right.x +
  654. m[1 * 2 - 1] * right.y +
  655. m[1 * 3 - 1] * right.z +
  656. m[1 * 4 - 1],
  657.  
  658. m[2 * 1 - 1] * right.x +
  659. m[2 * 2 - 1] * right.y +
  660. m[2 * 3 - 1] * right.z +
  661. m[2 * 4 - 1],
  662.  
  663. m[3 * 1 - 1] * right.x +
  664. m[3 * 2 - 1] * right.y +
  665. m[3 * 3 - 1] * right.z +
  666. m[3 * 4 - 1],
  667.  
  668. m[4 * 1 - 1] * right.x +
  669. m[4 * 2 - 1] * right.y +
  670. m[4 * 3 - 1] * right.z +
  671. m[4 * 4 - 1]
  672. );
  673. }
  674.  
  675. RMatrix4<T> operator* ( const RMatrix4<T>& right ) {
  676. RMatrix4<T> r = {
  677. (right.m[1 * 1 - 1] * m[1 * 1 - 1] + right.m[1 * 2 - 1] * m[2 * 1 - 1] + right.m[1 * 3 - 1] * m[3 * 1 - 1] + right.m[1 * 4 - 1] * m[4 * 1 - 1]),
  678. (right.m[1 * 1 - 1] * m[1 * 2 - 1] + right.m[1 * 2 - 1] * m[2 * 2 - 1] + right.m[1 * 3 - 1] * m[3 * 2 - 1] + right.m[1 * 4 - 1] * m[4 * 2 - 1]),
  679. (right.m[1 * 1 - 1] * m[1 * 3 - 1] + right.m[1 * 2 - 1] * m[2 * 3 - 1] + right.m[1 * 3 - 1] * m[3 * 3 - 1] + right.m[1 * 4 - 1] * m[4 * 3 - 1]),
  680. (right.m[1 * 1 - 1] * m[1 * 4 - 1] + right.m[1 * 2 - 1] * m[2 * 4 - 1] + right.m[1 * 3 - 1] * m[3 * 4 - 1] + right.m[1 * 4 - 1] * m[4 * 4 - 1]),
  681. (right.m[2 * 1 - 1] * m[1 * 1 - 1] + right.m[2 * 2 - 1] * m[2 * 1 - 1] + right.m[2 * 3 - 1] * m[3 * 1 - 1] + right.m[2 * 4 - 1] * m[4 * 1 - 1]),
  682. (right.m[2 * 1 - 1] * m[1 * 2 - 1] + right.m[2 * 2 - 1] * m[2 * 2 - 1] + right.m[2 * 3 - 1] * m[3 * 2 - 1] + right.m[2 * 4 - 1] * m[4 * 2 - 1]),
  683. (right.m[2 * 1 - 1] * m[1 * 3 - 1] + right.m[2 * 2 - 1] * m[2 * 3 - 1] + right.m[2 * 3 - 1] * m[3 * 3 - 1] + right.m[2 * 4 - 1] * m[4 * 3 - 1]),
  684. (right.m[2 * 1 - 1] * m[1 * 4 - 1] + right.m[2 * 2 - 1] * m[2 * 4 - 1] + right.m[2 * 3 - 1] * m[3 * 4 - 1] + right.m[2 * 4 - 1] * m[4 * 4 - 1]),
  685. (right.m[3 * 1 - 1] * m[1 * 1 - 1] + right.m[3 * 2 - 1] * m[2 * 1 - 1] + right.m[3 * 3 - 1] * m[3 * 1 - 1] + right.m[3 * 4 - 1] * m[4 * 1 - 1]),
  686. (right.m[3 * 1 - 1] * m[1 * 2 - 1] + right.m[3 * 2 - 1] * m[2 * 2 - 1] + right.m[3 * 3 - 1] * m[3 * 2 - 1] + right.m[3 * 4 - 1] * m[4 * 2 - 1]),
  687. (right.m[3 * 1 - 1] * m[1 * 3 - 1] + right.m[3 * 2 - 1] * m[2 * 3 - 1] + right.m[3 * 3 - 1] * m[3 * 3 - 1] + right.m[3 * 4 - 1] * m[4 * 3 - 1]),
  688. (right.m[3 * 1 - 1] * m[1 * 4 - 1] + right.m[3 * 2 - 1] * m[2 * 4 - 1] + right.m[3 * 3 - 1] * m[3 * 4 - 1] + right.m[3 * 4 - 1] * m[4 * 4 - 1]),
  689. (right.m[4 * 1 - 1] * m[1 * 1 - 1] + right.m[4 * 2 - 1] * m[2 * 1 - 1] + right.m[4 * 3 - 1] * m[3 * 1 - 1] + right.m[4 * 4 - 1] * m[4 * 1 - 1]),
  690. (right.m[4 * 1 - 1] * m[1 * 2 - 1] + right.m[4 * 2 - 1] * m[2 * 2 - 1] + right.m[4 * 3 - 1] * m[3 * 2 - 1] + right.m[4 * 4 - 1] * m[4 * 2 - 1]),
  691. (right.m[4 * 1 - 1] * m[1 * 3 - 1] + right.m[4 * 2 - 1] * m[2 * 3 - 1] + right.m[4 * 3 - 1] * m[3 * 3 - 1] + right.m[4 * 4 - 1] * m[4 * 3 - 1]),
  692. (right.m[4 * 1 - 1] * m[1 * 4 - 1] + right.m[4 * 2 - 1] * m[2 * 4 - 1] + right.m[4 * 3 - 1] * m[3 * 4 - 1] + right.m[4 * 4 - 1] * m[4 * 4 - 1])
  693. };
  694. return r;
  695. }
  696.  
  697. RMatrix4<T>& operator*= ( const RMatrix4<T>& right ) {
  698. T out[16] = {
  699. right.m[1 * 1 - 1] * m[1 * 1 - 1] + right.m[1 * 2 - 1] * m[2 * 1 - 1] + right.m[1 * 3 - 1] * m[3 * 1 - 1] + right.m[1 * 4 - 1] * m[4 * 1 - 1],
  700. right.m[1 * 1 - 1] * m[1 * 2 - 1] + right.m[1 * 2 - 1] * m[2 * 2 - 1] + right.m[1 * 3 - 1] * m[3 * 2 - 1] + right.m[1 * 4 - 1] * m[4 * 2 - 1],
  701. right.m[1 * 1 - 1] * m[1 * 3 - 1] + right.m[1 * 2 - 1] * m[2 * 3 - 1] + right.m[1 * 3 - 1] * m[3 * 3 - 1] + right.m[1 * 4 - 1] * m[4 * 3 - 1],
  702. right.m[1 * 1 - 1] * m[1 * 4 - 1] + right.m[1 * 2 - 1] * m[2 * 4 - 1] + right.m[1 * 3 - 1] * m[3 * 4 - 1] + right.m[1 * 4 - 1] * m[4 * 4 - 1],
  703. right.m[2 * 1 - 1] * m[1 * 1 - 1] + right.m[2 * 2 - 1] * m[2 * 1 - 1] + right.m[2 * 3 - 1] * m[3 * 1 - 1] + right.m[2 * 4 - 1] * m[4 * 1 - 1],
  704. right.m[2 * 1 - 1] * m[1 * 2 - 1] + right.m[2 * 2 - 1] * m[2 * 2 - 1] + right.m[2 * 3 - 1] * m[3 * 2 - 1] + right.m[2 * 4 - 1] * m[4 * 2 - 1],
  705. right.m[2 * 1 - 1] * m[1 * 3 - 1] + right.m[2 * 2 - 1] * m[2 * 3 - 1] + right.m[2 * 3 - 1] * m[3 * 3 - 1] + right.m[2 * 4 - 1] * m[4 * 3 - 1],
  706. right.m[2 * 1 - 1] * m[1 * 4 - 1] + right.m[2 * 2 - 1] * m[2 * 4 - 1] + right.m[2 * 3 - 1] * m[3 * 4 - 1] + right.m[2 * 4 - 1] * m[4 * 4 - 1],
  707. right.m[3 * 1 - 1] * m[1 * 1 - 1] + right.m[3 * 2 - 1] * m[2 * 1 - 1] + right.m[3 * 3 - 1] * m[3 * 1 - 1] + right.m[3 * 4 - 1] * m[4 * 1 - 1],
  708. right.m[3 * 1 - 1] * m[1 * 2 - 1] + right.m[3 * 2 - 1] * m[2 * 2 - 1] + right.m[3 * 3 - 1] * m[3 * 2 - 1] + right.m[3 * 4 - 1] * m[4 * 2 - 1],
  709. right.m[3 * 1 - 1] * m[1 * 3 - 1] + right.m[3 * 2 - 1] * m[2 * 3 - 1] + right.m[3 * 3 - 1] * m[3 * 3 - 1] + right.m[3 * 4 - 1] * m[4 * 3 - 1],
  710. right.m[3 * 1 - 1] * m[1 * 4 - 1] + right.m[3 * 2 - 1] * m[2 * 4 - 1] + right.m[3 * 3 - 1] * m[3 * 4 - 1] + right.m[3 * 4 - 1] * m[4 * 4 - 1],
  711. right.m[4 * 1 - 1] * m[1 * 1 - 1] + right.m[4 * 2 - 1] * m[2 * 1 - 1] + right.m[4 * 3 - 1] * m[3 * 1 - 1] + right.m[4 * 4 - 1] * m[4 * 1 - 1],
  712. right.m[4 * 1 - 1] * m[1 * 2 - 1] + right.m[4 * 2 - 1] * m[2 * 2 - 1] + right.m[4 * 3 - 1] * m[3 * 2 - 1] + right.m[4 * 4 - 1] * m[4 * 2 - 1],
  713. right.m[4 * 1 - 1] * m[1 * 3 - 1] + right.m[4 * 2 - 1] * m[2 * 3 - 1] + right.m[4 * 3 - 1] * m[3 * 3 - 1] + right.m[4 * 4 - 1] * m[4 * 3 - 1],
  714. right.m[4 * 1 - 1] * m[1 * 4 - 1] + right.m[4 * 2 - 1] * m[2 * 4 - 1] + right.m[4 * 3 - 1] * m[3 * 4 - 1] + right.m[4 * 4 - 1] * m[4 * 4 - 1]
  715. };
  716.  
  717. memcpy(m, out, sizeof(T) * 16);
  718.  
  719. return *this;
  720. }
  721.  
  722. bool operator== ( const RMatrix4<T>& right ) {
  723. return m[0] == right.m[0] &&
  724. m[1] == right.m[1] &&
  725. m[2] == right.m[2] &&
  726. m[3] == right.m[3] &&
  727. m[4] == right.m[4] &&
  728. m[5] == right.m[5] &&
  729. m[6] == right.m[6] &&
  730. m[7] == right.m[7] &&
  731. m[8] == right.m[8] &&
  732. m[9] == right.m[9] &&
  733. m[10] == right.m[10] &&
  734. m[11] == right.m[11] &&
  735. m[12] == right.m[12] &&
  736. m[13] == right.m[13] &&
  737. m[14] == right.m[14] &&
  738. m[15] == right.m[15];
  739. }
  740.  
  741. bool operator!= ( const RMatrix4<T>& right ) {
  742. return !(*this == right);
  743. }
  744.  
  745. bool operator== ( T* right ) {
  746. return m[0] == right[0] &&
  747. m[1] == right[1] &&
  748. m[2] == right[2] &&
  749. m[3] == right[3] &&
  750. m[4] == right[4] &&
  751. m[5] == right[5] &&
  752. m[6] == right[6] &&
  753. m[7] == right[7] &&
  754. m[8] == right[8] &&
  755. m[9] == right[9] &&
  756. m[10] == right[10] &&
  757. m[11] == right[11] &&
  758. m[12] == right[12] &&
  759. m[13] == right[13] &&
  760. m[14] == right[14] &&
  761. m[15] == right[15];
  762. }
  763.  
  764. bool operator!= ( T* right ) {
  765. return !(*this == right);
  766. }
  767.  
  768. bool Equals (const RMatrix4<T>& right) {
  769. return m[0] == right.m[0] &&
  770. m[1] == right.m[1] &&
  771. m[2] == right.m[2] &&
  772. m[3] == right.m[3] &&
  773. m[4] == right.m[4] &&
  774. m[5] == right.m[5] &&
  775. m[6] == right.m[6] &&
  776. m[7] == right.m[7] &&
  777. m[8] == right.m[8] &&
  778. m[9] == right.m[9] &&
  779. m[10] == right.m[10] &&
  780. m[11] == right.m[11] &&
  781. m[12] == right.m[12] &&
  782. m[13] == right.m[13] &&
  783. m[14] == right.m[14] &&
  784. m[15] == right.m[15];
  785. }
  786.  
  787. TVector4<T> operator* ( const TVector4<T>& right ) const {
  788. return TVector4<T> (
  789. m11 * right.x +
  790. m12 * right.y +
  791. m13 * right.z +
  792. m14 * right.w,
  793.  
  794. m21 * right.x +
  795. m22 * right.y +
  796. m23 * right.z +
  797. m24 * right.w,
  798.  
  799. m31 * right.x +
  800. m32 * right.y +
  801. m33 * right.z +
  802. m34 * right.w,
  803.  
  804. m41 * right.x +
  805. m42 * right.y +
  806. m43 * right.z +
  807. m44 * right.w
  808. );
  809. }
  810.  
  811. TVector3<T> operator* ( const TVector3<T>& right ) const {
  812. return TVector3<T> (
  813. m11 * right.x +
  814. m12 * right.y +
  815. m13 * right.z +
  816. m14,
  817.  
  818. m21 * right.x +
  819. m22 * right.y +
  820. m23 * right.z +
  821. m24,
  822.  
  823. m31 * right.x +
  824. m32 * right.y +
  825. m33 * right.z +
  826. m34,
  827.  
  828. m41 * right.x +
  829. m42 * right.y +
  830. m43 * right.z +
  831. m44
  832. );
  833. }
  834.  
  835. RMatrix4<T> operator* ( const RMatrix4<T>& right ) const {
  836. RMatrix4<T> r = { m[0] * right.m[0] +
  837. m[1] * right.m[4] +
  838. m[2] * right.m[8] +
  839. m[3] * right.m[12],
  840.  
  841. m[0] * right.m[1] +
  842. m[1] * right.m[5] +
  843. m[2] * right.m[9] +
  844. m[3] * right.m[13],
  845.  
  846. m[0] * right.m[2] +
  847. m[1] * right.m[6] +
  848. m[2] * right.m[10] +
  849. m[3] * right.m[14],
  850.  
  851. m[0] * right.m[3] +
  852. m[1] * right.m[7] +
  853. m[2] * right.m[11] +
  854. m[3] * right.m[15],
  855.  
  856. m[4] * right.m[0] +
  857. m[5] * right.m[4] +
  858. m[6] * right.m[8] +
  859. m[7] * right.m[12],
  860.  
  861. m[4] * right.m[1] +
  862. m[5] * right.m[5] +
  863. m[6] * right.m[9] +
  864. m[7] * right.m[13],
  865.  
  866. m[4] * right.m[2] +
  867. m[5] * right.m[6] +
  868. m[6] * right.m[10] +
  869. m[7] * right.m[14],
  870.  
  871. m[4] * right.m[3] +
  872. m[5] * right.m[7] +
  873. m[6] * right.m[11] +
  874. m[7] * right.m[15],
  875.  
  876. m[8] * right.m[0] +
  877. m[9] * right.m[4] +
  878. m[10] * right.m[8] +
  879. m[11] * right.m[12],
  880.  
  881. m[8] * right.m[1] +
  882. m[9] * right.m[5] +
  883. m[10] * right.m[9] +
  884. m[11] * right.m[13],
  885.  
  886. m[8] * right.m[2] +
  887. m[9] * right.m[6] +
  888. m[10] * right.m[10] +
  889. m[11] * right.m[14],
  890.  
  891. m[8] * right.m[3] +
  892. m[9] * right.m[7] +
  893. m[10] * right.m[11] +
  894. m[11] * right.m[15],
  895.  
  896. m[12] * right.m[0] +
  897. m[13] * right.m[4] +
  898. m[14] * right.m[8] +
  899. m[15] * right.m[12],
  900.  
  901. m[12] * right.m[1] +
  902. m[13] * right.m[5] +
  903. m[14] * right.m[9] +
  904. m[15] * right.m[13],
  905.  
  906. m[12] * right.m[2] +
  907. m[13] * right.m[6] +
  908. m[14] * right.m[10] +
  909. m[15] * right.m[14],
  910.  
  911. m[12] * right.m[3] +
  912. m[13] * right.m[7] +
  913. m[14] * right.m[11] +
  914. m[15] * right.m[15]
  915. };
  916. return r;
  917. }
  918.  
  919. bool operator== ( const RMatrix4<T>& right ) const {
  920. return memcmp(m, right.m, sizeof(T) * 16) == 0;
  921. }
  922.  
  923. bool operator!= ( const RMatrix4<T>& right ) const {
  924. return memcmp(m, right.m, sizeof(T) * 16) != 0;
  925. }
  926.  
  927. bool operator== ( T* right ) const {
  928. return memcmp(m, right, sizeof(T) * 16) == 0;
  929. }
  930.  
  931. bool operator!= ( T* right ) const {
  932. return memcmp(m, right, sizeof(T) * 16) != 0;
  933. }
  934.  
  935. operator T* () const {
  936. return (T*)m;
  937. }
  938.  
  939. T& operator[] (int index) {
  940. return m[index];
  941. }
  942.  
  943. T& operator() (int column, int row) {
  944. return m[row * 4 + column];
  945. }
  946.  
  947. static TVector3<T> Transform (const RMatrix4<T>& matrix, const TVector3<T>& source) {
  948. return matrix * source;
  949. }
  950.  
  951. static TVector4<T> Transform (const RMatrix4<T>& matrix, const TVector4<T>& source) {
  952. return matrix * source;
  953. }
  954.  
  955. static RMatrix4<T> Transpose (const RMatrix4<T>& matrix) {
  956. RMatrix4<T> r = {
  957. matrix.m[0],
  958. matrix.m[4],
  959. matrix.m[8],
  960. matrix.m[12],
  961. matrix.m[1],
  962. matrix.m[5],
  963. matrix.m[9],
  964. matrix.m[13],
  965. matrix.m[2],
  966. matrix.m[6],
  967. matrix.m[10],
  968. matrix.m[14],
  969. matrix.m[3],
  970. matrix.m[7],
  971. matrix.m[11],
  972. matrix.m[15]
  973. };
  974. return r;
  975. }
  976.  
  977. static RMatrix4<T> Adjoint (const RMatrix4<T>& matrix) {
  978. T a0 = matrix.m[0] * matrix.m[5] - matrix.m[1] * matrix.m[4];
  979. T a1 = matrix.m[0] * matrix.m[6] - matrix.m[2] * matrix.m[4];
  980. T a2 = matrix.m[0] * matrix.m[7] - matrix.m[3] * matrix.m[4];
  981. T a3 = matrix.m[1] * matrix.m[6] - matrix.m[2] * matrix.m[5];
  982. T a4 = matrix.m[1] * matrix.m[7] - matrix.m[3] * matrix.m[5];
  983. T a5 = matrix.m[2] * matrix.m[7] - matrix.m[3] * matrix.m[6];
  984. T b0 = matrix.m[8] * matrix.m[13] - matrix.m[9] * matrix.m[12];
  985. T b1 = matrix.m[8] * matrix.m[14] - matrix.m[10] * matrix.m[12];
  986. T b2 = matrix.m[8] * matrix.m[15] - matrix.m[11] * matrix.m[12];
  987. T b3 = matrix.m[9] * matrix.m[14] - matrix.m[10] * matrix.m[13];
  988. T b4 = matrix.m[9] * matrix.m[15] - matrix.m[11] * matrix.m[13];
  989. T b5 = matrix.m[10] * matrix.m[15] - matrix.m[11] * matrix.m[14];
  990.  
  991. RMatrix4<T> r = {
  992. + matrix.m[5] * b5 - matrix.m[6] * b4 + matrix.m[7] * b3,
  993. - matrix.m[1] * b5 + matrix.m[2] * b4 - matrix.m[3] * b3,
  994. + matrix.m[13] * a5 - matrix.m[14] * a4 + matrix.m[15] * a3,
  995. - matrix.m[9] * a5 + matrix.m[10] * a4 - matrix.m[11] * a3,
  996. - matrix.m[4] * b5 + matrix.m[6] * b2 - matrix.m[7] * b1,
  997. + matrix.m[0] * b5 - matrix.m[2] * b2 + matrix.m[3] * b1,
  998. - matrix.m[12] * a5 + matrix.m[14] * a2 - matrix.m[15] * a1,
  999. + matrix.m[8] * a5 - matrix.m[10] * a2 + matrix.m[11] * a1,
  1000. + matrix.m[4] * b4 - matrix.m[5] * b2 + matrix.m[7] * b0,
  1001. - matrix.m[0] * b4 + matrix.m[1] * b2 - matrix.m[3] * b0,
  1002. + matrix.m[12] * a4 - matrix.m[13] * a2 + matrix.m[15] * a0,
  1003. - matrix.m[8] * a4 + matrix.m[9] * a2 - matrix.m[11] * a0,
  1004. - matrix.m[4] * b3 + matrix.m[5] * b1 - matrix.m[6] * b0,
  1005. + matrix.m[0] * b3 - matrix.m[1] * b1 + matrix.m[2] * b0,
  1006. - matrix.m[12] * a3 + matrix.m[13] * a1 - matrix.m[14] * a0,
  1007. + matrix.m[8] * a3 - matrix.m[9] * a1 + matrix.m[10] * a0
  1008. };
  1009. return r;
  1010. }
  1011.  
  1012. static RMatrix4<T> Inverse (const RMatrix4<T>& matrix) {
  1013. T a0 = matrix.m[0] * matrix.m[5] - matrix.m[1] * matrix.m[4];
  1014. T a1 = matrix.m[0] * matrix.m[6] - matrix.m[2] * matrix.m[4];
  1015. T a2 = matrix.m[0] * matrix.m[7] - matrix.m[3] * matrix.m[4];
  1016. T a3 = matrix.m[1] * matrix.m[6] - matrix.m[2] * matrix.m[5];
  1017. T a4 = matrix.m[1] * matrix.m[7] - matrix.m[3] * matrix.m[5];
  1018. T a5 = matrix.m[2] * matrix.m[7] - matrix.m[3] * matrix.m[6];
  1019. T b0 = matrix.m[8] * matrix.m[13] - matrix.m[9] * matrix.m[12];
  1020. T b1 = matrix.m[8] * matrix.m[14] - matrix.m[10] * matrix.m[12];
  1021. T b2 = matrix.m[8] * matrix.m[15] - matrix.m[11] * matrix.m[12];
  1022. T b3 = matrix.m[9] * matrix.m[14] - matrix.m[10] * matrix.m[13];
  1023. T b4 = matrix.m[9] * matrix.m[15] - matrix.m[11] * matrix.m[13];
  1024. T b5 = matrix.m[10] * matrix.m[15] - matrix.m[11] * matrix.m[14];
  1025.  
  1026. T det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
  1027. RMatrix4<T> inverse = { 0 };
  1028. if (Mathema<T>::Abs(det) > T(0)) {
  1029. inverse.m[0] = + matrix.m[5] * b5 - matrix.m[6] * b4 + matrix.m[7] * b3;
  1030. inverse.m[4] = - matrix.m[4] * b5 + matrix.m[6] * b2 - matrix.m[7] * b1;
  1031. inverse.m[8] = + matrix.m[4] * b4 - matrix.m[5] * b2 + matrix.m[7] * b0;
  1032. inverse.m[12] = - matrix.m[4] * b3 + matrix.m[5] * b1 - matrix.m[6] * b0;
  1033. inverse.m[1] = - matrix.m[1] * b5 + matrix.m[2] * b4 - matrix.m[3] * b3;
  1034. inverse.m[5] = + matrix.m[0] * b5 - matrix.m[2] * b2 + matrix.m[3] * b1;
  1035. inverse.m[9] = - matrix.m[0] * b4 + matrix.m[1] * b2 - matrix.m[3] * b0;
  1036. inverse.m[13] = + matrix.m[0] * b3 - matrix.m[1] * b1 + matrix.m[2] * b0;
  1037. inverse.m[2] = + matrix.m[13] * a5 - matrix.m[14] * a4 + matrix.m[15] * a3;
  1038. inverse.m[6] = - matrix.m[12] * a5 + matrix.m[14] * a2 - matrix.m[15] * a1;
  1039. inverse.m[10] = + matrix.m[12] * a4 - matrix.m[13] * a2 + matrix.m[15] * a0;
  1040. inverse.m[14] = - matrix.m[12] * a3 + matrix.m[13] * a1 - matrix.m[14] * a0;
  1041. inverse.m[3] = - matrix.m[9] * a5 + matrix.m[10] * a4 - matrix.m[11] * a3;
  1042. inverse.m[7] = + matrix.m[8] * a5 - matrix.m[10] * a2 + matrix.m[11] * a1;
  1043. inverse.m[11] = - matrix.m[8] * a4 + matrix.m[9] * a2 - matrix.m[11] * a0;
  1044. inverse.m[15] = + matrix.m[8] * a3 - matrix.m[9] * a1 + matrix.m[10] * a0;
  1045.  
  1046. T invDet = (T(1)) / det;
  1047. inverse.m[0] *= invDet;
  1048. inverse.m[1] *= invDet;
  1049. inverse.m[2] *= invDet;
  1050. inverse.m[3] *= invDet;
  1051. inverse.m[4] *= invDet;
  1052. inverse.m[5] *= invDet;
  1053. inverse.m[6] *= invDet;
  1054. inverse.m[7] *= invDet;
  1055. inverse.m[8] *= invDet;
  1056. inverse.m[9] *= invDet;
  1057. inverse.m[10] *= invDet;
  1058. inverse.m[11] *= invDet;
  1059. inverse.m[12] *= invDet;
  1060. inverse.m[13] *= invDet;
  1061. inverse.m[14] *= invDet;
  1062. inverse.m[15] *= invDet;
  1063.  
  1064. }
  1065.  
  1066. return inverse;
  1067. }
  1068.  
  1069. static bool Invert (const RMatrix4<T>& matrix, RMatrix4<T>& out) {
  1070. T a0 = matrix.m[0] * matrix.m[5] - matrix.m[1] * matrix.m[4];
  1071. T a1 = matrix.m[0] * matrix.m[6] - matrix.m[2] * matrix.m[4];
  1072. T a2 = matrix.m[0] * matrix.m[7] - matrix.m[3] * matrix.m[4];
  1073. T a3 = matrix.m[1] * matrix.m[6] - matrix.m[2] * matrix.m[5];
  1074. T a4 = matrix.m[1] * matrix.m[7] - matrix.m[3] * matrix.m[5];
  1075. T a5 = matrix.m[2] * matrix.m[7] - matrix.m[3] * matrix.m[6];
  1076. T b0 = matrix.m[8] * matrix.m[13] - matrix.m[9] * matrix.m[12];
  1077. T b1 = matrix.m[8] * matrix.m[14] - matrix.m[10] * matrix.m[12];
  1078. T b2 = matrix.m[8] * matrix.m[15] - matrix.m[11] * matrix.m[12];
  1079. T b3 = matrix.m[9] * matrix.m[14] - matrix.m[10] * matrix.m[13];
  1080. T b4 = matrix.m[9] * matrix.m[15] - matrix.m[11] * matrix.m[13];
  1081. T b5 = matrix.m[10] * matrix.m[15] - matrix.m[11] * matrix.m[14];
  1082.  
  1083. T det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
  1084. if (Mathema<T>::Abs(det) > T(0)) {
  1085. out.m[0] = + matrix.m[5] * b5 - matrix.m[6] * b4 + matrix.m[7] * b3;
  1086. out.m[4] = - matrix.m[4] * b5 + matrix.m[6] * b2 - matrix.m[7] * b1;
  1087. out.m[8] = + matrix.m[4] * b4 - matrix.m[5] * b2 + matrix.m[7] * b0;
  1088. out.m[12] = - matrix.m[4] * b3 + matrix.m[5] * b1 - matrix.m[6] * b0;
  1089. out.m[1] = - matrix.m[1] * b5 + matrix.m[2] * b4 - matrix.m[3] * b3;
  1090. out.m[5] = + matrix.m[0] * b5 - matrix.m[2] * b2 + matrix.m[3] * b1;
  1091. out.m[9] = - matrix.m[0] * b4 + matrix.m[1] * b2 - matrix.m[3] * b0;
  1092. out.m[13] = + matrix.m[0] * b3 - matrix.m[1] * b1 + matrix.m[2] * b0;
  1093. out.m[2] = + matrix.m[13] * a5 - matrix.m[14] * a4 + matrix.m[15] * a3;
  1094. out.m[6] = - matrix.m[12] * a5 + matrix.m[14] * a2 - matrix.m[15] * a1;
  1095. out.m[10] = + matrix.m[12] * a4 - matrix.m[13] * a2 + matrix.m[15] * a0;
  1096. out.m[14] = - matrix.m[12] * a3 + matrix.m[13] * a1 - matrix.m[14] * a0;
  1097. out.m[3] = - matrix.m[9] * a5 + matrix.m[10] * a4 - matrix.m[11] * a3;
  1098. out.m[7] = + matrix.m[8] * a5 - matrix.m[10] * a2 + matrix.m[11] * a1;
  1099. out.m[11] = - matrix.m[8] * a4 + matrix.m[9] * a2 - matrix.m[11] * a0;
  1100. out.m[15] = + matrix.m[8] * a3 - matrix.m[9] * a1 + matrix.m[10] * a0;
  1101.  
  1102. T invDet = (T(1)) / det;
  1103. out.m[0] *= invDet;
  1104. out.m[1] *= invDet;
  1105. out.m[2] *= invDet;
  1106. out.m[3] *= invDet;
  1107. out.m[4] *= invDet;
  1108. out.m[5] *= invDet;
  1109. out.m[6] *= invDet;
  1110. out.m[7] *= invDet;
  1111. out.m[8] *= invDet;
  1112. out.m[9] *= invDet;
  1113. out.m[10] *= invDet;
  1114. out.m[11] *= invDet;
  1115. out.m[12] *= invDet;
  1116. out.m[13] *= invDet;
  1117. out.m[14] *= invDet;
  1118. out.m[15] *= invDet;
  1119.  
  1120. return true;
  1121. }
  1122.  
  1123. return false;
  1124. }
  1125.  
  1126. static RMatrix4<T> CreateTranslation (T dx, T dy, T dz) {
  1127. RMatrix4<T> r = { T(1), T(0), T(0), T(0),
  1128. T(0), T(1), T(0), T(0),
  1129. T(0), T(0), T(1), T(0),
  1130. dx, dy, dz, T(1)};
  1131. return r;
  1132. }
  1133.  
  1134. static RMatrix4<T> CreateTranslation (const TVector3<T>& translation) {
  1135. return CreateTranslation(translation.x, translation.y, translation.z);
  1136. }
  1137.  
  1138. static RMatrix4<T> CreateRotationX (T radians) {
  1139. T cosa = Mathema<T>::Cos(radians);
  1140. T sina = Mathema<T>::Sin(radians);
  1141. RMatrix4<T> r = {
  1142. T(1), T(0), T(0), T(0),
  1143. T(0), cosa, -sina, T(0),
  1144. T(0), sina, cosa, T(0),
  1145. T(0), T(0), T(0), T(1)};
  1146. return r;
  1147. }
  1148.  
  1149. static RMatrix4<T> CreateRotationY (T radians) {
  1150. T cosa = Mathema<T>::Cos(radians);
  1151. T sina = Mathema<T>::Sin(radians);
  1152. RMatrix4<T> r = {
  1153. cosa, T(0), sina, T(0),
  1154. T(0), T(1), T(0), T(0),
  1155. -sina, T(0), cosa, T(0),
  1156. T(0), T(0), T(0), T(1) };
  1157. return r;
  1158. }
  1159.  
  1160. static RMatrix4<T> CreateRotationZ (T radians) {
  1161. T cosa = Mathema<T>::Cos(radians);
  1162. T sina = Mathema<T>::Sin(radians);
  1163. RMatrix4<T> r = {
  1164. cosa, -sina, T(0), T(0),
  1165. sina, cosa, T(0), T(0),
  1166. T(0), T(0), T(1), T(0),
  1167. T(0), T(0), T(0), T(1) };
  1168. return r;
  1169. }
  1170.  
  1171. static RMatrix4<T> CreateRotation (T xradians, T yradians, T zradians) {
  1172. T xcos = Mathema<T>::Cos(xradians);
  1173. T xsin = Mathema<T>::Sin(xradians);
  1174. T zcos = Mathema<T>::Cos(zradians);
  1175. T zsin = Mathema<T>::Sin(zradians);
  1176. T ycos = Mathema<T>::Cos(yradians);
  1177. T ysin = Mathema<T>::Sin(yradians);
  1178. RMatrix4<T> r = {
  1179. ycos * zcos, -xcos * zsin + xsin * ysin * zcos, xsin * zsin + xcos * ysin * zcos, T(0),
  1180. ycos * zsin, xcos * zcos + xsin * ysin * zsin, -xsin * zcos + xcos * ysin * zsin, T(0),
  1181. ysin, xsin * ycos, xcos * ycos, T(0),
  1182. T(0), T(0), T(0), T(1) };
  1183. return r;
  1184. }
  1185.  
  1186. static RMatrix4<T> CreateRotation (const TVector3<T>& yawpitchroll) {
  1187. return CreateRotation(yawpitchroll.x, yawpitchroll.y, yawpitchroll.z);
  1188. }
  1189.  
  1190. static RMatrix4<T> CreateRotationAxis (TVector3<T> axis, T radians) {
  1191. axis.Normalize();
  1192. T cosa = Mathema<T>::Cos(radians);
  1193. T sina = Mathema<T>::Sin(radians);
  1194. T affcosa = T(1) - cosa;
  1195. RMatrix4<T> r = {
  1196. (axis.x * axis.x) * affcosa + cosa, (axis.x * axis.y) * affcosa - (axis.z * sina), (axis.x * axis.z) * affcosa + (axis.y * sina), T(0),
  1197. (axis.y * axis.x) * affcosa + (axis.z * sina), (axis.y * axis.y) * affcosa + cosa, (axis.y * axis.z) * affcosa - (axis.x * sina), T(0),
  1198. (axis.z * axis.x) * affcosa - (axis.y * sina), (axis.z * axis.y) * affcosa + (axis.x * sina), (axis.z * axis.z) * affcosa + cosa, T(0),
  1199. T(0), T(0), T(0), T(1) };
  1200. return r;
  1201. }
  1202.  
  1203. static RMatrix4<T> CreateRotationQuaternion (const TQuaternion<T>& quaternion) {
  1204. T w2 = castto(T, quaternion.w * quaternion.w);
  1205. T x2 = castto(T, quaternion.x * quaternion.x);
  1206. T y2 = castto(T, quaternion.y * quaternion.y);
  1207. T z2 = castto(T, quaternion.z * quaternion.z);
  1208. T dx = castto(T, 2 * quaternion.x);
  1209. T dy = castto(T, 2 * quaternion.y);
  1210. T dw = castto(T, 2 * quaternion.w);
  1211. RMatrix4<T> r = {
  1212. w2 + x2 - y2 - z2, dx * quaternion.y - dw * quaternion.z, dx * quaternion.z + dw * quaternion.y, T(0),
  1213. dx * quaternion.y + dw * quaternion.z, w2 - x2 + y2 - z2, dy * quaternion.z + dw * quaternion.x, T(0),
  1214. dx * quaternion.z - dw * quaternion.y, dy * quaternion.z - dw * quaternion.x, w2 - x2 - y2 + z2, T(0),
  1215. T(0), T(0), T(0), T(1) };
  1216. return r;
  1217. }
  1218.  
  1219. static RMatrix4<T> CreateScale (T sx, T sy, T sz) {
  1220. RMatrix4<T> r = {
  1221. sx, T(0), T(0), T(0),
  1222. T(0), sy, T(0), T(0),
  1223. T(0), T(0), sz, T(0),
  1224. T(0), T(0), T(0), T(1) };
  1225. return r;
  1226. }
  1227.  
  1228. static RMatrix4<T> CreateScale (T s) {
  1229. return CreateScale(s, s, s);
  1230. }
  1231.  
  1232. static RMatrix4<T> CreateScale (const TVector3<T>& s) {
  1233. return CreateScale(s.x, s.y, s.z);
  1234. }
  1235.  
  1236. static RMatrix4<T> CreateScale (T sx, T sy, T sz, const TVector3<T>& origin) {
  1237. RMatrix4<T> r = {
  1238. sx, T(0), T(0), origin.x * (T(1) - sx),
  1239. T(0), sy, T(0), origin.y * (T(1) - sy),
  1240. T(0), T(0), sz, origin.z * (T(1) - sz),
  1241. T(0), T(0), T(0), T(1) };
  1242. return r;
  1243. }
  1244.  
  1245. static RMatrix4<T> CreateScale (T s, const TVector3<T>& origin) {
  1246. return CreateScale(s, s, s, origin);
  1247. }
  1248.  
  1249. static RMatrix4<T> CreateScale (const TVector3<T>& s, const TVector3<T>& origin) {
  1250. return CreateScale(s.x, s.y, s.z, origin);
  1251. }
  1252.  
  1253. static RMatrix4<T> CreateReflectionX () {
  1254. RMatrix4<T> r = {
  1255. -T(1), T(0), T(0), T(0),
  1256. T(0), T(1), T(0), T(0),
  1257. T(0), T(0), T(1), T(0),
  1258. T(0), T(0), T(0), T(1) };
  1259. return r;
  1260. }
  1261.  
  1262. static RMatrix4<T> CreateReflectionY () {
  1263. RMatrix4<T> r = {
  1264. T(1), T(0), T(0), T(0),
  1265. T(0), -T(1), T(0), T(0),
  1266. T(0), T(0), T(1), T(0),
  1267. T(0), T(0), T(0), T(1) };
  1268. return r;
  1269. }
  1270.  
  1271. static RMatrix4<T> CreateReflectionZ () {
  1272. RMatrix4<T> r = {
  1273. T(1), T(0), T(0), T(0),
  1274. T(0), T(1), T(0), T(0),
  1275. T(0), T(0), -T(1), T(0),
  1276. T(0), T(0), T(0), T(1) };
  1277. return r;
  1278. }
  1279.  
  1280. static RMatrix4<T> CreateReflection (const TVector3<T>& normal, const TVector3<T>& origin) {
  1281. T doubledotnormorigin = ((T)2) * (normal.Dot(origin));
  1282. RMatrix4<T> r = {
  1283. T(1) - ((T)2) * normal[0] * normal[0],
  1284. -((T)2) * normal[0] * normal[1],
  1285. -((T)2) * normal[0] * normal[2],
  1286. doubledotnormorigin * normal[0],
  1287. -((T)2) * normal[1] * normal[0],
  1288. T(1) - ((T)2) * normal[1] * normal[1],
  1289. -((T)2) * normal[1] * normal[2],
  1290. doubledotnormorigin * normal[1],
  1291. -((T)2) * normal[2] * normal[0],
  1292. -((T)2) * normal[2] * normal[1],
  1293. T(1) - ((T)2) * normal[2] * normal[2],
  1294. doubledotnormorigin * normal[2],
  1295. T(0),
  1296. T(0),
  1297. T(0),
  1298. T(1)
  1299. };
  1300. return r;
  1301. }
  1302.  
  1303. static RMatrix4<T> CreateObliqueProjection (const TVector3<T>& normal, const TVector3<T>& origin, const TVector3<T>& direction) {
  1304. T normaldotdir = normal.Dot(direction);
  1305. T normaldotorigin = normal.Dot(origin);
  1306.  
  1307. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1308. RMatrix4<T> r = {
  1309. direction[0] * normal[0] - normaldotdir,
  1310. direction[0] * normal[1],
  1311. direction[0] * normal[2],
  1312. -normaldotorigin * direction[0],
  1313. direction[1] * normal[0],
  1314. direction[1] * normal[1] - normaldotdir,
  1315. direction[1] * normal[2],
  1316. -normaldotorigin * direction[1],
  1317. -direction[2] * normal[0],
  1318. -direction[2] * normal[1],
  1319. -direction[2] * normal[2] - normaldotdir,
  1320. normaldotorigin * direction[2],
  1321. T(0),
  1322. T(0),
  1323. T(0),
  1324. -normaldotdir
  1325. };
  1326. #else
  1327. RMatrix4<T> r = {
  1328. direction[0] * normal[0] - normaldotdir,
  1329. direction[0] * normal[1],
  1330. direction[0] * normal[2],
  1331. -normaldotorigin * direction[0],
  1332. direction[1] * normal[0],
  1333. direction[1] * normal[1] - normaldotdir,
  1334. direction[1] * normal[2],
  1335. -normaldotorigin * direction[1],
  1336. direction[2] * normal[0],
  1337. direction[2] * normal[1],
  1338. direction[2] * normal[2] - normaldotdir,
  1339. -normaldotorigin * direction[2],
  1340. T(0),
  1341. T(0),
  1342. T(0),
  1343. -normaldotdir
  1344. };
  1345. #endif
  1346.  
  1347. return r;
  1348. }
  1349.  
  1350. static RMatrix4<T> CreateOrthographicProjectionOffCenter ( T left, T right, T bottom, T top ) {
  1351. return CreateOrthographicProjectionOffCenter(left, right, bottom, top, (T)-1, (T)1 );
  1352. }
  1353.  
  1354. static RMatrix4<T> CreateOrthographicProjectionOffCenter ( T left, T right, T bottom, T top, T nearplane, T farplane ) {
  1355. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1356. RMatrix4<T> r = {
  1357. T(2) / (right - left), T(0), T(0), T(0),
  1358. T(0), T(2) / (top - bottom), T(0), T(0),
  1359. -T(0), -T(0), T(2) / (farplane - nearplane), -T(0),
  1360. - (right + left) / (right - left), - (top + bottom) / (top - bottom), - (farplane + nearplane) / (farplane - nearplane), T(1)
  1361. };
  1362. #else
  1363. RMatrix4<T> r = {
  1364. T(2) / (right - left), T(0), T(0), T(0),
  1365. T(0), T(2) / (top - bottom), T(0), T(0),
  1366. T(0), T(0), -T(2) / (farplane - nearplane), T(0),
  1367. - (right + left) / (right - left), - (top + bottom) / (top - bottom), - (farplane + nearplane) / (farplane - nearplane), T(1)
  1368. };
  1369. #endif
  1370. return r;
  1371. }
  1372.  
  1373. static RMatrix4<T> CreateOrthographicProjection ( T left, T right, T bottom, T top ) {
  1374. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1375. RMatrix4<T> r = {
  1376. T(2) / (right - left), T(0), T(0), T(0),
  1377. T(0), T(2) / (top - bottom), T(0), T(0),
  1378. -T(0), -T(0), T(1), -T(0),
  1379. - (right + left) / (right - left), - (top + bottom) / (top - bottom), T(0), T(1)
  1380. };
  1381. #else
  1382. RMatrix4<T> r = {
  1383. T(2) / (right - left), T(0), T(0), T(0),
  1384. T(0), T(2) / (top - bottom), T(0), T(0),
  1385. T(0), T(0), -T(1), T(0),
  1386. - (right + left) / (right - left), - (top + bottom) / (top - bottom), T(0), T(1)
  1387. };
  1388. #endif
  1389. return r;
  1390. }
  1391.  
  1392. static RMatrix4<T> CreatePerspectiveProjection ( T left, T right, T bottom, T top, T nearplane, T farplane ) {
  1393. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1394. RMatrix4<T> = r {
  1395. (T(2) * nearplane) / (right - left), T(0), (right + left) / (right - left), T(0),
  1396. T(0), (T(2) * nearplane) / (top - bottom), (top + bottom) / (top - bottom), T(0),
  1397. -T(0), -T(0), (farplane + nearplane) / (farplane - nearplane), (T(2) * farplane * nearplane) / (farplane - nearplane),
  1398. T(0), T(0), -T(1), T(0)
  1399. };
  1400. #else
  1401. RMatrix4<T> r = {
  1402. (T(2) * nearplane) / (right - left), T(0), (right + left) / (right - left), T(0),
  1403. T(0), (T(2) * nearplane) / (top - bottom), (top + bottom) / (top - bottom), T(0),
  1404. T(0), T(0), -(farplane + nearplane) / (farplane - nearplane), -(T(2) * farplane * nearplane) / (farplane - nearplane),
  1405. T(0), T(0), -T(1), T(0)
  1406. };
  1407. #endif
  1408. return r;
  1409. }
  1410.  
  1411. static RMatrix4<T> CreatePerspectiveProjection ( T fovy, T aspect, T nearplane, T farplane) {
  1412. T range = Mathema<T>::Tan(fovy / T(2)) * nearplane;
  1413. T left = -range * aspect;
  1414. T right = range * aspect;
  1415. T bottom = -range;
  1416. T top = range;
  1417. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1418. RMatrix4<T> r = {
  1419. (T(2) * nearplane) / (right - left), T(0), (right + left) / (right - left), T(0),
  1420. T(0), (T(2) * nearplane) / (top - bottom), (top + bottom) / (top - bottom), T(0),
  1421. -T(0), -T(0), (farplane + nearplane) / (farplane - nearplane), (T(2) * farplane * nearplane) / (farplane - nearplane),
  1422. T(0), T(0), -T(1), T(0)
  1423. };
  1424. #else
  1425. RMatrix4<T> r = {
  1426. (T(2) * nearplane) / (right - left), T(0), (right + left) / (right - left), T(0),
  1427. T(0), (T(2) * nearplane) / (top - bottom), (top + bottom) / (top - bottom), T(0),
  1428. T(0), T(0), -(farplane + nearplane) / (farplane - nearplane), -(T(2) * farplane * nearplane) / (farplane - nearplane),
  1429. T(0), T(0), -T(1), T(0)
  1430. };
  1431. #endif
  1432. return r;
  1433. }
  1434.  
  1435. static RMatrix4<T> CreatePerspectiveFoV ( T fov, T width, T height, T nearplane, T farplane) {
  1436. T rad = (T)Mathema<T>::Radians(fov);
  1437. T h = Mathema<T>::Cos(T(0.5) * rad) / Mathema<T>::Sin(T(0.5) * rad);
  1438. T w = h * height / width;
  1439.  
  1440. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1441. RMatrix4<T> r = {
  1442. w, T(0), T(0), T(0),
  1443. T(0), h, T(0), T(0),
  1444. -T(0), -T(0), (farplane + nearplane) / (farplane - nearplane), (T(2) * farplane * nearplane) / (farplane - nearplane),
  1445. T(0), T(0), -T(1), T(0)
  1446. };
  1447. #else
  1448. RMatrix4<T> r = {
  1449. w, T(0), T(0), T(0),
  1450. T(0), h, T(0), T(0),
  1451. T(0), T(0), -(farplane + nearplane) / (farplane - nearplane), -T(1),
  1452. T(0), T(0), -(T(2) * farplane * nearplane) / (farplane - nearplane), T(0)
  1453. };
  1454. #endif
  1455. return r;
  1456. }
  1457.  
  1458. static RMatrix4<T> CreateInfinitePerspective (T fovy, T aspect, T nearplane) {
  1459. T range = Mathema<T>::Tan(fovy / T(2)) * nearplane;
  1460. T left = -range * aspect;
  1461. T right = range * aspect;
  1462. T bottom = -range;
  1463. T top = range;
  1464.  
  1465. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1466. RMatrix4<T> r = {
  1467. (T(2) * nearplane) / (right - left), T(0), T(0), T(0),
  1468. T(0), (T(2) * nearplane) / (top - bottom), T(0), T(0),
  1469. -T(0), -T(0), T(1), T(1),
  1470. T(0), T(0), -T(2) * nearplane, T(0)
  1471. };
  1472. #else
  1473. RMatrix4<T> r = {
  1474. (T(2) * nearplane) / (right - left), T(0), T(0), T(0),
  1475. T(0), (T(2) * nearplane) / (top - bottom), T(0), T(0),
  1476. T(0), T(0), -T(1), -T(1),
  1477. T(0), T(0), -T(2) * nearplane, T(0)
  1478. };
  1479. #endif
  1480. return r;
  1481. }
  1482.  
  1483. static RMatrix4<T> CreateInfinitePerspective2 (T fovy, T aspect, T nearplane) {
  1484. T range = Mathema<T>::Tan((fovy / T(2))) * nearplane;
  1485. T left = -range * aspect;
  1486. T right = range * aspect;
  1487. T bottom = -range;
  1488. T top = range;
  1489. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1490. RMatrix4<T> r = {
  1491. (T(2) * nearplane) / (right - left), T(0), T(0), T(0),
  1492. T(0), (T(2) * nearplane) / (top - bottom), T(0), T(0),
  1493. -T(0), -T(0), T(0.0001) + T(1), T(1),
  1494. T(0), T(0), (T(0.0001) - T(2)) * nearplane, T(0)
  1495. };
  1496. #else
  1497. RMatrix4<T> r = {
  1498. (T(2) * nearplane) / (right - left), T(0), T(0), T(0),
  1499. T(0), (T(2) * nearplane) / (top - bottom), T(0), T(0),
  1500. T(0), T(0), T(0.0001) - T(1), -T(1),
  1501. T(0), T(0), (T(0.0001) - T(2)) * nearplane, T(0)
  1502. };
  1503. #endif
  1504. return r;
  1505. }
  1506.  
  1507. static RMatrix4<T> CreateLookAt ( const TVector3<T>& eye, const TVector3<T>& center, const TVector3<T>& up) {
  1508. TVector3<T> f = TVector3<T>::Normalize(center - eye);
  1509. TVector3<T> u = TVector3<T>::Normalize(up);
  1510. TVector3<T> s = TVector3<T>::Normalize(f.Cross(u));
  1511. u = s.Cross(f);
  1512.  
  1513. #ifdef FURROVINECOORDINATESYSTEM_LEFTHANDED
  1514. RMatrix4<T> r = {
  1515. s.x, s.y, s.z, -s.Dot(eye),
  1516. u.x, u.y, u.z, -u.Dot(eye),
  1517. f.x, f.y, f.z, -f.Dot(eye),
  1518. T(0), T(0), T(0), T(1)
  1519. };
  1520. #else
  1521. RMatrix4<T> r = {
  1522. s.x, s.y, s.z, -s.Dot(eye),
  1523. u.x, u.y, u.z, -u.Dot(eye),
  1524. f.x, f.y, f.z, -f.Dot(eye),
  1525. T(0), T(0), T(0), T(1)
  1526. };
  1527. #endif
  1528. return r;
  1529. }
  1530.  
  1531. static RMatrix4<T> CreateShearX (T dyradians, T dzradians) {
  1532. dyradians = Mathema<T>::Tan(dyradians);
  1533. dzradians = Mathema<T>::Tan(dzradians);
  1534. RMatrix4<T> r = {
  1535. T(1), dyradians, dzradians, T(0),
  1536. T(0), T(1), T(0), T(0),
  1537. T(0), T(0), T(1), T(0),
  1538. T(0), T(0), T(0), T(1) };
  1539. return r;
  1540. }
  1541.  
  1542. static RMatrix4<T> CreateShearX (T radians) {
  1543. radians = Mathema<T>::Tan(radians);
  1544. RMatrix4<T> r = {
  1545. T(1), radians, radians, T(0),
  1546. T(0), T(1), T(0), T(0),
  1547. T(0), T(0), T(1), T(0),
  1548. T(0), T(0), T(0), T(1) };
  1549. return r;
  1550. }
  1551.  
  1552. static RMatrix4<T> CreateShearY (T radians) {
  1553. radians = Mathema<T>::Tan(radians);
  1554. RMatrix4<T> r = {
  1555. T(1), T(0), T(0), T(0),
  1556. radians, T(1), radians, T(0),
  1557. T(0), T(0), T(1), T(0),
  1558. T(0), T(0), T(0), T(1) };
  1559. return r;
  1560. }
  1561.  
  1562. static RMatrix4<T> CreateShearY (T dxradians, T dzradians) {
  1563. dxradians = Mathema<T>::Tan(dxradians);
  1564. dzradians = Mathema<T>::Tan(dzradians);
  1565. RMatrix4<T> r = {
  1566. T(1), T(0), T(0), T(0),
  1567. dxradians, T(1), dzradians, T(0),
  1568. T(0), T(0), T(1), T(0),
  1569. T(0), T(0), T(0), T(1) };
  1570. return r;
  1571. }
  1572.  
  1573. static RMatrix4<T> CreateShearZ (T radians) {
  1574. radians = Mathema<T>::Tan(radians);
  1575. RMatrix4<T> r = {
  1576. T(1), T(0), T(0), T(0),
  1577. T(0), T(1), T(0), T(0),
  1578. radians, radians, T(1), T(0),
  1579. T(0), T(0), T(0), T(1) };
  1580. return r;
  1581. }
  1582.  
  1583. static RMatrix4<T> CreateShearZ (T dxradians, T dyradians) {
  1584. dxradians = Mathema<T>::Tan(dxradians);
  1585. dyradians = Mathema<T>::Tan(dyradians);
  1586. RMatrix4<T> r = {
  1587. T(1), T(0), T(0), T(0),
  1588. T(0), T(1), T(0), T(0),
  1589. dxradians, dyradians, T(1), T(0),
  1590. T(0), T(0), T(0), T(1) };
  1591. return r;
  1592. }
  1593.  
  1594. static RMatrix4<T> CreateShear (T xradians = T(0), T yradians = T(0), T zradians = T(0)) {
  1595. xradians = Mathema<T>::Tan(xradians);
  1596. yradians = Mathema<T>::Tan(yradians);
  1597. zradians = Mathema<T>::Tan(zradians);
  1598. RMatrix4<T> r = {
  1599. T(1), xradians, xradians, T(0),
  1600. yradians, T(1), yradians, T(0),
  1601. zradians, zradians, T(1), T(0),
  1602. T(0), T(0), T(0), T(1) };
  1603. return r;
  1604. }
  1605.  
  1606. static RMatrix4<T> CreateShear (const TVector3<T>& radians) {
  1607. return CreateShear(radians.x, radians.y, radians.z);
  1608. }
  1609.  
  1610. };
  1611.  
  1612. }
  1613.  
  1614. #endif /* FURROVINERMATRIX4_H */
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty