BsVector3.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. #include "BsMath.h"
  4. namespace BansheeEngine
  5. {
  6. /**
  7. * @brief A three dimensional vector.
  8. */
  9. class BS_UTILITY_EXPORT Vector3
  10. {
  11. public:
  12. float x, y, z;
  13. public:
  14. Vector3()
  15. :x(0.0f), y(0.0f), z(0.0f)
  16. { }
  17. Vector3(float x, float y, float z)
  18. :x(x), y(y), z(z)
  19. { }
  20. /**
  21. * @brief Exchange the contents of this vector with another.
  22. */
  23. void swap(Vector3& other)
  24. {
  25. std::swap(x, other.x);
  26. std::swap(y, other.y);
  27. std::swap(z, other.z);
  28. }
  29. float operator[] (UINT32 i) const
  30. {
  31. assert(i < 3);
  32. return *(&x+i);
  33. }
  34. float& operator[] (UINT32 i)
  35. {
  36. assert(i < 3);
  37. return *(&x+i);
  38. }
  39. /**
  40. * @brief Pointer accessor for direct copying.
  41. */
  42. float* ptr()
  43. {
  44. return &x;
  45. }
  46. /**
  47. * @brief Pointer accessor for direct copying.
  48. */
  49. const float* ptr() const
  50. {
  51. return &x;
  52. }
  53. Vector3& operator= (const Vector3& rhs)
  54. {
  55. x = rhs.x;
  56. y = rhs.y;
  57. z = rhs.z;
  58. return *this;
  59. }
  60. Vector3& operator= (float rhs)
  61. {
  62. x = rhs;
  63. y = rhs;
  64. z = rhs;
  65. return *this;
  66. }
  67. bool operator== (const Vector3& rhs) const
  68. {
  69. return (x == rhs.x && y == rhs.y && z == rhs.z);
  70. }
  71. bool operator!= (const Vector3& rhs) const
  72. {
  73. return (x != rhs.x || y != rhs.y || z != rhs.z);
  74. }
  75. Vector3 operator+ (const Vector3& rhs) const
  76. {
  77. return Vector3(x + rhs.x, y + rhs.y, z + rhs.z);
  78. }
  79. Vector3 operator- (const Vector3& rhs) const
  80. {
  81. return Vector3(x - rhs.x, y - rhs.y, z - rhs.z);
  82. }
  83. Vector3 operator* (float rhs) const
  84. {
  85. return Vector3(x * rhs, y * rhs, z * rhs);
  86. }
  87. Vector3 operator* (const Vector3& rhs) const
  88. {
  89. return Vector3(x * rhs.x, y * rhs.y, z * rhs.z);
  90. }
  91. Vector3 operator/ (float val) const
  92. {
  93. assert(val != 0.0);
  94. float fInv = 1.0f / val;
  95. return Vector3(x * fInv, y * fInv, z * fInv);
  96. }
  97. Vector3 operator/ (const Vector3& rhs) const
  98. {
  99. return Vector3(x / rhs.x, y / rhs.y, z / rhs.z);
  100. }
  101. const Vector3& operator+ () const
  102. {
  103. return *this;
  104. }
  105. Vector3 operator- () const
  106. {
  107. return Vector3(-x, -y, -z);
  108. }
  109. friend Vector3 operator* (float lhs, const Vector3& rhs)
  110. {
  111. return Vector3(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
  112. }
  113. friend Vector3 operator/ (float lhs, const Vector3& rhs)
  114. {
  115. return Vector3(lhs / rhs.x, lhs / rhs.y, lhs / rhs.z);
  116. }
  117. friend Vector3 operator+ (const Vector3& lhs, float rhs)
  118. {
  119. return Vector3(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs);
  120. }
  121. friend Vector3 operator+ (float lhs, const Vector3& rhs)
  122. {
  123. return Vector3(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z);
  124. }
  125. friend Vector3 operator- (const Vector3& lhs, float rhs)
  126. {
  127. return Vector3(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs);
  128. }
  129. friend Vector3 operator- (float lhs, const Vector3& rhs)
  130. {
  131. return Vector3(lhs - rhs.x, lhs - rhs.y, lhs - rhs.z);
  132. }
  133. Vector3& operator+= (const Vector3& rhs)
  134. {
  135. x += rhs.x;
  136. y += rhs.y;
  137. z += rhs.z;
  138. return *this;
  139. }
  140. Vector3& operator+= (float rhs)
  141. {
  142. x += rhs;
  143. y += rhs;
  144. z += rhs;
  145. return *this;
  146. }
  147. Vector3& operator-= (const Vector3& rhs)
  148. {
  149. x -= rhs.x;
  150. y -= rhs.y;
  151. z -= rhs.z;
  152. return *this;
  153. }
  154. Vector3& operator-= (float rhs)
  155. {
  156. x -= rhs;
  157. y -= rhs;
  158. z -= rhs;
  159. return *this;
  160. }
  161. Vector3& operator*= (float rhs)
  162. {
  163. x *= rhs;
  164. y *= rhs;
  165. z *= rhs;
  166. return *this;
  167. }
  168. Vector3& operator*= (const Vector3& rhs)
  169. {
  170. x *= rhs.x;
  171. y *= rhs.y;
  172. z *= rhs.z;
  173. return *this;
  174. }
  175. Vector3& operator/= (float rhs)
  176. {
  177. assert(rhs != 0.0f);
  178. float inv = 1.0f / rhs;
  179. x *= inv;
  180. y *= inv;
  181. z *= inv;
  182. return *this;
  183. }
  184. Vector3& operator/= (const Vector3& rhs)
  185. {
  186. x /= rhs.x;
  187. y /= rhs.y;
  188. z /= rhs.z;
  189. return *this;
  190. }
  191. /**
  192. * @brief Returns the length (magnitude) of the vector.
  193. */
  194. float length() const
  195. {
  196. return Math::sqrt(x * x + y * y + z * z);
  197. }
  198. /**
  199. * @brief Returns the square of the length(magnitude) of the vector.
  200. */
  201. float squaredLength() const
  202. {
  203. return x * x + y * y + z * z;
  204. }
  205. /**
  206. * @brief Returns the distance to another vector.
  207. */
  208. float distance(const Vector3& rhs) const
  209. {
  210. return (*this - rhs).length();
  211. }
  212. /**
  213. * @brief Returns the square of the distance to another vector.
  214. */
  215. float squaredDistance(const Vector3& rhs) const
  216. {
  217. return (*this - rhs).squaredLength();
  218. }
  219. /**
  220. * @brief Calculates the dot (scalar) product of this vector with another
  221. */
  222. float dot(const Vector3& vec) const
  223. {
  224. return x * vec.x + y * vec.y + z * vec.z;
  225. }
  226. /**
  227. * @brief Normalizes the vector.
  228. */
  229. float normalize()
  230. {
  231. float len = Math::sqrt(x * x + y * y + z * z);
  232. // Will also work for zero-sized vectors, but will change nothing
  233. if (len > 1e-08)
  234. {
  235. float invLen = 1.0f / len;
  236. x *= invLen;
  237. y *= invLen;
  238. z *= invLen;
  239. }
  240. return len;
  241. }
  242. /**
  243. * @brief Calculates the cross-product of 2 vectors, i.e. the vector that
  244. * lies perpendicular to them both.
  245. */
  246. Vector3 cross(const Vector3& other) const
  247. {
  248. return Vector3(
  249. y * other.z - z * other.y,
  250. z * other.x - x * other.z,
  251. x * other.y - y * other.x);
  252. }
  253. /**
  254. * @brief Sets this vector's components to the minimum of its own and the
  255. * ones of the passed in vector.
  256. */
  257. void floor(const Vector3& cmp)
  258. {
  259. if(cmp.x < x) x = cmp.x;
  260. if(cmp.y < y) y = cmp.y;
  261. if(cmp.z < z) z = cmp.z;
  262. }
  263. /**
  264. * @brief Sets this vector's components to the maximum of its own and the
  265. * ones of the passed in vector.
  266. */
  267. void ceil(const Vector3& cmp)
  268. {
  269. if(cmp.x > x) x = cmp.x;
  270. if(cmp.y > y) y = cmp.y;
  271. if(cmp.z > z) z = cmp.z;
  272. }
  273. /**
  274. * @brief Generates a vector perpendicular to this vector.
  275. */
  276. Vector3 perpendicular() const
  277. {
  278. static const float squareZero = (float)(1e-06 * 1e-06);
  279. Vector3 perp = this->cross(Vector3::UNIT_X);
  280. if(perp.squaredLength() < squareZero)
  281. perp = this->cross(Vector3::UNIT_Y);
  282. perp.normalize();
  283. return perp;
  284. }
  285. /**
  286. * @brief Gets the angle between 2 vectors.
  287. */
  288. Radian angleBetween(const Vector3& dest)
  289. {
  290. float lenProduct = length() * dest.length();
  291. // Divide by zero check
  292. if(lenProduct < 1e-6f)
  293. lenProduct = 1e-6f;
  294. float f = dot(dest) / lenProduct;
  295. f = Math::clamp(f, -1.0f, 1.0f);
  296. return Math::acos(f);
  297. }
  298. /**
  299. * @brief Returns true if this vector is zero length.
  300. */
  301. bool isZeroLength() const
  302. {
  303. float sqlen = (x * x) + (y * y) + (z * z);
  304. return (sqlen < (1e-06 * 1e-06));
  305. }
  306. /**
  307. * @brief Calculates a reflection vector to the plane with the given normal.
  308. */
  309. Vector3 reflect(const Vector3& normal) const
  310. {
  311. return Vector3(*this - (2 * this->dot(normal) * normal));
  312. }
  313. /**
  314. * @brief Calculates two vectors orthonormal to the current vector, and
  315. * normalizes the current vector if not already.
  316. */
  317. void orthogonalComplement(Vector3& a, Vector3& b)
  318. {
  319. if (fabs(a.x) > fabs(a.y))
  320. a = Vector3(-a.z, 0, a.x);
  321. else
  322. a = Vector3(0, a.z, -a.y);
  323. b = cross(a);
  324. orthonormalize(*this, a, b);
  325. }
  326. /**
  327. * @brief Performs Gram-Schmidt orthonormalization
  328. */
  329. static void orthonormalize(Vector3& vec0, Vector3& vec1, Vector3& vec2)
  330. {
  331. vec0.normalize();
  332. float dot0 = vec0.dot(vec1);
  333. vec1 -= dot0*vec0;
  334. vec1.normalize();
  335. float dot1 = vec1.dot(vec2);
  336. dot0 = vec0.dot(vec2);
  337. vec2 -= dot0*vec0 + dot1*vec1;
  338. vec2.normalize();
  339. }
  340. /**
  341. * @brief Normalizes the provided vector and returns a new normalized instance.
  342. */
  343. static Vector3 normalize(const Vector3& val)
  344. {
  345. float len = Math::sqrt(val.x * val.x + val.y * val.y + val.z * val.z);
  346. // Will also work for zero-sized vectors, but will change nothing
  347. if (len > 1e-08)
  348. {
  349. float invLen = 1.0f / len;
  350. Vector3 normalizedVec;
  351. normalizedVec.x = val.x * invLen;
  352. normalizedVec.y = val.y * invLen;
  353. normalizedVec.z = val.z * invLen;
  354. return normalizedVec;
  355. }
  356. else
  357. return val;
  358. }
  359. /**
  360. * @brief Checks are any of the vector components NaN.
  361. */
  362. bool isNaN() const
  363. {
  364. return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z);
  365. }
  366. /**
  367. * @brief Returns the minimum of all the vector components as a
  368. * new vector.
  369. */
  370. static Vector3 min(const Vector3& a, const Vector3& b)
  371. {
  372. return Vector3(std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z));
  373. }
  374. /**
  375. * @brief Returns the maximum of all the vector components as a
  376. * new vector.
  377. */
  378. static Vector3 max(const Vector3& a, const Vector3& b)
  379. {
  380. return Vector3(std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z));
  381. }
  382. static const Vector3 ZERO;
  383. static const Vector3 ONE;
  384. static const Vector3 INF;
  385. static const Vector3 UNIT_X;
  386. static const Vector3 UNIT_Y;
  387. static const Vector3 UNIT_Z;
  388. };
  389. BS_ALLOW_MEMCPY_SERIALIZATION(Vector3);
  390. }