Vector3.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  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. namespace Atomic
  25. {
  26. /// Three-dimensional vector with integer values.
  27. class ATOMIC_API IntVector3
  28. {
  29. public:
  30. /// Construct a zero vector.
  31. IntVector3() :
  32. x_(0),
  33. y_(0),
  34. z_(0)
  35. {
  36. }
  37. /// Construct from coordinates.
  38. IntVector3(int x, int y, int z) :
  39. x_(x),
  40. y_(y),
  41. z_(z)
  42. {
  43. }
  44. /// Construct from an int array.
  45. IntVector3(const int* data) :
  46. x_(data[0]),
  47. y_(data[1]),
  48. z_(data[2])
  49. {
  50. }
  51. /// Copy-construct from another vector.
  52. IntVector3(const IntVector3& rhs) :
  53. x_(rhs.x_),
  54. y_(rhs.y_),
  55. z_(rhs.z_)
  56. {
  57. }
  58. /// Assign from another vector.
  59. IntVector3& operator =(const IntVector3& rhs)
  60. {
  61. x_ = rhs.x_;
  62. y_ = rhs.y_;
  63. z_ = rhs.z_;
  64. return *this;
  65. }
  66. /// Test for equality with another vector.
  67. bool operator ==(const IntVector3& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_ && z_ == rhs.z_; }
  68. /// Test for inequality with another vector.
  69. bool operator !=(const IntVector3& rhs) const { return x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_; }
  70. /// Add a vector.
  71. IntVector3 operator +(const IntVector3& rhs) const { return IntVector3(x_ + rhs.x_, y_ + rhs.y_, z_ + rhs.z_); }
  72. /// Return negation.
  73. IntVector3 operator -() const { return IntVector3(-x_, -y_, -z_); }
  74. /// Subtract a vector.
  75. IntVector3 operator -(const IntVector3& rhs) const { return IntVector3(x_ - rhs.x_, y_ - rhs.y_, z_ - rhs.z_); }
  76. /// Multiply with a scalar.
  77. IntVector3 operator *(int rhs) const { return IntVector3(x_ * rhs, y_ * rhs, z_ * rhs); }
  78. /// Divide by a scalar.
  79. IntVector3 operator /(int rhs) const { return IntVector3(x_ / rhs, y_ / rhs, z_ / rhs); }
  80. /// Add-assign a vector.
  81. IntVector3& operator +=(const IntVector3& rhs)
  82. {
  83. x_ += rhs.x_;
  84. y_ += rhs.y_;
  85. z_ += rhs.z_;
  86. return *this;
  87. }
  88. /// Subtract-assign a vector.
  89. IntVector3& operator -=(const IntVector3& rhs)
  90. {
  91. x_ -= rhs.x_;
  92. y_ -= rhs.y_;
  93. z_ -= rhs.z_;
  94. return *this;
  95. }
  96. /// Multiply-assign a scalar.
  97. IntVector3& operator *=(int rhs)
  98. {
  99. x_ *= rhs;
  100. y_ *= rhs;
  101. z_ *= rhs;
  102. return *this;
  103. }
  104. /// Divide-assign a scalar.
  105. IntVector3& operator /=(int rhs)
  106. {
  107. x_ /= rhs;
  108. y_ /= rhs;
  109. z_ /= rhs;
  110. return *this;
  111. }
  112. /// Return integer data.
  113. const int* Data() const { return &x_; }
  114. /// Return as string.
  115. String ToString() const;
  116. /// Return hash value for HashSet & HashMap.
  117. unsigned ToHash() const { return (unsigned)x_ * 31 * 31 + (unsigned)y_ * 31 + (unsigned)z_; }
  118. /// Return length.
  119. float Length() const { return sqrtf((float)(x_ * x_ + y_ * y_ + z_ * z_)); }
  120. /// X coordinate.
  121. int x_;
  122. /// Y coordinate.
  123. int y_;
  124. /// Z coordinate.
  125. int z_;
  126. /// Zero vector.
  127. static const IntVector3 ZERO;
  128. /// (-1,0,0) vector.
  129. static const IntVector3 LEFT;
  130. /// (1,0,0) vector.
  131. static const IntVector3 RIGHT;
  132. /// (0,1,0) vector.
  133. static const IntVector3 UP;
  134. /// (0,-1,0) vector.
  135. static const IntVector3 DOWN;
  136. /// (0,0,1) vector.
  137. static const IntVector3 FORWARD;
  138. /// (0,0,-1) vector.
  139. static const IntVector3 BACK;
  140. /// (1,1,1) vector.
  141. static const IntVector3 ONE;
  142. };
  143. /// Three-dimensional vector.
  144. class ATOMIC_API Vector3
  145. {
  146. public:
  147. /// Construct a zero vector.
  148. Vector3() :
  149. x_(0.0f),
  150. y_(0.0f),
  151. z_(0.0f)
  152. {
  153. }
  154. /// Copy-construct from another vector.
  155. Vector3(const Vector3& vector) :
  156. x_(vector.x_),
  157. y_(vector.y_),
  158. z_(vector.z_)
  159. {
  160. }
  161. /// Construct from a two-dimensional vector and the Z coordinate.
  162. Vector3(const Vector2& vector, float z) :
  163. x_(vector.x_),
  164. y_(vector.y_),
  165. z_(z)
  166. {
  167. }
  168. /// Construct from a two-dimensional vector (for Atomic2D).
  169. Vector3(const Vector2& vector) :
  170. x_(vector.x_),
  171. y_(vector.y_),
  172. z_(0.0f)
  173. {
  174. }
  175. /// Construct from an IntVector3.
  176. explicit Vector3(const IntVector3& vector) :
  177. x_((float)vector.x_),
  178. y_((float)vector.y_),
  179. z_((float)vector.z_)
  180. {
  181. }
  182. /// Construct from coordinates.
  183. Vector3(float x, float y, float z) :
  184. x_(x),
  185. y_(y),
  186. z_(z)
  187. {
  188. }
  189. /// Construct from two-dimensional coordinates (for Atomic2D).
  190. Vector3(float x, float y) :
  191. x_(x),
  192. y_(y),
  193. z_(0.0f)
  194. {
  195. }
  196. /// Construct from a float array.
  197. explicit Vector3(const float* data) :
  198. x_(data[0]),
  199. y_(data[1]),
  200. z_(data[2])
  201. {
  202. }
  203. /// Assign from another vector.
  204. Vector3& operator =(const Vector3& rhs)
  205. {
  206. x_ = rhs.x_;
  207. y_ = rhs.y_;
  208. z_ = rhs.z_;
  209. return *this;
  210. }
  211. /// Test for equality with another vector without epsilon.
  212. bool operator ==(const Vector3& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_ && z_ == rhs.z_; }
  213. /// Test for inequality with another vector without epsilon.
  214. bool operator !=(const Vector3& rhs) const { return x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_; }
  215. /// Add a vector.
  216. Vector3 operator +(const Vector3& rhs) const { return Vector3(x_ + rhs.x_, y_ + rhs.y_, z_ + rhs.z_); }
  217. /// Return negation.
  218. Vector3 operator -() const { return Vector3(-x_, -y_, -z_); }
  219. /// Subtract a vector.
  220. Vector3 operator -(const Vector3& rhs) const { return Vector3(x_ - rhs.x_, y_ - rhs.y_, z_ - rhs.z_); }
  221. /// Multiply with a scalar.
  222. Vector3 operator *(float rhs) const { return Vector3(x_ * rhs, y_ * rhs, z_ * rhs); }
  223. /// Multiply with a vector.
  224. Vector3 operator *(const Vector3& rhs) const { return Vector3(x_ * rhs.x_, y_ * rhs.y_, z_ * rhs.z_); }
  225. /// Divide by a scalar.
  226. Vector3 operator /(float rhs) const { return Vector3(x_ / rhs, y_ / rhs, z_ / rhs); }
  227. /// Divide by a vector.
  228. Vector3 operator /(const Vector3& rhs) const { return Vector3(x_ / rhs.x_, y_ / rhs.y_, z_ / rhs.z_); }
  229. /// Add-assign a vector.
  230. Vector3& operator +=(const Vector3& rhs)
  231. {
  232. x_ += rhs.x_;
  233. y_ += rhs.y_;
  234. z_ += rhs.z_;
  235. return *this;
  236. }
  237. /// Subtract-assign a vector.
  238. Vector3& operator -=(const Vector3& rhs)
  239. {
  240. x_ -= rhs.x_;
  241. y_ -= rhs.y_;
  242. z_ -= rhs.z_;
  243. return *this;
  244. }
  245. /// Multiply-assign a scalar.
  246. Vector3& operator *=(float rhs)
  247. {
  248. x_ *= rhs;
  249. y_ *= rhs;
  250. z_ *= rhs;
  251. return *this;
  252. }
  253. /// Multiply-assign a vector.
  254. Vector3& operator *=(const Vector3& rhs)
  255. {
  256. x_ *= rhs.x_;
  257. y_ *= rhs.y_;
  258. z_ *= rhs.z_;
  259. return *this;
  260. }
  261. /// Divide-assign a scalar.
  262. Vector3& operator /=(float rhs)
  263. {
  264. float invRhs = 1.0f / rhs;
  265. x_ *= invRhs;
  266. y_ *= invRhs;
  267. z_ *= invRhs;
  268. return *this;
  269. }
  270. /// Divide-assign a vector.
  271. Vector3& operator /=(const Vector3& rhs)
  272. {
  273. x_ /= rhs.x_;
  274. y_ /= rhs.y_;
  275. z_ /= rhs.z_;
  276. return *this;
  277. }
  278. /// Normalize to unit length.
  279. void Normalize()
  280. {
  281. float lenSquared = LengthSquared();
  282. if (!Atomic::Equals(lenSquared, 1.0f) && lenSquared > 0.0f)
  283. {
  284. float invLen = 1.0f / sqrtf(lenSquared);
  285. x_ *= invLen;
  286. y_ *= invLen;
  287. z_ *= invLen;
  288. }
  289. }
  290. /// Return length.
  291. float Length() const { return sqrtf(x_ * x_ + y_ * y_ + z_ * z_); }
  292. /// Return squared length.
  293. float LengthSquared() const { return x_ * x_ + y_ * y_ + z_ * z_; }
  294. /// Calculate dot product.
  295. float DotProduct(const Vector3& rhs) const { return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_; }
  296. /// Calculate absolute dot product.
  297. float AbsDotProduct(const Vector3& rhs) const
  298. {
  299. return Atomic::Abs(x_ * rhs.x_) + Atomic::Abs(y_ * rhs.y_) + Atomic::Abs(z_ * rhs.z_);
  300. }
  301. /// Project vector onto axis.
  302. float ProjectOntoAxis(const Vector3& axis) const { return DotProduct(axis.Normalized()); }
  303. /// Calculate cross product.
  304. Vector3 CrossProduct(const Vector3& rhs) const
  305. {
  306. return Vector3(
  307. y_ * rhs.z_ - z_ * rhs.y_,
  308. z_ * rhs.x_ - x_ * rhs.z_,
  309. x_ * rhs.y_ - y_ * rhs.x_
  310. );
  311. }
  312. /// Return absolute vector.
  313. Vector3 Abs() const { return Vector3(Atomic::Abs(x_), Atomic::Abs(y_), Atomic::Abs(z_)); }
  314. /// Linear interpolation with another vector.
  315. Vector3 Lerp(const Vector3& rhs, float t) const { return *this * (1.0f - t) + rhs * t; }
  316. /// Test for equality with another vector with epsilon.
  317. bool Equals(const Vector3& rhs) const
  318. {
  319. return Atomic::Equals(x_, rhs.x_) && Atomic::Equals(y_, rhs.y_) && Atomic::Equals(z_, rhs.z_);
  320. }
  321. /// Returns the angle between this vector and another vector in degrees.
  322. float Angle(const Vector3& rhs) const { return Atomic::Acos(DotProduct(rhs) / (Length() * rhs.Length())); }
  323. /// Return whether is NaN.
  324. bool IsNaN() const { return Atomic::IsNaN(x_) || Atomic::IsNaN(y_) || Atomic::IsNaN(z_); }
  325. /// Return normalized to unit length.
  326. Vector3 Normalized() const
  327. {
  328. float lenSquared = LengthSquared();
  329. if (!Atomic::Equals(lenSquared, 1.0f) && lenSquared > 0.0f)
  330. {
  331. float invLen = 1.0f / sqrtf(lenSquared);
  332. return *this * invLen;
  333. }
  334. else
  335. return *this;
  336. }
  337. // ATOMIC BEGIN
  338. Vector3 ClampedLerp(const Vector3& rhs, float t) const
  339. {
  340. if (t > 1)
  341. t = 1;
  342. else if (t < 0)
  343. t = 0;
  344. return *this * (1.0f - t) + rhs * t;
  345. }
  346. static void GetRandomInSphere( Vector3& result, const Vector3& center, float radius )
  347. {
  348. Vector3 dir;
  349. GetRandomDirection(dir);
  350. result = center + dir * radius;
  351. }
  352. static void GetRandomDirection( Vector3& result )
  353. {
  354. float len;
  355. do
  356. {
  357. result.x_ = (RandZeroOne() * 2.0f - 1.0f);
  358. result.y_ = (RandZeroOne() * 2.0f - 1.0f);
  359. result.z_ = (RandZeroOne() * 2.0f - 1.0f);
  360. len = result.Length();
  361. } while( len > 1.0f );
  362. result /= len;
  363. }
  364. static void GetRandomHemisphereDirection( Vector3& result, const Vector3& normal )
  365. {
  366. GetRandomDirection(result);
  367. if( result.DotProduct(normal) < 0 ) {
  368. result = -result;
  369. }
  370. }
  371. // ATOMIC END
  372. /// Return float data.
  373. const float* Data() const { return &x_; }
  374. /// Return as string.
  375. String ToString() const;
  376. /// X coordinate.
  377. float x_;
  378. /// Y coordinate.
  379. float y_;
  380. /// Z coordinate.
  381. float z_;
  382. /// Zero vector.
  383. static const Vector3 ZERO;
  384. /// (-1,0,0) vector.
  385. static const Vector3 LEFT;
  386. /// (1,0,0) vector.
  387. static const Vector3 RIGHT;
  388. /// (0,1,0) vector.
  389. static const Vector3 UP;
  390. /// (0,-1,0) vector.
  391. static const Vector3 DOWN;
  392. /// (0,0,1) vector.
  393. static const Vector3 FORWARD;
  394. /// (0,0,-1) vector.
  395. static const Vector3 BACK;
  396. /// (1,1,1) vector.
  397. static const Vector3 ONE;
  398. };
  399. /// Multiply Vector3 with a scalar.
  400. inline Vector3 operator *(float lhs, const Vector3& rhs) { return rhs * lhs; }
  401. /// Multiply IntVector3 with a scalar.
  402. inline IntVector3 operator *(int lhs, const IntVector3& rhs) { return rhs * lhs; }
  403. /// Per-component linear interpolation between two 3-vectors.
  404. inline Vector3 VectorLerp(const Vector3& lhs, const Vector3& rhs, const Vector3& t) { return lhs + (rhs - lhs) * t; }
  405. /// Per-component min of two 3-vectors.
  406. 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_)); }
  407. /// Per-component max of two 3-vectors.
  408. 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_)); }
  409. /// Per-component floor of 3-vector.
  410. inline Vector3 VectorFloor(const Vector3& vec) { return Vector3(Floor(vec.x_), Floor(vec.y_), Floor(vec.z_)); }
  411. /// Per-component round of 3-vector.
  412. inline Vector3 VectorRound(const Vector3& vec) { return Vector3(Round(vec.x_), Round(vec.y_), Round(vec.z_)); }
  413. /// Per-component ceil of 3-vector.
  414. inline Vector3 VectorCeil(const Vector3& vec) { return Vector3(Ceil(vec.x_), Ceil(vec.y_), Ceil(vec.z_)); }
  415. /// Per-component floor of 3-vector. Returns IntVector3.
  416. inline IntVector3 VectorFloorToInt(const Vector3& vec) { return IntVector3(FloorToInt(vec.x_), FloorToInt(vec.y_), FloorToInt(vec.z_)); }
  417. /// Per-component round of 3-vector. Returns IntVector3.
  418. inline IntVector3 VectorRoundToInt(const Vector3& vec) { return IntVector3(RoundToInt(vec.x_), RoundToInt(vec.y_), RoundToInt(vec.z_)); }
  419. /// Per-component ceil of 3-vector. Returns IntVector3.
  420. inline IntVector3 VectorCeilToInt(const Vector3& vec) { return IntVector3(CeilToInt(vec.x_), CeilToInt(vec.y_), CeilToInt(vec.z_)); }
  421. /// Per-component min of two 3-vectors.
  422. 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_)); }
  423. /// Per-component max of two 3-vectors.
  424. 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_)); }
  425. /// Return a random value from [0, 1) from 3-vector seed.
  426. inline float StableRandom(const Vector3& seed) { return StableRandom(Vector2(StableRandom(Vector2(seed.x_, seed.y_)), seed.z_)); }
  427. // ATOMIC BEGIN
  428. inline float AreaOfTriangle(const Vector3& v0, const Vector3& v1, const Vector3& v2)
  429. {
  430. float a = (v0 - v1).Length();
  431. float b = (v1 - v2).Length();
  432. float c = (v2 - v0).Length();
  433. float s = (a + b + c) * 0.5f;
  434. return (float) Sqrt<float>(s * (s-a) * (s-b) * (s-c));
  435. }
  436. // ATOMIC END
  437. }