Vector4.cs 9.1 KB

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