Vector4.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. // Copyright (c) 2008-2023 the Urho3D project
  2. // License: MIT
  3. #pragma once
  4. #include "../Math/Vector3.h"
  5. namespace Urho3D
  6. {
  7. /// Four-dimensional vector.
  8. class URHO3D_API Vector4
  9. {
  10. public:
  11. /// Construct a zero vector.
  12. Vector4() noexcept :
  13. x_(0.0f),
  14. y_(0.0f),
  15. z_(0.0f),
  16. w_(0.0f)
  17. {
  18. }
  19. /// Copy-construct from another vector.
  20. Vector4(const Vector4& vector) noexcept = default;
  21. /// Construct from a 3-dimensional vector and the W coordinate.
  22. Vector4(const Vector3& vector, float w) noexcept :
  23. x_(vector.x_),
  24. y_(vector.y_),
  25. z_(vector.z_),
  26. w_(w)
  27. {
  28. }
  29. /// Construct from coordinates.
  30. Vector4(float x, float y, float z, float w) noexcept :
  31. x_(x),
  32. y_(y),
  33. z_(z),
  34. w_(w)
  35. {
  36. }
  37. /// Construct from a float array.
  38. explicit Vector4(const float* data) noexcept :
  39. x_(data[0]),
  40. y_(data[1]),
  41. z_(data[2]),
  42. w_(data[3])
  43. {
  44. }
  45. /// Assign from another vector.
  46. Vector4& operator =(const Vector4& rhs) noexcept = default;
  47. /// Test for equality with another vector without epsilon.
  48. bool operator ==(const Vector4& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_ && z_ == rhs.z_ && w_ == rhs.w_; }
  49. /// Test for inequality with another vector without epsilon.
  50. bool operator !=(const Vector4& rhs) const { return x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ || w_ != rhs.w_; }
  51. /// Add a vector.
  52. Vector4 operator +(const Vector4& rhs) const { return Vector4(x_ + rhs.x_, y_ + rhs.y_, z_ + rhs.z_, w_ + rhs.w_); }
  53. /// Return negation.
  54. Vector4 operator -() const { return Vector4(-x_, -y_, -z_, -w_); }
  55. /// Subtract a vector.
  56. Vector4 operator -(const Vector4& rhs) const { return Vector4(x_ - rhs.x_, y_ - rhs.y_, z_ - rhs.z_, w_ - rhs.w_); }
  57. /// Multiply with a scalar.
  58. Vector4 operator *(float rhs) const { return Vector4(x_ * rhs, y_ * rhs, z_ * rhs, w_ * rhs); }
  59. /// Multiply with a vector.
  60. Vector4 operator *(const Vector4& rhs) const { return Vector4(x_ * rhs.x_, y_ * rhs.y_, z_ * rhs.z_, w_ * rhs.w_); }
  61. /// Divide by a scalar.
  62. Vector4 operator /(float rhs) const { return Vector4(x_ / rhs, y_ / rhs, z_ / rhs, w_ / rhs); }
  63. /// Divide by a vector.
  64. Vector4 operator /(const Vector4& rhs) const { return Vector4(x_ / rhs.x_, y_ / rhs.y_, z_ / rhs.z_, w_ / rhs.w_); }
  65. /// Add-assign a vector.
  66. Vector4& operator +=(const Vector4& rhs)
  67. {
  68. x_ += rhs.x_;
  69. y_ += rhs.y_;
  70. z_ += rhs.z_;
  71. w_ += rhs.w_;
  72. return *this;
  73. }
  74. /// Subtract-assign a vector.
  75. Vector4& operator -=(const Vector4& rhs)
  76. {
  77. x_ -= rhs.x_;
  78. y_ -= rhs.y_;
  79. z_ -= rhs.z_;
  80. w_ -= rhs.w_;
  81. return *this;
  82. }
  83. /// Multiply-assign a scalar.
  84. Vector4& operator *=(float rhs)
  85. {
  86. x_ *= rhs;
  87. y_ *= rhs;
  88. z_ *= rhs;
  89. w_ *= rhs;
  90. return *this;
  91. }
  92. /// Multiply-assign a vector.
  93. Vector4& operator *=(const Vector4& rhs)
  94. {
  95. x_ *= rhs.x_;
  96. y_ *= rhs.y_;
  97. z_ *= rhs.z_;
  98. w_ *= rhs.w_;
  99. return *this;
  100. }
  101. /// Divide-assign a scalar.
  102. Vector4& operator /=(float rhs)
  103. {
  104. float invRhs = 1.0f / rhs;
  105. x_ *= invRhs;
  106. y_ *= invRhs;
  107. z_ *= invRhs;
  108. w_ *= invRhs;
  109. return *this;
  110. }
  111. /// Divide-assign a vector.
  112. Vector4& operator /=(const Vector4& rhs)
  113. {
  114. x_ /= rhs.x_;
  115. y_ /= rhs.y_;
  116. z_ /= rhs.z_;
  117. w_ /= rhs.w_;
  118. return *this;
  119. }
  120. /// Return const value by index.
  121. float operator[](i32 index) const { return (&x_)[index]; }
  122. /// Return mutable value by index.
  123. float& operator[](i32 index) { return (&x_)[index]; }
  124. /// Calculate dot product.
  125. float DotProduct(const Vector4& rhs) const { return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_ + w_ * rhs.w_; }
  126. /// Calculate absolute dot product.
  127. float AbsDotProduct(const Vector4& rhs) const
  128. {
  129. return Urho3D::Abs(x_ * rhs.x_) + Urho3D::Abs(y_ * rhs.y_) + Urho3D::Abs(z_ * rhs.z_) + Urho3D::Abs(w_ * rhs.w_);
  130. }
  131. /// Project vector onto axis.
  132. float ProjectOntoAxis(const Vector3& axis) const { return DotProduct(Vector4(axis.Normalized(), 0.0f)); }
  133. /// Return absolute vector.
  134. Vector4 Abs() const { return Vector4(Urho3D::Abs(x_), Urho3D::Abs(y_), Urho3D::Abs(z_), Urho3D::Abs(w_)); }
  135. /// Linear interpolation with another vector.
  136. Vector4 Lerp(const Vector4& rhs, float t) const { return *this * (1.0f - t) + rhs * t; }
  137. /// Test for equality with another vector with epsilon.
  138. bool Equals(const Vector4& rhs) const
  139. {
  140. return Urho3D::Equals(x_, rhs.x_) && Urho3D::Equals(y_, rhs.y_) && Urho3D::Equals(z_, rhs.z_) && Urho3D::Equals(w_, rhs.w_);
  141. }
  142. /// Return whether any component is NaN.
  143. bool IsNaN() const { return Urho3D::IsNaN(x_) || Urho3D::IsNaN(y_) || Urho3D::IsNaN(z_) || Urho3D::IsNaN(w_); }
  144. /// Return whether any component is Inf.
  145. bool IsInf() const { return Urho3D::IsInf(x_) || Urho3D::IsInf(y_) || Urho3D::IsInf(z_) || Urho3D::IsInf(w_); }
  146. /// Convert to Vector2.
  147. explicit operator Vector2() const { return { x_, y_ }; }
  148. /// Convert to Vector3.
  149. explicit operator Vector3() const { return { x_, y_, z_ }; }
  150. /// Return float data.
  151. const float* Data() const { return &x_; }
  152. /// Return as string.
  153. String ToString() const;
  154. /// Return hash value for HashSet & HashMap.
  155. hash32 ToHash() const
  156. {
  157. hash32 hash = 37;
  158. hash = 37 * hash + FloatToRawIntBits(x_);
  159. hash = 37 * hash + FloatToRawIntBits(y_);
  160. hash = 37 * hash + FloatToRawIntBits(z_);
  161. hash = 37 * hash + FloatToRawIntBits(w_);
  162. return hash;
  163. }
  164. /// X coordinate.
  165. float x_;
  166. /// Y coordinate.
  167. float y_;
  168. /// Z coordinate.
  169. float z_;
  170. /// W coordinate.
  171. float w_;
  172. /// Zero vector.
  173. static const Vector4 ZERO;
  174. /// (1,1,1) vector.
  175. static const Vector4 ONE;
  176. };
  177. /// Multiply Vector4 with a scalar.
  178. inline Vector4 operator *(float lhs, const Vector4& rhs) { return rhs * lhs; }
  179. /// Per-component linear interpolation between two 4-vectors.
  180. inline Vector4 VectorLerp(const Vector4& lhs, const Vector4& rhs, const Vector4& t) { return lhs + (rhs - lhs) * t; }
  181. /// Per-component min of two 4-vectors.
  182. inline Vector4 VectorMin(const Vector4& lhs, const Vector4& rhs) { return Vector4(Min(lhs.x_, rhs.x_), Min(lhs.y_, rhs.y_), Min(lhs.z_, rhs.z_), Min(lhs.w_, rhs.w_)); }
  183. /// Per-component max of two 4-vectors.
  184. inline Vector4 VectorMax(const Vector4& lhs, const Vector4& rhs) { return Vector4(Max(lhs.x_, rhs.x_), Max(lhs.y_, rhs.y_), Max(lhs.z_, rhs.z_), Max(lhs.w_, rhs.w_)); }
  185. /// Per-component floor of 4-vector.
  186. inline Vector4 VectorFloor(const Vector4& vec) { return Vector4(Floor(vec.x_), Floor(vec.y_), Floor(vec.z_), Floor(vec.w_)); }
  187. /// Per-component round of 4-vector.
  188. inline Vector4 VectorRound(const Vector4& vec) { return Vector4(Round(vec.x_), Round(vec.y_), Round(vec.z_), Round(vec.w_)); }
  189. /// Per-component ceil of 4-vector.
  190. inline Vector4 VectorCeil(const Vector4& vec) { return Vector4(Ceil(vec.x_), Ceil(vec.y_), Ceil(vec.z_), Ceil(vec.w_)); }
  191. }