Matrix3.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. #region --- License ---
  2. /*
  3. Copyright (c) 2006 - 2008 The Open Toolkit library.
  4. Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. this software and associated documentation files (the "Software"), to deal in
  6. the Software without restriction, including without limitation the rights to
  7. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  8. of the Software, and to permit persons to whom the Software is furnished to do
  9. so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. */
  20. #endregion
  21. using System;
  22. using System.Runtime.InteropServices;
  23. namespace Urho
  24. {
  25. // Todo: Remove this warning when the code goes public.
  26. #pragma warning disable 3019
  27. [StructLayout(LayoutKind.Sequential)]
  28. public struct Matrix3 : IEquatable<Matrix3>
  29. {
  30. #region Fields & Access
  31. /// <summary>Row 0, Column 0</summary>
  32. public float R0C0;
  33. /// <summary>Row 0, Column 1</summary>
  34. public float R0C1;
  35. /// <summary>Row 0, Column 2</summary>
  36. public float R0C2;
  37. /// <summary>Row 1, Column 0</summary>
  38. public float R1C0;
  39. /// <summary>Row 1, Column 1</summary>
  40. public float R1C1;
  41. /// <summary>Row 1, Column 2</summary>
  42. public float R1C2;
  43. /// <summary>Row 2, Column 0</summary>
  44. public float R2C0;
  45. /// <summary>Row 2, Column 1</summary>
  46. public float R2C1;
  47. /// <summary>Row 2, Column 2</summary>
  48. public float R2C2;
  49. /// <summary>Gets the component at the given row and column in the matrix.</summary>
  50. /// <param name="row">The row of the matrix.</param>
  51. /// <param name="column">The column of the matrix.</param>
  52. /// <returns>The component at the given row and column in the matrix.</returns>
  53. public float this[int row, int column]
  54. {
  55. get
  56. {
  57. switch( row )
  58. {
  59. case 0:
  60. switch (column)
  61. {
  62. case 0: return R0C0;
  63. case 1: return R0C1;
  64. case 2: return R0C2;
  65. }
  66. break;
  67. case 1:
  68. switch (column)
  69. {
  70. case 0: return R1C0;
  71. case 1: return R1C1;
  72. case 2: return R1C2;
  73. }
  74. break;
  75. case 2:
  76. switch (column)
  77. {
  78. case 0: return R2C0;
  79. case 1: return R2C1;
  80. case 2: return R2C2;
  81. }
  82. break;
  83. }
  84. throw new IndexOutOfRangeException();
  85. }
  86. set
  87. {
  88. switch( row )
  89. {
  90. case 0:
  91. switch (column)
  92. {
  93. case 0: R0C0 = value; return;
  94. case 1: R0C1 = value; return;
  95. case 2: R0C2 = value; return;
  96. }
  97. break;
  98. case 1:
  99. switch (column)
  100. {
  101. case 0: R1C0 = value; return;
  102. case 1: R1C1 = value; return;
  103. case 2: R1C2 = value; return;
  104. }
  105. break;
  106. case 2:
  107. switch (column)
  108. {
  109. case 0: R2C0 = value; return;
  110. case 1: R2C1 = value; return;
  111. case 2: R2C2 = value; return;
  112. }
  113. break;
  114. }
  115. throw new IndexOutOfRangeException();
  116. }
  117. }
  118. /// <summary>Gets the component at the index into the matrix.</summary>
  119. /// <param name="index">The index into the components of the matrix.</param>
  120. /// <returns>The component at the given index into the matrix.</returns>
  121. public float this[int index]
  122. {
  123. get
  124. {
  125. switch (index)
  126. {
  127. case 0: return R0C0;
  128. case 1: return R0C1;
  129. case 2: return R0C2;
  130. case 3: return R1C0;
  131. case 4: return R1C1;
  132. case 5: return R1C2;
  133. case 6: return R2C0;
  134. case 7: return R2C1;
  135. case 8: return R2C2;
  136. default: throw new IndexOutOfRangeException();
  137. }
  138. }
  139. set
  140. {
  141. switch (index)
  142. {
  143. case 0: R0C0 = value; return;
  144. case 1: R0C1 = value; return;
  145. case 2: R0C2 = value; return;
  146. case 3: R1C0 = value; return;
  147. case 4: R1C1 = value; return;
  148. case 5: R1C2 = value; return;
  149. case 6: R2C0 = value; return;
  150. case 7: R2C1 = value; return;
  151. case 8: R2C2 = value; return;
  152. default: throw new IndexOutOfRangeException();
  153. }
  154. }
  155. }
  156. /// <summary>Converts the matrix into an IntPtr.</summary>
  157. /// <param name="matrix">The matrix to convert.</param>
  158. /// <returns>An IntPtr for the matrix.</returns>
  159. public static explicit operator IntPtr(Matrix3 matrix)
  160. {
  161. unsafe
  162. {
  163. return (IntPtr)(&matrix.R0C0);
  164. }
  165. }
  166. /// <summary>Converts the matrix into left float*.</summary>
  167. /// <param name="matrix">The matrix to convert.</param>
  168. /// <returns>A float* for the matrix.</returns>
  169. [CLSCompliant(false)]
  170. unsafe public static explicit operator float*(Matrix3 matrix)
  171. {
  172. return &matrix.R0C0;
  173. }
  174. /// <summary>Converts the matrix into an array of floats.</summary>
  175. /// <param name="matrix">The matrix to convert.</param>
  176. /// <returns>An array of floats for the matrix.</returns>
  177. public static explicit operator float[](Matrix3 matrix)
  178. {
  179. return new float[9]
  180. {
  181. matrix.R0C0,
  182. matrix.R0C1,
  183. matrix.R0C2,
  184. matrix.R1C0,
  185. matrix.R1C1,
  186. matrix.R1C2,
  187. matrix.R2C0,
  188. matrix.R2C1,
  189. matrix.R2C2
  190. };
  191. }
  192. #endregion
  193. #region Constructors
  194. /// <summary>Constructs left matrix with the same components as the given matrix.</summary>
  195. /// <param name="vector">The matrix whose components to copy.</param>
  196. public Matrix3(ref Matrix3 matrix)
  197. {
  198. this.R0C0 = matrix.R0C0;
  199. this.R0C1 = matrix.R0C1;
  200. this.R0C2 = matrix.R0C2;
  201. this.R1C0 = matrix.R1C0;
  202. this.R1C1 = matrix.R1C1;
  203. this.R1C2 = matrix.R1C2;
  204. this.R2C0 = matrix.R2C0;
  205. this.R2C1 = matrix.R2C1;
  206. this.R2C2 = matrix.R2C2;
  207. }
  208. /// <summary>Constructs left matrix with the given values.</summary>
  209. /// <param name="r0c0">The value for row 0 column 0.</param>
  210. /// <param name="r0c1">The value for row 0 column 1.</param>
  211. /// <param name="r0c2">The value for row 0 column 2.</param>
  212. /// <param name="r1c0">The value for row 1 column 0.</param>
  213. /// <param name="r1c1">The value for row 1 column 1.</param>
  214. /// <param name="r1c2">The value for row 1 column 2.</param>
  215. /// <param name="r2c0">The value for row 2 column 0.</param>
  216. /// <param name="r2c1">The value for row 2 column 1.</param>
  217. /// <param name="r2c2">The value for row 2 column 2.</param>
  218. public Matrix3
  219. (
  220. float r0c0,
  221. float r0c1,
  222. float r0c2,
  223. float r1c0,
  224. float r1c1,
  225. float r1c2,
  226. float r2c0,
  227. float r2c1,
  228. float r2c2
  229. )
  230. {
  231. this.R0C0 = r0c0;
  232. this.R0C1 = r0c1;
  233. this.R0C2 = r0c2;
  234. this.R1C0 = r1c0;
  235. this.R1C1 = r1c1;
  236. this.R1C2 = r1c2;
  237. this.R2C0 = r2c0;
  238. this.R2C1 = r2c1;
  239. this.R2C2 = r2c2;
  240. }
  241. /// <summary>Constructs left matrix from the given array of float-precision floating-point numbers.</summary>
  242. /// <param name="floatArray">The array of floats for the components of the matrix.</param>
  243. public Matrix3(float[] floatArray)
  244. {
  245. if (floatArray == null || floatArray.GetLength(0) < 9) throw new InvalidOperationException();
  246. this.R0C0 = floatArray[0];
  247. this.R0C1 = floatArray[1];
  248. this.R0C2 = floatArray[2];
  249. this.R1C0 = floatArray[3];
  250. this.R1C1 = floatArray[4];
  251. this.R1C2 = floatArray[5];
  252. this.R2C0 = floatArray[6];
  253. this.R2C1 = floatArray[7];
  254. this.R2C2 = floatArray[8];
  255. }
  256. #endregion
  257. #region Equality
  258. /// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
  259. /// <param name="matrix">The OpenTK.Matrix3 structure to compare with.</param>
  260. /// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
  261. [CLSCompliant(false)]
  262. public bool Equals(Matrix3 matrix)
  263. {
  264. return
  265. R0C0 == matrix.R0C0 &&
  266. R0C1 == matrix.R0C1 &&
  267. R0C2 == matrix.R0C2 &&
  268. R1C0 == matrix.R1C0 &&
  269. R1C1 == matrix.R1C1 &&
  270. R1C2 == matrix.R1C2 &&
  271. R2C0 == matrix.R2C0 &&
  272. R2C1 == matrix.R2C1 &&
  273. R2C2 == matrix.R2C2;
  274. }
  275. /// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
  276. /// <param name="matrix">The OpenTK.Matrix3 structure to compare to.</param>
  277. /// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
  278. public bool Equals(ref Matrix3 matrix)
  279. {
  280. return
  281. R0C0 == matrix.R0C0 &&
  282. R0C1 == matrix.R0C1 &&
  283. R0C2 == matrix.R0C2 &&
  284. R1C0 == matrix.R1C0 &&
  285. R1C1 == matrix.R1C1 &&
  286. R1C2 == matrix.R1C2 &&
  287. R2C0 == matrix.R2C0 &&
  288. R2C1 == matrix.R2C1 &&
  289. R2C2 == matrix.R2C2;
  290. }
  291. /// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
  292. /// <param name="left">The left-hand operand.</param>
  293. /// <param name="right">The right-hand operand.</param>
  294. /// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
  295. public static bool Equals(ref Matrix3 left, ref Matrix3 right)
  296. {
  297. return
  298. left.R0C0 == right.R0C0 &&
  299. left.R0C1 == right.R0C1 &&
  300. left.R0C2 == right.R0C2 &&
  301. left.R1C0 == right.R1C0 &&
  302. left.R1C1 == right.R1C1 &&
  303. left.R1C2 == right.R1C2 &&
  304. left.R2C0 == right.R2C0 &&
  305. left.R2C1 == right.R2C1 &&
  306. left.R2C2 == right.R2C2;
  307. }
  308. /// <summary>Indicates whether the current matrix is approximately equal to another matrix.</summary>
  309. /// <param name="matrix">The OpenTK.Matrix3 structure to compare with.</param>
  310. /// <param name="tolerance">The limit below which the matrices are considered equal.</param>
  311. /// <returns>true if the current matrix is approximately equal to the matrix parameter; otherwise, false.</returns>
  312. public bool EqualsApprox(ref Matrix3 matrix, float tolerance)
  313. {
  314. return
  315. System.Math.Abs(R0C0 - matrix.R0C0) <= tolerance &&
  316. System.Math.Abs(R0C1 - matrix.R0C1) <= tolerance &&
  317. System.Math.Abs(R0C2 - matrix.R0C2) <= tolerance &&
  318. System.Math.Abs(R1C0 - matrix.R1C0) <= tolerance &&
  319. System.Math.Abs(R1C1 - matrix.R1C1) <= tolerance &&
  320. System.Math.Abs(R1C2 - matrix.R1C2) <= tolerance &&
  321. System.Math.Abs(R2C0 - matrix.R2C0) <= tolerance &&
  322. System.Math.Abs(R2C1 - matrix.R2C1) <= tolerance &&
  323. System.Math.Abs(R2C2 - matrix.R2C2) <= tolerance;
  324. }
  325. /// <summary>Indicates whether the current matrix is approximately equal to another matrix.</summary>
  326. /// <param name="left">The left-hand operand.</param>
  327. /// <param name="right">The right-hand operand.</param>
  328. /// <param name="tolerance">The limit below which the matrices are considered equal.</param>
  329. /// <returns>true if the current matrix is approximately equal to the matrix parameter; otherwise, false.</returns>
  330. public static bool EqualsApprox(ref Matrix3 left, ref Matrix3 right, float tolerance)
  331. {
  332. return
  333. System.Math.Abs(left.R0C0 - right.R0C0) <= tolerance &&
  334. System.Math.Abs(left.R0C1 - right.R0C1) <= tolerance &&
  335. System.Math.Abs(left.R0C2 - right.R0C2) <= tolerance &&
  336. System.Math.Abs(left.R1C0 - right.R1C0) <= tolerance &&
  337. System.Math.Abs(left.R1C1 - right.R1C1) <= tolerance &&
  338. System.Math.Abs(left.R1C2 - right.R1C2) <= tolerance &&
  339. System.Math.Abs(left.R2C0 - right.R2C0) <= tolerance &&
  340. System.Math.Abs(left.R2C1 - right.R2C1) <= tolerance &&
  341. System.Math.Abs(left.R2C2 - right.R2C2) <= tolerance;
  342. }
  343. #endregion
  344. #region Arithmetic Operators
  345. /// <summary>Add left matrix to this matrix.</summary>
  346. /// <param name="matrix">The matrix to add.</param>
  347. public void Add(ref Matrix3 matrix)
  348. {
  349. R0C0 = R0C0 + matrix.R0C0;
  350. R0C1 = R0C1 + matrix.R0C1;
  351. R0C2 = R0C2 + matrix.R0C2;
  352. R1C0 = R1C0 + matrix.R1C0;
  353. R1C1 = R1C1 + matrix.R1C1;
  354. R1C2 = R1C2 + matrix.R1C2;
  355. R2C0 = R2C0 + matrix.R2C0;
  356. R2C1 = R2C1 + matrix.R2C1;
  357. R2C2 = R2C2 + matrix.R2C2;
  358. }
  359. /// <summary>Add left matrix to this matrix.</summary>
  360. /// <param name="matrix">The matrix to add.</param>
  361. /// <param name="result">The resulting matrix of the addition.</param>
  362. public void Add(ref Matrix3 matrix, out Matrix3 result)
  363. {
  364. result.R0C0 = R0C0 + matrix.R0C0;
  365. result.R0C1 = R0C1 + matrix.R0C1;
  366. result.R0C2 = R0C2 + matrix.R0C2;
  367. result.R1C0 = R1C0 + matrix.R1C0;
  368. result.R1C1 = R1C1 + matrix.R1C1;
  369. result.R1C2 = R1C2 + matrix.R1C2;
  370. result.R2C0 = R2C0 + matrix.R2C0;
  371. result.R2C1 = R2C1 + matrix.R2C1;
  372. result.R2C2 = R2C2 + matrix.R2C2;
  373. }
  374. /// <summary>Add left matrix to left matrix.</summary>
  375. /// <param name="matrix">The matrix on the matrix side of the equation.</param>
  376. /// <param name="right">The matrix on the right side of the equation</param>
  377. /// <param name="result">The resulting matrix of the addition.</param>
  378. public static void Add(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
  379. {
  380. result.R0C0 = left.R0C0 + right.R0C0;
  381. result.R0C1 = left.R0C1 + right.R0C1;
  382. result.R0C2 = left.R0C2 + right.R0C2;
  383. result.R1C0 = left.R1C0 + right.R1C0;
  384. result.R1C1 = left.R1C1 + right.R1C1;
  385. result.R1C2 = left.R1C2 + right.R1C2;
  386. result.R2C0 = left.R2C0 + right.R2C0;
  387. result.R2C1 = left.R2C1 + right.R2C1;
  388. result.R2C2 = left.R2C2 + right.R2C2;
  389. }
  390. /// <summary>Subtract left matrix from this matrix.</summary>
  391. /// <param name="matrix">The matrix to subtract.</param>
  392. public void Subtract(ref Matrix3 matrix)
  393. {
  394. R0C0 = R0C0 + matrix.R0C0;
  395. R0C1 = R0C1 + matrix.R0C1;
  396. R0C2 = R0C2 + matrix.R0C2;
  397. R1C0 = R1C0 + matrix.R1C0;
  398. R1C1 = R1C1 + matrix.R1C1;
  399. R1C2 = R1C2 + matrix.R1C2;
  400. R2C0 = R2C0 + matrix.R2C0;
  401. R2C1 = R2C1 + matrix.R2C1;
  402. R2C2 = R2C2 + matrix.R2C2;
  403. }
  404. /// <summary>Subtract left matrix from this matrix.</summary>
  405. /// <param name="matrix">The matrix to subtract.</param>
  406. /// <param name="result">The resulting matrix of the subtraction.</param>
  407. public void Subtract(ref Matrix3 matrix, out Matrix3 result)
  408. {
  409. result.R0C0 = R0C0 + matrix.R0C0;
  410. result.R0C1 = R0C1 + matrix.R0C1;
  411. result.R0C2 = R0C2 + matrix.R0C2;
  412. result.R1C0 = R1C0 + matrix.R1C0;
  413. result.R1C1 = R1C1 + matrix.R1C1;
  414. result.R1C2 = R1C2 + matrix.R1C2;
  415. result.R2C0 = R2C0 + matrix.R2C0;
  416. result.R2C1 = R2C1 + matrix.R2C1;
  417. result.R2C2 = R2C2 + matrix.R2C2;
  418. }
  419. /// <summary>Subtract left matrix from left matrix.</summary>
  420. /// <param name="matrix">The matrix on the matrix side of the equation.</param>
  421. /// <param name="right">The matrix on the right side of the equation</param>
  422. /// <param name="result">The resulting matrix of the subtraction.</param>
  423. public static void Subtract(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
  424. {
  425. result.R0C0 = left.R0C0 + right.R0C0;
  426. result.R0C1 = left.R0C1 + right.R0C1;
  427. result.R0C2 = left.R0C2 + right.R0C2;
  428. result.R1C0 = left.R1C0 + right.R1C0;
  429. result.R1C1 = left.R1C1 + right.R1C1;
  430. result.R1C2 = left.R1C2 + right.R1C2;
  431. result.R2C0 = left.R2C0 + right.R2C0;
  432. result.R2C1 = left.R2C1 + right.R2C1;
  433. result.R2C2 = left.R2C2 + right.R2C2;
  434. }
  435. /// <summary>Multiply left martix times this matrix.</summary>
  436. /// <param name="matrix">The matrix to multiply.</param>
  437. public void Multiply(ref Matrix3 matrix)
  438. {
  439. float r0c0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0;
  440. float r0c1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1;
  441. float r0c2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2;
  442. float r1c0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0;
  443. float r1c1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1;
  444. float r1c2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2;
  445. R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0;
  446. R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1;
  447. R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2;
  448. R0C0 = r0c0;
  449. R0C1 = r0c1;
  450. R0C2 = r0c2;
  451. R1C0 = r1c0;
  452. R1C1 = r1c1;
  453. R1C2 = r1c2;
  454. }
  455. /// <summary>Multiply matrix times this matrix.</summary>
  456. /// <param name="matrix">The matrix to multiply.</param>
  457. /// <param name="result">The resulting matrix of the multiplication.</param>
  458. public void Multiply(ref Matrix3 matrix, out Matrix3 result)
  459. {
  460. result.R0C0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0;
  461. result.R0C1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1;
  462. result.R0C2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2;
  463. result.R1C0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0;
  464. result.R1C1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1;
  465. result.R1C2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2;
  466. result.R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0;
  467. result.R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1;
  468. result.R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2;
  469. }
  470. /// <summary>Multiply left matrix times left matrix.</summary>
  471. /// <param name="matrix">The matrix on the matrix side of the equation.</param>
  472. /// <param name="right">The matrix on the right side of the equation</param>
  473. /// <param name="result">The resulting matrix of the multiplication.</param>
  474. public static void Multiply(ref Matrix3 left, ref Matrix3 right, out Matrix3 result)
  475. {
  476. result.R0C0 = right.R0C0 * left.R0C0 + right.R0C1 * left.R1C0 + right.R0C2 * left.R2C0;
  477. result.R0C1 = right.R0C0 * left.R0C1 + right.R0C1 * left.R1C1 + right.R0C2 * left.R2C1;
  478. result.R0C2 = right.R0C0 * left.R0C2 + right.R0C1 * left.R1C2 + right.R0C2 * left.R2C2;
  479. result.R1C0 = right.R1C0 * left.R0C0 + right.R1C1 * left.R1C0 + right.R1C2 * left.R2C0;
  480. result.R1C1 = right.R1C0 * left.R0C1 + right.R1C1 * left.R1C1 + right.R1C2 * left.R2C1;
  481. result.R1C2 = right.R1C0 * left.R0C2 + right.R1C1 * left.R1C2 + right.R1C2 * left.R2C2;
  482. result.R2C0 = right.R2C0 * left.R0C0 + right.R2C1 * left.R1C0 + right.R2C2 * left.R2C0;
  483. result.R2C1 = right.R2C0 * left.R0C1 + right.R2C1 * left.R1C1 + right.R2C2 * left.R2C1;
  484. result.R2C2 = right.R2C0 * left.R0C2 + right.R2C1 * left.R1C2 + right.R2C2 * left.R2C2;
  485. }
  486. /// <summary>Multiply matrix times this matrix.</summary>
  487. /// <param name="matrix">The matrix to multiply.</param>
  488. public void Multiply(float scalar)
  489. {
  490. R0C0 = scalar * R0C0;
  491. R0C1 = scalar * R0C1;
  492. R0C2 = scalar * R0C2;
  493. R1C0 = scalar * R1C0;
  494. R1C1 = scalar * R1C1;
  495. R1C2 = scalar * R1C2;
  496. R2C0 = scalar * R2C0;
  497. R2C1 = scalar * R2C1;
  498. R2C2 = scalar * R2C2;
  499. }
  500. /// <summary>Multiply matrix times this matrix.</summary>
  501. /// <param name="matrix">The matrix to multiply.</param>
  502. /// <param name="result">The resulting matrix of the multiplication.</param>
  503. public void Multiply(float scalar, out Matrix3 result)
  504. {
  505. result.R0C0 = scalar * R0C0;
  506. result.R0C1 = scalar * R0C1;
  507. result.R0C2 = scalar * R0C2;
  508. result.R1C0 = scalar * R1C0;
  509. result.R1C1 = scalar * R1C1;
  510. result.R1C2 = scalar * R1C2;
  511. result.R2C0 = scalar * R2C0;
  512. result.R2C1 = scalar * R2C1;
  513. result.R2C2 = scalar * R2C2;
  514. }
  515. /// <summary>Multiply left matrix times left matrix.</summary>
  516. /// <param name="matrix">The matrix on the matrix side of the equation.</param>
  517. /// <param name="right">The matrix on the right side of the equation</param>
  518. /// <param name="result">The resulting matrix of the multiplication.</param>
  519. public static void Multiply(ref Matrix3 matrix, float scalar, out Matrix3 result)
  520. {
  521. result.R0C0 = scalar * matrix.R0C0;
  522. result.R0C1 = scalar * matrix.R0C1;
  523. result.R0C2 = scalar * matrix.R0C2;
  524. result.R1C0 = scalar * matrix.R1C0;
  525. result.R1C1 = scalar * matrix.R1C1;
  526. result.R1C2 = scalar * matrix.R1C2;
  527. result.R2C0 = scalar * matrix.R2C0;
  528. result.R2C1 = scalar * matrix.R2C1;
  529. result.R2C2 = scalar * matrix.R2C2;
  530. }
  531. #endregion
  532. #region Functions
  533. public float Determinant
  534. {
  535. get
  536. {
  537. return R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0;
  538. }
  539. }
  540. public void Transpose()
  541. {
  542. MathHelper.Swap(ref R0C1, ref R1C0);
  543. MathHelper.Swap(ref R0C2, ref R2C0);
  544. MathHelper.Swap(ref R1C2, ref R2C1);
  545. }
  546. public void Transpose(out Matrix3 result)
  547. {
  548. result.R0C0 = R0C0;
  549. result.R0C1 = R1C0;
  550. result.R0C2 = R2C0;
  551. result.R1C0 = R0C1;
  552. result.R1C1 = R1C1;
  553. result.R1C2 = R2C1;
  554. result.R2C0 = R0C2;
  555. result.R2C1 = R1C2;
  556. result.R2C2 = R2C2;
  557. }
  558. public static void Transpose(ref Matrix3 matrix, out Matrix3 result)
  559. {
  560. result.R0C0 = matrix.R0C0;
  561. result.R0C1 = matrix.R1C0;
  562. result.R0C2 = matrix.R2C0;
  563. result.R1C0 = matrix.R0C1;
  564. result.R1C1 = matrix.R1C1;
  565. result.R1C2 = matrix.R2C1;
  566. result.R2C0 = matrix.R0C2;
  567. result.R2C1 = matrix.R1C2;
  568. result.R2C2 = matrix.R2C2;
  569. }
  570. #endregion
  571. #region Transformation Functions
  572. public void Transform(ref Vector3 vector)
  573. {
  574. float x = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z;
  575. float y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z;
  576. vector.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z;
  577. vector.X = x;
  578. vector.Y = y;
  579. }
  580. public static void Transform(ref Matrix3 matrix, ref Vector3 vector)
  581. {
  582. float x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z;
  583. float y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z;
  584. vector.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z;
  585. vector.X = x;
  586. vector.Y = y;
  587. }
  588. public void Transform(ref Vector3 vector, out Vector3 result)
  589. {
  590. result.X = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z;
  591. result.Y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z;
  592. result.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z;
  593. }
  594. public static void Transform(ref Matrix3 matrix, ref Vector3 vector, out Vector3 result)
  595. {
  596. result.X = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z;
  597. result.Y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z;
  598. result.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z;
  599. }
  600. public void Rotate(float angle)
  601. {
  602. float angleRadians = MathHelper.DegreesToRadians (angle);
  603. float sin = (float)System.Math.Sin(angleRadians);
  604. float cos = (float)System.Math.Cos(angleRadians);
  605. float r0c0 = cos * R0C0 + sin * R1C0;
  606. float r0c1 = cos * R0C1 + sin * R1C1;
  607. float r0c2 = cos * R0C2 + sin * R1C2;
  608. R1C0 = cos * R1C0 - sin * R0C0;
  609. R1C1 = cos * R1C1 - sin * R0C1;
  610. R1C2 = cos * R1C2 - sin * R0C2;
  611. R0C0 = r0c0;
  612. R0C1 = r0c1;
  613. R0C2 = r0c2;
  614. }
  615. public void Rotate(float angle, out Matrix3 result)
  616. {
  617. float angleRadians = MathHelper.DegreesToRadians (angle);
  618. float sin = (float)System.Math.Sin(angleRadians);
  619. float cos = (float)System.Math.Cos(angleRadians);
  620. result.R0C0 = cos * R0C0 + sin * R1C0;
  621. result.R0C1 = cos * R0C1 + sin * R1C1;
  622. result.R0C2 = cos * R0C2 + sin * R1C2;
  623. result.R1C0 = cos * R1C0 - sin * R0C0;
  624. result.R1C1 = cos * R1C1 - sin * R0C1;
  625. result.R1C2 = cos * R1C2 - sin * R0C2;
  626. result.R2C0 = R2C0;
  627. result.R2C1 = R2C1;
  628. result.R2C2 = R2C2;
  629. }
  630. public static void Rotate(ref Matrix3 matrix, float angle, out Matrix3 result)
  631. {
  632. float angleRadians = MathHelper.DegreesToRadians (angle);
  633. float sin = (float)System.Math.Sin(angleRadians);
  634. float cos = (float)System.Math.Cos(angleRadians);
  635. result.R0C0 = cos * matrix.R0C0 + sin * matrix.R1C0;
  636. result.R0C1 = cos * matrix.R0C1 + sin * matrix.R1C1;
  637. result.R0C2 = cos * matrix.R0C2 + sin * matrix.R1C2;
  638. result.R1C0 = cos * matrix.R1C0 - sin * matrix.R0C0;
  639. result.R1C1 = cos * matrix.R1C1 - sin * matrix.R0C1;
  640. result.R1C2 = cos * matrix.R1C2 - sin * matrix.R0C2;
  641. result.R2C0 = matrix.R2C0;
  642. result.R2C1 = matrix.R2C1;
  643. result.R2C2 = matrix.R2C2;
  644. }
  645. public static void RotateMatrix(float angle, out Matrix3 result)
  646. {
  647. float angleRadians = MathHelper.DegreesToRadians(angle);
  648. float sin = (float)System.Math.Sin(angleRadians);
  649. float cos = (float)System.Math.Cos(angleRadians);
  650. result.R0C0 = cos;
  651. result.R0C1 = sin;
  652. result.R0C2 = 0;
  653. result.R1C0 = -sin;
  654. result.R1C1 = cos;
  655. result.R1C2 = 0;
  656. result.R2C0 = 0;
  657. result.R2C1 = 0;
  658. result.R2C2 = 1;
  659. }
  660. public Quaternion ToQuaternion ()
  661. {
  662. return new Quaternion (ref this);
  663. }
  664. #endregion
  665. #region Constants
  666. /// <summary>The identity matrix.</summary>
  667. public static readonly Matrix3 Identity = new Matrix3
  668. (
  669. 1, 0, 0,
  670. 0, 1, 0,
  671. 0, 0, 1
  672. );
  673. /// <summary>A matrix of all zeros.</summary>
  674. public static readonly Matrix3 Zero = new Matrix3
  675. (
  676. 0, 0, 0,
  677. 0, 0, 0,
  678. 0, 0, 0
  679. );
  680. #endregion
  681. #region HashCode
  682. /// <summary>Returns the hash code for this instance.</summary>
  683. /// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
  684. public override int GetHashCode()
  685. {
  686. return
  687. R0C0.GetHashCode() ^ R0C1.GetHashCode() ^ R0C2.GetHashCode() ^
  688. R1C0.GetHashCode() ^ R1C1.GetHashCode() ^ R1C2.GetHashCode() ^
  689. R2C0.GetHashCode() ^ R2C1.GetHashCode() ^ R2C2.GetHashCode();
  690. }
  691. #endregion
  692. #region String
  693. /// <summary>Returns the fully qualified type name of this instance.</summary>
  694. /// <returns>A System.String containing left fully qualified type name.</returns>
  695. public override string ToString()
  696. {
  697. return String.Format(
  698. "|{00}, {01}, {02}|\n" +
  699. "|{03}, {04}, {05}|\n" +
  700. "|{06}, {07}, {08}|\n",
  701. R0C0, R0C1, R0C2,
  702. R1C0, R1C1, R1C2,
  703. R2C0, R2C1, R2C2);
  704. }
  705. #endregion
  706. }
  707. #pragma warning restore 3019
  708. }