Cry_Vector4.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Description : Common vector class
  9. #pragma once
  10. ///////////////////////////////////////////////////////////////////////////////
  11. ///////////////////////////////////////////////////////////////////////////////
  12. ///////////////////////////////////////////////////////////////////////////////
  13. // class Vec4
  14. ///////////////////////////////////////////////////////////////////////////////
  15. ///////////////////////////////////////////////////////////////////////////////
  16. ///////////////////////////////////////////////////////////////////////////////
  17. struct Vec4
  18. {
  19. using value_type = f32;
  20. enum
  21. {
  22. component_count = 4
  23. };
  24. f32 x, y, z, w;
  25. #if defined(_DEBUG)
  26. ILINE Vec4()
  27. {
  28. if constexpr (sizeof(f32) == 4)
  29. {
  30. uint32* p = alias_cast<uint32*>(&x);
  31. p[0] = F32NAN;
  32. p[1] = F32NAN;
  33. p[2] = F32NAN;
  34. p[3] = F32NAN;
  35. }
  36. }
  37. #else
  38. ILINE Vec4() {}
  39. #endif
  40. ILINE Vec4(f32 vx, f32 vy, f32 vz, f32 vw) { x = vx; y = vy; z = vz; w = vw; }
  41. ILINE Vec4(const Vec3_tpl<f32>& v, f32 vw) { x = v.x; y = v.y; z = v.z; w = vw; }
  42. explicit ILINE Vec4(f32 m) { x = y = z = w = m; }
  43. ILINE Vec4(type_zero) { x = y = z = w = f32(0); }
  44. ILINE void operator () (f32 vx, f32 vy, f32 vz, f32 vw) { x = vx; y = vy; z = vz; w = vw; }
  45. ILINE void operator () (const Vec3_tpl<f32>& v, f32 vw) { x = v.x; y = v.y; z = v.z; w = vw; }
  46. ILINE f32& operator [] (int index) { assert(index >= 0 && index <= 3); return ((f32*)this)[index]; }
  47. ILINE f32 operator [] (int index) const { assert(index >= 0 && index <= 3); return ((f32*)this)[index]; }
  48. ILINE Vec4& zero() { x = y = z = w = 0; return *this; }
  49. ILINE bool IsEquivalent(const Vec4& v1, f32 epsilon = VEC_EPSILON) const
  50. {
  51. assert(v1.IsValid());
  52. assert(this->IsValid());
  53. return ((fabs_tpl(x - v1.x) <= epsilon) && (fabs_tpl(y - v1.y) <= epsilon) && (fabs_tpl(z - v1.z) <= epsilon) && (fabs_tpl(w - v1.w) <= epsilon));
  54. }
  55. ILINE Vec4& operator=(const Vec4& src)
  56. {
  57. x = src.x;
  58. y = src.y;
  59. z = src.z;
  60. w = src.w;
  61. return *this;
  62. }
  63. ILINE Vec4 operator * (f32 k) const
  64. {
  65. return Vec4(x * k, y * k, z * k, w * k);
  66. }
  67. ILINE Vec4 operator / (f32 k) const
  68. {
  69. k = (f32)1.0 / k;
  70. return Vec4(x * k, y * k, z * k, w * k);
  71. }
  72. ILINE Vec4& operator *= (f32 k)
  73. {
  74. x *= k;
  75. y *= k;
  76. z *= k;
  77. w *= k;
  78. return *this;
  79. }
  80. ILINE Vec4& operator /= (f32 k)
  81. {
  82. k = (f32)1.0 / k;
  83. x *= k;
  84. y *= k;
  85. z *= k;
  86. w *= k;
  87. return *this;
  88. }
  89. ILINE void operator += (const Vec4& v)
  90. {
  91. x += v.x;
  92. y += v.y;
  93. z += v.z;
  94. w += v.w;
  95. }
  96. ILINE void operator -= (const Vec4& v)
  97. {
  98. x -= v.x;
  99. y -= v.y;
  100. z -= v.z;
  101. w -= v.w;
  102. }
  103. ILINE f32 Dot (const Vec4& vec2) const
  104. {
  105. return x * vec2.x + y * vec2.y + z * vec2.z + w * vec2.w;
  106. }
  107. ILINE f32 GetLength() const
  108. {
  109. return sqrt_tpl(Dot(*this));
  110. }
  111. ILINE f32 GetLengthSquared() const
  112. {
  113. return Dot(*this);
  114. }
  115. bool IsValid() const
  116. {
  117. if (!NumberValid(x))
  118. {
  119. return false;
  120. }
  121. if (!NumberValid(y))
  122. {
  123. return false;
  124. }
  125. if (!NumberValid(z))
  126. {
  127. return false;
  128. }
  129. if (!NumberValid(w))
  130. {
  131. return false;
  132. }
  133. return true;
  134. }
  135. /*!
  136. * functions and operators to compare vector
  137. *
  138. * Example:
  139. * if (v0==v1) dosomething;
  140. */
  141. ILINE bool operator==(const Vec4& vec)
  142. {
  143. return x == vec.x && y == vec.y && z == vec.z && w == vec.w;
  144. }
  145. ILINE bool operator!=(const Vec4& vec) { return !(*this == vec); }
  146. ILINE friend bool operator ==(const Vec4& v0, const Vec4& v1)
  147. {
  148. return ((v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z) && (v0.w == v1.w));
  149. }
  150. ILINE friend bool operator !=(const Vec4& v0, const Vec4& v1) { return !(v0 == v1); }
  151. //! normalize the vector
  152. // The default Normalize function is in fact "safe". 0 vectors remain unchanged.
  153. ILINE void Normalize()
  154. {
  155. assert(this->IsValid());
  156. f32 fInvLen = isqrt_safe_tpl(x * x + y * y + z * z + w * w);
  157. x *= fInvLen;
  158. y *= fInvLen;
  159. z *= fInvLen;
  160. w *= fInvLen;
  161. }
  162. //! may be faster and less accurate
  163. ILINE void NormalizeFast()
  164. {
  165. assert(this->IsValid());
  166. f32 fInvLen = isqrt_fast_tpl(x * x + y * y + z * z + w * w);
  167. x *= fInvLen;
  168. y *= fInvLen;
  169. z *= fInvLen;
  170. w *= fInvLen;
  171. }
  172. };
  173. //vector addition
  174. ILINE Vec4 operator + (const Vec4& v0, const Vec4& v1)
  175. {
  176. return Vec4(v0.x + v1.x, v0.y + v1.y, v0.z + v1.z, v0.w + v1.w);
  177. }
  178. //vector subtraction
  179. ILINE Vec4 operator - (const Vec4& v0, const Vec4& v1)
  180. {
  181. return Vec4(v0.x - v1.x, v0.y - v1.y, v0.z - v1.z, v0.w - v1.w);
  182. }