summaryrefslogtreecommitdiffstats
path: root/include/godot_cpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/godot_cpp')
-rw-r--r--include/godot_cpp/classes/wrapped.hpp6
-rw-r--r--include/godot_cpp/core/binder_common.hpp3
-rw-r--r--include/godot_cpp/core/class_db.hpp10
-rw-r--r--include/godot_cpp/core/defs.hpp4
-rw-r--r--include/godot_cpp/core/math.hpp21
-rw-r--r--include/godot_cpp/variant/aabb.hpp7
-rw-r--r--include/godot_cpp/variant/basis.hpp209
-rw-r--r--include/godot_cpp/variant/color.hpp7
-rw-r--r--include/godot_cpp/variant/plane.hpp7
-rw-r--r--include/godot_cpp/variant/projection.hpp17
-rw-r--r--include/godot_cpp/variant/quaternion.hpp108
-rw-r--r--include/godot_cpp/variant/rect2.hpp11
-rw-r--r--include/godot_cpp/variant/rect2i.hpp9
-rw-r--r--include/godot_cpp/variant/transform2d.hpp7
-rw-r--r--include/godot_cpp/variant/transform3d.hpp136
-rw-r--r--include/godot_cpp/variant/vector2.hpp22
-rw-r--r--include/godot_cpp/variant/vector2i.hpp11
-rw-r--r--include/godot_cpp/variant/vector3.hpp43
-rw-r--r--include/godot_cpp/variant/vector3i.hpp14
-rw-r--r--include/godot_cpp/variant/vector4.hpp77
-rw-r--r--include/godot_cpp/variant/vector4i.hpp15
21 files changed, 380 insertions, 364 deletions
diff --git a/include/godot_cpp/classes/wrapped.hpp b/include/godot_cpp/classes/wrapped.hpp
index 62ec0d8..94f9f97 100644
--- a/include/godot_cpp/classes/wrapped.hpp
+++ b/include/godot_cpp/classes/wrapped.hpp
@@ -145,9 +145,9 @@ protected:
return (::godot::String(::godot::Wrapped::*)()) & m_class::_to_string; \
} \
\
- template <class T> \
+ template <class T, class B> \
static void register_virtuals() { \
- m_inherits::register_virtuals<T>(); \
+ m_inherits::register_virtuals<T, B>(); \
} \
\
public: \
@@ -159,7 +159,7 @@ public:
m_inherits::initialize_class(); \
if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
_bind_methods(); \
- m_inherits::register_virtuals<m_class>(); \
+ m_inherits::register_virtuals<m_class, m_inherits>(); \
} \
initialized = true; \
} \
diff --git a/include/godot_cpp/core/binder_common.hpp b/include/godot_cpp/core/binder_common.hpp
index 93ed731..cdfbdeb 100644
--- a/include/godot_cpp/core/binder_common.hpp
+++ b/include/godot_cpp/core/binder_common.hpp
@@ -579,4 +579,7 @@ void call_with_ptr_args_static_method_ret(R (*p_method)(P...), const GDNativeTyp
} // namespace godot
+#include <godot_cpp/classes/global_constants_binds.hpp>
+#include <godot_cpp/variant/builtin_binds.hpp>
+
#endif // ! GODOT_CPP_BINDER_COMMON_HPP
diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp
index e027ad4..c9a6186 100644
--- a/include/godot_cpp/core/class_db.hpp
+++ b/include/godot_cpp/core/class_db.hpp
@@ -89,10 +89,12 @@ public:
std::unordered_map<std::string, GDNativeExtensionClassCallVirtual> virtual_methods;
std::set<std::string> property_names;
std::set<std::string> constant_names;
+ // Pointer to the parent custom class, if any. Will be null if the parent class is a Godot class.
ClassInfo *parent_ptr = nullptr;
};
private:
+ // This may only contain custom classes, not Godot classes
static std::unordered_map<std::string, ClassInfo> classes;
static MethodBind *bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const MethodDefinition &method_name, const void **p_defs, int p_defcount);
@@ -158,10 +160,12 @@ void ClassDB::register_class() {
cl.name = T::get_class_static();
cl.parent_name = T::get_parent_class_static();
cl.level = current_level;
- classes[cl.name] = cl;
- if (classes.find(cl.parent_name) != classes.end()) {
- cl.parent_ptr = &classes[cl.parent_name];
+ std::unordered_map<std::string, ClassInfo>::iterator parent_it = classes.find(cl.parent_name);
+ if (parent_it != classes.end()) {
+ // Assign parent if it is also a custom class
+ cl.parent_ptr = &parent_it->second;
}
+ classes[cl.name] = cl;
// Register this class with Godot
GDNativeExtensionClassCreationInfo class_info = {
diff --git a/include/godot_cpp/core/defs.hpp b/include/godot_cpp/core/defs.hpp
index 9d300f4..70c4f7a 100644
--- a/include/godot_cpp/core/defs.hpp
+++ b/include/godot_cpp/core/defs.hpp
@@ -72,6 +72,10 @@
#endif
#endif
+#ifndef _NO_DISCARD_
+#define _NO_DISCARD_ [[nodiscard]]
+#endif
+
// Windows badly defines a lot of stuff we'll never use. Undefine it.
#ifdef _WIN32
#undef min // override standard definition
diff --git a/include/godot_cpp/core/math.hpp b/include/godot_cpp/core/math.hpp
index 6bc2344..78f90ca 100644
--- a/include/godot_cpp/core/math.hpp
+++ b/include/godot_cpp/core/math.hpp
@@ -537,6 +537,27 @@ inline bool is_zero_approx(double s) {
return abs(s) < CMP_EPSILON;
}
+inline float absf(float g) {
+ union {
+ float f;
+ uint32_t i;
+ } u;
+
+ u.f = g;
+ u.i &= 2147483647u;
+ return u.f;
+}
+
+inline double absd(double g) {
+ union {
+ double d;
+ uint64_t i;
+ } u;
+ u.d = g;
+ u.i &= (uint64_t)9223372036854775807ull;
+ return u.d;
+}
+
inline double smoothstep(double p_from, double p_to, double p_weight) {
if (is_equal_approx(static_cast<real_t>(p_from), static_cast<real_t>(p_to))) {
return p_from;
diff --git a/include/godot_cpp/variant/aabb.hpp b/include/godot_cpp/variant/aabb.hpp
index eaea36d..06ddc15 100644
--- a/include/godot_cpp/variant/aabb.hpp
+++ b/include/godot_cpp/variant/aabb.hpp
@@ -43,12 +43,7 @@
namespace godot {
-class AABB {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ AABB {
Vector3 position;
Vector3 size;
diff --git a/include/godot_cpp/variant/basis.hpp b/include/godot_cpp/variant/basis.hpp
index 7e11f39..48c3b0c 100644
--- a/include/godot_cpp/variant/basis.hpp
+++ b/include/godot_cpp/variant/basis.hpp
@@ -37,22 +37,17 @@
namespace godot {
-class Basis {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Basis {
Vector3 rows[3] = {
Vector3(1, 0, 0),
Vector3(0, 1, 0),
Vector3(0, 0, 1)
};
- inline const Vector3 &operator[](int axis) const {
+ _FORCE_INLINE_ const Vector3 &operator[](int axis) const {
return rows[axis];
}
- inline Vector3 &operator[](int axis) {
+ _FORCE_INLINE_ Vector3 &operator[](int axis) {
return rows[axis];
}
@@ -62,67 +57,53 @@ public:
Basis inverse() const;
Basis transposed() const;
- inline real_t determinant() const;
+ _FORCE_INLINE_ real_t determinant() const;
- void from_z(const Vector3 &p_z);
+ enum EulerOrder {
+ EULER_ORDER_XYZ,
+ EULER_ORDER_XZY,
+ EULER_ORDER_YXZ,
+ EULER_ORDER_YZX,
+ EULER_ORDER_ZXY,
+ EULER_ORDER_ZYX
+ };
- inline Vector3 get_axis(int p_axis) const {
- // get actual basis axis (rows is transposed for performance)
- return Vector3(rows[0][p_axis], rows[1][p_axis], rows[2][p_axis]);
- }
- inline void set_axis(int p_axis, const Vector3 &p_value) {
- // get actual basis axis (rows is transposed for performance)
- rows[0][p_axis] = p_value.x;
- rows[1][p_axis] = p_value.y;
- rows[2][p_axis] = p_value.z;
- }
+ void from_z(const Vector3 &p_z);
- void rotate(const Vector3 &p_axis, real_t p_phi);
- Basis rotated(const Vector3 &p_axis, real_t p_phi) const;
+ void rotate(const Vector3 &p_axis, real_t p_angle);
+ Basis rotated(const Vector3 &p_axis, real_t p_angle) const;
- void rotate_local(const Vector3 &p_axis, real_t p_phi);
- Basis rotated_local(const Vector3 &p_axis, real_t p_phi) const;
+ void rotate_local(const Vector3 &p_axis, real_t p_angle);
+ Basis rotated_local(const Vector3 &p_axis, real_t p_angle) const;
- void rotate(const Vector3 &p_euler);
- Basis rotated(const Vector3 &p_euler) const;
+ void rotate(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ);
+ Basis rotated(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ) const;
- void rotate(const Quaternion &p_quat);
- Basis rotated(const Quaternion &p_quat) const;
+ void rotate(const Quaternion &p_quaternion);
+ Basis rotated(const Quaternion &p_quaternion) const;
- Vector3 get_rotation_euler() const;
+ Vector3 get_euler_normalized(EulerOrder p_order = EULER_ORDER_YXZ) const;
void get_rotation_axis_angle(Vector3 &p_axis, real_t &p_angle) const;
void get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) const;
Quaternion get_rotation_quaternion() const;
- Vector3 get_rotation() const { return get_rotation_euler(); };
-
- Vector3 rotref_posscale_decomposition(Basis &rotref) const;
-
- Vector3 get_euler_xyz() const;
- void set_euler_xyz(const Vector3 &p_euler);
-
- Vector3 get_euler_xzy() const;
- void set_euler_xzy(const Vector3 &p_euler);
-
- Vector3 get_euler_yzx() const;
- void set_euler_yzx(const Vector3 &p_euler);
- Vector3 get_euler_yxz() const;
- void set_euler_yxz(const Vector3 &p_euler);
+ void rotate_to_align(Vector3 p_start_direction, Vector3 p_end_direction);
- Vector3 get_euler_zxy() const;
- void set_euler_zxy(const Vector3 &p_euler);
+ Vector3 rotref_posscale_decomposition(Basis &rotref) const;
- Vector3 get_euler_zyx() const;
- void set_euler_zyx(const Vector3 &p_euler);
+ Vector3 get_euler(EulerOrder p_order = EULER_ORDER_YXZ) const;
+ void set_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ);
+ static Basis from_euler(const Vector3 &p_euler, EulerOrder p_order = EULER_ORDER_YXZ) {
+ Basis b;
+ b.set_euler(p_euler, p_order);
+ return b;
+ }
Quaternion get_quaternion() const;
- void set_quaternion(const Quaternion &p_quat);
-
- Vector3 get_euler() const { return get_euler_yxz(); }
- void set_euler(const Vector3 &p_euler) { set_euler_yxz(p_euler); }
+ void set_quaternion(const Quaternion &p_quaternion);
void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const;
- void set_axis_angle(const Vector3 &p_axis, real_t p_phi);
+ void set_axis_angle(const Vector3 &p_axis, real_t p_angle);
void scale(const Vector3 &p_scale);
Basis scaled(const Vector3 &p_scale) const;
@@ -130,6 +111,9 @@ public:
void scale_local(const Vector3 &p_scale);
Basis scaled_local(const Vector3 &p_scale) const;
+ void scale_orthogonal(const Vector3 &p_scale);
+ Basis scaled_orthogonal(const Vector3 &p_scale) const;
+
void make_scale_uniform();
float get_uniform_scale() const;
@@ -137,18 +121,18 @@ public:
Vector3 get_scale_abs() const;
Vector3 get_scale_local() const;
- void set_axis_angle_scale(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale);
- void set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale);
- void set_quaternion_scale(const Quaternion &p_quat, const Vector3 &p_scale);
+ void set_axis_angle_scale(const Vector3 &p_axis, real_t p_angle, const Vector3 &p_scale);
+ void set_euler_scale(const Vector3 &p_euler, const Vector3 &p_scale, EulerOrder p_order = EULER_ORDER_YXZ);
+ void set_quaternion_scale(const Quaternion &p_quaternion, const Vector3 &p_scale);
// transposed dot products
- inline real_t tdotx(const Vector3 &v) const {
+ _FORCE_INLINE_ real_t tdotx(const Vector3 &v) const {
return rows[0][0] * v[0] + rows[1][0] * v[1] + rows[2][0] * v[2];
}
- inline real_t tdoty(const Vector3 &v) const {
+ _FORCE_INLINE_ real_t tdoty(const Vector3 &v) const {
return rows[0][1] * v[0] + rows[1][1] * v[1] + rows[2][1] * v[2];
}
- inline real_t tdotz(const Vector3 &v) const {
+ _FORCE_INLINE_ real_t tdotz(const Vector3 &v) const {
return rows[0][2] * v[0] + rows[1][2] * v[1] + rows[2][2] * v[2];
}
@@ -157,26 +141,22 @@ public:
bool operator==(const Basis &p_matrix) const;
bool operator!=(const Basis &p_matrix) const;
- inline Vector3 xform(const Vector3 &p_vector) const;
- inline Vector3 xform_inv(const Vector3 &p_vector) const;
- inline void operator*=(const Basis &p_matrix);
- inline Basis operator*(const Basis &p_matrix) const;
- inline void operator+=(const Basis &p_matrix);
- inline Basis operator+(const Basis &p_matrix) const;
- inline void operator-=(const Basis &p_matrix);
- inline Basis operator-(const Basis &p_matrix) const;
- inline void operator*=(real_t p_val);
- inline Basis operator*(real_t p_val) const;
-
- int get_orthogonal_index() const;
- void set_orthogonal_index(int p_index);
-
- void set_diagonal(const Vector3 &p_diag);
+ _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const;
+ _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const;
+ _FORCE_INLINE_ void operator*=(const Basis &p_matrix);
+ _FORCE_INLINE_ Basis operator*(const Basis &p_matrix) const;
+ _FORCE_INLINE_ void operator+=(const Basis &p_matrix);
+ _FORCE_INLINE_ Basis operator+(const Basis &p_matrix) const;
+ _FORCE_INLINE_ void operator-=(const Basis &p_matrix);
+ _FORCE_INLINE_ Basis operator-(const Basis &p_matrix) const;
+ _FORCE_INLINE_ void operator*=(const real_t p_val);
+ _FORCE_INLINE_ Basis operator*(const real_t p_val) const;
bool is_orthogonal() const;
bool is_diagonal() const;
bool is_rotation() const;
+ Basis lerp(const Basis &p_to, const real_t &p_weight) const;
Basis slerp(const Basis &p_to, const real_t &p_weight) const;
void rotate_sh(real_t *p_values);
@@ -184,7 +164,7 @@ public:
/* create / set */
- 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) {
+ _FORCE_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) {
rows[0][0] = xx;
rows[0][1] = xy;
rows[0][2] = xz;
@@ -195,35 +175,35 @@ public:
rows[2][1] = zy;
rows[2][2] = zz;
}
- inline void set(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) {
- set_axis(0, p_x);
- set_axis(1, p_y);
- set_axis(2, p_z);
- }
- inline Vector3 get_column(int i) const {
- return Vector3(rows[0][i], rows[1][i], rows[2][i]);
+ _FORCE_INLINE_ void set_columns(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) {
+ set_column(0, p_x);
+ set_column(1, p_y);
+ set_column(2, p_z);
}
- inline Vector3 get_row(int i) const {
- return Vector3(rows[i][0], rows[i][1], rows[i][2]);
+ _FORCE_INLINE_ Vector3 get_column(int p_index) const {
+ // Get actual basis axis column (we store transposed as rows for performance).
+ return Vector3(rows[0][p_index], rows[1][p_index], rows[2][p_index]);
}
- inline Vector3 get_main_diagonal() const {
- return Vector3(rows[0][0], rows[1][1], rows[2][2]);
+
+ _FORCE_INLINE_ void set_column(int p_index, const Vector3 &p_value) {
+ // Set actual basis axis column (we store transposed as rows for performance).
+ rows[0][p_index] = p_value.x;
+ rows[1][p_index] = p_value.y;
+ rows[2][p_index] = p_value.z;
}
- inline void set_row(int i, const Vector3 &p_row) {
- rows[i][0] = p_row.x;
- rows[i][1] = p_row.y;
- rows[i][2] = p_row.z;
+ _FORCE_INLINE_ Vector3 get_main_diagonal() const {
+ return Vector3(rows[0][0], rows[1][1], rows[2][2]);
}
- inline void set_zero() {
+ _FORCE_INLINE_ void set_zero() {
rows[0].zero();
rows[1].zero();
rows[2].zero();
}
- inline Basis transpose_xform(const Basis &m) const {
+ _FORCE_INLINE_ Basis transpose_xform(const Basis &m) const {
return Basis(
rows[0].x * m[0].x + rows[1].x * m[1].x + rows[2].x * m[2].x,
rows[0].x * m[0].y + rows[1].x * m[1].y + rows[2].x * m[2].y,
@@ -242,6 +222,9 @@ public:
void orthonormalize();
Basis orthonormalized() const;
+ void orthogonalize();
+ Basis orthogonalized() const;
+
#ifdef MATH_CHECKS
bool is_symmetric() const;
#endif
@@ -249,69 +232,71 @@ public:
operator Quaternion() const { return get_quaternion(); }
- Basis(const Quaternion &p_quat) { set_quaternion(p_quat); };
- Basis(const Quaternion &p_quat, const Vector3 &p_scale) { set_quaternion_scale(p_quat, p_scale); }
+ static Basis looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
- Basis(const Vector3 &p_euler) { set_euler(p_euler); }
- Basis(const Vector3 &p_euler, const Vector3 &p_scale) { set_euler_scale(p_euler, p_scale); }
+ Basis(const Quaternion &p_quaternion) { set_quaternion(p_quaternion); };
+ Basis(const Quaternion &p_quaternion, const Vector3 &p_scale) { set_quaternion_scale(p_quaternion, p_scale); }
- Basis(const Vector3 &p_axis, real_t p_phi) { set_axis_angle(p_axis, p_phi); }
- Basis(const Vector3 &p_axis, real_t p_phi, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_phi, p_scale); }
+ Basis(const Vector3 &p_axis, real_t p_angle) { set_axis_angle(p_axis, p_angle); }
+ Basis(const Vector3 &p_axis, real_t p_angle, const Vector3 &p_scale) { set_axis_angle_scale(p_axis, p_angle, p_scale); }
+ static Basis from_scale(const Vector3 &p_scale);
- inline Basis(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) {
- set_axis(0, p_x);
- set_axis(1, p_y);
- set_axis(2, p_z);
+ _FORCE_INLINE_ Basis(const Vector3 &p_x_axis, const Vector3 &p_y_axis, const Vector3 &p_z_axis) {
+ set_columns(p_x_axis, p_y_axis, p_z_axis);
}
- inline Basis() {}
+ _FORCE_INLINE_ Basis() {}
+
+private:
+ // Helper method.
+ void _set_diagonal(const Vector3 &p_diag);
};
-inline void Basis::operator*=(const Basis &p_matrix) {
+_FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) {
set(
p_matrix.tdotx(rows[0]), p_matrix.tdoty(rows[0]), p_matrix.tdotz(rows[0]),
p_matrix.tdotx(rows[1]), p_matrix.tdoty(rows[1]), p_matrix.tdotz(rows[1]),
p_matrix.tdotx(rows[2]), p_matrix.tdoty(rows[2]), p_matrix.tdotz(rows[2]));
}
-inline Basis Basis::operator*(const Basis &p_matrix) const {
+_FORCE_INLINE_ Basis Basis::operator*(const Basis &p_matrix) const {
return Basis(
p_matrix.tdotx(rows[0]), p_matrix.tdoty(rows[0]), p_matrix.tdotz(rows[0]),
p_matrix.tdotx(rows[1]), p_matrix.tdoty(rows[1]), p_matrix.tdotz(rows[1]),
p_matrix.tdotx(rows[2]), p_matrix.tdoty(rows[2]), p_matrix.tdotz(rows[2]));
}
-inline void Basis::operator+=(const Basis &p_matrix) {
+_FORCE_INLINE_ void Basis::operator+=(const Basis &p_matrix) {
rows[0] += p_matrix.rows[0];
rows[1] += p_matrix.rows[1];
rows[2] += p_matrix.rows[2];
}
-inline Basis Basis::operator+(const Basis &p_matrix) const {
+_FORCE_INLINE_ Basis Basis::operator+(const Basis &p_matrix) const {
Basis ret(*this);
ret += p_matrix;
return ret;
}
-inline void Basis::operator-=(const Basis &p_matrix) {
+_FORCE_INLINE_ void Basis::operator-=(const Basis &p_matrix) {
rows[0] -= p_matrix.rows[0];
rows[1] -= p_matrix.rows[1];
rows[2] -= p_matrix.rows[2];
}
-inline Basis Basis::operator-(const Basis &p_matrix) const {
+_FORCE_INLINE_ Basis Basis::operator-(const Basis &p_matrix) const {
Basis ret(*this);
ret -= p_matrix;
return ret;
}
-inline void Basis::operator*=(real_t p_val) {
+_FORCE_INLINE_ void Basis::operator*=(const real_t p_val) {
rows[0] *= p_val;
rows[1] *= p_val;
rows[2] *= p_val;
}
-inline Basis Basis::operator*(real_t p_val) const {
+_FORCE_INLINE_ Basis Basis::operator*(const real_t p_val) const {
Basis ret(*this);
ret *= p_val;
return ret;
@@ -333,8 +318,8 @@ Vector3 Basis::xform_inv(const Vector3 &p_vector) const {
real_t Basis::determinant() const {
return rows[0][0] * (rows[1][1] * rows[2][2] - rows[2][1] * rows[1][2]) -
- rows[1][0] * (rows[0][1] * rows[2][2] - rows[2][1] * rows[0][2]) +
- rows[2][0] * (rows[0][1] * rows[1][2] - rows[1][1] * rows[0][2]);
+ rows[1][0] * (rows[0][1] * rows[2][2] - rows[2][1] * rows[0][2]) +
+ rows[2][0] * (rows[0][1] * rows[1][2] - rows[1][1] * rows[0][2]);
}
} // namespace godot
diff --git a/include/godot_cpp/variant/color.hpp b/include/godot_cpp/variant/color.hpp
index 5d141a2..f328d7f 100644
--- a/include/godot_cpp/variant/color.hpp
+++ b/include/godot_cpp/variant/color.hpp
@@ -37,12 +37,7 @@ namespace godot {
class String;
-class Color {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Color {
union {
struct {
float r;
diff --git a/include/godot_cpp/variant/plane.hpp b/include/godot_cpp/variant/plane.hpp
index 3b1ec85..3a13ed2 100644
--- a/include/godot_cpp/variant/plane.hpp
+++ b/include/godot_cpp/variant/plane.hpp
@@ -37,12 +37,7 @@
namespace godot {
-class Plane {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Plane {
Vector3 normal;
real_t d = 0;
diff --git a/include/godot_cpp/variant/projection.hpp b/include/godot_cpp/variant/projection.hpp
index f26ce5a..5472490 100644
--- a/include/godot_cpp/variant/projection.hpp
+++ b/include/godot_cpp/variant/projection.hpp
@@ -39,18 +39,13 @@
namespace godot {
-class AABB;
-class Plane;
-class Rect2;
-class Transform3D;
-class Vector2;
+struct AABB;
+struct Plane;
+struct Rect2;
+struct Transform3D;
+struct Vector2;
-class Projection {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Projection {
enum Planes {
PLANE_NEAR,
PLANE_FAR,
diff --git a/include/godot_cpp/variant/quaternion.hpp b/include/godot_cpp/variant/quaternion.hpp
index b17afc5..e84202d 100644
--- a/include/godot_cpp/variant/quaternion.hpp
+++ b/include/godot_cpp/variant/quaternion.hpp
@@ -28,20 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_QUAT_HPP
-#define GODOT_QUAT_HPP
+#ifndef GODOT_QUATERNION_HPP
+#define GODOT_QUATERNION_HPP
#include <godot_cpp/core/math.hpp>
#include <godot_cpp/variant/vector3.hpp>
namespace godot {
-class Quaternion {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Quaternion {
union {
struct {
real_t x;
@@ -52,20 +47,23 @@ public:
real_t components[4] = { 0, 0, 0, 1.0 };
};
- inline real_t &operator[](int idx) {
+ _FORCE_INLINE_ real_t &operator[](int idx) {
return components[idx];
}
- inline const real_t &operator[](int idx) const {
+ _FORCE_INLINE_ const real_t &operator[](int idx) const {
return components[idx];
}
- inline real_t length_squared() const;
- bool is_equal_approx(const Quaternion &p_quat) const;
+ _FORCE_INLINE_ real_t length_squared() const;
+ bool is_equal_approx(const Quaternion &p_quaternion) const;
real_t length() const;
void normalize();
Quaternion normalized() const;
bool is_normalized() const;
Quaternion inverse() const;
- inline real_t dot(const Quaternion &p_q) const;
+ Quaternion log() const;
+ Quaternion exp() const;
+ _FORCE_INLINE_ real_t dot(const Quaternion &p_q) const;
+ real_t angle_to(const Quaternion &p_to) const;
Vector3 get_euler_xyz() const;
Vector3 get_euler_yxz() const;
@@ -73,9 +71,13 @@ public:
Quaternion slerp(const Quaternion &p_to, const real_t &p_weight) const;
Quaternion slerpni(const Quaternion &p_to, const real_t &p_weight) const;
- Quaternion cubic_slerp(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const;
+ Quaternion spherical_cubic_interpolate(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight) const;
+ Quaternion spherical_cubic_interpolate_in_time(const Quaternion &p_b, const Quaternion &p_pre_a, const Quaternion &p_post_b, const real_t &p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
+
+ Vector3 get_axis() const;
+ real_t get_angle() const;
- inline void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
+ _FORCE_INLINE_ void get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
r_angle = 2 * Math::acos(w);
real_t r = ((real_t)1) / Math::sqrt(1 - w * w);
r_axis.x = x * r;
@@ -86,44 +88,37 @@ public:
void operator*=(const Quaternion &p_q);
Quaternion operator*(const Quaternion &p_q) const;
- Quaternion operator*(const Vector3 &v) const {
- return Quaternion(w * v.x + y * v.z - z * v.y,
- w * v.y + z * v.x - x * v.z,
- w * v.z + x * v.y - y * v.x,
- -x * v.x - y * v.y - z * v.z);
- }
-
- inline Vector3 xform(const Vector3 &v) const {
+ _FORCE_INLINE_ Vector3 xform(const Vector3 &v) const {
#ifdef MATH_CHECKS
- ERR_FAIL_COND_V(!is_normalized(), v);
+ ERR_FAIL_COND_V_MSG(!is_normalized(), v, "The quaternion must be normalized.");
#endif
Vector3 u(x, y, z);
Vector3 uv = u.cross(v);
return v + ((uv * w) + u.cross(uv)) * ((real_t)2);
}
- inline Vector3 xform_inv(const Vector3 &v) const {
+ _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &v) const {
return inverse().xform(v);
}
- inline void operator+=(const Quaternion &p_q);
- inline void operator-=(const Quaternion &p_q);
- inline void operator*=(const real_t &s);
- inline void operator/=(const real_t &s);
- inline Quaternion operator+(const Quaternion &q2) const;
- inline Quaternion operator-(const Quaternion &q2) const;
- inline Quaternion operator-() const;
- inline Quaternion operator*(const real_t &s) const;
- inline Quaternion operator/(const real_t &s) const;
+ _FORCE_INLINE_ void operator+=(const Quaternion &p_q);
+ _FORCE_INLINE_ void operator-=(const Quaternion &p_q);
+ _FORCE_INLINE_ void operator*=(const real_t &s);
+ _FORCE_INLINE_ void operator/=(const real_t &s);
+ _FORCE_INLINE_ Quaternion operator+(const Quaternion &q2) const;
+ _FORCE_INLINE_ Quaternion operator-(const Quaternion &q2) const;
+ _FORCE_INLINE_ Quaternion operator-() const;
+ _FORCE_INLINE_ Quaternion operator*(const real_t &s) const;
+ _FORCE_INLINE_ Quaternion operator/(const real_t &s) const;
- inline bool operator==(const Quaternion &p_quat) const;
- inline bool operator!=(const Quaternion &p_quat) const;
+ _FORCE_INLINE_ bool operator==(const Quaternion &p_quaternion) const;
+ _FORCE_INLINE_ bool operator!=(const Quaternion &p_quaternion) const;
operator String() const;
- inline Quaternion() {}
+ _FORCE_INLINE_ Quaternion() {}
- inline Quaternion(real_t p_x, real_t p_y, real_t p_z, real_t p_w) :
+ _FORCE_INLINE_ Quaternion(real_t p_x, real_t p_y, real_t p_z, real_t p_w) :
x(p_x),
y(p_y),
z(p_z),
@@ -141,12 +136,11 @@ public:
w(p_q.w) {
}
- Quaternion &operator=(const Quaternion &p_q) {
+ void operator=(const Quaternion &p_q) {
x = p_q.x;
y = p_q.y;
z = p_q.z;
w = p_q.w;
- return *this;
}
Quaternion(const Vector3 &v0, const Vector3 &v1) // shortest arc
@@ -154,19 +148,19 @@ public:
Vector3 c = v0.cross(v1);
real_t d = v0.dot(v1);
- if (d < (real_t)-1.0 + CMP_EPSILON) {
- x = (real_t)0.0;
- y = (real_t)1.0;
- z = (real_t)0.0;
- w = (real_t)0.0;
+ if (d < -1.0f + (real_t)CMP_EPSILON) {
+ x = 0;
+ y = 1;
+ z = 0;
+ w = 0;
} else {
- real_t s = Math::sqrt(((real_t)1.0 + d) * (real_t)2.0);
- real_t rs = (real_t)1.0 / s;
+ real_t s = Math::sqrt((1.0f + d) * 2.0f);
+ real_t rs = 1.0f / s;
x = c.x * rs;
y = c.y * rs;
z = c.z * rs;
- w = s * (real_t)0.5;
+ w = s * 0.5f;
}
}
};
@@ -201,7 +195,7 @@ void Quaternion::operator*=(const real_t &s) {
}
void Quaternion::operator/=(const real_t &s) {
- *this *= (real_t)1.0 / s;
+ *this *= 1.0f / s;
}
Quaternion Quaternion::operator+(const Quaternion &q2) const {
@@ -224,21 +218,21 @@ Quaternion Quaternion::operator*(const real_t &s) const {
}
Quaternion Quaternion::operator/(const real_t &s) const {
- return *this * ((real_t)1.0 / s);
+ return *this * (1.0f / s);
}
-bool Quaternion::operator==(const Quaternion &p_quat) const {
- return x == p_quat.x && y == p_quat.y && z == p_quat.z && w == p_quat.w;
+bool Quaternion::operator==(const Quaternion &p_quaternion) const {
+ return x == p_quaternion.x && y == p_quaternion.y && z == p_quaternion.z && w == p_quaternion.w;
}
-bool Quaternion::operator!=(const Quaternion &p_quat) const {
- return x != p_quat.x || y != p_quat.y || z != p_quat.z || w != p_quat.w;
+bool Quaternion::operator!=(const Quaternion &p_quaternion) const {
+ return x != p_quaternion.x || y != p_quaternion.y || z != p_quaternion.z || w != p_quaternion.w;
}
-inline Quaternion operator*(const real_t &p_real, const Quaternion &p_quat) {
- return p_quat * p_real;
+_FORCE_INLINE_ Quaternion operator*(const real_t &p_real, const Quaternion &p_quaternion) {
+ return p_quaternion * p_real;
}
} // namespace godot
-#endif // GODOT_QUAT_HPP
+#endif // GODOT_QUATERNION_HPP
diff --git a/include/godot_cpp/variant/rect2.hpp b/include/godot_cpp/variant/rect2.hpp
index 70b041d..6be075d 100644
--- a/include/godot_cpp/variant/rect2.hpp
+++ b/include/godot_cpp/variant/rect2.hpp
@@ -37,16 +37,11 @@
namespace godot {
-class Rect2i;
class String;
-class Transform2D;
+struct Rect2i;
+struct Transform2D;
-class Rect2 {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Rect2 {
Point2 position;
Size2 size;
diff --git a/include/godot_cpp/variant/rect2i.hpp b/include/godot_cpp/variant/rect2i.hpp
index a930cbd..30c7d2d 100644
--- a/include/godot_cpp/variant/rect2i.hpp
+++ b/include/godot_cpp/variant/rect2i.hpp
@@ -37,15 +37,10 @@
namespace godot {
-class Rect2;
class String;
+struct Rect2;
-class Rect2i {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Rect2i {
Point2i position;
Size2i size;
diff --git a/include/godot_cpp/variant/transform2d.hpp b/include/godot_cpp/variant/transform2d.hpp
index be81687..dd0c409 100644
--- a/include/godot_cpp/variant/transform2d.hpp
+++ b/include/godot_cpp/variant/transform2d.hpp
@@ -39,12 +39,7 @@
namespace godot {
-class Transform2D {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Transform2D {
// Warning #1: basis of Transform2D is stored differently from Basis. In terms of columns array, the basis matrix looks like "on paper":
// M = (columns[0][0] columns[1][0])
// (columns[0][1] columns[1][1])
diff --git a/include/godot_cpp/variant/transform3d.hpp b/include/godot_cpp/variant/transform3d.hpp
index 01d7887..e4c8c74 100644
--- a/include/godot_cpp/variant/transform3d.hpp
+++ b/include/godot_cpp/variant/transform3d.hpp
@@ -39,12 +39,7 @@
namespace godot {
-class Transform3D {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
-
- friend class Variant;
-
-public:
+struct _NO_DISCARD_ Transform3D {
Basis basis;
Vector3 origin;
@@ -54,11 +49,11 @@ public:
void affine_invert();
Transform3D affine_inverse() const;
- Transform3D rotated(const Vector3 &p_axis, real_t p_phi) const;
+ Transform3D rotated(const Vector3 &p_axis, real_t p_angle) const;
Transform3D rotated_local(const Vector3 &p_axis, real_t p_angle) const;
- void rotate(const Vector3 &p_axis, real_t p_phi);
- void rotate_basis(const Vector3 &p_axis, real_t p_phi);
+ void rotate(const Vector3 &p_axis, real_t p_angle);
+ void rotate_basis(const Vector3 &p_axis, real_t p_angle);
void set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0));
Transform3D looking_at(const Vector3 &p_target, const Vector3 &p_up = Vector3(0, 1, 0)) const;
@@ -67,8 +62,8 @@ public:
Transform3D scaled(const Vector3 &p_scale) const;
Transform3D scaled_local(const Vector3 &p_scale) const;
void scale_basis(const Vector3 &p_scale);
- void translate(real_t p_tx, real_t p_ty, real_t p_tz);
- void translate(const Vector3 &p_translation);
+ void translate_local(real_t p_tx, real_t p_ty, real_t p_tz);
+ void translate_local(const Vector3 &p_translation);
Transform3D translated(const Vector3 &p_translation) const;
Transform3D translated_local(const Vector3 &p_translation) const;
@@ -80,29 +75,41 @@ public:
void orthonormalize();
Transform3D orthonormalized() const;
+ void orthogonalize();
+ Transform3D orthogonalized() const;
bool is_equal_approx(const Transform3D &p_transform) const;
bool operator==(const Transform3D &p_transform) const;
bool operator!=(const Transform3D &p_transform) const;
- inline Vector3 xform(const Vector3 &p_vector) const;
- inline Vector3 xform_inv(const Vector3 &p_vector) const;
+ _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vector) const;
+ _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const;
+ _FORCE_INLINE_ PackedVector3Array xform(const PackedVector3Array &p_array) const;
- inline Plane xform(const Plane &p_plane) const;
- inline Plane xform_inv(const Plane &p_plane) const;
+ // NOTE: These are UNSAFE with non-uniform scaling, and will produce incorrect results.
+ // They use the transpose.
+ // For safe inverse transforms, xform by the affine_inverse.
+ _FORCE_INLINE_ Vector3 xform_inv(const Vector3 &p_vector) const;
+ _FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const;
+ _FORCE_INLINE_ PackedVector3Array xform_inv(const PackedVector3Array &p_array) const;
- inline AABB xform(const AABB &p_aabb) const;
- inline AABB xform_inv(const AABB &p_aabb) const;
+ // Safe with non-uniform scaling (uses affine_inverse).
+ _FORCE_INLINE_ Plane xform(const Plane &p_plane) const;
+ _FORCE_INLINE_ Plane xform_inv(const Plane &p_plane) const;
- inline PackedVector3Array xform(const PackedVector3Array &p_array) const;
- inline PackedVector3Array xform_inv(const PackedVector3Array &p_array) const;
+ // These fast versions use precomputed affine inverse, and should be used in bottleneck areas where
+ // multiple planes are to be transformed.
+ _FORCE_INLINE_ Plane xform_fast(const Plane &p_plane, const Basis &p_basis_inverse_transpose) const;
+ static _FORCE_INLINE_ Plane xform_inv_fast(const Plane &p_plane, const Transform3D &p_inverse, const Basis &p_basis_transpose);
void operator*=(const Transform3D &p_transform);
Transform3D operator*(const Transform3D &p_transform) const;
+ void operator*=(const real_t p_val);
+ Transform3D operator*(const real_t p_val) const;
Transform3D interpolate_with(const Transform3D &p_transform, real_t p_c) const;
- inline Transform3D inverse_xform(const Transform3D &t) const {
+ _FORCE_INLINE_ Transform3D inverse_xform(const Transform3D &t) const {
Vector3 v = t.origin - origin;
return Transform3D(basis.transpose_xform(t.basis),
basis.xform(v));
@@ -123,14 +130,14 @@ public:
Transform3D(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, real_t ox, real_t oy, real_t oz);
};
-inline Vector3 Transform3D::xform(const Vector3 &p_vector) const {
+_FORCE_INLINE_ Vector3 Transform3D::xform(const Vector3 &p_vector) const {
return Vector3(
basis[0].dot(p_vector) + origin.x,
basis[1].dot(p_vector) + origin.y,
basis[2].dot(p_vector) + origin.z);
}
-inline Vector3 Transform3D::xform_inv(const Vector3 &p_vector) const {
+_FORCE_INLINE_ Vector3 Transform3D::xform_inv(const Vector3 &p_vector) const {
Vector3 v = p_vector - origin;
return Vector3(
@@ -139,34 +146,24 @@ inline Vector3 Transform3D::xform_inv(const Vector3 &p_vector) const {
(basis.rows[0][2] * v.x) + (basis.rows[1][2] * v.y) + (basis.rows[2][2] * v.z));
}
-inline Plane Transform3D::xform(const Plane &p_plane) const {
- Vector3 point = p_plane.normal * p_plane.d;
- Vector3 point_dir = point + p_plane.normal;
- point = xform(point);
- point_dir = xform(point_dir);
-
- Vector3 normal = point_dir - point;
- normal.normalize();
- real_t d = normal.dot(point);
-
- return Plane(normal, d);
+// Neither the plane regular xform or xform_inv are particularly efficient,
+// as they do a basis inverse. For xforming a large number
+// of planes it is better to pre-calculate the inverse transpose basis once
+// and reuse it for each plane, by using the 'fast' version of the functions.
+_FORCE_INLINE_ Plane Transform3D::xform(const Plane &p_plane) const {
+ Basis b = basis.inverse();
+ b.transpose();
+ return xform_fast(p_plane, b);
}
-inline Plane Transform3D::xform_inv(const Plane &p_plane) const {
- Vector3 point = p_plane.normal * p_plane.d;
- Vector3 point_dir = point + p_plane.normal;
- point = xform_inv(point);
- point_dir = xform_inv(point_dir);
-
- Vector3 normal = point_dir - point;
- normal.normalize();
- real_t d = normal.dot(point);
-
- return Plane(normal, d);
+_FORCE_INLINE_ Plane Transform3D::xform_inv(const Plane &p_plane) const {
+ Transform3D inv = affine_inverse();
+ Basis basis_transpose = basis.transposed();
+ return xform_inv_fast(p_plane, inv, basis_transpose);
}
-inline AABB Transform3D::xform(const AABB &p_aabb) const {
- /* http://dev.theomader.com/transform-bounding-boxes/ */
+_FORCE_INLINE_ AABB Transform3D::xform(const AABB &p_aabb) const {
+ /* https://dev.theomader.com/transform-bounding-boxes/ */
Vector3 min = p_aabb.position;
Vector3 max = p_aabb.position + p_aabb.size;
Vector3 tmin, tmax;
@@ -190,7 +187,7 @@ inline AABB Transform3D::xform(const AABB &p_aabb) const {
return r_aabb;
}
-inline AABB Transform3D::xform_inv(const AABB &p_aabb) const {
+_FORCE_INLINE_ AABB Transform3D::xform_inv(const AABB &p_aabb) const {
/* define vertices */
Vector3 vertices[8] = {
Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z),
@@ -218,8 +215,11 @@ PackedVector3Array Transform3D::xform(const PackedVector3Array &p_array) const {
PackedVector3Array array;
array.resize(p_array.size());
+ const Vector3 *r = p_array.ptr();
+ Vector3 *w = array.ptrw();
+
for (int i = 0; i < p_array.size(); ++i) {
- array[i] = xform(p_array[i]);
+ w[i] = xform(r[i]);
}
return array;
}
@@ -228,12 +228,48 @@ PackedVector3Array Transform3D::xform_inv(const PackedVector3Array &p_array) con
PackedVector3Array array;
array.resize(p_array.size());
+ const Vector3 *r = p_array.ptr();
+ Vector3 *w = array.ptrw();
+
for (int i = 0; i < p_array.size(); ++i) {
- array[i] = xform_inv(p_array[i]);
+ w[i] = xform_inv(r[i]);
}
return array;
}
+_FORCE_INLINE_ Plane Transform3D::xform_fast(const Plane &p_plane, const Basis &p_basis_inverse_transpose) const {
+ // Transform a single point on the plane.
+ Vector3 point = p_plane.normal * p_plane.d;
+ point = xform(point);
+
+ // Use inverse transpose for correct normals with non-uniform scaling.
+ Vector3 normal = p_basis_inverse_transpose.xform(p_plane.normal);
+ normal.normalize();
+
+ real_t d = normal.dot(point);
+ return Plane(normal, d);
+}
+
+_FORCE_INLINE_ Plane Transform3D::xform_inv_fast(const Plane &p_plane, const Transform3D &p_inverse, const Basis &p_basis_transpose) {
+ // Transform a single point on the plane.
+ Vector3 point = p_plane.normal * p_plane.d;
+ point = p_inverse.xform(point);
+
+ // Note that instead of precalculating the transpose, an alternative
+ // would be to use the transpose for the basis transform.
+ // However that would be less SIMD friendly (requiring a swizzle).
+ // So the cost is one extra precalced value in the calling code.
+ // This is probably worth it, as this could be used in bottleneck areas. And
+ // where it is not a bottleneck, the non-fast method is fine.
+
+ // Use transpose for correct normals with non-uniform scaling.
+ Vector3 normal = p_basis_transpose.xform(p_plane.normal);
+ normal.normalize();
+
+ real_t d = normal.dot(point);
+ return Plane(normal, d);
+}
+
} // namespace godot
-#endif // GODOT_TRANSFORM_HPP
+#endif // GODOT_TRANSFORM3D_HPP
diff --git a/include/godot_cpp/variant/vector2.hpp b/include/godot_cpp/variant/vector2.hpp
index d965ced..725a283 100644
--- a/include/godot_cpp/variant/vector2.hpp
+++ b/include/godot_cpp/variant/vector2.hpp
@@ -37,14 +37,11 @@
namespace godot {
class String;
-class Vector2i;
+struct Vector2i;
-class Vector2 {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
+struct _NO_DISCARD_ Vector2 {
+ static const int AXIS_COUNT = 2;
- friend class Variant;
-
-public:
enum Axis {
AXIS_X,
AXIS_Y,
@@ -74,10 +71,6 @@ public:
return coord[p_idx];
}
- _FORCE_INLINE_ void set_all(const real_t p_value) {
- x = y = p_value;
- }
-
_FORCE_INLINE_ Vector2::Axis min_axis_index() const {
return x < y ? Vector2::AXIS_X : Vector2::AXIS_Y;
}
@@ -119,6 +112,7 @@ public:
_FORCE_INLINE_ Vector2 lerp(const Vector2 &p_to, const real_t p_weight) const;
_FORCE_INLINE_ Vector2 slerp(const Vector2 &p_to, const real_t p_weight) const;
_FORCE_INLINE_ Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight) const;
+ _FORCE_INLINE_ Vector2 cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
_FORCE_INLINE_ Vector2 bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const;
Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const;
@@ -128,6 +122,7 @@ public:
Vector2 reflect(const Vector2 &p_normal) const;
bool is_equal_approx(const Vector2 &p_v) const;
+ bool is_zero_approx() const;
Vector2 operator+(const Vector2 &p_v) const;
void operator+=(const Vector2 &p_v);
@@ -275,6 +270,13 @@ Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, c
return res;
}
+Vector2 Vector2::cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
+ Vector2 res = *this;
+ res.x = Math::cubic_interpolate_in_time(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
+ res.y = Math::cubic_interpolate_in_time(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
+ return res;
+}
+
Vector2 Vector2::bezier_interpolate(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const {
Vector2 res = *this;
diff --git a/include/godot_cpp/variant/vector2i.hpp b/include/godot_cpp/variant/vector2i.hpp
index 5aa131a..3428e1f 100644
--- a/include/godot_cpp/variant/vector2i.hpp
+++ b/include/godot_cpp/variant/vector2i.hpp
@@ -37,14 +37,11 @@
namespace godot {
class String;
-class Vector2;
+struct Vector2;
-class Vector2i {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
+struct _NO_DISCARD_ Vector2i {
+ static const int AXIS_COUNT = 2;
- friend class Variant;
-
-public:
enum Axis {
AXIS_X,
AXIS_Y,
@@ -122,7 +119,7 @@ public:
real_t aspect() const { return width / (real_t)height; }
Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
- Vector2i abs() const { return Vector2i(ABS(x), ABS(y)); }
+ Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
operator String() const;
diff --git a/include/godot_cpp/variant/vector3.hpp b/include/godot_cpp/variant/vector3.hpp
index 0c666cf..85c89d8 100644
--- a/include/godot_cpp/variant/vector3.hpp
+++ b/include/godot_cpp/variant/vector3.hpp
@@ -36,17 +36,14 @@
namespace godot {
-class Basis;
class String;
-class Vector2;
-class Vector3i;
+struct Basis;
+struct Vector2;
+struct Vector3i;
-class Vector3 {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
+struct _NO_DISCARD_ Vector3 {
+ static const int AXIS_COUNT = 3;
- friend class Variant;
-
-public:
enum Axis {
AXIS_X,
AXIS_Y,
@@ -73,13 +70,6 @@ public:
return coord[p_axis];
}
- void set_axis(const int p_axis, const real_t p_value);
- real_t get_axis(const int p_axis) const;
-
- _FORCE_INLINE_ void set_all(const real_t p_value) {
- x = y = z = p_value;
- }
-
_FORCE_INLINE_ Vector3::Axis min_axis_index() const {
return x < y ? (x < z ? Vector3::AXIS_X : Vector3::AXIS_Z) : (y < z ? Vector3::AXIS_Y : Vector3::AXIS_Z);
}
@@ -110,12 +100,15 @@ public:
_FORCE_INLINE_ Vector3 lerp(const Vector3 &p_to, const real_t p_weight) const;
_FORCE_INLINE_ Vector3 slerp(const Vector3 &p_to, const real_t p_weight) const;
_FORCE_INLINE_ Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const;
+ _FORCE_INLINE_ Vector3 cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
_FORCE_INLINE_ Vector3 bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const;
Vector3 move_toward(const Vector3 &p_to, const real_t p_delta) const;
Vector2 octahedron_encode() const;
static Vector3 octahedron_decode(const Vector2 &p_oct);
+ Vector2 octahedron_tangent_encode(const float sign) const;
+ static Vector3 octahedron_tangent_decode(const Vector2 &p_oct, float *sign);
_FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const;
_FORCE_INLINE_ real_t dot(const Vector3 &p_with) const;
@@ -144,6 +137,7 @@ public:
_FORCE_INLINE_ Vector3 reflect(const Vector3 &p_normal) const;
bool is_equal_approx(const Vector3 &p_v) const;
+ bool is_zero_approx() const;
/* Operators */
@@ -222,16 +216,25 @@ Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const {
}
Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const {
+ // This method seems more complicated than it really is, since we write out
+ // the internals of some methods for efficiency (mainly, checking length).
real_t start_length_sq = length_squared();
real_t end_length_sq = p_to.length_squared();
if (unlikely(start_length_sq == 0.0f || end_length_sq == 0.0f)) {
// Zero length vectors have no angle, so the best we can do is either lerp or throw an error.
return lerp(p_to, p_weight);
}
+ Vector3 axis = cross(p_to);
+ real_t axis_length_sq = axis.length_squared();
+ if (unlikely(axis_length_sq == 0.0f)) {
+ // Colinear vectors have no rotation axis or angle between them, so the best we can do is lerp.
+ return lerp(p_to, p_weight);
+ }
+ axis /= Math::sqrt(axis_length_sq);
real_t start_length = Math::sqrt(start_length_sq);
real_t result_length = Math::lerp(start_length, Math::sqrt(end_length_sq), p_weight);
real_t angle = angle_to(p_to);
- return rotated(cross(p_to).normalized(), angle * p_weight) * (result_length / start_length);
+ return rotated(axis, angle * p_weight) * (result_length / start_length);
}
Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight) const {
@@ -242,6 +245,14 @@ Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, c
return res;
}
+Vector3 Vector3::cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const {
+ Vector3 res = *this;
+ res.x = Math::cubic_interpolate_in_time(res.x, p_b.x, p_pre_a.x, p_post_b.x, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
+ res.y = Math::cubic_interpolate_in_time(res.y, p_b.y, p_pre_a.y, p_post_b.y, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
+ res.z = Math::cubic_interpolate_in_time(res.z, p_b.z, p_pre_a.z, p_post_b.z, p_weight, p_b_t, p_pre_a_t, p_post_b_t);
+ return res;
+}
+
Vector3 Vector3::bezier_interpolate(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const {
Vector3 res = *this;
diff --git a/include/godot_cpp/variant/vector3i.hpp b/include/godot_cpp/variant/vector3i.hpp
index a3d9fa1..913ea3d 100644
--- a/include/godot_cpp/variant/vector3i.hpp
+++ b/include/godot_cpp/variant/vector3i.hpp
@@ -37,14 +37,11 @@
namespace godot {
class String;
-class Vector3;
+struct Vector3;
-class Vector3i {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
+struct _NO_DISCARD_ Vector3i {
+ static const int AXIS_COUNT = 3;
- friend class Variant;
-
-public:
enum Axis {
AXIS_X,
AXIS_Y,
@@ -71,9 +68,6 @@ public:
return coord[p_axis];
}
- void set_axis(const int p_axis, const int32_t p_value);
- int32_t get_axis(const int p_axis) const;
-
Vector3i::Axis min_axis_index() const;
Vector3i::Axis max_axis_index() const;
@@ -135,7 +129,7 @@ double Vector3i::length() const {
}
Vector3i Vector3i::abs() const {
- return Vector3i(ABS(x), ABS(y), ABS(z));
+ return Vector3i(Math::abs(x), Math::abs(y), Math::abs(z));
}
Vector3i Vector3i::sign() const {
diff --git a/include/godot_cpp/variant/vector4.hpp b/include/godot_cpp/variant/vector4.hpp
index 4ad3eec..4b4f6f1 100644
--- a/include/godot_cpp/variant/vector4.hpp
+++ b/include/godot_cpp/variant/vector4.hpp
@@ -38,12 +38,9 @@ namespace godot {
class String;
-class Vector4 {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
+struct _NO_DISCARD_ Vector4 {
+ static const int AXIS_COUNT = 4;
- friend class Variant;
-
-public:
enum Axis {
AXIS_X,
AXIS_Y,
@@ -61,30 +58,46 @@ public:
real_t components[4] = { 0, 0, 0, 0 };
};
- _FORCE_INLINE_ real_t &operator[](int idx) {
- return components[idx];
+ _FORCE_INLINE_ real_t &operator[](const int p_axis) {
+ DEV_ASSERT((unsigned int)p_axis < 4);
+ return components[p_axis];
}
- _FORCE_INLINE_ const real_t &operator[](int idx) const {
- return components[idx];
+ _FORCE_INLINE_ const real_t &operator[](const int p_axis) const {
+ DEV_ASSERT((unsigned int)p_axis < 4);
+ return components[p_axis];
}
+
+ Vector4::Axis min_axis_index() const;
+ Vector4::Axis max_axis_index() const;
+
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Vector4 &p_vec4) const;
+ bool is_zero_approx() const;
real_t length() const;
void normalize();
Vector4 normalized() const;
bool is_normalized() const;
+
+ real_t distance_to(const Vector4 &p_to) const;
+ real_t distance_squared_to(const Vector4 &p_to) const;
+ Vector4 direction_to(const Vector4 &p_to) const;
+
Vector4 abs() const;
Vector4 sign() const;
Vector4 floor() const;
Vector4 ceil() const;
Vector4 round() const;
+ Vector4 lerp(const Vector4 &p_to, const real_t p_weight) const;
+ Vector4 cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight) const;
+ Vector4 cubic_interpolate_in_time(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight, const real_t &p_b_t, const real_t &p_pre_a_t, const real_t &p_post_b_t) const;
- Vector4::Axis min_axis_index() const;
- Vector4::Axis max_axis_index() const;
+ Vector4 posmod(const real_t p_mod) const;
+ Vector4 posmodv(const Vector4 &p_modv) const;
+ void snap(const Vector4 &p_step);
+ Vector4 snapped(const Vector4 &p_step) const;
Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const;
Vector4 inverse() const;
- Vector4 lerp(const Vector4 &p_to, const real_t p_weight) const;
_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;
_FORCE_INLINE_ void operator+=(const Vector4 &p_vec4);
@@ -197,7 +210,7 @@ Vector4 Vector4::operator/(const Vector4 &p_vec4) const {
}
Vector4 Vector4::operator-() const {
- return Vector4(x, y, z, w);
+ return Vector4(-x, -y, -z, -w);
}
Vector4 Vector4::operator*(const real_t &s) const {
@@ -221,15 +234,12 @@ bool Vector4::operator<(const Vector4 &p_v) const {
if (y == p_v.y) {
if (z == p_v.z) {
return w < p_v.w;
- } else {
- return z < p_v.z;
}
- } else {
- return y < p_v.y;
+ return z < p_v.z;
}
- } else {
- return x < p_v.x;
+ return y < p_v.y;
}
+ return x < p_v.x;
}
bool Vector4::operator>(const Vector4 &p_v) const {
@@ -237,15 +247,12 @@ bool Vector4::operator>(const Vector4 &p_v) const {
if (y == p_v.y) {
if (z == p_v.z) {
return w > p_v.w;
- } else {
- return z > p_v.z;
}
- } else {
- return y > p_v.y;
+ return z > p_v.z;
}
- } else {
- return x > p_v.x;
+ return y > p_v.y;
}
+ return x > p_v.x;
}
bool Vector4::operator<=(const Vector4 &p_v) const {
@@ -253,15 +260,12 @@ bool Vector4::operator<=(const Vector4 &p_v) const {
if (y == p_v.y) {
if (z == p_v.z) {
return w <= p_v.w;
- } else {
- return z < p_v.z;
}
- } else {
- return y < p_v.y;
+ return z < p_v.z;
}
- } else {
- return x < p_v.x;
+ return y < p_v.y;
}
+ return x < p_v.x;
}
bool Vector4::operator>=(const Vector4 &p_v) const {
@@ -269,15 +273,12 @@ bool Vector4::operator>=(const Vector4 &p_v) const {
if (y == p_v.y) {
if (z == p_v.z) {
return w >= p_v.w;
- } else {
- return z > p_v.z;
}
- } else {
- return y > p_v.y;
+ return z > p_v.z;
}
- } else {
- return x > p_v.x;
+ return y > p_v.y;
}
+ return x > p_v.x;
}
_FORCE_INLINE_ Vector4 operator*(const float p_scalar, const Vector4 &p_vec) {
@@ -298,4 +299,4 @@ _FORCE_INLINE_ Vector4 operator*(const int64_t p_scalar, const Vector4 &p_vec) {
} // namespace godot
-#endif // GODOT_VECTOR3_HPP
+#endif // GODOT_VECTOR4_HPP
diff --git a/include/godot_cpp/variant/vector4i.hpp b/include/godot_cpp/variant/vector4i.hpp
index ce485c2..773198b 100644
--- a/include/godot_cpp/variant/vector4i.hpp
+++ b/include/godot_cpp/variant/vector4i.hpp
@@ -37,14 +37,11 @@
namespace godot {
class String;
-class Vector4;
+struct Vector4;
-class Vector4i {
- _FORCE_INLINE_ GDNativeTypePtr _native_ptr() const { return (void *)this; }
+struct _NO_DISCARD_ Vector4i {
+ static const int AXIS_COUNT = 4;
- friend class Variant;
-
-public:
enum Axis {
AXIS_X,
AXIS_Y,
@@ -64,10 +61,12 @@ public:
};
_FORCE_INLINE_ const int32_t &operator[](const int p_axis) const {
+ DEV_ASSERT((unsigned int)p_axis < 4);
return coord[p_axis];
}
_FORCE_INLINE_ int32_t &operator[](const int p_axis) {
+ DEV_ASSERT((unsigned int)p_axis < 4);
return coord[p_axis];
}
@@ -137,11 +136,11 @@ double Vector4i::length() const {
}
Vector4i Vector4i::abs() const {
- return Vector4i(ABS(x), ABS(y), ABS(z), ABS(w));
+ return Vector4i(Math::abs(x), Math::abs(y), Math::abs(z), Math::abs(w));
}
Vector4i Vector4i::sign() const {
- return Vector4i(SIGN(x), SIGN(y), SIGN(z), SIGN(w));
+ return Vector4i(Math::sign(x), Math::sign(y), Math::sign(z), Math::sign(w));
}
/* Operators */