Vector4.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Runtime.InteropServices;
  5. namespace BansheeEngine
  6. {
  7. /** @addtogroup Math
  8. * @{
  9. */
  10. /// <summary>
  11. /// A four dimensional vector with a homogeneous w coordinate.
  12. /// </summary>
  13. [StructLayout(LayoutKind.Sequential), SerializeObject]
  14. public struct Vector4
  15. {
  16. public static readonly Vector4 Zero = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
  17. public static readonly Vector4 One = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
  18. public static readonly Vector4 XAxis = new Vector4(1.0f, 0.0f, 0.0f, 0.0f);
  19. public static readonly Vector4 YAxis = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
  20. public static readonly Vector4 ZAxis = new Vector4(0.0f, 0.0f, 1.0f, 0.0f);
  21. public float x;
  22. public float y;
  23. public float z;
  24. public float w;
  25. /// <summary>
  26. /// Accesses a specific component of the vector.
  27. /// </summary>
  28. /// <param name="index">Index of the component.</param>
  29. /// <returns>Value of the specific component.</returns>
  30. public float this[int index]
  31. {
  32. get
  33. {
  34. switch (index)
  35. {
  36. case 0:
  37. return x;
  38. case 1:
  39. return y;
  40. case 2:
  41. return z;
  42. case 3:
  43. return w;
  44. default:
  45. throw new IndexOutOfRangeException("Invalid Vector4 index.");
  46. }
  47. }
  48. set
  49. {
  50. switch (index)
  51. {
  52. case 0:
  53. x = value;
  54. break;
  55. case 1:
  56. y = value;
  57. break;
  58. case 2:
  59. z = value;
  60. break;
  61. case 3:
  62. w = value;
  63. break;
  64. default:
  65. throw new IndexOutOfRangeException("Invalid Vector4 index.");
  66. }
  67. }
  68. }
  69. /// <summary>
  70. /// Returns a normalized copy of the vector.
  71. /// </summary>
  72. public Vector4 Normalized
  73. {
  74. get
  75. {
  76. return Normalize(this);
  77. }
  78. }
  79. /// <summary>
  80. /// Returns the length of the vector.
  81. /// </summary>
  82. public float Length
  83. {
  84. get
  85. {
  86. return MathEx.Sqrt(x * x + y * y + z * z + w * w);
  87. }
  88. }
  89. /// <summary>
  90. /// Returns the squared length of the vector.
  91. /// </summary>
  92. public float SqrdLength
  93. {
  94. get
  95. {
  96. return (x * x + y * y + z * z + w * w);
  97. }
  98. }
  99. /// <summary>
  100. /// Creates a new four dimensional vector.
  101. /// </summary>
  102. /// <param name="x">X coordinate.</param>
  103. /// <param name="y">Y coordinate.</param>
  104. /// <param name="z">Z coordinate.</param>
  105. /// <param name="w">Homogeneous W coordinate.</param>
  106. public Vector4(float x, float y, float z, float w)
  107. {
  108. this.x = x;
  109. this.y = y;
  110. this.z = z;
  111. this.w = w;
  112. }
  113. /// <summary>
  114. /// Converts a homogenous vector into a three dimensional vector. w component is discarded.
  115. /// </summary>
  116. /// <param name="vec">Vector to convert.</param>
  117. /// <returns>A new three dimensional vector.</returns>
  118. public static explicit operator Vector3(Vector4 vec)
  119. {
  120. return new Vector3(vec.x, vec.y, vec.z);
  121. }
  122. public static Vector4 operator+ (Vector4 a, Vector4 b)
  123. {
  124. return new Vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
  125. }
  126. public static Vector4 operator- (Vector4 a, Vector4 b)
  127. {
  128. return new Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
  129. }
  130. public static Vector4 operator- (Vector4 v)
  131. {
  132. return new Vector4(-v.x, -v.y, -v.z, -v.w);
  133. }
  134. public static Vector4 operator *(Vector4 a, Vector4 b)
  135. {
  136. return new Vector4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
  137. }
  138. public static Vector4 operator* (Vector4 v, float d)
  139. {
  140. return new Vector4(v.x * d, v.y * d, v.z * d, v.w * d);
  141. }
  142. public static Vector4 operator* (float d, Vector4 v)
  143. {
  144. return new Vector4(v.x * d, v.y * d, v.z * d, v.w * d);
  145. }
  146. public static Vector4 operator /(Vector4 v, float d)
  147. {
  148. return new Vector4(v.x / d, v.y / d, v.z / d, v.w / d);
  149. }
  150. public static bool operator== (Vector4 lhs, Vector4 rhs)
  151. {
  152. return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w;
  153. }
  154. public static bool operator!= (Vector4 lhs, Vector4 rhs)
  155. {
  156. return !(lhs == rhs);
  157. }
  158. /// <summary>
  159. /// Scales one vector by another.
  160. /// </summary>
  161. /// <param name="a">First four dimensional vector.</param>
  162. /// <param name="b">Second four dimensional vector.</param>
  163. /// <returns>One vector scaled by another.</returns>
  164. public static Vector4 Scale(Vector4 a, Vector4 b)
  165. {
  166. return new Vector4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
  167. }
  168. /// <summary>
  169. /// Normalizes the provided vector and returns the normalized copy.
  170. /// </summary>
  171. /// <param name="value">Vector to normalize.</param>
  172. /// <returns>Normalized copy of the vector.</returns>
  173. public static Vector4 Normalize(Vector4 value)
  174. {
  175. float num = Magnitude(value);
  176. if (num > 9.999999E-06)
  177. return value / num;
  178. return Zero;
  179. }
  180. /// <summary>
  181. /// Calculates the inner product of the two vectors.
  182. /// </summary>
  183. /// <param name="lhs">First four dimensional vector.</param>
  184. /// <param name="rhs">Second four dimensional vector.</param>
  185. /// <returns>Inner product between the two vectors.</returns>
  186. public static float Dot(Vector4 lhs, Vector4 rhs)
  187. {
  188. return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w;
  189. }
  190. /// <summary>
  191. /// Calculates the distance between two points.
  192. /// </summary>
  193. /// <param name="a">First four dimensional point.</param>
  194. /// <param name="b">Second four dimensional point.</param>
  195. /// <returns>Distance between the two points.</returns>
  196. public static float Distance(Vector4 a, Vector4 b)
  197. {
  198. Vector4 vector4 = new Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
  199. return MathEx.Sqrt(vector4.x * vector4.x + vector4.y * vector4.y + vector4.z * vector4.z + vector4.w * vector4.w);
  200. }
  201. /// <summary>
  202. /// Calculates the magnitude of the provided vector.
  203. /// </summary>
  204. /// <param name="v">Vector to calculate the magnitude for.</param>
  205. /// <returns>Magnitude of the vector.</returns>
  206. public static float Magnitude(Vector4 v)
  207. {
  208. return MathEx.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
  209. }
  210. /// <summary>
  211. /// Calculates the squared magnitude of the provided vector.
  212. /// </summary>
  213. /// <param name="v">Vector to calculate the magnitude for.</param>
  214. /// <returns>Squared magnitude of the vector.</returns>
  215. public static float SqrMagnitude(Vector4 v)
  216. {
  217. return (v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w);
  218. }
  219. /// <summary>
  220. /// Scales the components of the vector by specified scale factors.
  221. /// </summary>
  222. /// <param name="scale">Scale factors to multiply components by.</param>
  223. public void Scale(Vector4 scale)
  224. {
  225. x *= scale.x;
  226. y *= scale.y;
  227. z *= scale.z;
  228. w *= scale.w;
  229. }
  230. /// <summary>
  231. /// Normalizes the vector.
  232. /// </summary>
  233. public void Normalize()
  234. {
  235. float num = Magnitude(this);
  236. if (num > 9.999999e-06f)
  237. this /= num;
  238. else
  239. this = Zero;
  240. }
  241. /// <inheritdoc/>
  242. public override int GetHashCode()
  243. {
  244. return x.GetHashCode() ^ y.GetHashCode() << 2 ^ z.GetHashCode() >> 2 ^ w.GetHashCode() >> 1;
  245. }
  246. /// <inheritdoc/>
  247. public override bool Equals(object other)
  248. {
  249. if (!(other is Vector4))
  250. return false;
  251. Vector4 vec = (Vector4)other;
  252. if (x.Equals(vec.x) && y.Equals(vec.y) && z.Equals(vec.z) && w.Equals(vec.w))
  253. return true;
  254. return false;
  255. }
  256. /// <inheritdoc/>
  257. public override string ToString()
  258. {
  259. return "(" + x + ", " + y + ", " + z + ", " + w + ")";
  260. }
  261. }
  262. /** @} */
  263. }