basis.hpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. #ifndef GODOT_BASIS_HPP
  2. #define GODOT_BASIS_HPP
  3. #include <godot_cpp/core/math.hpp>
  4. #include <godot_cpp/variant/quaternion.hpp>
  5. #include <godot_cpp/variant/vector3.hpp>
  6. namespace godot {
  7. class Basis {
  8. public:
  9. _FORCE_INLINE_ GDNativeTypePtr ptr() const { return (void *)this; }
  10. Vector3 elements[3] = {
  11. Vector3(1, 0, 0),
  12. Vector3(0, 1, 0),
  13. Vector3(0, 0, 1)
  14. };
  15. inline const Vector3 &operator[](int axis) const {
  16. return elements[axis];
  17. }
  18. inline Vector3 &operator[](int axis) {
  19. return elements[axis];
  20. }
  21. void invert();
  22. void transpose();
  23. Basis inverse() const;
  24. Basis transposed() const;
  25. inline real_t determinant() const;
  26. void from_z(const Vector3 &p_z);
  27. inline Vector3 get_axis(int p_axis) const {
  28. // get actual basis axis (elements is transposed for performance)
  29. return Vector3(elements[0][p_axis], elements[1][p_axis], elements[2][p_axis]);
  30. }
  31. inline void set_axis(int p_axis, const Vector3 &p_value) {
  32. // get actual basis axis (elements is transposed for performance)
  33. elements[0][p_axis] = p_value.x;
  34. elements[1][p_axis] = p_value.y;
  35. elements[2][p_axis] = p_value.z;
  36. }
  37. void rotate(const Vector3 &p_axis, real_t p_phi);
  38. Basis rotated(const Vector3 &p_axis, real_t p_phi) const;
  39. void rotate_local(const Vector3 &p_axis, real_t p_phi);
  40. Basis rotated_local(const Vector3 &p_axis, real_t p_phi) const;
  41. void rotate(const Vector3 &p_euler);
  42. Basis rotated(const Vector3 &p_euler) const;
  43. void rotate(const Quaternion &p_quat);
  44. Basis rotated(const Quaternion &p_quat) const;
  45. Vector3 get_rotation_euler() const;
  46. void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const;
  47. void get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) const;
  48. Quaternion get_rotation_quat() const;
  49. Vector3 get_rotation() const { return get_rotation_euler(); };
  50. Vector3 rotref_posscale_decomposition(Basis &rotref) const;
  51. Vector3 get_euler_xyz() const;
  52. void set_euler_xyz(const Vector3 &p_euler);
  53. Vector3 get_euler_xzy() const;
  54. void set_euler_xzy(const Vector3 &p_euler);
  55. Vector3 get_euler_yzx() const;
  56. void set_euler_yzx(const Vector3 &p_euler);
  57. Vector3 get_euler_yxz() const;
  58. void set_euler_yxz(const Vector3 &p_euler);
  59. Vector3 get_euler_zxy() const;
  60. void set_euler_zxy(const Vector3 &p_euler);
  61. Vector3 get_euler_zyx() const;
  62. void set_euler_zyx(const Vector3 &p_euler);
  63. Quaternion get_quat() const;
  64. void set_quat(const Quaternion &p_quat);
  65. Vector3 get_euler() const { return get_euler_yxz(); }
  66. void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); }
  67. void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const;
  68. void set_axis_angle(const Vector3 &p_axis, real_t p_phi);
  69. void scale(const Vector3 &p_scale);
  70. Basis scaled(const Vector3 &p_scale) const;
  71. void scale_local(const Vector3 &p_scale);
  72. Basis scaled_local(const Vector3 &p_scale) const;
  73. void make_scale_uniform();
  74. float get_uniform_scale() const;
  75. Vector3 get_scale() const;
  76. Vector3 get_scale_abs() const;
  77. Vector3 get_scale_local() const;
  78. void set_axis_angle_scale(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale);
  79. void set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale);
  80. void set_quat_scale(const Quaternion &p_quat, const Vector3 &p_scale);
  81. // transposed dot products
  82. inline real_t tdotx(const Vector3 &v) const {
  83. return elements[0][0] * v[0] + elements[1][0] * v[1] + elements[2][0] * v[2];
  84. }
  85. inline real_t tdoty(const Vector3 &v) const {
  86. return elements[0][1] * v[0] + elements[1][1] * v[1] + elements[2][1] * v[2];
  87. }
  88. inline real_t tdotz(const Vector3 &v) const {
  89. return elements[0][2] * v[0] + elements[1][2] * v[1] + elements[2][2] * v[2];
  90. }
  91. bool is_equal_approx(const Basis &p_basis) const;
  92. bool operator==(const Basis &p_matrix) const;
  93. bool operator!=(const Basis &p_matrix) const;
  94. inline Vector3 xform(const Vector3 &p_vector) const;
  95. inline Vector3 xform_inv(const Vector3 &p_vector) const;
  96. inline void operator*=(const Basis &p_matrix);
  97. inline Basis operator*(const Basis &p_matrix) const;
  98. inline void operator+=(const Basis &p_matrix);
  99. inline Basis operator+(const Basis &p_matrix) const;
  100. inline void operator-=(const Basis &p_matrix);
  101. inline Basis operator-(const Basis &p_matrix) const;
  102. inline void operator*=(real_t p_val);
  103. inline Basis operator*(real_t p_val) const;
  104. int get_orthogonal_index() const;
  105. void set_orthogonal_index(int p_index);
  106. void set_diagonal(const Vector3 &p_diag);
  107. bool is_orthogonal() const;
  108. bool is_diagonal() const;
  109. bool is_rotation() const;
  110. Basis slerp(const Basis &p_to, const real_t &p_weight) const;
  111. void rotate_sh(real_t *p_values);
  112. operator String() const;
  113. /* create / set */
  114. inline void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
  115. elements[0][0] = xx;
  116. elements[0][1] = xy;
  117. elements[0][2] = xz;
  118. elements[1][0] = yx;
  119. elements[1][1] = yy;
  120. elements[1][2] = yz;
  121. elements[2][0] = zx;
  122. elements[2][1] = zy;
  123. elements[2][2] = zz;
  124. }
  125. inline void set(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) {
  126. set_axis(0, p_x);
  127. set_axis(1, p_y);
  128. set_axis(2, p_z);
  129. }
  130. inline Vector3 get_column(int i) const {
  131. return Vector3(elements[0][i], elements[1][i], elements[2][i]);
  132. }
  133. inline Vector3 get_row(int i) const {
  134. return Vector3(elements[i][0], elements[i][1], elements[i][2]);
  135. }
  136. inline Vector3 get_main_diagonal() const {
  137. return Vector3(elements[0][0], elements[1][1], elements[2][2]);
  138. }
  139. inline void set_row(int i, const Vector3 &p_row) {
  140. elements[i][0] = p_row.x;
  141. elements[i][1] = p_row.y;
  142. elements[i][2] = p_row.z;
  143. }
  144. inline void set_zero() {
  145. elements[0].zero();
  146. elements[1].zero();
  147. elements[2].zero();
  148. }
  149. inline Basis transpose_xform(const Basis &m) const {
  150. return Basis(
  151. elements[0].x * m[0].x + elements[1].x * m[1].x + elements[2].x * m[2].x,
  152. elements[0].x * m[0].y + elements[1].x * m[1].y + elements[2].x * m[2].y,
  153. elements[0].x * m[0].z + elements[1].x * m[1].z + elements[2].x * m[2].z,
  154. elements[0].y * m[0].x + elements[1].y * m[1].x + elements[2].y * m[2].x,
  155. elements[0].y * m[0].y + elements[1].y * m[1].y + elements[2].y * m[2].y,
  156. elements[0].y * m[0].z + elements[1].y * m[1].z + elements[2].y * m[2].z,
  157. elements[0].z * m[0].x + elements[1].z * m[1].x + elements[2].z * m[2].x,
  158. elements[0].z * m[0].y + elements[1].z * m[1].y + elements[2].z * m[2].y,
  159. elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z);
  160. }
  161. Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
  162. set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
  163. }
  164. void orthonormalize();
  165. Basis orthonormalized() const;
  166. #ifdef MATH_CHECKS
  167. bool is_symmetric() const;
  168. #endif
  169. Basis diagonalize();
  170. operator Quaternion() const { return get_quat(); }
  171. Basis(const Quaternion &p_quat) { set_quat(p_quat); };
  172. Basis(const Quaternion &p_quat, const Vector3 &p_scale) { set_quat_scale(p_quat, p_scale); }
  173. Basis(const Vector3 &p_euler) { set_euler(p_euler); }
  174. Basis(const Vector3 &p_euler, const Vector3 &p_scale) { set_euler_scale(p_euler, p_scale); }
  175. Basis(const Vector3 &p_axis, real_t p_phi) { set_axis_angle(p_axis, p_phi); }
  176. Basis(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_phi, p_scale); }
  177. inline Basis(const Vector3 &row0, const Vector3 &row1, const Vector3 &row2) {
  178. elements[0] = row0;
  179. elements[1] = row1;
  180. elements[2] = row2;
  181. }
  182. inline Basis() {}
  183. };
  184. inline void Basis::operator*=(const Basis &p_matrix) {
  185. set(
  186. p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
  187. p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
  188. p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2]));
  189. }
  190. inline Basis Basis::operator*(const Basis &p_matrix) const {
  191. return Basis(
  192. p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
  193. p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
  194. p_matrix.tdotx(elements[2]), p_matrix.tdoty(elements[2]), p_matrix.tdotz(elements[2]));
  195. }
  196. inline void Basis::operator+=(const Basis &p_matrix) {
  197. elements[0] += p_matrix.elements[0];
  198. elements[1] += p_matrix.elements[1];
  199. elements[2] += p_matrix.elements[2];
  200. }
  201. inline Basis Basis::operator+(const Basis &p_matrix) const {
  202. Basis ret(*this);
  203. ret += p_matrix;
  204. return ret;
  205. }
  206. inline void Basis::operator-=(const Basis &p_matrix) {
  207. elements[0] -= p_matrix.elements[0];
  208. elements[1] -= p_matrix.elements[1];
  209. elements[2] -= p_matrix.elements[2];
  210. }
  211. inline Basis Basis::operator-(const Basis &p_matrix) const {
  212. Basis ret(*this);
  213. ret -= p_matrix;
  214. return ret;
  215. }
  216. inline void Basis::operator*=(real_t p_val) {
  217. elements[0] *= p_val;
  218. elements[1] *= p_val;
  219. elements[2] *= p_val;
  220. }
  221. inline Basis Basis::operator*(real_t p_val) const {
  222. Basis ret(*this);
  223. ret *= p_val;
  224. return ret;
  225. }
  226. Vector3 Basis::xform(const Vector3 &p_vector) const {
  227. return Vector3(
  228. elements[0].dot(p_vector),
  229. elements[1].dot(p_vector),
  230. elements[2].dot(p_vector));
  231. }
  232. Vector3 Basis::xform_inv(const Vector3 &p_vector) const {
  233. return Vector3(
  234. (elements[0][0] * p_vector.x) + (elements[1][0] * p_vector.y) + (elements[2][0] * p_vector.z),
  235. (elements[0][1] * p_vector.x) + (elements[1][1] * p_vector.y) + (elements[2][1] * p_vector.z),
  236. (elements[0][2] * p_vector.x) + (elements[1][2] * p_vector.y) + (elements[2][2] * p_vector.z));
  237. }
  238. real_t Basis::determinant() const {
  239. return elements[0][0] * (elements[1][1] * elements[2][2] - elements[2][1] * elements[1][2]) -
  240. elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) +
  241. elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]);
  242. }
  243. } // namespace godot
  244. #endif // GODOT_BASIS_HPP