vector3.hpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. #ifndef GODOT_VECTOR3_HPP
  2. #define GODOT_VECTOR3_HPP
  3. #include <godot_cpp/core/math.hpp>
  4. #include <godot_cpp/variant/string.hpp>
  5. namespace godot {
  6. class Basis;
  7. class Vector3i;
  8. class Vector3 {
  9. public:
  10. _FORCE_INLINE_ GDNativeTypePtr ptr() const { return (void *)this; }
  11. enum Axis {
  12. AXIS_X,
  13. AXIS_Y,
  14. AXIS_Z,
  15. };
  16. union {
  17. struct {
  18. real_t x;
  19. real_t y;
  20. real_t z;
  21. };
  22. real_t coord[3] = { 0 };
  23. };
  24. inline const real_t &operator[](int p_axis) const {
  25. return coord[p_axis];
  26. }
  27. inline real_t &operator[](int p_axis) {
  28. return coord[p_axis];
  29. }
  30. void set_axis(int p_axis, real_t p_value);
  31. real_t get_axis(int p_axis) const;
  32. int min_axis() const;
  33. int max_axis() const;
  34. inline real_t length() const;
  35. inline real_t length_squared() const;
  36. inline void normalize();
  37. inline Vector3 normalized() const;
  38. inline bool is_normalized() const;
  39. inline Vector3 inverse() const;
  40. inline void zero();
  41. void snap(Vector3 p_val);
  42. Vector3 snapped(Vector3 p_val) const;
  43. void rotate(const Vector3 &p_axis, real_t p_phi);
  44. Vector3 rotated(const Vector3 &p_axis, real_t p_phi) const;
  45. /* Static Methods between 2 vector3s */
  46. inline Vector3 lerp(const Vector3 &p_to, real_t p_weight) const;
  47. inline Vector3 slerp(const Vector3 &p_to, real_t p_weight) const;
  48. Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_weight) const;
  49. Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const;
  50. inline Vector3 cross(const Vector3 &p_b) const;
  51. inline real_t dot(const Vector3 &p_b) const;
  52. Basis outer(const Vector3 &p_b) const;
  53. Basis to_diagonal_matrix() const;
  54. inline Vector3 abs() const;
  55. inline Vector3 floor() const;
  56. inline Vector3 sign() const;
  57. inline Vector3 ceil() const;
  58. inline Vector3 round() const;
  59. inline real_t distance_to(const Vector3 &p_to) const;
  60. inline real_t distance_squared_to(const Vector3 &p_to) const;
  61. inline Vector3 posmod(const real_t p_mod) const;
  62. inline Vector3 posmodv(const Vector3 &p_modv) const;
  63. inline Vector3 project(const Vector3 &p_to) const;
  64. inline real_t angle_to(const Vector3 &p_to) const;
  65. inline Vector3 direction_to(const Vector3 &p_to) const;
  66. inline Vector3 slide(const Vector3 &p_normal) const;
  67. inline Vector3 bounce(const Vector3 &p_normal) const;
  68. inline Vector3 reflect(const Vector3 &p_normal) const;
  69. bool is_equal_approx(const Vector3 &p_v) const;
  70. /* Operators */
  71. inline Vector3 &operator+=(const Vector3 &p_v);
  72. inline Vector3 operator+(const Vector3 &p_v) const;
  73. inline Vector3 &operator-=(const Vector3 &p_v);
  74. inline Vector3 operator-(const Vector3 &p_v) const;
  75. inline Vector3 &operator*=(const Vector3 &p_v);
  76. inline Vector3 operator*(const Vector3 &p_v) const;
  77. inline Vector3 &operator/=(const Vector3 &p_v);
  78. inline Vector3 operator/(const Vector3 &p_v) const;
  79. inline Vector3 &operator*=(real_t p_scalar);
  80. inline Vector3 operator*(real_t p_scalar) const;
  81. inline Vector3 &operator/=(real_t p_scalar);
  82. inline Vector3 operator/(real_t p_scalar) const;
  83. inline Vector3 operator-() const;
  84. inline bool operator==(const Vector3 &p_v) const;
  85. inline bool operator!=(const Vector3 &p_v) const;
  86. inline bool operator<(const Vector3 &p_v) const;
  87. inline bool operator<=(const Vector3 &p_v) const;
  88. inline bool operator>(const Vector3 &p_v) const;
  89. inline bool operator>=(const Vector3 &p_v) const;
  90. operator String() const;
  91. operator Vector3i() const;
  92. inline Vector3() {}
  93. inline Vector3(real_t p_x, real_t p_y, real_t p_z) {
  94. x = p_x;
  95. y = p_y;
  96. z = p_z;
  97. }
  98. Vector3(const Vector3i &p_ivec);
  99. };
  100. Vector3 Vector3::cross(const Vector3 &p_b) const {
  101. Vector3 ret(
  102. (y * p_b.z) - (z * p_b.y),
  103. (z * p_b.x) - (x * p_b.z),
  104. (x * p_b.y) - (y * p_b.x));
  105. return ret;
  106. }
  107. real_t Vector3::dot(const Vector3 &p_b) const {
  108. return x * p_b.x + y * p_b.y + z * p_b.z;
  109. }
  110. Vector3 Vector3::abs() const {
  111. return Vector3(Math::abs(x), Math::abs(y), Math::abs(z));
  112. }
  113. Vector3 Vector3::sign() const {
  114. return Vector3(Math::sign(x), Math::sign(y), Math::sign(z));
  115. }
  116. Vector3 Vector3::floor() const {
  117. return Vector3(Math::floor(x), Math::floor(y), Math::floor(z));
  118. }
  119. Vector3 Vector3::ceil() const {
  120. return Vector3(Math::ceil(x), Math::ceil(y), Math::ceil(z));
  121. }
  122. Vector3 Vector3::round() const {
  123. return Vector3(Math::round(x), Math::round(y), Math::round(z));
  124. }
  125. Vector3 Vector3::lerp(const Vector3 &p_to, real_t p_weight) const {
  126. return Vector3(
  127. x + (p_weight * (p_to.x - x)),
  128. y + (p_weight * (p_to.y - y)),
  129. z + (p_weight * (p_to.z - z)));
  130. }
  131. Vector3 Vector3::slerp(const Vector3 &p_to, real_t p_weight) const {
  132. real_t theta = angle_to(p_to);
  133. return rotated(cross(p_to).normalized(), theta * p_weight);
  134. }
  135. real_t Vector3::distance_to(const Vector3 &p_to) const {
  136. return (p_to - *this).length();
  137. }
  138. real_t Vector3::distance_squared_to(const Vector3 &p_to) const {
  139. return (p_to - *this).length_squared();
  140. }
  141. Vector3 Vector3::posmod(const real_t p_mod) const {
  142. return Vector3(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod));
  143. }
  144. Vector3 Vector3::posmodv(const Vector3 &p_modv) const {
  145. return Vector3(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y), Math::fposmod(z, p_modv.z));
  146. }
  147. Vector3 Vector3::project(const Vector3 &p_to) const {
  148. return p_to * (dot(p_to) / p_to.length_squared());
  149. }
  150. real_t Vector3::angle_to(const Vector3 &p_to) const {
  151. return Math::atan2(cross(p_to).length(), dot(p_to));
  152. }
  153. Vector3 Vector3::direction_to(const Vector3 &p_to) const {
  154. Vector3 ret(p_to.x - x, p_to.y - y, p_to.z - z);
  155. ret.normalize();
  156. return ret;
  157. }
  158. /* Operators */
  159. Vector3 &Vector3::operator+=(const Vector3 &p_v) {
  160. x += p_v.x;
  161. y += p_v.y;
  162. z += p_v.z;
  163. return *this;
  164. }
  165. Vector3 Vector3::operator+(const Vector3 &p_v) const {
  166. return Vector3(x + p_v.x, y + p_v.y, z + p_v.z);
  167. }
  168. Vector3 &Vector3::operator-=(const Vector3 &p_v) {
  169. x -= p_v.x;
  170. y -= p_v.y;
  171. z -= p_v.z;
  172. return *this;
  173. }
  174. Vector3 Vector3::operator-(const Vector3 &p_v) const {
  175. return Vector3(x - p_v.x, y - p_v.y, z - p_v.z);
  176. }
  177. Vector3 &Vector3::operator*=(const Vector3 &p_v) {
  178. x *= p_v.x;
  179. y *= p_v.y;
  180. z *= p_v.z;
  181. return *this;
  182. }
  183. Vector3 Vector3::operator*(const Vector3 &p_v) const {
  184. return Vector3(x * p_v.x, y * p_v.y, z * p_v.z);
  185. }
  186. Vector3 &Vector3::operator/=(const Vector3 &p_v) {
  187. x /= p_v.x;
  188. y /= p_v.y;
  189. z /= p_v.z;
  190. return *this;
  191. }
  192. Vector3 Vector3::operator/(const Vector3 &p_v) const {
  193. return Vector3(x / p_v.x, y / p_v.y, z / p_v.z);
  194. }
  195. Vector3 &Vector3::operator*=(real_t p_scalar) {
  196. x *= p_scalar;
  197. y *= p_scalar;
  198. z *= p_scalar;
  199. return *this;
  200. }
  201. inline Vector3 operator*(real_t p_scalar, const Vector3 &p_vec) {
  202. return p_vec * p_scalar;
  203. }
  204. Vector3 Vector3::operator*(real_t p_scalar) const {
  205. return Vector3(x * p_scalar, y * p_scalar, z * p_scalar);
  206. }
  207. Vector3 &Vector3::operator/=(real_t p_scalar) {
  208. x /= p_scalar;
  209. y /= p_scalar;
  210. z /= p_scalar;
  211. return *this;
  212. }
  213. Vector3 Vector3::operator/(real_t p_scalar) const {
  214. return Vector3(x / p_scalar, y / p_scalar, z / p_scalar);
  215. }
  216. Vector3 Vector3::operator-() const {
  217. return Vector3(-x, -y, -z);
  218. }
  219. bool Vector3::operator==(const Vector3 &p_v) const {
  220. return x == p_v.x && y == p_v.y && z == p_v.z;
  221. }
  222. bool Vector3::operator!=(const Vector3 &p_v) const {
  223. return x != p_v.x || y != p_v.y || z != p_v.z;
  224. }
  225. bool Vector3::operator<(const Vector3 &p_v) const {
  226. if (x == p_v.x) {
  227. if (y == p_v.y) {
  228. return z < p_v.z;
  229. }
  230. return y < p_v.y;
  231. }
  232. return x < p_v.x;
  233. }
  234. bool Vector3::operator>(const Vector3 &p_v) const {
  235. if (x == p_v.x) {
  236. if (y == p_v.y) {
  237. return z > p_v.z;
  238. }
  239. return y > p_v.y;
  240. }
  241. return x > p_v.x;
  242. }
  243. bool Vector3::operator<=(const Vector3 &p_v) const {
  244. if (x == p_v.x) {
  245. if (y == p_v.y) {
  246. return z <= p_v.z;
  247. }
  248. return y < p_v.y;
  249. }
  250. return x < p_v.x;
  251. }
  252. bool Vector3::operator>=(const Vector3 &p_v) const {
  253. if (x == p_v.x) {
  254. if (y == p_v.y) {
  255. return z >= p_v.z;
  256. }
  257. return y > p_v.y;
  258. }
  259. return x > p_v.x;
  260. }
  261. inline Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {
  262. return p_a.cross(p_b);
  263. }
  264. inline real_t vec3_dot(const Vector3 &p_a, const Vector3 &p_b) {
  265. return p_a.dot(p_b);
  266. }
  267. real_t Vector3::length() const {
  268. real_t x2 = x * x;
  269. real_t y2 = y * y;
  270. real_t z2 = z * z;
  271. return Math::sqrt(x2 + y2 + z2);
  272. }
  273. real_t Vector3::length_squared() const {
  274. real_t x2 = x * x;
  275. real_t y2 = y * y;
  276. real_t z2 = z * z;
  277. return x2 + y2 + z2;
  278. }
  279. void Vector3::normalize() {
  280. real_t lengthsq = length_squared();
  281. if (lengthsq == 0) {
  282. x = y = z = 0;
  283. } else {
  284. real_t length = Math::sqrt(lengthsq);
  285. x /= length;
  286. y /= length;
  287. z /= length;
  288. }
  289. }
  290. Vector3 Vector3::normalized() const {
  291. Vector3 v = *this;
  292. v.normalize();
  293. return v;
  294. }
  295. bool Vector3::is_normalized() const {
  296. // use length_squared() instead of length() to avoid sqrt(), makes it more stringent.
  297. return Math::is_equal_approx(length_squared(), 1.0, UNIT_EPSILON);
  298. }
  299. Vector3 Vector3::inverse() const {
  300. return Vector3(1.0 / x, 1.0 / y, 1.0 / z);
  301. }
  302. void Vector3::zero() {
  303. x = y = z = 0;
  304. }
  305. // slide returns the component of the vector along the given plane, specified by its normal vector.
  306. Vector3 Vector3::slide(const Vector3 &p_normal) const {
  307. #ifdef MATH_CHECKS
  308. ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector3());
  309. #endif
  310. return *this - p_normal * this->dot(p_normal);
  311. }
  312. Vector3 Vector3::bounce(const Vector3 &p_normal) const {
  313. return -reflect(p_normal);
  314. }
  315. Vector3 Vector3::reflect(const Vector3 &p_normal) const {
  316. #ifdef MATH_CHECKS
  317. ERR_FAIL_COND_V(!p_normal.is_normalized(), Vector3());
  318. #endif
  319. return 2.0 * p_normal * this->dot(p_normal) - *this;
  320. }
  321. } // namespace godot
  322. #endif // GODOT_VECTOR3_HPP