Skip to content

Commit

Permalink
Implement snappedi, snappedf, and Vector[2/3/4]i.snapped
Browse files Browse the repository at this point in the history
  • Loading branch information
MewPurPur committed Nov 19, 2022
1 parent a1bc636 commit e26f090
Show file tree
Hide file tree
Showing 18 changed files with 222 additions and 40 deletions.
6 changes: 6 additions & 0 deletions core/math/vector2i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions core/math/vector2i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions core/math/vector3i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) + ")";
}
Expand Down
1 change: 1 addition & 0 deletions core/math/vector3i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
8 changes: 8 additions & 0 deletions core/math/vector4i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) + ")";
}
Expand Down
1 change: 1 addition & 0 deletions core/math/vector4i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
3 changes: 3 additions & 0 deletions core/variant/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,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 */

Expand Down Expand Up @@ -1734,6 +1735,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 */

Expand Down Expand Up @@ -1773,6 +1775,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 */

Expand Down
87 changes: 84 additions & 3 deletions core/variant/variant_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -1132,6 +1176,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: \
Expand Down Expand Up @@ -1415,6 +1493,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);
Expand All @@ -1428,7 +1510,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);
Expand Down
59 changes: 46 additions & 13 deletions doc/classes/@GlobalScope.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<return type="Variant" />
<param index="0" name="x" type="Variant" />
<description>
Returns the absolute value of a [Variant] parameter [param x] (i.e. non-negative value). Variant types [int], [float], [Vector2], [Vector2i], [Vector3] and [Vector3i] are supported.
Returns the absolute value of a [Variant] parameter [param x] (i.e. non-negative value). Supported types: [int], [float], [Vector2], [Vector2i], [Vector3], [Vector3i], [Vector4], [Vector4i].
[codeblock]
var a = abs(-1)
# a is 1
Expand All @@ -36,6 +36,7 @@
var f = abs(Vector3i(-7, -8, -9))
# f is (7, 8, 9)
[/codeblock]
[b]Note:[/b] For better type safety, use [method absf], [method absi], [method Vector2.abs], [method Vector2i.abs], [method Vector3.abs], [method Vector3i.abs], [method Vector4.abs], or [method Vector4i.abs].
</description>
</method>
<method name="absf">
Expand Down Expand Up @@ -143,7 +144,7 @@
i = ceil(1.001) # i is 2.0
[/codeblock]
See also [method floor], [method round], and [method snapped].
[b]Note:[/b] For better type safety, see [method ceilf], [method ceili], [method Vector2.ceil], [method Vector3.ceil] and [method Vector4.ceil].
[b]Note:[/b] For better type safety, use [method ceilf], [method ceili], [method Vector2.ceil], [method Vector3.ceil], or [method Vector4.ceil].
</description>
</method>
<method name="ceilf">
Expand All @@ -168,7 +169,7 @@
<param index="1" name="min" type="Variant" />
<param index="2" name="max" type="Variant" />
<description>
Clamps the [param value], returning a [Variant] not less than [param min] and not more than [param max]. Variant types [int], [float], [Vector2], [Vector2i], [Vector3] and [Vector3i] are supported.
Clamps the [param value], returning a [Variant] not less than [param min] and not more than [param max]. Supported types: [int], [float], [Vector2], [Vector2i], [Vector3], [Vector3i], [Vector4], [Vector4i].
[codeblock]
var a = clamp(-10, -1, 5)
# a is -1
Expand All @@ -188,6 +189,7 @@
var f = clamp(Vector3i(-7, -8, -9), Vector3i(-1, 2, 3), Vector3i(-4, -5, -6))
# f is (-4, -5, -6)
[/codeblock]
[b]Note:[/b] For better type safety, use [method clampf], [method clampi], [method Vector2.clamp], [method Vector2i.clamp], [method Vector3.clamp], [method Vector3i.clamp], [method Vector4.clamp], or [method Vector4i.clamp].
</description>
</method>
<method name="clampf">
Expand Down Expand Up @@ -367,7 +369,7 @@
a = floor(-2.99) # a is -3.0
[/codeblock]
See also [method ceil], [method round], and [method snapped].
[b]Note:[/b] For better type safety, see [method floorf], [method floori], [method Vector2.floor], [method Vector3.floor] and [method Vector4.floor].
[b]Note:[/b] For better type safety, use [method floorf], [method floori], [method Vector2.floor], [method Vector3.floor], or [method Vector4.floor].
</description>
</method>
<method name="floorf">
Expand Down Expand Up @@ -950,7 +952,7 @@
round(2.6) # Returns 3
[/codeblock]
See also [method floor], [method ceil], and [method snapped].
[b]Note:[/b] For better type safety, use [method roundf], [method roundi], [method Vector2.round], [method Vector3.round] or [method Vector4.round], instead.
[b]Note:[/b] For better type safety, use [method roundf], [method roundi], [method Vector2.round], [method Vector3.round], or [method Vector4.round].
</description>
</method>
<method name="roundf">
Expand Down Expand Up @@ -987,21 +989,22 @@
<return type="Variant" />
<param index="0" name="x" type="Variant" />
<description>
Returns the sign of [param x] as same type of [Variant] as [param x] with each component being -1, 0 and 1 for each negative, zero and positive values respectively. Variant types [int], [float], [Vector2], [Vector2i], [Vector3] and [Vector3i] are supported.
Returns the same type of [Variant] as [param x], with [code]-1[/code] for negative values, [code]1[/code] for positive values, and [code]0[/code] for zeros. Supported types: [int], [float], [Vector2], [Vector2i], [Vector3], [Vector3i], [Vector4], [Vector4i].
[codeblock]
sign(-6.0) # Returns -1
sign(0.0) # Returns 0
sign(6.0) # Returns 1

sign(Vector3(-6.0, 0.0, 6.0) # Returns (-1, 0, 1)
sign(Vector3(-6.0, 0.0, 6.0)) # Returns (-1, 0, 1)
[/codeblock]
[b]Note:[/b] For better type safety, use [method signf], [method signi], [method Vector2.sign], [method Vector2i.sign], [method Vector3.sign], [method Vector3i.sign], [method Vector4.sign], or [method Vector4i.sign].
</description>
</method>
<method name="signf">
<return type="float" />
<param index="0" name="x" type="float" />
<description>
Returns the sign of [param x] as a [float]: -1.0 or 1.0. Returns 0.0 if [param x] is 0.0.
Returns [code]-1.0[/code] if [param x] is negative, [code]1.0[/code] if [param x] is positive, and [code]0.0[/code] if if [param x] is zero.
[codeblock]
sign(-6.5) # Returns -1.0
sign(0.0) # Returns 0.0
Expand All @@ -1013,7 +1016,7 @@
<return type="int" />
<param index="0" name="x" type="int" />
<description>
Returns the sign of [param x] as an [int]: -1 or 1. Returns 0 if [param x] is 0.
Returns [code]-1[/code] if [param x] is negative, [code]1[/code] if [param x] is positive, and [code]0[/code] if if [param x] is zero.
[codeblock]
sign(-6) # Returns -1
sign(0) # Returns 0
Expand Down Expand Up @@ -1063,16 +1066,46 @@
</description>
</method>
<method name="snapped">
<return type="Variant" />
<param index="0" name="x" type="Variant" />
<param index="1" name="step" type="Variant" />
<description>
Returns the multiple of [param step] that is the closest to [param x]. This can also be used to round a floating point number to an arbitrary number of decimals.
The returned value is the same type of [Variant] as [param step]. Supported types: [int], [float], [Vector2], [Vector2i], [Vector3], [Vector3i], [Vector4], [Vector4i].
[codeblock]
snapped(100, 32) # Returns 96
snapped(3.14159, 0.01) # Returns 3.14

snapped(Vector2(34, 70), Vector2(8, 8)) # Returns (32, 72)
[/codeblock]
See also [method ceil], [method floor], and [method round].
[b]Note:[/b] For better type safety, use [method snappedf], [method snappedi], [method Vector2.snapped], [method Vector2i.snapped], [method Vector3.snapped], [method Vector3i.snapped], [method Vector4.snapped], or [method Vector4i.snapped].
</description>
</method>
<method name="snappedf">
<return type="float" />
<param index="0" name="x" type="float" />
<param index="1" name="step" type="float" />
<description>
Snaps the float value [param x] to a given [param step]. This can also be used to round a floating point number to an arbitrary number of decimals.
Returns the multiple of [param step] that is the closest to [param x]. This can also be used to round a floating point number to an arbitrary number of decimals.
A type-safe version of [method snapped], returning a [float].
[codeblock]
snapped(100, 32) # Returns 96
snapped(3.14159, 0.01) # Returns 3.14
snapped(32.0, 2.5) # Returns 32.5
snapped(3.14159, 0.01) # Returns 3.14
[/codeblock]
</description>
</method>
<method name="snappedi">
<return type="int" />
<param index="0" name="x" type="float" />
<param index="1" name="step" type="int" />
<description>
Returns the multiple of [param step] that is the closest to [param x].
A type-safe version of [method snapped], returning an [int].
[codeblock]
snapped(53, 16) # Returns 48
snapped(4096, 100) # Returns 4100
[/codeblock]
See also [method ceil], [method floor], and [method round].
</description>
</method>
<method name="sqrt">
Expand Down
Loading

0 comments on commit e26f090

Please sign in to comment.