summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/math/color.h10
-rw-r--r--core/math/vector2.h29
-rw-r--r--core/math/vector2i.cpp6
-rw-r--r--core/math/vector2i.h1
-rw-r--r--core/math/vector3.h34
-rw-r--r--core/math/vector3i.cpp7
-rw-r--r--core/math/vector3i.h1
-rw-r--r--core/math/vector4.cpp11
-rw-r--r--core/math/vector4i.cpp8
-rw-r--r--core/math/vector4i.h1
-rw-r--r--core/variant/variant_call.cpp3
-rw-r--r--core/variant/variant_utility.cpp87
12 files changed, 142 insertions, 56 deletions
diff --git a/core/math/color.h b/core/math/color.h
index a23a4953ce..5630539aa7 100644
--- a/core/math/color.h
+++ b/core/math/color.h
@@ -105,12 +105,10 @@ struct _NO_DISCARD_ Color {
_FORCE_INLINE_ Color lerp(const Color &p_to, float p_weight) const {
Color res = *this;
-
- res.r += (p_weight * (p_to.r - r));
- res.g += (p_weight * (p_to.g - g));
- res.b += (p_weight * (p_to.b - b));
- res.a += (p_weight * (p_to.a - a));
-
+ res.r = Math::lerp(res.r, p_to.r, p_weight);
+ res.g = Math::lerp(res.g, p_to.g, p_weight);
+ res.b = Math::lerp(res.b, p_to.b, p_weight);
+ res.a = Math::lerp(res.a, p_to.a, p_weight);
return res;
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index 1266561a81..835c3d1ba6 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -243,10 +243,8 @@ _FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const {
Vector2 Vector2::lerp(const Vector2 &p_to, const real_t p_weight) const {
Vector2 res = *this;
-
- res.x += (p_weight * (p_to.x - x));
- res.y += (p_weight * (p_to.y - y));
-
+ res.x = Math::lerp(res.x, p_to.x, p_weight);
+ res.y = Math::lerp(res.y, p_to.y, p_weight);
return res;
}
@@ -279,27 +277,16 @@ Vector2 Vector2::cubic_interpolate_in_time(const Vector2 &p_b, const Vector2 &p_
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;
-
- /* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - p_t);
- real_t omt2 = omt * omt;
- real_t omt3 = omt2 * omt;
- real_t t2 = p_t * p_t;
- real_t t3 = t2 * p_t;
-
- return res * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3;
+ res.x = Math::bezier_interpolate(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
+ res.y = Math::bezier_interpolate(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
+ return res;
}
Vector2 Vector2::bezier_derivative(const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) const {
Vector2 res = *this;
-
- /* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - p_t);
- real_t omt2 = omt * omt;
- real_t t2 = p_t * p_t;
-
- Vector2 d = (p_control_1 - res) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2;
- return d;
+ res.x = Math::bezier_derivative(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
+ res.y = Math::bezier_derivative(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
+ return res;
}
Vector2 Vector2::direction_to(const Vector2 &p_to) const {
diff --git a/core/math/vector2i.cpp b/core/math/vector2i.cpp
index dfed42e4d6..ff8693ee5b 100644
--- a/core/math/vector2i.cpp
+++ b/core/math/vector2i.cpp
@@ -39,6 +39,12 @@ Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const {
CLAMP(y, p_min.y, p_max.y));
}
+Vector2i Vector2i::snapped(const Vector2i &p_step) const {
+ return Vector2i(
+ Math::snapped(x, p_step.x),
+ Math::snapped(y, p_step.y));
+}
+
int64_t Vector2i::length_squared() const {
return x * (int64_t)x + y * (int64_t)y;
}
diff --git a/core/math/vector2i.h b/core/math/vector2i.h
index e131bdea94..927be11030 100644
--- a/core/math/vector2i.h
+++ b/core/math/vector2i.h
@@ -119,6 +119,7 @@ struct _NO_DISCARD_ Vector2i {
Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
+ Vector2i snapped(const Vector2i &p_step) const;
operator String() const;
operator Vector2() const;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index f5fe76a92c..dc74096690 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -209,10 +209,11 @@ Vector3 Vector3::round() const {
}
Vector3 Vector3::lerp(const Vector3 &p_to, const real_t p_weight) const {
- return Vector3(
- x + (p_weight * (p_to.x - x)),
- y + (p_weight * (p_to.y - y)),
- z + (p_weight * (p_to.z - z)));
+ Vector3 res = *this;
+ res.x = Math::lerp(res.x, p_to.x, p_weight);
+ res.y = Math::lerp(res.y, p_to.y, p_weight);
+ res.z = Math::lerp(res.z, p_to.z, p_weight);
+ return res;
}
Vector3 Vector3::slerp(const Vector3 &p_to, const real_t p_weight) const {
@@ -255,27 +256,18 @@ Vector3 Vector3::cubic_interpolate_in_time(const Vector3 &p_b, const Vector3 &p_
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;
-
- /* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - p_t);
- real_t omt2 = omt * omt;
- real_t omt3 = omt2 * omt;
- real_t t2 = p_t * p_t;
- real_t t3 = t2 * p_t;
-
- return res * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3;
+ res.x = Math::bezier_interpolate(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
+ res.y = Math::bezier_interpolate(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
+ res.z = Math::bezier_interpolate(res.z, p_control_1.z, p_control_2.z, p_end.z, p_t);
+ return res;
}
Vector3 Vector3::bezier_derivative(const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) const {
Vector3 res = *this;
-
- /* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - p_t);
- real_t omt2 = omt * omt;
- real_t t2 = p_t * p_t;
-
- Vector3 d = (p_control_1 - res) * 3.0 * omt2 + (p_control_2 - p_control_1) * 6.0 * omt * p_t + (p_end - p_control_2) * 3.0 * t2;
- return d;
+ res.x = Math::bezier_derivative(res.x, p_control_1.x, p_control_2.x, p_end.x, p_t);
+ res.y = Math::bezier_derivative(res.y, p_control_1.y, p_control_2.y, p_end.y, p_t);
+ res.z = Math::bezier_derivative(res.z, p_control_1.z, p_control_2.z, p_end.z, p_t);
+ return res;
}
real_t Vector3::distance_to(const Vector3 &p_to) const {
diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp
index b248f35035..901f2b5a64 100644
--- a/core/math/vector3i.cpp
+++ b/core/math/vector3i.cpp
@@ -48,6 +48,13 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const {
CLAMP(z, p_min.z, p_max.z));
}
+Vector3i Vector3i::snapped(const Vector3i &p_step) const {
+ return Vector3i(
+ Math::snapped(x, p_step.x),
+ Math::snapped(y, p_step.y),
+ Math::snapped(z, p_step.z));
+}
+
Vector3i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
}
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 710fd96376..36bac3d8ae 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -77,6 +77,7 @@ struct _NO_DISCARD_ Vector3i {
_FORCE_INLINE_ Vector3i abs() const;
_FORCE_INLINE_ Vector3i sign() const;
Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
+ Vector3i snapped(const Vector3i &p_step) const;
/* Operators */
diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp
index 3b189f7ed4..5ddf2bb6f6 100644
--- a/core/math/vector4.cpp
+++ b/core/math/vector4.cpp
@@ -130,11 +130,12 @@ Vector4 Vector4::round() const {
}
Vector4 Vector4::lerp(const Vector4 &p_to, const real_t p_weight) const {
- return Vector4(
- x + (p_weight * (p_to.x - x)),
- y + (p_weight * (p_to.y - y)),
- z + (p_weight * (p_to.z - z)),
- w + (p_weight * (p_to.w - w)));
+ Vector4 res = *this;
+ res.x = Math::lerp(res.x, p_to.x, p_weight);
+ res.y = Math::lerp(res.y, p_to.y, p_weight);
+ res.z = Math::lerp(res.z, p_to.z, p_weight);
+ res.w = Math::lerp(res.w, p_to.w, p_weight);
+ return res;
}
Vector4 Vector4::cubic_interpolate(const Vector4 &p_b, const Vector4 &p_pre_a, const Vector4 &p_post_b, const real_t p_weight) const {
diff --git a/core/math/vector4i.cpp b/core/math/vector4i.cpp
index 77f6fbd5b7..e906ab45ad 100644
--- a/core/math/vector4i.cpp
+++ b/core/math/vector4i.cpp
@@ -65,6 +65,14 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const {
CLAMP(w, p_min.w, p_max.w));
}
+Vector4i Vector4i::snapped(const Vector4i &p_step) const {
+ return Vector4i(
+ Math::snapped(x, p_step.x),
+ Math::snapped(y, p_step.y),
+ Math::snapped(z, p_step.z),
+ Math::snapped(w, p_step.w));
+}
+
Vector4i::operator String() const {
return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
}
diff --git a/core/math/vector4i.h b/core/math/vector4i.h
index a32414bb18..cb5a48daf9 100644
--- a/core/math/vector4i.h
+++ b/core/math/vector4i.h
@@ -79,6 +79,7 @@ struct _NO_DISCARD_ Vector4i {
_FORCE_INLINE_ Vector4i abs() const;
_FORCE_INLINE_ Vector4i sign() const;
Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const;
+ Vector4i snapped(const Vector4i &p_step) const;
/* Operators */
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 8f0e47a520..1e80e2681d 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1647,6 +1647,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2i, sign, sarray(), varray());
bind_method(Vector2i, abs, sarray(), varray());
bind_method(Vector2i, clamp, sarray("min", "max"), varray());
+ bind_method(Vector2i, snapped, sarray("step"), varray());
/* Rect2 */
@@ -1736,6 +1737,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3i, sign, sarray(), varray());
bind_method(Vector3i, abs, sarray(), varray());
bind_method(Vector3i, clamp, sarray("min", "max"), varray());
+ bind_method(Vector3i, snapped, sarray("step"), varray());
/* Vector4 */
@@ -1775,6 +1777,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector4i, sign, sarray(), varray());
bind_method(Vector4i, abs, sarray(), varray());
bind_method(Vector4i, clamp, sarray("min", "max"), varray());
+ bind_method(Vector4i, snapped, sarray("step"), varray());
/* Plane */
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index bf4f761f2b..4b82981fa9 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -322,8 +322,52 @@ struct VariantUtilityFunctions {
return Math::step_decimals(step);
}
- static inline double snapped(double value, double step) {
- return Math::snapped(value, step);
+ static inline Variant snapped(const Variant &x, const Variant &step, Callable::CallError &r_error) {
+ r_error.error = Callable::CallError::CALL_OK;
+ if (x.get_type() != step.get_type() && !((x.get_type() == Variant::INT && step.get_type() == Variant::FLOAT) || (x.get_type() == Variant::FLOAT && step.get_type() == Variant::INT))) {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = 1;
+ return Variant();
+ }
+
+ switch (step.get_type()) {
+ case Variant::INT: {
+ return snappedi(x, VariantInternalAccessor<int64_t>::get(&step));
+ } break;
+ case Variant::FLOAT: {
+ return snappedf(x, VariantInternalAccessor<double>::get(&step));
+ } break;
+ case Variant::VECTOR2: {
+ return VariantInternalAccessor<Vector2>::get(&x).snapped(VariantInternalAccessor<Vector2>::get(&step));
+ } break;
+ case Variant::VECTOR2I: {
+ return VariantInternalAccessor<Vector2i>::get(&x).snapped(VariantInternalAccessor<Vector2i>::get(&step));
+ } break;
+ case Variant::VECTOR3: {
+ return VariantInternalAccessor<Vector3>::get(&x).snapped(VariantInternalAccessor<Vector3>::get(&step));
+ } break;
+ case Variant::VECTOR3I: {
+ return VariantInternalAccessor<Vector3i>::get(&x).snapped(VariantInternalAccessor<Vector3i>::get(&step));
+ } break;
+ case Variant::VECTOR4: {
+ return VariantInternalAccessor<Vector4>::get(&x).snapped(VariantInternalAccessor<Vector4>::get(&step));
+ } break;
+ case Variant::VECTOR4I: {
+ return VariantInternalAccessor<Vector4i>::get(&x).snapped(VariantInternalAccessor<Vector4i>::get(&step));
+ } break;
+ default: {
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
+ return Variant();
+ }
+ }
+ }
+
+ static inline double snappedf(double x, double step) {
+ return Math::snapped(x, step);
+ }
+
+ static inline int64_t snappedi(double x, int64_t step) {
+ return Math::snapped(x, step);
}
static inline Variant lerp(const Variant &from, const Variant &to, double weight, Callable::CallError &r_error) {
@@ -1139,6 +1183,40 @@ static _FORCE_INLINE_ Variant::Type get_ret_type_helper(void (*p_func)(P...)) {
}; \
register_utility_function<Func_##m_func>(#m_func, m_args)
+#define FUNCBINDVR2(m_func, m_args, m_category) \
+ class Func_##m_func { \
+ public: \
+ static void call(Variant *r_ret, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { \
+ r_error.error = Callable::CallError::CALL_OK; \
+ *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], r_error); \
+ } \
+ static void validated_call(Variant *r_ret, const Variant **p_args, int p_argcount) { \
+ Callable::CallError ce; \
+ *r_ret = VariantUtilityFunctions::m_func(*p_args[0], *p_args[1], ce); \
+ } \
+ static void ptrcall(void *ret, const void **p_args, int p_argcount) { \
+ Callable::CallError ce; \
+ Variant r; \
+ r = VariantUtilityFunctions::m_func(PtrToArg<Variant>::convert(p_args[0]), PtrToArg<Variant>::convert(p_args[1]), ce); \
+ PtrToArg<Variant>::encode(r, ret); \
+ } \
+ static int get_argument_count() { \
+ return 2; \
+ } \
+ static Variant::Type get_argument_type(int p_arg) { \
+ return Variant::NIL; \
+ } \
+ static Variant::Type get_return_type() { \
+ return Variant::NIL; \
+ } \
+ static bool has_return_type() { \
+ return true; \
+ } \
+ static bool is_vararg() { return false; } \
+ static Variant::UtilityFunctionType get_type() { return m_category; } \
+ }; \
+ register_utility_function<Func_##m_func>(#m_func, m_args)
+
#define FUNCBINDVR3(m_func, m_args, m_category) \
class Func_##m_func { \
public: \
@@ -1422,6 +1500,10 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(signf, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(signi, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDVR2(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(snappedf, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
+ FUNCBINDR(snappedi, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
+
FUNCBINDR(pow, sarray("base", "exp"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(log, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(exp, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
@@ -1435,7 +1517,6 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(ease, sarray("x", "curve"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(step_decimals, sarray("x"), Variant::UTILITY_FUNC_TYPE_MATH);
- FUNCBINDR(snapped, sarray("x", "step"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDVR3(lerp, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);
FUNCBINDR(lerpf, sarray("from", "to", "weight"), Variant::UTILITY_FUNC_TYPE_MATH);