Vec3.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #ifndef Vec3_H
  2. #define Vec3_H
  3. #include "FrameworkMath.h"
  4. namespace Framework
  5. {
  6. template<typename T, T defaultValue = (T)0>
  7. //! A 3D vector
  8. class Vec3
  9. {
  10. public:
  11. T x; //! X component of the vector
  12. T y; //! Y component of the vector
  13. T z; //! Z component of the vector
  14. //! Constructor
  15. inline Vec3()
  16. : x(defaultValue),
  17. y(defaultValue),
  18. z(defaultValue)
  19. {}
  20. //! Constructor
  21. //! \param x The X component of the new vector
  22. //! \param y The Y component of the new vector
  23. //! \param z The Z component of the new vector
  24. inline Vec3(T x, T y, T z)
  25. : x(x),
  26. y(y),
  27. z(z)
  28. {}
  29. //! Constructor
  30. //! \param vect A vector whose values should be copied
  31. inline Vec3(const Vec3& vect)
  32. : Vec3(vect.x, vect.y, vect.z)
  33. {}
  34. //! Scales the vector so that it has length 1
  35. inline Vec3& normalize()
  36. {
  37. const T length = getLength();
  38. x /= length;
  39. y /= length;
  40. z /= length;
  41. return *this;
  42. }
  43. //! Swaps the values of the vector with those of another vector
  44. //! \param vect The other vector
  45. inline Vec3& swap(Vec3& vect)
  46. {
  47. const Vec3 tmp = vect;
  48. vect = *this;
  49. *this = tmp;
  50. return *this;
  51. }
  52. //! Calculates an angle between this and another vector
  53. inline float angle(Vec3 vect)
  54. {
  55. return lowPrecisionACos(
  56. (float)(*this * vect)
  57. / ((float)getLength() * (float)vect.getLength()));
  58. }
  59. //! Copies the values of another vector
  60. //! \param r The other vector
  61. inline Vec3 operator=(const Vec3& r)
  62. {
  63. x = r.x;
  64. y = r.y;
  65. z = r.z;
  66. return *this;
  67. }
  68. //! Adds another vector to this one
  69. //! \param r The other vector
  70. inline Vec3 operator+=(const Vec3& r)
  71. {
  72. x += r.x;
  73. y += r.y;
  74. z += r.z;
  75. return *this;
  76. }
  77. //! Subtracts another vector from this one
  78. //! \param r The other vector
  79. inline Vec3 operator-=(const Vec3& r)
  80. {
  81. x -= r.x;
  82. y -= r.y;
  83. z -= r.z;
  84. return *this;
  85. }
  86. //! Scales this vector
  87. //! \param r The factor
  88. inline Vec3 operator*=(const T& r)
  89. {
  90. x *= r;
  91. y *= r;
  92. z *= r;
  93. return *this;
  94. }
  95. //! Scales this vector by 1/factor
  96. //! \param r The factor
  97. inline Vec3 operator/=(const T& r)
  98. {
  99. x /= r;
  100. y /= r;
  101. z /= r;
  102. return *this;
  103. }
  104. //! Calculates the square of the distance between two vectors
  105. //! \param p The other vector
  106. inline T distanceSq(const Vec3& p) const
  107. {
  108. return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y)
  109. + (z - p.z) * (z - p.z);
  110. }
  111. //! Calculates the distance between two vectors
  112. //! \param p The other vector
  113. inline T distance(const Vec3& p) const
  114. {
  115. return sqrt(distanceSq(p));
  116. }
  117. //! Returns a new vector that is the negation of this one
  118. inline Vec3 operator-() const
  119. {
  120. return {-x, -y, -z};
  121. }
  122. template<typename T2>
  123. //! Converts the vector type to another
  124. inline operator Vec3<T2>() const
  125. {
  126. return {(T2)x, (T2)y, (T2)z};
  127. }
  128. //! Calculates the square of the vector's length
  129. inline T getLengthSq() const
  130. {
  131. return *this * *this;
  132. }
  133. //! Calculates the length of the vector
  134. inline T getLength() const
  135. {
  136. return (T)sqrt(getLengthSq());
  137. }
  138. //! Calculates the dot product between two vectors
  139. //! \param r The other vector
  140. inline T operator*(const Vec3& r) const
  141. {
  142. return x * r.x + y * r.y + z * r.z;
  143. }
  144. //! Calculates the sum of two vectors
  145. //! \param r The other vector
  146. inline Vec3 operator+(const Vec3& r) const
  147. {
  148. return Vec3(*this) += r;
  149. }
  150. //! Subtracts two vectors from each other
  151. //! \param r The other vector
  152. inline Vec3 operator-(const Vec3& r) const
  153. {
  154. return Vec3(*this) -= r;
  155. }
  156. //! Scales the vector without modifying it
  157. //! \param r The factor
  158. inline Vec3 operator*(const T& r) const
  159. {
  160. return Vec3(*this) *= r;
  161. }
  162. //! Scales the vector by 1/factor without modifying it
  163. //! \param r The factor
  164. inline Vec3 operator/(const T& r) const
  165. {
  166. return Vec3(*this) /= r;
  167. }
  168. //! Checks two vectors for equality
  169. //! \param r The other vector
  170. inline bool operator==(const Vec3& r) const
  171. {
  172. return x == r.x && y == r.y && z == r.z;
  173. }
  174. //! Checks two vectors for inequality
  175. //! \param r The other vector
  176. inline bool operator!=(const Vec3& r) const
  177. {
  178. return !(*this == r);
  179. }
  180. //! Returns the cross product between this and another vector
  181. //! \param b The other vector
  182. inline Vec3 crossProduct(const Vec3& b) const
  183. {
  184. return Vec3(
  185. y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x);
  186. }
  187. inline Vec3& rotateY(float radian)
  188. {
  189. const float cosTheta = lowPrecisionCos(radian);
  190. const float sinTheta = lowPrecisionSin(radian);
  191. float x = cosTheta * this->x + sinTheta * this->z;
  192. float z = -sinTheta * this->x + cosTheta * this->z;
  193. this->x = (T)x;
  194. this->z = (T)z;
  195. return *this;
  196. }
  197. inline Vec3& rotateX(float radian)
  198. {
  199. const float cosTheta = lowPrecisionCos(radian);
  200. const float sinTheta = lowPrecisionSin(radian);
  201. float y = cosTheta * this->y + -sinTheta * this->z;
  202. float z = sinTheta * this->y + cosTheta * this->z;
  203. this->y = (T)y;
  204. this->z = (T)z;
  205. return *this;
  206. }
  207. inline Vec3& rotateZ(float radian)
  208. {
  209. const float cosTheta = lowPrecisionCos(radian);
  210. const float sinTheta = lowPrecisionSin(radian);
  211. float x = cosTheta * this->x + -sinTheta * this->y;
  212. float y = sinTheta * this->x + cosTheta * this->y;
  213. this->x = (T)x;
  214. this->y = (T)y;
  215. return *this;
  216. }
  217. };
  218. } // namespace Framework
  219. #endif