Vector3.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. //
  2. // Copyright (c) 2008-2017 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Math/Vector2.h"
  24. #include "../Math/MathDefs.h"
  25. namespace Atomic
  26. {
  27. /// Three-dimensional vector with integer values.
  28. class ATOMIC_API IntVector3
  29. {
  30. public:
  31. /// Construct a zero vector.
  32. IntVector3() :
  33. x_(0),
  34. y_(0),
  35. z_(0)
  36. {
  37. }
  38. /// Construct from coordinates.
  39. IntVector3(int x, int y, int z) :
  40. x_(x),
  41. y_(y),
  42. z_(z)
  43. {
  44. }
  45. /// Construct from an int array.
  46. IntVector3(const int* data) :
  47. x_(data[0]),
  48. y_(data[1]),
  49. z_(data[2])
  50. {
  51. }
  52. /// Copy-construct from another vector.
  53. IntVector3(const IntVector3& rhs) :
  54. x_(rhs.x_),
  55. y_(rhs.y_),
  56. z_(rhs.z_)
  57. {
  58. }
  59. /// Assign from another vector.
  60. IntVector3& operator =(const IntVector3& rhs)
  61. {
  62. x_ = rhs.x_;
  63. y_ = rhs.y_;
  64. z_ = rhs.z_;
  65. return *this;
  66. }
  67. /// Test for equality with another vector.
  68. bool operator ==(const IntVector3& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_ && z_ == rhs.z_; }
  69. /// Test for inequality with another vector.
  70. bool operator !=(const IntVector3& rhs) const { return x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_; }
  71. /// Add a vector.
  72. IntVector3 operator +(const IntVector3& rhs) const { return IntVector3(x_ + rhs.x_, y_ + rhs.y_, z_ + rhs.z_); }
  73. /// Return negation.
  74. IntVector3 operator -() const { return IntVector3(-x_, -y_, -z_); }
  75. /// Subtract a vector.
  76. IntVector3 operator -(const IntVector3& rhs) const { return IntVector3(x_ - rhs.x_, y_ - rhs.y_, z_ - rhs.z_); }
  77. /// Multiply with a scalar.
  78. IntVector3 operator *(int rhs) const { return IntVector3(x_ * rhs, y_ * rhs, z_ * rhs); }
  79. /// Divide by a scalar.
  80. IntVector3 operator /(int rhs) const { return IntVector3(x_ / rhs, y_ / rhs, z_ / rhs); }
  81. /// Add-assign a vector.
  82. IntVector3& operator +=(const IntVector3& rhs)
  83. {
  84. x_ += rhs.x_;
  85. y_ += rhs.y_;
  86. z_ += rhs.z_;
  87. return *this;
  88. }
  89. /// Subtract-assign a vector.
  90. IntVector3& operator -=(const IntVector3& rhs)
  91. {
  92. x_ -= rhs.x_;
  93. y_ -= rhs.y_;
  94. z_ -= rhs.z_;
  95. return *this;
  96. }
  97. /// Multiply-assign a scalar.
  98. IntVector3& operator *=(int rhs)
  99. {
  100. x_ *= rhs;
  101. y_ *= rhs;
  102. z_ *= rhs;
  103. return *this;
  104. }
  105. /// Divide-assign a scalar.
  106. IntVector3& operator /=(int rhs)
  107. {
  108. x_ /= rhs;
  109. y_ /= rhs;
  110. z_ /= rhs;
  111. return *this;
  112. }
  113. /// Return integer data.
  114. const int* Data() const { return &x_; }
  115. /// Return as string.
  116. String ToString() const;
  117. /// Return hash value for HashSet & HashMap.
  118. unsigned ToHash() const { return (unsigned)x_ * 31 * 31 + (unsigned)y_ * 31 + (unsigned)z_; }
  119. /// Return length.
  120. float Length() const { return sqrtf((float)(x_ * x_ + y_ * y_ + z_ * z_)); }
  121. /// X coordinate.
  122. int x_;
  123. /// Y coordinate.
  124. int y_;
  125. /// Z coordinate.
  126. int z_;
  127. /// Zero vector.
  128. static const IntVector3 ZERO;
  129. /// (-1,0,0) vector.
  130. static const IntVector3 LEFT;
  131. /// (1,0,0) vector.
  132. static const IntVector3 RIGHT;
  133. /// (0,1,0) vector.
  134. static const IntVector3 UP;
  135. /// (0,-1,0) vector.
  136. static const IntVector3 DOWN;
  137. /// (0,0,1) vector.
  138. static const IntVector3 FORWARD;
  139. /// (0,0,-1) vector.
  140. static const IntVector3 BACK;
  141. /// (1,1,1) vector.
  142. static const IntVector3 ONE;
  143. };
  144. /// Three-dimensional vector.
  145. class ATOMIC_API Vector3
  146. {
  147. public:
  148. /// Construct a zero vector.
  149. Vector3() :
  150. x_(0.0f),
  151. y_(0.0f),
  152. z_(0.0f)
  153. {
  154. }
  155. /// Copy-construct from another vector.
  156. Vector3(const Vector3& vector) :
  157. x_(vector.x_),
  158. y_(vector.y_),
  159. z_(vector.z_)
  160. {
  161. }
  162. /// Construct from a two-dimensional vector and the Z coordinate.
  163. Vector3(const Vector2& vector, float z) :
  164. x_(vector.x_),
  165. y_(vector.y_),
  166. z_(z)
  167. {
  168. }
  169. /// Construct from a two-dimensional vector (for Atomic2D).
  170. Vector3(const Vector2& vector) :
  171. x_(vector.x_),
  172. y_(vector.y_),
  173. z_(0.0f)
  174. {
  175. }
  176. /// Construct from an IntVector3.
  177. explicit Vector3(const IntVector3& vector) :
  178. x_((float)vector.x_),
  179. y_((float)vector.y_),
  180. z_((float)vector.z_)
  181. {
  182. }
  183. /// Construct from coordinates.
  184. Vector3(float x, float y, float z) :
  185. x_(x),
  186. y_(y),
  187. z_(z)
  188. {
  189. }
  190. /// Construct from two-dimensional coordinates (for Atomic2D).
  191. Vector3(float x, float y) :
  192. x_(x),
  193. y_(y),
  194. z_(0.0f)
  195. {
  196. }
  197. /// Construct from a float array.
  198. explicit Vector3(const float* data) :
  199. x_(data[0]),
  200. y_(data[1]),
  201. z_(data[2])
  202. {
  203. }
  204. /// Assign from another vector.
  205. Vector3& operator =(const Vector3& rhs)
  206. {
  207. x_ = rhs.x_;
  208. y_ = rhs.y_;
  209. z_ = rhs.z_;
  210. return *this;
  211. }
  212. /// Test for equality with another vector without epsilon.
  213. bool operator ==(const Vector3& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_ && z_ == rhs.z_; }
  214. /// Test for inequality with another vector without epsilon.
  215. bool operator !=(const Vector3& rhs) const { return x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_; }
  216. /// Add a vector.
  217. Vector3 operator +(const Vector3& rhs) const { return Vector3(x_ + rhs.x_, y_ + rhs.y_, z_ + rhs.z_); }
  218. /// Return negation.
  219. Vector3 operator -() const { return Vector3(-x_, -y_, -z_); }
  220. /// Subtract a vector.
  221. Vector3 operator -(const Vector3& rhs) const { return Vector3(x_ - rhs.x_, y_ - rhs.y_, z_ - rhs.z_); }
  222. /// Multiply with a scalar.
  223. Vector3 operator *(float rhs) const { return Vector3(x_ * rhs, y_ * rhs, z_ * rhs); }
  224. /// Multiply with a vector.
  225. Vector3 operator *(const Vector3& rhs) const { return Vector3(x_ * rhs.x_, y_ * rhs.y_, z_ * rhs.z_); }
  226. /// Divide by a scalar.
  227. Vector3 operator /(float rhs) const { return Vector3(x_ / rhs, y_ / rhs, z_ / rhs); }
  228. /// Divide by a vector.
  229. Vector3 operator /(const Vector3& rhs) const { return Vector3(x_ / rhs.x_, y_ / rhs.y_, z_ / rhs.z_); }
  230. /// Add-assign a vector.
  231. Vector3& operator +=(const Vector3& rhs)
  232. {
  233. x_ += rhs.x_;
  234. y_ += rhs.y_;
  235. z_ += rhs.z_;
  236. return *this;
  237. }
  238. /// Subtract-assign a vector.
  239. Vector3& operator -=(const Vector3& rhs)
  240. {
  241. x_ -= rhs.x_;
  242. y_ -= rhs.y_;
  243. z_ -= rhs.z_;
  244. return *this;
  245. }
  246. /// Multiply-assign a scalar.
  247. Vector3& operator *=(float rhs)
  248. {
  249. x_ *= rhs;
  250. y_ *= rhs;
  251. z_ *= rhs;
  252. return *this;
  253. }
  254. /// Multiply-assign a vector.
  255. Vector3& operator *=(const Vector3& rhs)
  256. {
  257. x_ *= rhs.x_;
  258. y_ *= rhs.y_;
  259. z_ *= rhs.z_;
  260. return *this;
  261. }
  262. /// Divide-assign a scalar.
  263. Vector3& operator /=(float rhs)
  264. {
  265. float invRhs = 1.0f / rhs;
  266. x_ *= invRhs;
  267. y_ *= invRhs;
  268. z_ *= invRhs;
  269. return *this;
  270. }
  271. /// Divide-assign a vector.
  272. Vector3& operator /=(const Vector3& rhs)
  273. {
  274. x_ /= rhs.x_;
  275. y_ /= rhs.y_;
  276. z_ /= rhs.z_;
  277. return *this;
  278. }
  279. /// Normalize to unit length.
  280. void Normalize()
  281. {
  282. float lenSquared = LengthSquared();
  283. if (!Atomic::Equals(lenSquared, 1.0f) && lenSquared > 0.0f)
  284. {
  285. float invLen = 1.0f / sqrtf(lenSquared);
  286. x_ *= invLen;
  287. y_ *= invLen;
  288. z_ *= invLen;
  289. }
  290. }
  291. /// Return length.
  292. float Length() const { return sqrtf(x_ * x_ + y_ * y_ + z_ * z_); }
  293. /// Return squared length.
  294. float LengthSquared() const { return x_ * x_ + y_ * y_ + z_ * z_; }
  295. /// Calculate dot product.
  296. float DotProduct(const Vector3& rhs) const { return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_; }
  297. /// Calculate absolute dot product.
  298. float AbsDotProduct(const Vector3& rhs) const
  299. {
  300. return Atomic::Abs(x_ * rhs.x_) + Atomic::Abs(y_ * rhs.y_) + Atomic::Abs(z_ * rhs.z_);
  301. }
  302. /// Project vector onto axis.
  303. float ProjectOntoAxis(const Vector3& axis) const { return DotProduct(axis.Normalized()); }
  304. /// Make vector orthogonal to the axis.
  305. Vector3 Orthogonalize(const Vector3& axis) const { return axis.CrossProduct(*this).CrossProduct(axis).Normalized(); }
  306. /// Calculate cross product.
  307. Vector3 CrossProduct(const Vector3& rhs) const
  308. {
  309. return Vector3(
  310. y_ * rhs.z_ - z_ * rhs.y_,
  311. z_ * rhs.x_ - x_ * rhs.z_,
  312. x_ * rhs.y_ - y_ * rhs.x_
  313. );
  314. }
  315. /// Return absolute vector.
  316. Vector3 Abs() const { return Vector3(Atomic::Abs(x_), Atomic::Abs(y_), Atomic::Abs(z_)); }
  317. /// Linear interpolation with another vector.
  318. Vector3 Lerp(const Vector3& rhs, float t) const { return *this * (1.0f - t) + rhs * t; }
  319. /// Test for equality with another vector with epsilon.
  320. bool Equals(const Vector3& rhs) const
  321. {
  322. return Atomic::Equals(x_, rhs.x_) && Atomic::Equals(y_, rhs.y_) && Atomic::Equals(z_, rhs.z_);
  323. }
  324. /// Returns the angle between this vector and another vector in degrees.
  325. float Angle(const Vector3& rhs) const { return Atomic::Acos(DotProduct(rhs) / (Length() * rhs.Length())); }
  326. /// Return whether is NaN.
  327. bool IsNaN() const { return Atomic::IsNaN(x_) || Atomic::IsNaN(y_) || Atomic::IsNaN(z_); }
  328. /// Return normalized to unit length.
  329. Vector3 Normalized() const
  330. {
  331. float lenSquared = LengthSquared();
  332. if (!Atomic::Equals(lenSquared, 1.0f) && lenSquared > 0.0f)
  333. {
  334. float invLen = 1.0f / sqrtf(lenSquared);
  335. return *this * invLen;
  336. }
  337. else
  338. return *this;
  339. }
  340. // ATOMIC BEGIN
  341. Vector3 ClampedLerp(const Vector3& rhs, float t) const
  342. {
  343. if (t > 1)
  344. t = 1;
  345. else if (t < 0)
  346. t = 0;
  347. return *this * (1.0f - t) + rhs * t;
  348. }
  349. // ATOMIC END
  350. /// Return float data.
  351. const float* Data() const { return &x_; }
  352. /// Return as string.
  353. String ToString() const;
  354. /// Return hash value for HashSet & HashMap.
  355. unsigned ToHash() const
  356. {
  357. unsigned hash = 37;
  358. hash = 37 * hash + FloatToRawIntBits(x_);
  359. hash = 37 * hash + FloatToRawIntBits(y_);
  360. hash = 37 * hash + FloatToRawIntBits(z_);
  361. return hash;
  362. }
  363. /// X coordinate.
  364. float x_;
  365. /// Y coordinate.
  366. float y_;
  367. /// Z coordinate.
  368. float z_;
  369. /// Zero vector.
  370. static const Vector3 ZERO;
  371. /// (-1,0,0) vector.
  372. static const Vector3 LEFT;
  373. /// (1,0,0) vector.
  374. static const Vector3 RIGHT;
  375. /// (0,1,0) vector.
  376. static const Vector3 UP;
  377. /// (0,-1,0) vector.
  378. static const Vector3 DOWN;
  379. /// (0,0,1) vector.
  380. static const Vector3 FORWARD;
  381. /// (0,0,-1) vector.
  382. static const Vector3 BACK;
  383. /// (1,1,1) vector.
  384. static const Vector3 ONE;
  385. };
  386. /// Multiply Vector3 with a scalar.
  387. inline Vector3 operator *(float lhs, const Vector3& rhs) { return rhs * lhs; }
  388. /// Multiply IntVector3 with a scalar.
  389. inline IntVector3 operator *(int lhs, const IntVector3& rhs) { return rhs * lhs; }
  390. /// Per-component linear interpolation between two 3-vectors.
  391. inline Vector3 VectorLerp(const Vector3& lhs, const Vector3& rhs, const Vector3& t) { return lhs + (rhs - lhs) * t; }
  392. /// Per-component min of two 3-vectors.
  393. inline Vector3 VectorMin(const Vector3& lhs, const Vector3& rhs) { return Vector3(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_), Min(lhs.z_, rhs.z_)); }
  394. /// Per-component max of two 3-vectors.
  395. inline Vector3 VectorMax(const Vector3& lhs, const Vector3& rhs) { return Vector3(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_), Max(lhs.z_, rhs.z_)); }
  396. /// Per-component floor of 3-vector.
  397. inline Vector3 VectorFloor(const Vector3& vec) { return Vector3(Floor(vec.x_), Floor(vec.y_), Floor(vec.z_)); }
  398. /// Per-component round of 3-vector.
  399. inline Vector3 VectorRound(const Vector3& vec) { return Vector3(Round(vec.x_), Round(vec.y_), Round(vec.z_)); }
  400. /// Per-component ceil of 3-vector.
  401. inline Vector3 VectorCeil(const Vector3& vec) { return Vector3(Ceil(vec.x_), Ceil(vec.y_), Ceil(vec.z_)); }
  402. /// Per-component floor of 3-vector. Returns IntVector3.
  403. inline IntVector3 VectorFloorToInt(const Vector3& vec) { return IntVector3(FloorToInt(vec.x_), FloorToInt(vec.y_), FloorToInt(vec.z_)); }
  404. /// Per-component round of 3-vector. Returns IntVector3.
  405. inline IntVector3 VectorRoundToInt(const Vector3& vec) { return IntVector3(RoundToInt(vec.x_), RoundToInt(vec.y_), RoundToInt(vec.z_)); }
  406. /// Per-component ceil of 3-vector. Returns IntVector3.
  407. inline IntVector3 VectorCeilToInt(const Vector3& vec) { return IntVector3(CeilToInt(vec.x_), CeilToInt(vec.y_), CeilToInt(vec.z_)); }
  408. /// Per-component min of two 3-vectors.
  409. inline IntVector3 VectorMin(const IntVector3& lhs, const IntVector3& rhs) { return IntVector3(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_), Min(lhs.z_, rhs.z_)); }
  410. /// Per-component max of two 3-vectors.
  411. inline IntVector3 VectorMax(const IntVector3& lhs, const IntVector3& rhs) { return IntVector3(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_), Max(lhs.z_, rhs.z_)); }
  412. /// Return a random value from [0, 1) from 3-vector seed.
  413. inline float StableRandom(const Vector3& seed) { return StableRandom(Vector2(StableRandom(Vector2(seed.x_, seed.y_)), seed.z_)); }
  414. }