TSMatrix4x4.cs 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. /* Copyright (C) <2009-2011> <Thorben Linneweber, Jitter Physics>
  2. *
  3. * This software is provided 'as-is', without any express or implied
  4. * warranty. In no event will the authors be held liable for any damages
  5. * arising from the use of this software.
  6. *
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. *
  11. * 1. The origin of this software must not be misrepresented; you must not
  12. * claim that you wrote the original software. If you use this software
  13. * in a product, an acknowledgment in the product documentation would be
  14. * appreciated but is not required.
  15. * 2. Altered source versions must be plainly marked as such, and must not be
  16. * misrepresented as being the original software.
  17. * 3. This notice may not be removed or altered from any source distribution.
  18. */
  19. namespace TrueSync
  20. {
  21. /// <summary>
  22. /// 3x3 Matrix.
  23. /// </summary>
  24. public struct TSMatrix4x4
  25. {
  26. /// <summary>
  27. /// M11
  28. /// </summary>
  29. public FP M11; // 1st row vector
  30. /// <summary>
  31. /// M12
  32. /// </summary>
  33. public FP M12;
  34. /// <summary>
  35. /// M13
  36. /// </summary>
  37. public FP M13;
  38. /// <summary>
  39. /// M14
  40. /// </summary>
  41. public FP M14;
  42. /// <summary>
  43. /// M21
  44. /// </summary>
  45. public FP M21; // 2nd row vector
  46. /// <summary>
  47. /// M22
  48. /// </summary>
  49. public FP M22;
  50. /// <summary>
  51. /// M23
  52. /// </summary>
  53. public FP M23;
  54. /// <summary>
  55. /// M24
  56. /// </summary>
  57. public FP M24;
  58. /// <summary>
  59. /// M31
  60. /// </summary>
  61. public FP M31; // 3rd row vector
  62. /// <summary>
  63. /// M32
  64. /// </summary>
  65. public FP M32;
  66. /// <summary>
  67. /// M33
  68. /// </summary>
  69. public FP M33;
  70. /// <summary>
  71. /// M34
  72. /// </summary>
  73. public FP M34;
  74. /// <summary>
  75. /// M41
  76. /// </summary>
  77. public FP M41; // 4rd row vector
  78. /// <summary>
  79. /// M42
  80. /// </summary>
  81. public FP M42;
  82. /// <summary>
  83. /// M43
  84. /// </summary>
  85. public FP M43;
  86. /// <summary>
  87. /// M44
  88. /// </summary>
  89. public FP M44;
  90. internal static TSMatrix4x4 InternalIdentity;
  91. /// <summary>
  92. /// Identity matrix.
  93. /// </summary>
  94. public static readonly TSMatrix4x4 Identity;
  95. public static readonly TSMatrix4x4 Zero;
  96. static TSMatrix4x4()
  97. {
  98. Zero = new TSMatrix4x4();
  99. Identity = new TSMatrix4x4();
  100. Identity.M11 = FP.One;
  101. Identity.M22 = FP.One;
  102. Identity.M33 = FP.One;
  103. Identity.M44 = FP.One;
  104. InternalIdentity = Identity;
  105. }
  106. /// <summary>
  107. /// Initializes a new instance of the matrix structure.
  108. /// </summary>
  109. /// <param name="m11">m11</param>
  110. /// <param name="m12">m12</param>
  111. /// <param name="m13">m13</param>
  112. /// <param name="m14">m14</param>
  113. /// <param name="m21">m21</param>
  114. /// <param name="m22">m22</param>
  115. /// <param name="m23">m23</param>
  116. /// <param name="m24">m24</param>
  117. /// <param name="m31">m31</param>
  118. /// <param name="m32">m32</param>
  119. /// <param name="m33">m33</param>
  120. /// <param name="m34">m34</param>
  121. /// <param name="m41">m41</param>
  122. /// <param name="m42">m42</param>
  123. /// <param name="m43">m43</param>
  124. /// <param name="m44">m44</param>
  125. public TSMatrix4x4(FP m11, FP m12, FP m13, FP m14,
  126. FP m21, FP m22, FP m23, FP m24,
  127. FP m31, FP m32, FP m33, FP m34,
  128. FP m41, FP m42, FP m43, FP m44)
  129. {
  130. this.M11 = m11;
  131. this.M12 = m12;
  132. this.M13 = m13;
  133. this.M14 = m14;
  134. this.M21 = m21;
  135. this.M22 = m22;
  136. this.M23 = m23;
  137. this.M24 = m24;
  138. this.M31 = m31;
  139. this.M32 = m32;
  140. this.M33 = m33;
  141. this.M34 = m34;
  142. this.M41 = m41;
  143. this.M42 = m42;
  144. this.M43 = m43;
  145. this.M44 = m44;
  146. }
  147. /// <summary>
  148. /// Multiply two matrices. Notice: matrix multiplication is not commutative.
  149. /// </summary>
  150. /// <param name="matrix1">The first matrix.</param>
  151. /// <param name="matrix2">The second matrix.</param>
  152. /// <returns>The product of both matrices.</returns>
  153. public static TSMatrix4x4 Multiply(TSMatrix4x4 matrix1, TSMatrix4x4 matrix2)
  154. {
  155. TSMatrix4x4 result;
  156. TSMatrix4x4.Multiply(ref matrix1, ref matrix2, out result);
  157. return result;
  158. }
  159. /// <summary>
  160. /// Multiply two matrices. Notice: matrix multiplication is not commutative.
  161. /// </summary>
  162. /// <param name="matrix1">The first matrix.</param>
  163. /// <param name="matrix2">The second matrix.</param>
  164. /// <param name="result">The product of both matrices.</param>
  165. public static void Multiply(ref TSMatrix4x4 matrix1, ref TSMatrix4x4 matrix2, out TSMatrix4x4 result)
  166. {
  167. // First row
  168. result.M11 = matrix1.M11 * matrix2.M11 + matrix1.M12 * matrix2.M21 + matrix1.M13 * matrix2.M31 + matrix1.M14 * matrix2.M41;
  169. result.M12 = matrix1.M11 * matrix2.M12 + matrix1.M12 * matrix2.M22 + matrix1.M13 * matrix2.M32 + matrix1.M14 * matrix2.M42;
  170. result.M13 = matrix1.M11 * matrix2.M13 + matrix1.M12 * matrix2.M23 + matrix1.M13 * matrix2.M33 + matrix1.M14 * matrix2.M43;
  171. result.M14 = matrix1.M11 * matrix2.M14 + matrix1.M12 * matrix2.M24 + matrix1.M13 * matrix2.M34 + matrix1.M14 * matrix2.M44;
  172. // Second row
  173. result.M21 = matrix1.M21 * matrix2.M11 + matrix1.M22 * matrix2.M21 + matrix1.M23 * matrix2.M31 + matrix1.M24 * matrix2.M41;
  174. result.M22 = matrix1.M21 * matrix2.M12 + matrix1.M22 * matrix2.M22 + matrix1.M23 * matrix2.M32 + matrix1.M24 * matrix2.M42;
  175. result.M23 = matrix1.M21 * matrix2.M13 + matrix1.M22 * matrix2.M23 + matrix1.M23 * matrix2.M33 + matrix1.M24 * matrix2.M43;
  176. result.M24 = matrix1.M21 * matrix2.M14 + matrix1.M22 * matrix2.M24 + matrix1.M23 * matrix2.M34 + matrix1.M24 * matrix2.M44;
  177. // Third row
  178. result.M31 = matrix1.M31 * matrix2.M11 + matrix1.M32 * matrix2.M21 + matrix1.M33 * matrix2.M31 + matrix1.M34 * matrix2.M41;
  179. result.M32 = matrix1.M31 * matrix2.M12 + matrix1.M32 * matrix2.M22 + matrix1.M33 * matrix2.M32 + matrix1.M34 * matrix2.M42;
  180. result.M33 = matrix1.M31 * matrix2.M13 + matrix1.M32 * matrix2.M23 + matrix1.M33 * matrix2.M33 + matrix1.M34 * matrix2.M43;
  181. result.M34 = matrix1.M31 * matrix2.M14 + matrix1.M32 * matrix2.M24 + matrix1.M33 * matrix2.M34 + matrix1.M34 * matrix2.M44;
  182. // Fourth row
  183. result.M41 = matrix1.M41 * matrix2.M11 + matrix1.M42 * matrix2.M21 + matrix1.M43 * matrix2.M31 + matrix1.M44 * matrix2.M41;
  184. result.M42 = matrix1.M41 * matrix2.M12 + matrix1.M42 * matrix2.M22 + matrix1.M43 * matrix2.M32 + matrix1.M44 * matrix2.M42;
  185. result.M43 = matrix1.M41 * matrix2.M13 + matrix1.M42 * matrix2.M23 + matrix1.M43 * matrix2.M33 + matrix1.M44 * matrix2.M43;
  186. result.M44 = matrix1.M41 * matrix2.M14 + matrix1.M42 * matrix2.M24 + matrix1.M43 * matrix2.M34 + matrix1.M44 * matrix2.M44;
  187. }
  188. /// <summary>
  189. /// Matrices are added.
  190. /// </summary>
  191. /// <param name="matrix1">The first matrix.</param>
  192. /// <param name="matrix2">The second matrix.</param>
  193. /// <returns>The sum of both matrices.</returns>
  194. public static TSMatrix4x4 Add(TSMatrix4x4 matrix1, TSMatrix4x4 matrix2)
  195. {
  196. TSMatrix4x4 result;
  197. TSMatrix4x4.Add(ref matrix1, ref matrix2, out result);
  198. return result;
  199. }
  200. /// <summary>
  201. /// Matrices are added.
  202. /// </summary>
  203. /// <param name="matrix1">The first matrix.</param>
  204. /// <param name="matrix2">The second matrix.</param>
  205. /// <param name="result">The sum of both matrices.</param>
  206. public static void Add(ref TSMatrix4x4 matrix1, ref TSMatrix4x4 matrix2, out TSMatrix4x4 result)
  207. {
  208. result.M11 = matrix1.M11 + matrix2.M11;
  209. result.M12 = matrix1.M12 + matrix2.M12;
  210. result.M13 = matrix1.M13 + matrix2.M13;
  211. result.M14 = matrix1.M14 + matrix2.M14;
  212. result.M21 = matrix1.M21 + matrix2.M21;
  213. result.M22 = matrix1.M22 + matrix2.M22;
  214. result.M23 = matrix1.M23 + matrix2.M23;
  215. result.M24 = matrix1.M24 + matrix2.M24;
  216. result.M31 = matrix1.M31 + matrix2.M31;
  217. result.M32 = matrix1.M32 + matrix2.M32;
  218. result.M33 = matrix1.M33 + matrix2.M33;
  219. result.M34 = matrix1.M34 + matrix2.M34;
  220. result.M41 = matrix1.M41 + matrix2.M41;
  221. result.M42 = matrix1.M42 + matrix2.M42;
  222. result.M43 = matrix1.M43 + matrix2.M43;
  223. result.M44 = matrix1.M44 + matrix2.M44;
  224. }
  225. /// <summary>
  226. /// Calculates the inverse of a give matrix.
  227. /// </summary>
  228. /// <param name="matrix">The matrix to invert.</param>
  229. /// <returns>The inverted JMatrix.</returns>
  230. public static TSMatrix4x4 Inverse(TSMatrix4x4 matrix)
  231. {
  232. TSMatrix4x4 result;
  233. TSMatrix4x4.Inverse(ref matrix, out result);
  234. return result;
  235. }
  236. public FP determinant
  237. {
  238. get
  239. {
  240. // | a b c d | | f g h | | e g h | | e f h | | e f g |
  241. // | e f g h | = a | j k l | - b | i k l | + c | i j l | - d | i j k |
  242. // | i j k l | | n o p | | m o p | | m n p | | m n o |
  243. // | m n o p |
  244. //
  245. // | f g h |
  246. // a | j k l | = a ( f ( kp - lo ) - g ( jp - ln ) + h ( jo - kn ) )
  247. // | n o p |
  248. //
  249. // | e g h |
  250. // b | i k l | = b ( e ( kp - lo ) - g ( ip - lm ) + h ( io - km ) )
  251. // | m o p |
  252. //
  253. // | e f h |
  254. // c | i j l | = c ( e ( jp - ln ) - f ( ip - lm ) + h ( in - jm ) )
  255. // | m n p |
  256. //
  257. // | e f g |
  258. // d | i j k | = d ( e ( jo - kn ) - f ( io - km ) + g ( in - jm ) )
  259. // | m n o |
  260. //
  261. // Cost of operation
  262. // 17 adds and 28 muls.
  263. //
  264. // add: 6 + 8 + 3 = 17
  265. // mul: 12 + 16 = 28
  266. FP a = M11, b = M12, c = M13, d = M14;
  267. FP e = M21, f = M22, g = M23, h = M24;
  268. FP i = M31, j = M32, k = M33, l = M34;
  269. FP m = M41, n = M42, o = M43, p = M44;
  270. FP kp_lo = k * p - l * o;
  271. FP jp_ln = j * p - l * n;
  272. FP jo_kn = j * o - k * n;
  273. FP ip_lm = i * p - l * m;
  274. FP io_km = i * o - k * m;
  275. FP in_jm = i * n - j * m;
  276. return a * (f * kp_lo - g * jp_ln + h * jo_kn) -
  277. b * (e * kp_lo - g * ip_lm + h * io_km) +
  278. c * (e * jp_ln - f * ip_lm + h * in_jm) -
  279. d * (e * jo_kn - f * io_km + g * in_jm);
  280. }
  281. }
  282. /// <summary>
  283. /// Calculates the inverse of a give matrix.
  284. /// </summary>
  285. /// <param name="matrix">The matrix to invert.</param>
  286. /// <param name="result">The inverted JMatrix.</param>
  287. public static void Inverse(ref TSMatrix4x4 matrix, out TSMatrix4x4 result)
  288. {
  289. // -1
  290. // If you have matrix M, inverse Matrix M can compute
  291. //
  292. // -1 1
  293. // M = --------- A
  294. // det(M)
  295. //
  296. // A is adjugate (adjoint) of M, where,
  297. //
  298. // T
  299. // A = C
  300. //
  301. // C is Cofactor matrix of M, where,
  302. // i + j
  303. // C = (-1) * det(M )
  304. // ij ij
  305. //
  306. // [ a b c d ]
  307. // M = [ e f g h ]
  308. // [ i j k l ]
  309. // [ m n o p ]
  310. //
  311. // First Row
  312. // 2 | f g h |
  313. // C = (-1) | j k l | = + ( f ( kp - lo ) - g ( jp - ln ) + h ( jo - kn ) )
  314. // 11 | n o p |
  315. //
  316. // 3 | e g h |
  317. // C = (-1) | i k l | = - ( e ( kp - lo ) - g ( ip - lm ) + h ( io - km ) )
  318. // 12 | m o p |
  319. //
  320. // 4 | e f h |
  321. // C = (-1) | i j l | = + ( e ( jp - ln ) - f ( ip - lm ) + h ( in - jm ) )
  322. // 13 | m n p |
  323. //
  324. // 5 | e f g |
  325. // C = (-1) | i j k | = - ( e ( jo - kn ) - f ( io - km ) + g ( in - jm ) )
  326. // 14 | m n o |
  327. //
  328. // Second Row
  329. // 3 | b c d |
  330. // C = (-1) | j k l | = - ( b ( kp - lo ) - c ( jp - ln ) + d ( jo - kn ) )
  331. // 21 | n o p |
  332. //
  333. // 4 | a c d |
  334. // C = (-1) | i k l | = + ( a ( kp - lo ) - c ( ip - lm ) + d ( io - km ) )
  335. // 22 | m o p |
  336. //
  337. // 5 | a b d |
  338. // C = (-1) | i j l | = - ( a ( jp - ln ) - b ( ip - lm ) + d ( in - jm ) )
  339. // 23 | m n p |
  340. //
  341. // 6 | a b c |
  342. // C = (-1) | i j k | = + ( a ( jo - kn ) - b ( io - km ) + c ( in - jm ) )
  343. // 24 | m n o |
  344. //
  345. // Third Row
  346. // 4 | b c d |
  347. // C = (-1) | f g h | = + ( b ( gp - ho ) - c ( fp - hn ) + d ( fo - gn ) )
  348. // 31 | n o p |
  349. //
  350. // 5 | a c d |
  351. // C = (-1) | e g h | = - ( a ( gp - ho ) - c ( ep - hm ) + d ( eo - gm ) )
  352. // 32 | m o p |
  353. //
  354. // 6 | a b d |
  355. // C = (-1) | e f h | = + ( a ( fp - hn ) - b ( ep - hm ) + d ( en - fm ) )
  356. // 33 | m n p |
  357. //
  358. // 7 | a b c |
  359. // C = (-1) | e f g | = - ( a ( fo - gn ) - b ( eo - gm ) + c ( en - fm ) )
  360. // 34 | m n o |
  361. //
  362. // Fourth Row
  363. // 5 | b c d |
  364. // C = (-1) | f g h | = - ( b ( gl - hk ) - c ( fl - hj ) + d ( fk - gj ) )
  365. // 41 | j k l |
  366. //
  367. // 6 | a c d |
  368. // C = (-1) | e g h | = + ( a ( gl - hk ) - c ( el - hi ) + d ( ek - gi ) )
  369. // 42 | i k l |
  370. //
  371. // 7 | a b d |
  372. // C = (-1) | e f h | = - ( a ( fl - hj ) - b ( el - hi ) + d ( ej - fi ) )
  373. // 43 | i j l |
  374. //
  375. // 8 | a b c |
  376. // C = (-1) | e f g | = + ( a ( fk - gj ) - b ( ek - gi ) + c ( ej - fi ) )
  377. // 44 | i j k |
  378. //
  379. // Cost of operation
  380. // 53 adds, 104 muls, and 1 div.
  381. FP a = matrix.M11, b = matrix.M12, c = matrix.M13, d = matrix.M14;
  382. FP e = matrix.M21, f = matrix.M22, g = matrix.M23, h = matrix.M24;
  383. FP i = matrix.M31, j = matrix.M32, k = matrix.M33, l = matrix.M34;
  384. FP m = matrix.M41, n = matrix.M42, o = matrix.M43, p = matrix.M44;
  385. FP kp_lo = k * p - l * o;
  386. FP jp_ln = j * p - l * n;
  387. FP jo_kn = j * o - k * n;
  388. FP ip_lm = i * p - l * m;
  389. FP io_km = i * o - k * m;
  390. FP in_jm = i * n - j * m;
  391. FP a11 = (f * kp_lo - g * jp_ln + h * jo_kn);
  392. FP a12 = -(e * kp_lo - g * ip_lm + h * io_km);
  393. FP a13 = (e * jp_ln - f * ip_lm + h * in_jm);
  394. FP a14 = -(e * jo_kn - f * io_km + g * in_jm);
  395. FP det = a * a11 + b * a12 + c * a13 + d * a14;
  396. if (det == FP.Zero)
  397. {
  398. result.M11 = FP.PositiveInfinity;
  399. result.M12 = FP.PositiveInfinity;
  400. result.M13 = FP.PositiveInfinity;
  401. result.M14 = FP.PositiveInfinity;
  402. result.M21 = FP.PositiveInfinity;
  403. result.M22 = FP.PositiveInfinity;
  404. result.M23 = FP.PositiveInfinity;
  405. result.M24 = FP.PositiveInfinity;
  406. result.M31 = FP.PositiveInfinity;
  407. result.M32 = FP.PositiveInfinity;
  408. result.M33 = FP.PositiveInfinity;
  409. result.M34 = FP.PositiveInfinity;
  410. result.M41 = FP.PositiveInfinity;
  411. result.M42 = FP.PositiveInfinity;
  412. result.M43 = FP.PositiveInfinity;
  413. result.M44 = FP.PositiveInfinity;
  414. }
  415. else
  416. {
  417. FP invDet = FP.One / det;
  418. result.M11 = a11 * invDet;
  419. result.M21 = a12 * invDet;
  420. result.M31 = a13 * invDet;
  421. result.M41 = a14 * invDet;
  422. result.M12 = -(b * kp_lo - c * jp_ln + d * jo_kn) * invDet;
  423. result.M22 = (a * kp_lo - c * ip_lm + d * io_km) * invDet;
  424. result.M32 = -(a * jp_ln - b * ip_lm + d * in_jm) * invDet;
  425. result.M42 = (a * jo_kn - b * io_km + c * in_jm) * invDet;
  426. FP gp_ho = g * p - h * o;
  427. FP fp_hn = f * p - h * n;
  428. FP fo_gn = f * o - g * n;
  429. FP ep_hm = e * p - h * m;
  430. FP eo_gm = e * o - g * m;
  431. FP en_fm = e * n - f * m;
  432. result.M13 = (b * gp_ho - c * fp_hn + d * fo_gn) * invDet;
  433. result.M23 = -(a * gp_ho - c * ep_hm + d * eo_gm) * invDet;
  434. result.M33 = (a * fp_hn - b * ep_hm + d * en_fm) * invDet;
  435. result.M43 = -(a * fo_gn - b * eo_gm + c * en_fm) * invDet;
  436. FP gl_hk = g * l - h * k;
  437. FP fl_hj = f * l - h * j;
  438. FP fk_gj = f * k - g * j;
  439. FP el_hi = e * l - h * i;
  440. FP ek_gi = e * k - g * i;
  441. FP ej_fi = e * j - f * i;
  442. result.M14 = -(b * gl_hk - c * fl_hj + d * fk_gj) * invDet;
  443. result.M24 = (a * gl_hk - c * el_hi + d * ek_gi) * invDet;
  444. result.M34 = -(a * fl_hj - b * el_hi + d * ej_fi) * invDet;
  445. result.M44 = (a * fk_gj - b * ek_gi + c * ej_fi) * invDet;
  446. }
  447. }
  448. /// <summary>
  449. /// Multiply a matrix by a scalefactor.
  450. /// </summary>
  451. /// <param name="matrix1">The matrix.</param>
  452. /// <param name="scaleFactor">The scale factor.</param>
  453. /// <returns>A JMatrix multiplied by the scale factor.</returns>
  454. public static TSMatrix4x4 Multiply(TSMatrix4x4 matrix1, FP scaleFactor)
  455. {
  456. TSMatrix4x4 result;
  457. TSMatrix4x4.Multiply(ref matrix1, scaleFactor, out result);
  458. return result;
  459. }
  460. /// <summary>
  461. /// Multiply a matrix by a scalefactor.
  462. /// </summary>
  463. /// <param name="matrix1">The matrix.</param>
  464. /// <param name="scaleFactor">The scale factor.</param>
  465. /// <param name="result">A JMatrix multiplied by the scale factor.</param>
  466. public static void Multiply(ref TSMatrix4x4 matrix1, FP scaleFactor, out TSMatrix4x4 result)
  467. {
  468. FP num = scaleFactor;
  469. result.M11 = matrix1.M11 * num;
  470. result.M12 = matrix1.M12 * num;
  471. result.M13 = matrix1.M13 * num;
  472. result.M14 = matrix1.M14 * num;
  473. result.M21 = matrix1.M21 * num;
  474. result.M22 = matrix1.M22 * num;
  475. result.M23 = matrix1.M23 * num;
  476. result.M24 = matrix1.M24 * num;
  477. result.M31 = matrix1.M31 * num;
  478. result.M32 = matrix1.M32 * num;
  479. result.M33 = matrix1.M33 * num;
  480. result.M34 = matrix1.M34 * num;
  481. result.M41 = matrix1.M41 * num;
  482. result.M42 = matrix1.M42 * num;
  483. result.M43 = matrix1.M43 * num;
  484. result.M44 = matrix1.M44 * num;
  485. }
  486. public static TSMatrix4x4 Rotate(TSQuaternion quaternion)
  487. {
  488. TSMatrix4x4 result;
  489. TSMatrix4x4.Rotate(ref quaternion, out result);
  490. return result;
  491. }
  492. /// <summary>
  493. /// Creates a JMatrix representing an orientation from a quaternion.
  494. /// </summary>
  495. /// <param name="quaternion">The quaternion the matrix should be created from.</param>
  496. /// <param name="result">JMatrix representing an orientation.</param>
  497. public static void Rotate(ref TSQuaternion quaternion, out TSMatrix4x4 result)
  498. {
  499. // Precalculate coordinate products
  500. FP x = quaternion.x * 2;
  501. FP y = quaternion.y * 2;
  502. FP z = quaternion.z * 2;
  503. FP xx = quaternion.x * x;
  504. FP yy = quaternion.y * y;
  505. FP zz = quaternion.z * z;
  506. FP xy = quaternion.x * y;
  507. FP xz = quaternion.x * z;
  508. FP yz = quaternion.y * z;
  509. FP wx = quaternion.w * x;
  510. FP wy = quaternion.w * y;
  511. FP wz = quaternion.w * z;
  512. // Calculate 3x3 matrix from orthonormal basis
  513. result.M11 = FP.One - (yy + zz);
  514. result.M21 = xy + wz;
  515. result.M31 = xz - wy;
  516. result.M41 = FP.Zero;
  517. result.M12 = xy - wz;
  518. result.M22 = FP.One - (xx + zz);
  519. result.M32 = yz + wx;
  520. result.M42 = FP.Zero;
  521. result.M13 = xz + wy;
  522. result.M23 = yz - wx;
  523. result.M33 = FP.One - (xx + yy);
  524. result.M43 = FP.Zero;
  525. result.M14 = FP.Zero;
  526. result.M24 = FP.Zero;
  527. result.M34 = FP.Zero;
  528. result.M44 = FP.One;
  529. }
  530. /// <summary>
  531. /// Creates the transposed matrix.
  532. /// </summary>
  533. /// <param name="matrix">The matrix which should be transposed.</param>
  534. /// <returns>The transposed JMatrix.</returns>
  535. public static TSMatrix4x4 Transpose(TSMatrix4x4 matrix)
  536. {
  537. TSMatrix4x4 result;
  538. TSMatrix4x4.Transpose(ref matrix, out result);
  539. return result;
  540. }
  541. /// <summary>
  542. /// Creates the transposed matrix.
  543. /// </summary>
  544. /// <param name="matrix">The matrix which should be transposed.</param>
  545. /// <param name="result">The transposed JMatrix.</param>
  546. public static void Transpose(ref TSMatrix4x4 matrix, out TSMatrix4x4 result)
  547. {
  548. result.M11 = matrix.M11;
  549. result.M12 = matrix.M21;
  550. result.M13 = matrix.M31;
  551. result.M14 = matrix.M41;
  552. result.M21 = matrix.M12;
  553. result.M22 = matrix.M22;
  554. result.M23 = matrix.M32;
  555. result.M24 = matrix.M42;
  556. result.M31 = matrix.M13;
  557. result.M32 = matrix.M23;
  558. result.M33 = matrix.M33;
  559. result.M34 = matrix.M43;
  560. result.M41 = matrix.M14;
  561. result.M42 = matrix.M24;
  562. result.M43 = matrix.M34;
  563. result.M44 = matrix.M44;
  564. }
  565. /// <summary>
  566. /// Multiplies two matrices.
  567. /// </summary>
  568. /// <param name="value1">The first matrix.</param>
  569. /// <param name="value2">The second matrix.</param>
  570. /// <returns>The product of both values.</returns>
  571. public static TSMatrix4x4 operator *(TSMatrix4x4 value1, TSMatrix4x4 value2)
  572. {
  573. TSMatrix4x4 result;
  574. TSMatrix4x4.Multiply(ref value1, ref value2, out result);
  575. return result;
  576. }
  577. public FP Trace()
  578. {
  579. return this.M11 + this.M22 + this.M33 + this.M44;
  580. }
  581. /// <summary>
  582. /// Adds two matrices.
  583. /// </summary>
  584. /// <param name="value1">The first matrix.</param>
  585. /// <param name="value2">The second matrix.</param>
  586. /// <returns>The sum of both values.</returns>
  587. public static TSMatrix4x4 operator +(TSMatrix4x4 value1, TSMatrix4x4 value2)
  588. {
  589. TSMatrix4x4 result;
  590. TSMatrix4x4.Add(ref value1, ref value2, out result);
  591. return result;
  592. }
  593. /// <summary>
  594. /// Returns a new matrix with the negated elements of the given matrix.
  595. /// </summary>
  596. /// <param name="value">The source matrix.</param>
  597. /// <returns>The negated matrix.</returns>
  598. public static TSMatrix4x4 operator -(TSMatrix4x4 value)
  599. {
  600. TSMatrix4x4 result;
  601. result.M11 = -value.M11;
  602. result.M12 = -value.M12;
  603. result.M13 = -value.M13;
  604. result.M14 = -value.M14;
  605. result.M21 = -value.M21;
  606. result.M22 = -value.M22;
  607. result.M23 = -value.M23;
  608. result.M24 = -value.M24;
  609. result.M31 = -value.M31;
  610. result.M32 = -value.M32;
  611. result.M33 = -value.M33;
  612. result.M34 = -value.M34;
  613. result.M41 = -value.M41;
  614. result.M42 = -value.M42;
  615. result.M43 = -value.M43;
  616. result.M44 = -value.M44;
  617. return result;
  618. }
  619. /// <summary>
  620. /// Subtracts two matrices.
  621. /// </summary>
  622. /// <param name="value1">The first matrix.</param>
  623. /// <param name="value2">The second matrix.</param>
  624. /// <returns>The difference of both values.</returns>
  625. public static TSMatrix4x4 operator -(TSMatrix4x4 value1, TSMatrix4x4 value2)
  626. {
  627. TSMatrix4x4 result;
  628. TSMatrix4x4.Multiply(ref value2, -FP.One, out value2);
  629. TSMatrix4x4.Add(ref value1, ref value2, out result);
  630. return result;
  631. }
  632. public static bool operator ==(TSMatrix4x4 value1, TSMatrix4x4 value2)
  633. {
  634. return value1.M11 == value2.M11 &&
  635. value1.M12 == value2.M12 &&
  636. value1.M13 == value2.M13 &&
  637. value1.M14 == value2.M14 &&
  638. value1.M21 == value2.M21 &&
  639. value1.M22 == value2.M22 &&
  640. value1.M23 == value2.M23 &&
  641. value1.M24 == value2.M24 &&
  642. value1.M31 == value2.M31 &&
  643. value1.M32 == value2.M32 &&
  644. value1.M33 == value2.M33 &&
  645. value1.M34 == value2.M34 &&
  646. value1.M41 == value2.M41 &&
  647. value1.M42 == value2.M42 &&
  648. value1.M43 == value2.M43 &&
  649. value1.M44 == value2.M44;
  650. }
  651. public static bool operator !=(TSMatrix4x4 value1, TSMatrix4x4 value2)
  652. {
  653. return value1.M11 != value2.M11 ||
  654. value1.M12 != value2.M12 ||
  655. value1.M13 != value2.M13 ||
  656. value1.M14 != value2.M14 ||
  657. value1.M21 != value2.M21 ||
  658. value1.M22 != value2.M22 ||
  659. value1.M23 != value2.M23 ||
  660. value1.M24 != value2.M24 ||
  661. value1.M31 != value2.M31 ||
  662. value1.M32 != value2.M32 ||
  663. value1.M33 != value2.M33 ||
  664. value1.M34 != value2.M34 ||
  665. value1.M41 != value2.M41 ||
  666. value1.M42 != value2.M42 ||
  667. value1.M43 != value2.M43 ||
  668. value1.M44 != value2.M44;
  669. }
  670. public override bool Equals(object obj)
  671. {
  672. if (!(obj is TSMatrix4x4)) return false;
  673. TSMatrix4x4 other = (TSMatrix4x4)obj;
  674. return this.M11 == other.M11 &&
  675. this.M12 == other.M12 &&
  676. this.M13 == other.M13 &&
  677. this.M14 == other.M14 &&
  678. this.M21 == other.M21 &&
  679. this.M22 == other.M22 &&
  680. this.M23 == other.M23 &&
  681. this.M24 == other.M24 &&
  682. this.M31 == other.M31 &&
  683. this.M32 == other.M32 &&
  684. this.M33 == other.M33 &&
  685. this.M34 == other.M44 &&
  686. this.M41 == other.M41 &&
  687. this.M42 == other.M42 &&
  688. this.M43 == other.M43 &&
  689. this.M44 == other.M44 ;
  690. }
  691. public override int GetHashCode()
  692. {
  693. return M11.GetHashCode() ^
  694. M12.GetHashCode() ^
  695. M13.GetHashCode() ^
  696. M14.GetHashCode() ^
  697. M21.GetHashCode() ^
  698. M22.GetHashCode() ^
  699. M23.GetHashCode() ^
  700. M24.GetHashCode() ^
  701. M31.GetHashCode() ^
  702. M32.GetHashCode() ^
  703. M33.GetHashCode() ^
  704. M34.GetHashCode() ^
  705. M41.GetHashCode() ^
  706. M42.GetHashCode() ^
  707. M43.GetHashCode() ^
  708. M44.GetHashCode();
  709. }
  710. /// <summary>
  711. /// Creates a translation matrix.
  712. /// </summary>
  713. /// <param name="xPosition">The amount to translate on the X-axis.</param>
  714. /// <param name="yPosition">The amount to translate on the Y-axis.</param>
  715. /// <param name="zPosition">The amount to translate on the Z-axis.</param>
  716. /// <returns>The translation matrix.</returns>
  717. public static TSMatrix4x4 Translate(FP xPosition, FP yPosition, FP zPosition)
  718. {
  719. TSMatrix4x4 result;
  720. result.M11 = FP.One; result.M12 = FP.Zero; result.M13 = FP.Zero; result.M14 = xPosition;
  721. result.M21 = FP.Zero; result.M22 = FP.One; result.M23 = FP.Zero; result.M24 = yPosition;
  722. result.M31 = FP.Zero; result.M32 = FP.Zero; result.M33 = FP.One; result.M34 = zPosition;
  723. result.M41 = FP.Zero; result.M42 = FP.Zero; result.M43 = FP.Zero; result.M44 = FP.One;
  724. return result;
  725. }
  726. public static TSMatrix4x4 Translate(TSVector translation)
  727. {
  728. return Translate(translation.x, translation.y, translation.z);
  729. }
  730. /// <summary>
  731. /// Creates a scaling matrix.
  732. /// </summary>
  733. /// <param name="xScale">Value to scale by on the X-axis.</param>
  734. /// <param name="yScale">Value to scale by on the Y-axis.</param>
  735. /// <param name="zScale">Value to scale by on the Z-axis.</param>
  736. /// <returns>The scaling matrix.</returns>
  737. public static TSMatrix4x4 Scale(FP xScale, FP yScale, FP zScale)
  738. {
  739. TSMatrix4x4 result;
  740. result.M11 = xScale; result.M12 = FP.Zero; result.M13 = FP.Zero; result.M14 = FP.Zero;
  741. result.M21 = FP.Zero; result.M22 = yScale; result.M23 = FP.Zero; result.M24 = FP.Zero;
  742. result.M31 = FP.Zero; result.M32 = FP.Zero; result.M33 = zScale; result.M34 = FP.Zero;
  743. result.M41 = FP.Zero; result.M42 = FP.Zero; result.M43 = FP.Zero; result.M44 = FP.One;
  744. return result;
  745. }
  746. /// <summary>
  747. /// Creates a scaling matrix with a center point.
  748. /// </summary>
  749. /// <param name="xScale">Value to scale by on the X-axis.</param>
  750. /// <param name="yScale">Value to scale by on the Y-axis.</param>
  751. /// <param name="zScale">Value to scale by on the Z-axis.</param>
  752. /// <param name="centerPoint">The center point.</param>
  753. /// <returns>The scaling matrix.</returns>
  754. public static TSMatrix4x4 Scale(FP xScale, FP yScale, FP zScale, TSVector centerPoint)
  755. {
  756. TSMatrix4x4 result;
  757. FP tx = centerPoint.x * (FP.One - xScale);
  758. FP ty = centerPoint.y * (FP.One - yScale);
  759. FP tz = centerPoint.z * (FP.One - zScale);
  760. result.M11 = xScale; result.M12 = FP.Zero; result.M13 = FP.Zero; result.M14 = FP.Zero;
  761. result.M21 = FP.Zero; result.M22 = yScale; result.M23 = FP.Zero; result.M24 = FP.Zero;
  762. result.M31 = FP.Zero; result.M32 = FP.Zero; result.M33 = zScale; result.M34 = FP.Zero;
  763. result.M41 = tx; result.M42 = ty; result.M43 = tz; result.M44 = FP.One;
  764. return result;
  765. }
  766. /// <summary>
  767. /// Creates a scaling matrix.
  768. /// </summary>
  769. /// <param name="scales">The vector containing the amount to scale by on each axis.</param>
  770. /// <returns>The scaling matrix.</returns>
  771. public static TSMatrix4x4 Scale(TSVector scales)
  772. {
  773. return Scale(scales.x, scales.y, scales.z);
  774. }
  775. /// <summary>
  776. /// Creates a scaling matrix with a center point.
  777. /// </summary>
  778. /// <param name="scales">The vector containing the amount to scale by on each axis.</param>
  779. /// <param name="centerPoint">The center point.</param>
  780. /// <returns>The scaling matrix.</returns>
  781. public static TSMatrix4x4 Scale(TSVector scales, TSVector centerPoint)
  782. {
  783. return Scale(scales.x, scales.y, scales.z, centerPoint);
  784. }
  785. /// <summary>
  786. /// Creates a uniform scaling matrix that scales equally on each axis.
  787. /// </summary>
  788. /// <param name="scale">The uniform scaling factor.</param>
  789. /// <returns>The scaling matrix.</returns>
  790. public static TSMatrix4x4 Scale(FP scale)
  791. {
  792. return Scale(scale, scale, scale);
  793. }
  794. /// <summary>
  795. /// Creates a uniform scaling matrix that scales equally on each axis with a center point.
  796. /// </summary>
  797. /// <param name="scale">The uniform scaling factor.</param>
  798. /// <param name="centerPoint">The center point.</param>
  799. /// <returns>The scaling matrix.</returns>
  800. public static TSMatrix4x4 Scale(FP scale, TSVector centerPoint)
  801. {
  802. return Scale(scale, scale, scale, centerPoint);
  803. }
  804. /// <summary>
  805. /// Creates a matrix for rotating points around the X-axis.
  806. /// </summary>
  807. /// <param name="radians">The amount, in radians, by which to rotate around the X-axis.</param>
  808. /// <returns>The rotation matrix.</returns>
  809. public static TSMatrix4x4 RotateX(FP radians)
  810. {
  811. TSMatrix4x4 result;
  812. FP c = TSMath.Cos(radians);
  813. FP s = TSMath.Sin(radians);
  814. // [ 1 0 0 0 ]
  815. // [ 0 c s 0 ]
  816. // [ 0 -s c 0 ]
  817. // [ 0 0 0 1 ]
  818. result.M11 = FP.One;
  819. result.M12 = FP.Zero;
  820. result.M13 = FP.Zero;
  821. result.M14 = FP.Zero;
  822. result.M21 = FP.Zero;
  823. result.M22 = c;
  824. result.M23 = s;
  825. result.M24 = FP.Zero;
  826. result.M31 = FP.Zero;
  827. result.M32 = -s;
  828. result.M33 = c;
  829. result.M34 = FP.Zero;
  830. result.M41 = FP.Zero;
  831. result.M42 = FP.Zero;
  832. result.M43 = FP.Zero;
  833. result.M44 = FP.One;
  834. return result;
  835. }
  836. /// <summary>
  837. /// Creates a matrix for rotating points around the X-axis, from a center point.
  838. /// </summary>
  839. /// <param name="radians">The amount, in radians, by which to rotate around the X-axis.</param>
  840. /// <param name="centerPoint">The center point.</param>
  841. /// <returns>The rotation matrix.</returns>
  842. public static TSMatrix4x4 RotateX(FP radians, TSVector centerPoint)
  843. {
  844. TSMatrix4x4 result;
  845. FP c = TSMath.Cos(radians);
  846. FP s = TSMath.Sin(radians);
  847. FP y = centerPoint.y * (FP.One - c) + centerPoint.z * s;
  848. FP z = centerPoint.z * (FP.One - c) - centerPoint.y * s;
  849. // [ 1 0 0 0 ]
  850. // [ 0 c s 0 ]
  851. // [ 0 -s c 0 ]
  852. // [ 0 y z 1 ]
  853. result.M11 = FP.One;
  854. result.M12 = FP.Zero;
  855. result.M13 = FP.Zero;
  856. result.M14 = FP.Zero;
  857. result.M21 = FP.Zero;
  858. result.M22 = c;
  859. result.M23 = s;
  860. result.M24 = FP.Zero;
  861. result.M31 = FP.Zero;
  862. result.M32 = -s;
  863. result.M33 = c;
  864. result.M34 = FP.Zero;
  865. result.M41 = FP.Zero;
  866. result.M42 = y;
  867. result.M43 = z;
  868. result.M44 = FP.One;
  869. return result;
  870. }
  871. /// <summary>
  872. /// Creates a matrix for rotating points around the Y-axis.
  873. /// </summary>
  874. /// <param name="radians">The amount, in radians, by which to rotate around the Y-axis.</param>
  875. /// <returns>The rotation matrix.</returns>
  876. public static TSMatrix4x4 RotateY(FP radians)
  877. {
  878. TSMatrix4x4 result;
  879. FP c = TSMath.Cos(radians);
  880. FP s = TSMath.Sin(radians);
  881. // [ c 0 -s 0 ]
  882. // [ 0 1 0 0 ]
  883. // [ s 0 c 0 ]
  884. // [ 0 0 0 1 ]
  885. result.M11 = c;
  886. result.M12 = FP.Zero;
  887. result.M13 = -s;
  888. result.M14 = FP.Zero;
  889. result.M21 = FP.Zero;
  890. result.M22 = FP.One;
  891. result.M23 = FP.Zero;
  892. result.M24 = FP.Zero;
  893. result.M31 = s;
  894. result.M32 = FP.Zero;
  895. result.M33 = c;
  896. result.M34 = FP.Zero;
  897. result.M41 = FP.Zero;
  898. result.M42 = FP.Zero;
  899. result.M43 = FP.Zero;
  900. result.M44 = FP.One;
  901. return result;
  902. }
  903. /// <summary>
  904. /// Creates a matrix for rotating points around the Y-axis, from a center point.
  905. /// </summary>
  906. /// <param name="radians">The amount, in radians, by which to rotate around the Y-axis.</param>
  907. /// <param name="centerPoint">The center point.</param>
  908. /// <returns>The rotation matrix.</returns>
  909. public static TSMatrix4x4 RotateY(FP radians, TSVector centerPoint)
  910. {
  911. TSMatrix4x4 result;
  912. FP c = TSMath.Cos(radians);
  913. FP s = TSMath.Sin(radians);
  914. FP x = centerPoint.x * (FP.One - c) - centerPoint.z * s;
  915. FP z = centerPoint.x * (FP.One - c) + centerPoint.x * s;
  916. // [ c 0 -s 0 ]
  917. // [ 0 1 0 0 ]
  918. // [ s 0 c 0 ]
  919. // [ x 0 z 1 ]
  920. result.M11 = c;
  921. result.M12 = FP.Zero;
  922. result.M13 = -s;
  923. result.M14 = FP.Zero;
  924. result.M21 = FP.Zero;
  925. result.M22 = FP.One;
  926. result.M23 = FP.Zero;
  927. result.M24 = FP.Zero;
  928. result.M31 = s;
  929. result.M32 = FP.Zero;
  930. result.M33 = c;
  931. result.M34 = FP.Zero;
  932. result.M41 = x;
  933. result.M42 = FP.Zero;
  934. result.M43 = z;
  935. result.M44 = FP.One;
  936. return result;
  937. }
  938. /// <summary>
  939. /// Creates a matrix for rotating points around the Z-axis.
  940. /// </summary>
  941. /// <param name="radians">The amount, in radians, by which to rotate around the Z-axis.</param>
  942. /// <returns>The rotation matrix.</returns>
  943. public static TSMatrix4x4 RotateZ(FP radians)
  944. {
  945. TSMatrix4x4 result;
  946. FP c = TSMath.Cos(radians);
  947. FP s = TSMath.Sin(radians);
  948. // [ c s 0 0 ]
  949. // [ -s c 0 0 ]
  950. // [ 0 0 1 0 ]
  951. // [ 0 0 0 1 ]
  952. result.M11 = c;
  953. result.M12 = s;
  954. result.M13 = FP.Zero;
  955. result.M14 = FP.Zero;
  956. result.M21 = -s;
  957. result.M22 = c;
  958. result.M23 = FP.Zero;
  959. result.M24 = FP.Zero;
  960. result.M31 = FP.Zero;
  961. result.M32 = FP.Zero;
  962. result.M33 = FP.One;
  963. result.M34 = FP.Zero;
  964. result.M41 = FP.Zero;
  965. result.M42 = FP.Zero;
  966. result.M43 = FP.Zero;
  967. result.M44 = FP.One;
  968. return result;
  969. }
  970. /// <summary>
  971. /// Creates a matrix for rotating points around the Z-axis, from a center point.
  972. /// </summary>
  973. /// <param name="radians">The amount, in radians, by which to rotate around the Z-axis.</param>
  974. /// <param name="centerPoint">The center point.</param>
  975. /// <returns>The rotation matrix.</returns>
  976. public static TSMatrix4x4 RotateZ(FP radians, TSVector centerPoint)
  977. {
  978. TSMatrix4x4 result;
  979. FP c = TSMath.Cos(radians);
  980. FP s = TSMath.Sin(radians);
  981. FP x = centerPoint.x * (1 - c) + centerPoint.y * s;
  982. FP y = centerPoint.y * (1 - c) - centerPoint.x * s;
  983. // [ c s 0 0 ]
  984. // [ -s c 0 0 ]
  985. // [ 0 0 1 0 ]
  986. // [ x y 0 1 ]
  987. result.M11 = c;
  988. result.M12 = s;
  989. result.M13 = FP.Zero;
  990. result.M14 = FP.Zero;
  991. result.M21 = -s;
  992. result.M22 = c;
  993. result.M23 = FP.Zero;
  994. result.M24 = FP.Zero;
  995. result.M31 = FP.Zero;
  996. result.M32 = FP.Zero;
  997. result.M33 = FP.One;
  998. result.M34 = FP.Zero;
  999. result.M41 = FP.Zero;
  1000. result.M42 = FP.Zero;
  1001. result.M43 = FP.Zero;
  1002. result.M44 = FP.One;
  1003. return result;
  1004. }
  1005. /// <summary>
  1006. /// Creates a matrix which rotates around the given axis by the given angle.
  1007. /// </summary>
  1008. /// <param name="axis">The axis.</param>
  1009. /// <param name="angle">The angle.</param>
  1010. /// <param name="result">The resulting rotation matrix</param>
  1011. public static void AxisAngle(ref TSVector axis, FP angle, out TSMatrix4x4 result)
  1012. {
  1013. // a: angle
  1014. // x, y, z: unit vector for axis.
  1015. //
  1016. // Rotation matrix M can compute by using below equation.
  1017. //
  1018. // T T
  1019. // M = uu + (cos a)( I-uu ) + (sin a)S
  1020. //
  1021. // Where:
  1022. //
  1023. // u = ( x, y, z )
  1024. //
  1025. // [ 0 -z y ]
  1026. // S = [ z 0 -x ]
  1027. // [ -y x 0 ]
  1028. //
  1029. // [ 1 0 0 ]
  1030. // I = [ 0 1 0 ]
  1031. // [ 0 0 1 ]
  1032. //
  1033. //
  1034. // [ xx+cosa*(1-xx) yx-cosa*yx-sina*z zx-cosa*xz+sina*y ]
  1035. // M = [ xy-cosa*yx+sina*z yy+cosa(1-yy) yz-cosa*yz-sina*x ]
  1036. // [ zx-cosa*zx-sina*y zy-cosa*zy+sina*x zz+cosa*(1-zz) ]
  1037. //
  1038. FP x = axis.x, y = axis.y, z = axis.z;
  1039. FP sa = TSMath.Sin(angle), ca = TSMath.Cos(angle);
  1040. FP xx = x * x, yy = y * y, zz = z * z;
  1041. FP xy = x * y, xz = x * z, yz = y * z;
  1042. result.M11 = xx + ca * (FP.One - xx);
  1043. result.M12 = xy - ca * xy + sa * z;
  1044. result.M13 = xz - ca * xz - sa * y;
  1045. result.M14 = FP.Zero;
  1046. result.M21 = xy - ca * xy - sa * z;
  1047. result.M22 = yy + ca * (FP.One - yy);
  1048. result.M23 = yz - ca * yz + sa * x;
  1049. result.M24 = FP.Zero;
  1050. result.M31 = xz - ca * xz + sa * y;
  1051. result.M32 = yz - ca * yz - sa * x;
  1052. result.M33 = zz + ca * (FP.One - zz);
  1053. result.M34 = FP.Zero;
  1054. result.M41 = FP.Zero;
  1055. result.M42 = FP.Zero;
  1056. result.M43 = FP.Zero;
  1057. result.M44 = FP.One;
  1058. }
  1059. /// <summary>
  1060. /// Creates a matrix which rotates around the given axis by the given angle.
  1061. /// </summary>
  1062. /// <param name="axis">The axis.</param>
  1063. /// <param name="angle">The angle.</param>
  1064. /// <returns>The resulting rotation matrix</returns>
  1065. public static TSMatrix4x4 AngleAxis(FP angle, TSVector axis)
  1066. {
  1067. TSMatrix4x4 result;
  1068. AxisAngle(ref axis, angle, out result);
  1069. return result;
  1070. }
  1071. public override string ToString()
  1072. {
  1073. return string.Format("{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}|{10}|{11}|{12}|{13}|{14}|{15}",
  1074. M11.RawValue, M12.RawValue, M13.RawValue, M14.RawValue,
  1075. M21.RawValue, M22.RawValue, M23.RawValue, M24.RawValue,
  1076. M31.RawValue, M32.RawValue, M33.RawValue, M34.RawValue,
  1077. M41.RawValue, M42.RawValue, M43.RawValue, M44.RawValue);
  1078. }
  1079. public static void TRS(TSVector translation, TSQuaternion rotation, TSVector scale, out TSMatrix4x4 matrix)
  1080. {
  1081. matrix = TSMatrix4x4.Translate(translation) * TSMatrix4x4.Rotate(rotation) * TSMatrix4x4.Scale(scale);
  1082. }
  1083. public static TSMatrix4x4 TRS(TSVector translation, TSQuaternion rotation, TSVector scale)
  1084. {
  1085. TSMatrix4x4 result;
  1086. TRS(translation, rotation, scale, out result);
  1087. return result;
  1088. }
  1089. }
  1090. }