Quaternion.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. // MIT License - Copyright (C) The Mono.Xna Team
  2. // This file is subject to the terms and conditions defined in
  3. // file 'LICENSE.txt', which is part of this source code package.
  4. using System;
  5. using System.Diagnostics;
  6. using System.Runtime.Serialization;
  7. namespace CommonLang.Geometry
  8. {
  9. public struct Quaternion : IEquatable<Quaternion>
  10. {
  11. public float X;
  12. public float Y;
  13. public float Z;
  14. public float W;
  15. static Quaternion identity = new Quaternion(0, 0, 0, 1);
  16. public Quaternion(float x, float y, float z, float w)
  17. {
  18. this.X = x;
  19. this.Y = y;
  20. this.Z = z;
  21. this.W = w;
  22. }
  23. public Quaternion(Vector3 vectorPart, float scalarPart)
  24. {
  25. this.X = vectorPart.X;
  26. this.Y = vectorPart.Y;
  27. this.Z = vectorPart.Z;
  28. this.W = scalarPart;
  29. }
  30. public static Quaternion Identity
  31. {
  32. get{ return identity; }
  33. }
  34. public static Quaternion Add(Quaternion quaternion1, Quaternion quaternion2)
  35. {
  36. //Syderis
  37. Quaternion quaternion;
  38. quaternion.X = quaternion1.X + quaternion2.X;
  39. quaternion.Y = quaternion1.Y + quaternion2.Y;
  40. quaternion.Z = quaternion1.Z + quaternion2.Z;
  41. quaternion.W = quaternion1.W + quaternion2.W;
  42. return quaternion;
  43. }
  44. public static void Add(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
  45. {
  46. //Syderis
  47. result.X = quaternion1.X + quaternion2.X;
  48. result.Y = quaternion1.Y + quaternion2.Y;
  49. result.Z = quaternion1.Z + quaternion2.Z;
  50. result.W = quaternion1.W + quaternion2.W;
  51. }
  52. //Funcion añadida Syderis
  53. public static Quaternion Concatenate(Quaternion value1, Quaternion value2)
  54. {
  55. Quaternion quaternion;
  56. float x = value2.X;
  57. float y = value2.Y;
  58. float z = value2.Z;
  59. float w = value2.W;
  60. float num4 = value1.X;
  61. float num3 = value1.Y;
  62. float num2 = value1.Z;
  63. float num = value1.W;
  64. float num12 = (y * num2) - (z * num3);
  65. float num11 = (z * num4) - (x * num2);
  66. float num10 = (x * num3) - (y * num4);
  67. float num9 = ((x * num4) + (y * num3)) + (z * num2);
  68. quaternion.X = ((x * num) + (num4 * w)) + num12;
  69. quaternion.Y = ((y * num) + (num3 * w)) + num11;
  70. quaternion.Z = ((z * num) + (num2 * w)) + num10;
  71. quaternion.W = (w * num) - num9;
  72. return quaternion;
  73. }
  74. //Añadida por Syderis
  75. public static void Concatenate(ref Quaternion value1, ref Quaternion value2, out Quaternion result)
  76. {
  77. float x = value2.X;
  78. float y = value2.Y;
  79. float z = value2.Z;
  80. float w = value2.W;
  81. float num4 = value1.X;
  82. float num3 = value1.Y;
  83. float num2 = value1.Z;
  84. float num = value1.W;
  85. float num12 = (y * num2) - (z * num3);
  86. float num11 = (z * num4) - (x * num2);
  87. float num10 = (x * num3) - (y * num4);
  88. float num9 = ((x * num4) + (y * num3)) + (z * num2);
  89. result.X = ((x * num) + (num4 * w)) + num12;
  90. result.Y = ((y * num) + (num3 * w)) + num11;
  91. result.Z = ((z * num) + (num2 * w)) + num10;
  92. result.W = (w * num) - num9;
  93. }
  94. //Añadida por Syderis
  95. public void Conjugate()
  96. {
  97. this.X = -this.X;
  98. this.Y = -this.Y;
  99. this.Z = -this.Z;
  100. }
  101. //Añadida por Syderis
  102. public static Quaternion Conjugate(Quaternion value)
  103. {
  104. Quaternion quaternion;
  105. quaternion.X = -value.X;
  106. quaternion.Y = -value.Y;
  107. quaternion.Z = -value.Z;
  108. quaternion.W = value.W;
  109. return quaternion;
  110. }
  111. //Añadida por Syderis
  112. public static void Conjugate(ref Quaternion value, out Quaternion result)
  113. {
  114. result.X = -value.X;
  115. result.Y = -value.Y;
  116. result.Z = -value.Z;
  117. result.W = value.W;
  118. }
  119. public static Quaternion CreateFromAxisAngle(Vector3 axis, float angle)
  120. {
  121. Quaternion quaternion;
  122. float num2 = angle * 0.5f;
  123. float num = (float) Math.Sin((double) num2);
  124. float num3 = (float) Math.Cos((double) num2);
  125. quaternion.X = axis.X * num;
  126. quaternion.Y = axis.Y * num;
  127. quaternion.Z = axis.Z * num;
  128. quaternion.W = num3;
  129. return quaternion;
  130. }
  131. public static void CreateFromAxisAngle(ref Vector3 axis, float angle, out Quaternion result)
  132. {
  133. float num2 = angle * 0.5f;
  134. float num = (float) Math.Sin((double) num2);
  135. float num3 = (float) Math.Cos((double) num2);
  136. result.X = axis.X * num;
  137. result.Y = axis.Y * num;
  138. result.Z = axis.Z * num;
  139. result.W = num3;
  140. }
  141. public static Quaternion CreateFromRotationMatrix(Matrix matrix)
  142. {
  143. float num8 = (matrix.M11 + matrix.M22) + matrix.M33;
  144. Quaternion quaternion = new Quaternion();
  145. if (num8 > 0f)
  146. {
  147. float num = (float) Math.Sqrt((double) (num8 + 1f));
  148. quaternion.W = num * 0.5f;
  149. num = 0.5f / num;
  150. quaternion.X = (matrix.M23 - matrix.M32) * num;
  151. quaternion.Y = (matrix.M31 - matrix.M13) * num;
  152. quaternion.Z = (matrix.M12 - matrix.M21) * num;
  153. return quaternion;
  154. }
  155. if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
  156. {
  157. float num7 = (float) Math.Sqrt((double) (((1f + matrix.M11) - matrix.M22) - matrix.M33));
  158. float num4 = 0.5f / num7;
  159. quaternion.X = 0.5f * num7;
  160. quaternion.Y = (matrix.M12 + matrix.M21) * num4;
  161. quaternion.Z = (matrix.M13 + matrix.M31) * num4;
  162. quaternion.W = (matrix.M23 - matrix.M32) * num4;
  163. return quaternion;
  164. }
  165. if (matrix.M22 > matrix.M33)
  166. {
  167. float num6 = (float) Math.Sqrt((double) (((1f + matrix.M22) - matrix.M11) - matrix.M33));
  168. float num3 = 0.5f / num6;
  169. quaternion.X = (matrix.M21 + matrix.M12) * num3;
  170. quaternion.Y = 0.5f * num6;
  171. quaternion.Z = (matrix.M32 + matrix.M23) * num3;
  172. quaternion.W = (matrix.M31 - matrix.M13) * num3;
  173. return quaternion;
  174. }
  175. float num5 = (float) Math.Sqrt((double) (((1f + matrix.M33) - matrix.M11) - matrix.M22));
  176. float num2 = 0.5f / num5;
  177. quaternion.X = (matrix.M31 + matrix.M13) * num2;
  178. quaternion.Y = (matrix.M32 + matrix.M23) * num2;
  179. quaternion.Z = 0.5f * num5;
  180. quaternion.W = (matrix.M12 - matrix.M21) * num2;
  181. return quaternion;
  182. }
  183. public static void CreateFromRotationMatrix(ref Matrix matrix, out Quaternion result)
  184. {
  185. float num8 = (matrix.M11 + matrix.M22) + matrix.M33;
  186. if (num8 > 0f)
  187. {
  188. float num = (float) Math.Sqrt((double) (num8 + 1f));
  189. result.W = num * 0.5f;
  190. num = 0.5f / num;
  191. result.X = (matrix.M23 - matrix.M32) * num;
  192. result.Y = (matrix.M31 - matrix.M13) * num;
  193. result.Z = (matrix.M12 - matrix.M21) * num;
  194. }
  195. else if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
  196. {
  197. float num7 = (float) Math.Sqrt((double) (((1f + matrix.M11) - matrix.M22) - matrix.M33));
  198. float num4 = 0.5f / num7;
  199. result.X = 0.5f * num7;
  200. result.Y = (matrix.M12 + matrix.M21) * num4;
  201. result.Z = (matrix.M13 + matrix.M31) * num4;
  202. result.W = (matrix.M23 - matrix.M32) * num4;
  203. }
  204. else if (matrix.M22 > matrix.M33)
  205. {
  206. float num6 = (float) Math.Sqrt((double) (((1f + matrix.M22) - matrix.M11) - matrix.M33));
  207. float num3 = 0.5f / num6;
  208. result.X = (matrix.M21 + matrix.M12) * num3;
  209. result.Y = 0.5f * num6;
  210. result.Z = (matrix.M32 + matrix.M23) * num3;
  211. result.W = (matrix.M31 - matrix.M13) * num3;
  212. }
  213. else
  214. {
  215. float num5 = (float) Math.Sqrt((double) (((1f + matrix.M33) - matrix.M11) - matrix.M22));
  216. float num2 = 0.5f / num5;
  217. result.X = (matrix.M31 + matrix.M13) * num2;
  218. result.Y = (matrix.M32 + matrix.M23) * num2;
  219. result.Z = 0.5f * num5;
  220. result.W = (matrix.M12 - matrix.M21) * num2;
  221. }
  222. }
  223. public static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll)
  224. {
  225. Quaternion quaternion;
  226. float num9 = roll * 0.5f;
  227. float num6 = (float) Math.Sin((double) num9);
  228. float num5 = (float) Math.Cos((double) num9);
  229. float num8 = pitch * 0.5f;
  230. float num4 = (float) Math.Sin((double) num8);
  231. float num3 = (float) Math.Cos((double) num8);
  232. float num7 = yaw * 0.5f;
  233. float num2 = (float) Math.Sin((double) num7);
  234. float num = (float) Math.Cos((double) num7);
  235. quaternion.X = ((num * num4) * num5) + ((num2 * num3) * num6);
  236. quaternion.Y = ((num2 * num3) * num5) - ((num * num4) * num6);
  237. quaternion.Z = ((num * num3) * num6) - ((num2 * num4) * num5);
  238. quaternion.W = ((num * num3) * num5) + ((num2 * num4) * num6);
  239. return quaternion;
  240. }
  241. public static void CreateFromYawPitchRoll(float yaw, float pitch, float roll, out Quaternion result)
  242. {
  243. float num9 = roll * 0.5f;
  244. float num6 = (float) Math.Sin((double) num9);
  245. float num5 = (float) Math.Cos((double) num9);
  246. float num8 = pitch * 0.5f;
  247. float num4 = (float) Math.Sin((double) num8);
  248. float num3 = (float) Math.Cos((double) num8);
  249. float num7 = yaw * 0.5f;
  250. float num2 = (float) Math.Sin((double) num7);
  251. float num = (float) Math.Cos((double) num7);
  252. result.X = ((num * num4) * num5) + ((num2 * num3) * num6);
  253. result.Y = ((num2 * num3) * num5) - ((num * num4) * num6);
  254. result.Z = ((num * num3) * num6) - ((num2 * num4) * num5);
  255. result.W = ((num * num3) * num5) + ((num2 * num4) * num6);
  256. }
  257. public static Quaternion Divide(Quaternion quaternion1, Quaternion quaternion2)
  258. {
  259. Quaternion quaternion;
  260. float x = quaternion1.X;
  261. float y = quaternion1.Y;
  262. float z = quaternion1.Z;
  263. float w = quaternion1.W;
  264. float num14 = (((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y)) + (quaternion2.Z * quaternion2.Z)) + (quaternion2.W * quaternion2.W);
  265. float num5 = 1f / num14;
  266. float num4 = -quaternion2.X * num5;
  267. float num3 = -quaternion2.Y * num5;
  268. float num2 = -quaternion2.Z * num5;
  269. float num = quaternion2.W * num5;
  270. float num13 = (y * num2) - (z * num3);
  271. float num12 = (z * num4) - (x * num2);
  272. float num11 = (x * num3) - (y * num4);
  273. float num10 = ((x * num4) + (y * num3)) + (z * num2);
  274. quaternion.X = ((x * num) + (num4 * w)) + num13;
  275. quaternion.Y = ((y * num) + (num3 * w)) + num12;
  276. quaternion.Z = ((z * num) + (num2 * w)) + num11;
  277. quaternion.W = (w * num) - num10;
  278. return quaternion;
  279. }
  280. public static void Divide(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
  281. {
  282. float x = quaternion1.X;
  283. float y = quaternion1.Y;
  284. float z = quaternion1.Z;
  285. float w = quaternion1.W;
  286. float num14 = (((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y)) + (quaternion2.Z * quaternion2.Z)) + (quaternion2.W * quaternion2.W);
  287. float num5 = 1f / num14;
  288. float num4 = -quaternion2.X * num5;
  289. float num3 = -quaternion2.Y * num5;
  290. float num2 = -quaternion2.Z * num5;
  291. float num = quaternion2.W * num5;
  292. float num13 = (y * num2) - (z * num3);
  293. float num12 = (z * num4) - (x * num2);
  294. float num11 = (x * num3) - (y * num4);
  295. float num10 = ((x * num4) + (y * num3)) + (z * num2);
  296. result.X = ((x * num) + (num4 * w)) + num13;
  297. result.Y = ((y * num) + (num3 * w)) + num12;
  298. result.Z = ((z * num) + (num2 * w)) + num11;
  299. result.W = (w * num) - num10;
  300. }
  301. public static float Dot(Quaternion quaternion1, Quaternion quaternion2)
  302. {
  303. return ((((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W));
  304. }
  305. public static void Dot(ref Quaternion quaternion1, ref Quaternion quaternion2, out float result)
  306. {
  307. result = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
  308. }
  309. public override bool Equals(object obj)
  310. {
  311. bool flag = false;
  312. if (obj is Quaternion)
  313. {
  314. flag = this.Equals((Quaternion) obj);
  315. }
  316. return flag;
  317. }
  318. public bool Equals(Quaternion other)
  319. {
  320. return ((((this.X == other.X) && (this.Y == other.Y)) && (this.Z == other.Z)) && (this.W == other.W));
  321. }
  322. public override int GetHashCode()
  323. {
  324. return (((this.X.GetHashCode() + this.Y.GetHashCode()) + this.Z.GetHashCode()) + this.W.GetHashCode());
  325. }
  326. public static Quaternion Inverse(Quaternion quaternion)
  327. {
  328. Quaternion quaternion2;
  329. float num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
  330. float num = 1f / num2;
  331. quaternion2.X = -quaternion.X * num;
  332. quaternion2.Y = -quaternion.Y * num;
  333. quaternion2.Z = -quaternion.Z * num;
  334. quaternion2.W = quaternion.W * num;
  335. return quaternion2;
  336. }
  337. public static void Inverse(ref Quaternion quaternion, out Quaternion result)
  338. {
  339. float num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
  340. float num = 1f / num2;
  341. result.X = -quaternion.X * num;
  342. result.Y = -quaternion.Y * num;
  343. result.Z = -quaternion.Z * num;
  344. result.W = quaternion.W * num;
  345. }
  346. public float Length()
  347. {
  348. float num = (((this.X * this.X) + (this.Y * this.Y)) + (this.Z * this.Z)) + (this.W * this.W);
  349. return (float) Math.Sqrt((double) num);
  350. }
  351. public float LengthSquared()
  352. {
  353. return ((((this.X * this.X) + (this.Y * this.Y)) + (this.Z * this.Z)) + (this.W * this.W));
  354. }
  355. public static Quaternion Lerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
  356. {
  357. float num = amount;
  358. float num2 = 1f - num;
  359. Quaternion quaternion = new Quaternion();
  360. float num5 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
  361. if (num5 >= 0f)
  362. {
  363. quaternion.X = (num2 * quaternion1.X) + (num * quaternion2.X);
  364. quaternion.Y = (num2 * quaternion1.Y) + (num * quaternion2.Y);
  365. quaternion.Z = (num2 * quaternion1.Z) + (num * quaternion2.Z);
  366. quaternion.W = (num2 * quaternion1.W) + (num * quaternion2.W);
  367. }
  368. else
  369. {
  370. quaternion.X = (num2 * quaternion1.X) - (num * quaternion2.X);
  371. quaternion.Y = (num2 * quaternion1.Y) - (num * quaternion2.Y);
  372. quaternion.Z = (num2 * quaternion1.Z) - (num * quaternion2.Z);
  373. quaternion.W = (num2 * quaternion1.W) - (num * quaternion2.W);
  374. }
  375. float num4 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
  376. float num3 = 1f / ((float) Math.Sqrt((double) num4));
  377. quaternion.X *= num3;
  378. quaternion.Y *= num3;
  379. quaternion.Z *= num3;
  380. quaternion.W *= num3;
  381. return quaternion;
  382. }
  383. public static void Lerp(ref Quaternion quaternion1, ref Quaternion quaternion2, float amount, out Quaternion result)
  384. {
  385. float num = amount;
  386. float num2 = 1f - num;
  387. float num5 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
  388. if (num5 >= 0f)
  389. {
  390. result.X = (num2 * quaternion1.X) + (num * quaternion2.X);
  391. result.Y = (num2 * quaternion1.Y) + (num * quaternion2.Y);
  392. result.Z = (num2 * quaternion1.Z) + (num * quaternion2.Z);
  393. result.W = (num2 * quaternion1.W) + (num * quaternion2.W);
  394. }
  395. else
  396. {
  397. result.X = (num2 * quaternion1.X) - (num * quaternion2.X);
  398. result.Y = (num2 * quaternion1.Y) - (num * quaternion2.Y);
  399. result.Z = (num2 * quaternion1.Z) - (num * quaternion2.Z);
  400. result.W = (num2 * quaternion1.W) - (num * quaternion2.W);
  401. }
  402. float num4 = (((result.X * result.X) + (result.Y * result.Y)) + (result.Z * result.Z)) + (result.W * result.W);
  403. float num3 = 1f / ((float) Math.Sqrt((double) num4));
  404. result.X *= num3;
  405. result.Y *= num3;
  406. result.Z *= num3;
  407. result.W *= num3;
  408. }
  409. public static Quaternion Slerp(Quaternion quaternion1, Quaternion quaternion2, float amount)
  410. {
  411. float num2;
  412. float num3;
  413. Quaternion quaternion;
  414. float num = amount;
  415. float num4 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
  416. bool flag = false;
  417. if (num4 < 0f)
  418. {
  419. flag = true;
  420. num4 = -num4;
  421. }
  422. if (num4 > 0.999999f)
  423. {
  424. num3 = 1f - num;
  425. num2 = flag ? -num : num;
  426. }
  427. else
  428. {
  429. float num5 = (float) Math.Acos((double) num4);
  430. float num6 = (float) (1.0 / Math.Sin((double) num5));
  431. num3 = ((float) Math.Sin((double) ((1f - num) * num5))) * num6;
  432. num2 = flag ? (((float) -Math.Sin((double) (num * num5))) * num6) : (((float) Math.Sin((double) (num * num5))) * num6);
  433. }
  434. quaternion.X = (num3 * quaternion1.X) + (num2 * quaternion2.X);
  435. quaternion.Y = (num3 * quaternion1.Y) + (num2 * quaternion2.Y);
  436. quaternion.Z = (num3 * quaternion1.Z) + (num2 * quaternion2.Z);
  437. quaternion.W = (num3 * quaternion1.W) + (num2 * quaternion2.W);
  438. return quaternion;
  439. }
  440. public static void Slerp(ref Quaternion quaternion1, ref Quaternion quaternion2, float amount, out Quaternion result)
  441. {
  442. float num2;
  443. float num3;
  444. float num = amount;
  445. float num4 = (((quaternion1.X * quaternion2.X) + (quaternion1.Y * quaternion2.Y)) + (quaternion1.Z * quaternion2.Z)) + (quaternion1.W * quaternion2.W);
  446. bool flag = false;
  447. if (num4 < 0f)
  448. {
  449. flag = true;
  450. num4 = -num4;
  451. }
  452. if (num4 > 0.999999f)
  453. {
  454. num3 = 1f - num;
  455. num2 = flag ? -num : num;
  456. }
  457. else
  458. {
  459. float num5 = (float) Math.Acos((double) num4);
  460. float num6 = (float) (1.0 / Math.Sin((double) num5));
  461. num3 = ((float) Math.Sin((double) ((1f - num) * num5))) * num6;
  462. num2 = flag ? (((float) -Math.Sin((double) (num * num5))) * num6) : (((float) Math.Sin((double) (num * num5))) * num6);
  463. }
  464. result.X = (num3 * quaternion1.X) + (num2 * quaternion2.X);
  465. result.Y = (num3 * quaternion1.Y) + (num2 * quaternion2.Y);
  466. result.Z = (num3 * quaternion1.Z) + (num2 * quaternion2.Z);
  467. result.W = (num3 * quaternion1.W) + (num2 * quaternion2.W);
  468. }
  469. public static Quaternion Subtract(Quaternion quaternion1, Quaternion quaternion2)
  470. {
  471. Quaternion quaternion;
  472. quaternion.X = quaternion1.X - quaternion2.X;
  473. quaternion.Y = quaternion1.Y - quaternion2.Y;
  474. quaternion.Z = quaternion1.Z - quaternion2.Z;
  475. quaternion.W = quaternion1.W - quaternion2.W;
  476. return quaternion;
  477. }
  478. public static void Subtract(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
  479. {
  480. result.X = quaternion1.X - quaternion2.X;
  481. result.Y = quaternion1.Y - quaternion2.Y;
  482. result.Z = quaternion1.Z - quaternion2.Z;
  483. result.W = quaternion1.W - quaternion2.W;
  484. }
  485. public static Quaternion Multiply(Quaternion quaternion1, Quaternion quaternion2)
  486. {
  487. Quaternion quaternion;
  488. float x = quaternion1.X;
  489. float y = quaternion1.Y;
  490. float z = quaternion1.Z;
  491. float w = quaternion1.W;
  492. float num4 = quaternion2.X;
  493. float num3 = quaternion2.Y;
  494. float num2 = quaternion2.Z;
  495. float num = quaternion2.W;
  496. float num12 = (y * num2) - (z * num3);
  497. float num11 = (z * num4) - (x * num2);
  498. float num10 = (x * num3) - (y * num4);
  499. float num9 = ((x * num4) + (y * num3)) + (z * num2);
  500. quaternion.X = ((x * num) + (num4 * w)) + num12;
  501. quaternion.Y = ((y * num) + (num3 * w)) + num11;
  502. quaternion.Z = ((z * num) + (num2 * w)) + num10;
  503. quaternion.W = (w * num) - num9;
  504. return quaternion;
  505. }
  506. public static Quaternion Multiply(Quaternion quaternion1, float scaleFactor)
  507. {
  508. Quaternion quaternion;
  509. quaternion.X = quaternion1.X * scaleFactor;
  510. quaternion.Y = quaternion1.Y * scaleFactor;
  511. quaternion.Z = quaternion1.Z * scaleFactor;
  512. quaternion.W = quaternion1.W * scaleFactor;
  513. return quaternion;
  514. }
  515. public static void Multiply(ref Quaternion quaternion1, float scaleFactor, out Quaternion result)
  516. {
  517. result.X = quaternion1.X * scaleFactor;
  518. result.Y = quaternion1.Y * scaleFactor;
  519. result.Z = quaternion1.Z * scaleFactor;
  520. result.W = quaternion1.W * scaleFactor;
  521. }
  522. public static void Multiply(ref Quaternion quaternion1, ref Quaternion quaternion2, out Quaternion result)
  523. {
  524. float x = quaternion1.X;
  525. float y = quaternion1.Y;
  526. float z = quaternion1.Z;
  527. float w = quaternion1.W;
  528. float num4 = quaternion2.X;
  529. float num3 = quaternion2.Y;
  530. float num2 = quaternion2.Z;
  531. float num = quaternion2.W;
  532. float num12 = (y * num2) - (z * num3);
  533. float num11 = (z * num4) - (x * num2);
  534. float num10 = (x * num3) - (y * num4);
  535. float num9 = ((x * num4) + (y * num3)) + (z * num2);
  536. result.X = ((x * num) + (num4 * w)) + num12;
  537. result.Y = ((y * num) + (num3 * w)) + num11;
  538. result.Z = ((z * num) + (num2 * w)) + num10;
  539. result.W = (w * num) - num9;
  540. }
  541. public static Quaternion Negate(Quaternion quaternion)
  542. {
  543. Quaternion quaternion2;
  544. quaternion2.X = -quaternion.X;
  545. quaternion2.Y = -quaternion.Y;
  546. quaternion2.Z = -quaternion.Z;
  547. quaternion2.W = -quaternion.W;
  548. return quaternion2;
  549. }
  550. public static void Negate(ref Quaternion quaternion, out Quaternion result)
  551. {
  552. result.X = -quaternion.X;
  553. result.Y = -quaternion.Y;
  554. result.Z = -quaternion.Z;
  555. result.W = -quaternion.W;
  556. }
  557. public void Normalize()
  558. {
  559. float num2 = (((this.X * this.X) + (this.Y * this.Y)) + (this.Z * this.Z)) + (this.W * this.W);
  560. float num = 1f / ((float) Math.Sqrt((double) num2));
  561. this.X *= num;
  562. this.Y *= num;
  563. this.Z *= num;
  564. this.W *= num;
  565. }
  566. public static Quaternion Normalize(Quaternion quaternion)
  567. {
  568. Quaternion quaternion2;
  569. float num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
  570. float num = 1f / ((float) Math.Sqrt((double) num2));
  571. quaternion2.X = quaternion.X * num;
  572. quaternion2.Y = quaternion.Y * num;
  573. quaternion2.Z = quaternion.Z * num;
  574. quaternion2.W = quaternion.W * num;
  575. return quaternion2;
  576. }
  577. public static void Normalize(ref Quaternion quaternion, out Quaternion result)
  578. {
  579. float num2 = (((quaternion.X * quaternion.X) + (quaternion.Y * quaternion.Y)) + (quaternion.Z * quaternion.Z)) + (quaternion.W * quaternion.W);
  580. float num = 1f / ((float) Math.Sqrt((double) num2));
  581. result.X = quaternion.X * num;
  582. result.Y = quaternion.Y * num;
  583. result.Z = quaternion.Z * num;
  584. result.W = quaternion.W * num;
  585. }
  586. public static Quaternion operator +(Quaternion quaternion1, Quaternion quaternion2)
  587. {
  588. Quaternion quaternion;
  589. quaternion.X = quaternion1.X + quaternion2.X;
  590. quaternion.Y = quaternion1.Y + quaternion2.Y;
  591. quaternion.Z = quaternion1.Z + quaternion2.Z;
  592. quaternion.W = quaternion1.W + quaternion2.W;
  593. return quaternion;
  594. }
  595. public static Quaternion operator /(Quaternion quaternion1, Quaternion quaternion2)
  596. {
  597. Quaternion quaternion;
  598. float x = quaternion1.X;
  599. float y = quaternion1.Y;
  600. float z = quaternion1.Z;
  601. float w = quaternion1.W;
  602. float num14 = (((quaternion2.X * quaternion2.X) + (quaternion2.Y * quaternion2.Y)) + (quaternion2.Z * quaternion2.Z)) + (quaternion2.W * quaternion2.W);
  603. float num5 = 1f / num14;
  604. float num4 = -quaternion2.X * num5;
  605. float num3 = -quaternion2.Y * num5;
  606. float num2 = -quaternion2.Z * num5;
  607. float num = quaternion2.W * num5;
  608. float num13 = (y * num2) - (z * num3);
  609. float num12 = (z * num4) - (x * num2);
  610. float num11 = (x * num3) - (y * num4);
  611. float num10 = ((x * num4) + (y * num3)) + (z * num2);
  612. quaternion.X = ((x * num) + (num4 * w)) + num13;
  613. quaternion.Y = ((y * num) + (num3 * w)) + num12;
  614. quaternion.Z = ((z * num) + (num2 * w)) + num11;
  615. quaternion.W = (w * num) - num10;
  616. return quaternion;
  617. }
  618. public static bool operator ==(Quaternion quaternion1, Quaternion quaternion2)
  619. {
  620. return ((((quaternion1.X == quaternion2.X) && (quaternion1.Y == quaternion2.Y)) && (quaternion1.Z == quaternion2.Z)) && (quaternion1.W == quaternion2.W));
  621. }
  622. public static bool operator !=(Quaternion quaternion1, Quaternion quaternion2)
  623. {
  624. if (((quaternion1.X == quaternion2.X) && (quaternion1.Y == quaternion2.Y)) && (quaternion1.Z == quaternion2.Z))
  625. {
  626. return (quaternion1.W != quaternion2.W);
  627. }
  628. return true;
  629. }
  630. public static Quaternion operator *(Quaternion quaternion1, Quaternion quaternion2)
  631. {
  632. Quaternion quaternion;
  633. float x = quaternion1.X;
  634. float y = quaternion1.Y;
  635. float z = quaternion1.Z;
  636. float w = quaternion1.W;
  637. float num4 = quaternion2.X;
  638. float num3 = quaternion2.Y;
  639. float num2 = quaternion2.Z;
  640. float num = quaternion2.W;
  641. float num12 = (y * num2) - (z * num3);
  642. float num11 = (z * num4) - (x * num2);
  643. float num10 = (x * num3) - (y * num4);
  644. float num9 = ((x * num4) + (y * num3)) + (z * num2);
  645. quaternion.X = ((x * num) + (num4 * w)) + num12;
  646. quaternion.Y = ((y * num) + (num3 * w)) + num11;
  647. quaternion.Z = ((z * num) + (num2 * w)) + num10;
  648. quaternion.W = (w * num) - num9;
  649. return quaternion;
  650. }
  651. public static Quaternion operator *(Quaternion quaternion1, float scaleFactor)
  652. {
  653. Quaternion quaternion;
  654. quaternion.X = quaternion1.X * scaleFactor;
  655. quaternion.Y = quaternion1.Y * scaleFactor;
  656. quaternion.Z = quaternion1.Z * scaleFactor;
  657. quaternion.W = quaternion1.W * scaleFactor;
  658. return quaternion;
  659. }
  660. public static Quaternion operator -(Quaternion quaternion1, Quaternion quaternion2)
  661. {
  662. Quaternion quaternion;
  663. quaternion.X = quaternion1.X - quaternion2.X;
  664. quaternion.Y = quaternion1.Y - quaternion2.Y;
  665. quaternion.Z = quaternion1.Z - quaternion2.Z;
  666. quaternion.W = quaternion1.W - quaternion2.W;
  667. return quaternion;
  668. }
  669. public static Quaternion operator -(Quaternion quaternion)
  670. {
  671. Quaternion quaternion2;
  672. quaternion2.X = -quaternion.X;
  673. quaternion2.Y = -quaternion.Y;
  674. quaternion2.Z = -quaternion.Z;
  675. quaternion2.W = -quaternion.W;
  676. return quaternion2;
  677. }
  678. internal string DebugDisplayString
  679. {
  680. get
  681. {
  682. if (this == Quaternion.identity)
  683. {
  684. return "Identity";
  685. }
  686. return string.Concat(
  687. this.X.ToString(), " ",
  688. this.Y.ToString(), " ",
  689. this.Z.ToString(), " ",
  690. this.W.ToString()
  691. );
  692. }
  693. }
  694. public override string ToString()
  695. {
  696. System.Text.StringBuilder sb = new System.Text.StringBuilder(32);
  697. sb.Append("{X:");
  698. sb.Append(this.X);
  699. sb.Append(" Y:");
  700. sb.Append(this.Y);
  701. sb.Append(" Z:");
  702. sb.Append(this.Z);
  703. sb.Append(" W:");
  704. sb.Append(this.W);
  705. sb.Append("}");
  706. return sb.ToString();
  707. }
  708. internal Matrix ToMatrix ()
  709. {
  710. Matrix matrix = Matrix.Identity;
  711. ToMatrix(out matrix);
  712. return matrix;
  713. }
  714. internal void ToMatrix (out Matrix matrix)
  715. {
  716. Quaternion.ToMatrix(this, out matrix);
  717. }
  718. internal static void ToMatrix(Quaternion quaternion, out Matrix matrix)
  719. {
  720. // source -> http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation#Quaternion_to_Matrix
  721. float x2 = quaternion.X * quaternion.X;
  722. float y2 = quaternion.Y * quaternion.Y;
  723. float z2 = quaternion.Z * quaternion.Z;
  724. float xy = quaternion.X * quaternion.Y;
  725. float xz = quaternion.X * quaternion.Z;
  726. float yz = quaternion.Y * quaternion.Z;
  727. float wx = quaternion.W * quaternion.X;
  728. float wy = quaternion.W * quaternion.Y;
  729. float wz = quaternion.W * quaternion.Z;
  730. // This calculation would be a lot more complicated for non-unit length quaternions
  731. // Note: The constructor of Matrix4 expects the Matrix in column-major format like expected by
  732. // OpenGL
  733. matrix.M11 = 1.0f - 2.0f * (y2 + z2);
  734. matrix.M12 = 2.0f * (xy - wz);
  735. matrix.M13 = 2.0f * (xz + wy);
  736. matrix.M14 = 0.0f;
  737. matrix.M21 = 2.0f * (xy + wz);
  738. matrix.M22 = 1.0f - 2.0f * (x2 + z2);
  739. matrix.M23 = 2.0f * (yz - wx);
  740. matrix.M24 = 0.0f;
  741. matrix.M31 = 2.0f * (xz - wy);
  742. matrix.M32 = 2.0f * (yz + wx);
  743. matrix.M33 = 1.0f - 2.0f * (x2 + y2);
  744. matrix.M34 = 0.0f;
  745. matrix.M41 = 2.0f * (xz - wy);
  746. matrix.M42 = 2.0f * (yz + wx);
  747. matrix.M43 = 1.0f - 2.0f * (x2 + y2);
  748. matrix.M44 = 0.0f;
  749. //return Matrix4( 1.0f - 2.0f * (y2 + z2), 2.0f * (xy - wz), 2.0f * (xz + wy), 0.0f,
  750. // 2.0f * (xy + wz), 1.0f - 2.0f * (x2 + z2), 2.0f * (yz - wx), 0.0f,
  751. // 2.0f * (xz - wy), 2.0f * (yz + wx), 1.0f - 2.0f * (x2 + y2), 0.0f,
  752. // 0.0f, 0.0f, 0.0f, 1.0f)
  753. // }
  754. }
  755. internal Vector3 Xyz
  756. {
  757. get {
  758. return new Vector3(X, Y, Z);
  759. }
  760. set {
  761. X = value.X;
  762. Y = value.Y;
  763. Z = value.Z;
  764. }
  765. }
  766. }
  767. }