From b65970860e2cb0b255528553392965b893cbb35f Mon Sep 17 00:00:00 2001
From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Date: Sun, 3 Mar 2024 19:47:59 +0100
Subject: [PATCH] Add scalar versions of `Vector*` `min/max/clamp/snap(ped)`

Also added `snapped` to the integer vectors for completeness
---
 include/godot_cpp/variant/aabb.hpp     |  2 +-
 include/godot_cpp/variant/rect2.hpp    | 14 +++++---------
 include/godot_cpp/variant/rect2i.hpp   | 14 +++++---------
 include/godot_cpp/variant/vector2.hpp  | 10 ++++++++++
 include/godot_cpp/variant/vector2i.hpp | 11 +++++++++++
 include/godot_cpp/variant/vector3.hpp  | 11 +++++++++++
 include/godot_cpp/variant/vector3i.hpp | 11 +++++++++++
 include/godot_cpp/variant/vector4.hpp  | 11 +++++++++++
 include/godot_cpp/variant/vector4i.hpp | 11 +++++++++++
 src/variant/vector2.cpp                | 12 ++++++++++++
 src/variant/vector2i.cpp               | 18 ++++++++++++++++++
 src/variant/vector3.cpp                | 19 +++++++++++++++++++
 src/variant/vector3i.cpp               | 21 +++++++++++++++++++++
 src/variant/vector4.cpp                | 21 +++++++++++++++++++++
 src/variant/vector4i.cpp               | 24 ++++++++++++++++++++++++
 15 files changed, 191 insertions(+), 19 deletions(-)

diff --git a/include/godot_cpp/variant/aabb.hpp b/include/godot_cpp/variant/aabb.hpp
index 7706d5115..8f2bce762 100644
--- a/include/godot_cpp/variant/aabb.hpp
+++ b/include/godot_cpp/variant/aabb.hpp
@@ -102,7 +102,7 @@ struct _NO_DISCARD_ AABB {
 	_FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */
 
 	_FORCE_INLINE_ AABB abs() const {
-		return AABB(Vector3(position.x + MIN(size.x, (real_t)0), position.y + MIN(size.y, (real_t)0), position.z + MIN(size.z, (real_t)0)), size.abs());
+		return AABB(position + size.minf(0), size.abs());
 	}
 
 	Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
diff --git a/include/godot_cpp/variant/rect2.hpp b/include/godot_cpp/variant/rect2.hpp
index cfd24b2fb..201e02ba9 100644
--- a/include/godot_cpp/variant/rect2.hpp
+++ b/include/godot_cpp/variant/rect2.hpp
@@ -154,14 +154,12 @@ struct _NO_DISCARD_ Rect2 {
 			return Rect2();
 		}
 
-		new_rect.position.x = Math::max(p_rect.position.x, position.x);
-		new_rect.position.y = Math::max(p_rect.position.y, position.y);
+		new_rect.position = p_rect.position.max(position);
 
 		Point2 p_rect_end = p_rect.position + p_rect.size;
 		Point2 end = position + size;
 
-		new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
-		new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
+		new_rect.size = p_rect_end.min(end) - new_rect.position;
 
 		return new_rect;
 	}
@@ -174,11 +172,9 @@ struct _NO_DISCARD_ Rect2 {
 #endif
 		Rect2 new_rect;
 
-		new_rect.position.x = Math::min(p_rect.position.x, position.x);
-		new_rect.position.y = Math::min(p_rect.position.y, position.y);
+		new_rect.position = p_rect.position.min(position);
 
-		new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
-		new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
+		new_rect.size = (p_rect.position + p_rect.size).max(position + size);
 
 		new_rect.size = new_rect.size - new_rect.position; // Make relative again.
 
@@ -283,7 +279,7 @@ struct _NO_DISCARD_ Rect2 {
 	}
 
 	_FORCE_INLINE_ Rect2 abs() const {
-		return Rect2(Point2(position.x + Math::min(size.x, (real_t)0), position.y + Math::min(size.y, (real_t)0)), size.abs());
+		return Rect2(position + size.minf(0), size.abs());
 	}
 
 	Vector2 get_support(const Vector2 &p_normal) const {
diff --git a/include/godot_cpp/variant/rect2i.hpp b/include/godot_cpp/variant/rect2i.hpp
index c2a15ac3d..eff495836 100644
--- a/include/godot_cpp/variant/rect2i.hpp
+++ b/include/godot_cpp/variant/rect2i.hpp
@@ -97,14 +97,12 @@ struct _NO_DISCARD_ Rect2i {
 			return Rect2i();
 		}
 
-		new_rect.position.x = Math::max(p_rect.position.x, position.x);
-		new_rect.position.y = Math::max(p_rect.position.y, position.y);
+		new_rect.position = p_rect.position.max(position);
 
 		Point2i p_rect_end = p_rect.position + p_rect.size;
 		Point2i end = position + size;
 
-		new_rect.size.x = Math::min(p_rect_end.x, end.x) - new_rect.position.x;
-		new_rect.size.y = Math::min(p_rect_end.y, end.y) - new_rect.position.y;
+		new_rect.size = p_rect_end.min(end) - new_rect.position;
 
 		return new_rect;
 	}
@@ -117,11 +115,9 @@ struct _NO_DISCARD_ Rect2i {
 #endif
 		Rect2i new_rect;
 
-		new_rect.position.x = Math::min(p_rect.position.x, position.x);
-		new_rect.position.y = Math::min(p_rect.position.y, position.y);
+		new_rect.position = p_rect.position.min(position);
 
-		new_rect.size.x = Math::max(p_rect.position.x + p_rect.size.x, position.x + size.x);
-		new_rect.size.y = Math::max(p_rect.position.y + p_rect.size.y, position.y + size.y);
+		new_rect.size = (p_rect.position + p_rect.size).max(position + size);
 
 		new_rect.size = new_rect.size - new_rect.position; // Make relative again.
 
@@ -219,7 +215,7 @@ struct _NO_DISCARD_ Rect2i {
 	}
 
 	_FORCE_INLINE_ Rect2i abs() const {
-		return Rect2i(Point2i(position.x + Math::min(size.x, 0), position.y + Math::min(size.y, 0)), size.abs());
+		return Rect2i(position + size.mini(0), size.abs());
 	}
 
 	_FORCE_INLINE_ void set_end(const Vector2i &p_end) {
diff --git a/include/godot_cpp/variant/vector2.hpp b/include/godot_cpp/variant/vector2.hpp
index 13c0da6fe..51dd8cce0 100644
--- a/include/godot_cpp/variant/vector2.hpp
+++ b/include/godot_cpp/variant/vector2.hpp
@@ -91,10 +91,18 @@ struct _NO_DISCARD_ Vector2 {
 		return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y));
 	}
 
+	Vector2 minf(real_t p_scalar) const {
+		return Vector2(MIN(x, p_scalar), MIN(y, p_scalar));
+	}
+
 	Vector2 max(const Vector2 &p_vector2) const {
 		return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y));
 	}
 
+	Vector2 maxf(real_t p_scalar) const {
+		return Vector2(MAX(x, p_scalar), MAX(y, p_scalar));
+	}
+
 	real_t distance_to(const Vector2 &p_vector2) const;
 	real_t distance_squared_to(const Vector2 &p_vector2) const;
 	real_t angle_to(const Vector2 &p_vector2) const;
@@ -168,7 +176,9 @@ struct _NO_DISCARD_ Vector2 {
 	Vector2 ceil() const;
 	Vector2 round() const;
 	Vector2 snapped(const Vector2 &p_by) const;
+	Vector2 snappedf(real_t p_by) const;
 	Vector2 clamp(const Vector2 &p_min, const Vector2 &p_max) const;
+	Vector2 clampf(real_t p_min, real_t p_max) const;
 	real_t aspect() const { return width / height; }
 
 	operator String() const;
diff --git a/include/godot_cpp/variant/vector2i.hpp b/include/godot_cpp/variant/vector2i.hpp
index afeaeead3..0d787c3fc 100644
--- a/include/godot_cpp/variant/vector2i.hpp
+++ b/include/godot_cpp/variant/vector2i.hpp
@@ -83,10 +83,18 @@ struct _NO_DISCARD_ Vector2i {
 		return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y));
 	}
 
+	Vector2i mini(int32_t p_scalar) const {
+		return Vector2i(MIN(x, p_scalar), MIN(y, p_scalar));
+	}
+
 	Vector2i max(const Vector2i &p_vector2i) const {
 		return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y));
 	}
 
+	Vector2i maxi(int32_t p_scalar) const {
+		return Vector2i(MAX(x, p_scalar), MAX(y, p_scalar));
+	}
+
 	Vector2i operator+(const Vector2i &p_v) const;
 	void operator+=(const Vector2i &p_v);
 	Vector2i operator-(const Vector2i &p_v) const;
@@ -123,7 +131,10 @@ struct _NO_DISCARD_ Vector2i {
 	real_t aspect() const { return width / (real_t)height; }
 	Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
 	Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
+	Vector2i snapped(const Vector2i &p_step) const;
+	Vector2i snappedi(int32_t p_step) const;
 	Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
+	Vector2i clampi(int32_t p_min, int32_t p_max) const;
 
 	operator String() const;
 	operator Vector2() const;
diff --git a/include/godot_cpp/variant/vector3.hpp b/include/godot_cpp/variant/vector3.hpp
index a8d96ed0c..0d3ad62b4 100644
--- a/include/godot_cpp/variant/vector3.hpp
+++ b/include/godot_cpp/variant/vector3.hpp
@@ -82,10 +82,18 @@ struct _NO_DISCARD_ Vector3 {
 		return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z));
 	}
 
+	Vector3 minf(real_t p_scalar) const {
+		return Vector3(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
+	}
+
 	Vector3 max(const Vector3 &p_vector3) const {
 		return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
 	}
 
+	Vector3 maxf(real_t p_scalar) const {
+		return Vector3(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
+	}
+
 	_FORCE_INLINE_ real_t length() const;
 	_FORCE_INLINE_ real_t length_squared() const;
 
@@ -98,7 +106,9 @@ struct _NO_DISCARD_ Vector3 {
 	_FORCE_INLINE_ void zero();
 
 	void snap(const Vector3 p_val);
+	void snapf(real_t p_val);
 	Vector3 snapped(const Vector3 p_val) const;
+	Vector3 snappedf(real_t p_val) const;
 
 	void rotate(const Vector3 &p_axis, const real_t p_angle);
 	Vector3 rotated(const Vector3 &p_axis, const real_t p_angle) const;
@@ -128,6 +138,7 @@ struct _NO_DISCARD_ Vector3 {
 	_FORCE_INLINE_ Vector3 ceil() const;
 	_FORCE_INLINE_ Vector3 round() const;
 	Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const;
+	Vector3 clampf(real_t p_min, real_t p_max) const;
 
 	_FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const;
 	_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const;
diff --git a/include/godot_cpp/variant/vector3i.hpp b/include/godot_cpp/variant/vector3i.hpp
index ae5148ff0..b2cdbbdfd 100644
--- a/include/godot_cpp/variant/vector3i.hpp
+++ b/include/godot_cpp/variant/vector3i.hpp
@@ -75,10 +75,18 @@ struct _NO_DISCARD_ Vector3i {
 		return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
 	}
 
+	Vector3i mini(int32_t p_scalar) const {
+		return Vector3i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar));
+	}
+
 	Vector3i max(const Vector3i &p_vector3i) const {
 		return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
 	}
 
+	Vector3i maxi(int32_t p_scalar) const {
+		return Vector3i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar));
+	}
+
 	_FORCE_INLINE_ int64_t length_squared() const;
 	_FORCE_INLINE_ double length() const;
 
@@ -89,7 +97,10 @@ struct _NO_DISCARD_ Vector3i {
 
 	_FORCE_INLINE_ Vector3i abs() const;
 	_FORCE_INLINE_ Vector3i sign() const;
+	Vector3i snapped(const Vector3i &p_step) const;
+	Vector3i snappedi(int32_t p_step) const;
 	Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
+	Vector3i clampi(int32_t p_min, int32_t p_max) const;
 
 	/* Operators */
 
diff --git a/include/godot_cpp/variant/vector4.hpp b/include/godot_cpp/variant/vector4.hpp
index 26c57c357..a2e8faecc 100644
--- a/include/godot_cpp/variant/vector4.hpp
+++ b/include/godot_cpp/variant/vector4.hpp
@@ -74,10 +74,18 @@ struct _NO_DISCARD_ Vector4 {
 		return Vector4(MIN(x, p_vector4.x), MIN(y, p_vector4.y), MIN(z, p_vector4.z), MIN(w, p_vector4.w));
 	}
 
+	Vector4 minf(real_t p_scalar) const {
+		return Vector4(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
+	}
+
 	Vector4 max(const Vector4 &p_vector4) const {
 		return Vector4(MAX(x, p_vector4.x), MAX(y, p_vector4.y), MAX(z, p_vector4.z), MAX(w, p_vector4.w));
 	}
 
+	Vector4 maxf(real_t p_scalar) const {
+		return Vector4(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
+	}
+
 	_FORCE_INLINE_ real_t length_squared() const;
 	bool is_equal_approx(const Vector4 &p_vec4) const;
 	bool is_zero_approx() const;
@@ -102,8 +110,11 @@ struct _NO_DISCARD_ Vector4 {
 	Vector4 posmod(const real_t p_mod) const;
 	Vector4 posmodv(const Vector4 &p_modv) const;
 	void snap(const Vector4 &p_step);
+	void snapf(real_t p_step);
 	Vector4 snapped(const Vector4 &p_step) const;
+	Vector4 snappedf(real_t p_step) const;
 	Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const;
+	Vector4 clampf(real_t p_min, real_t p_max) const;
 
 	Vector4 inverse() const;
 	_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;
diff --git a/include/godot_cpp/variant/vector4i.hpp b/include/godot_cpp/variant/vector4i.hpp
index 36f2855e0..8e9510fd0 100644
--- a/include/godot_cpp/variant/vector4i.hpp
+++ b/include/godot_cpp/variant/vector4i.hpp
@@ -77,10 +77,18 @@ struct _NO_DISCARD_ Vector4i {
 		return Vector4i(MIN(x, p_vector4i.x), MIN(y, p_vector4i.y), MIN(z, p_vector4i.z), MIN(w, p_vector4i.w));
 	}
 
+	Vector4i mini(int32_t p_scalar) const {
+		return Vector4i(MIN(x, p_scalar), MIN(y, p_scalar), MIN(z, p_scalar), MIN(w, p_scalar));
+	}
+
 	Vector4i max(const Vector4i &p_vector4i) const {
 		return Vector4i(MAX(x, p_vector4i.x), MAX(y, p_vector4i.y), MAX(z, p_vector4i.z), MAX(w, p_vector4i.w));
 	}
 
+	Vector4i maxi(int32_t p_scalar) const {
+		return Vector4i(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar), MAX(w, p_scalar));
+	}
+
 	_FORCE_INLINE_ int64_t length_squared() const;
 	_FORCE_INLINE_ double length() const;
 
@@ -91,7 +99,10 @@ struct _NO_DISCARD_ Vector4i {
 
 	_FORCE_INLINE_ Vector4i abs() const;
 	_FORCE_INLINE_ Vector4i sign() const;
+	Vector4i snapped(const Vector4i &p_step) const;
+	Vector4i snappedi(int32_t p_step) const;
 	Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const;
+	Vector4i clampi(int32_t p_min, int32_t p_max) const;
 
 	/* Operators */
 
diff --git a/src/variant/vector2.cpp b/src/variant/vector2.cpp
index df8708053..409ba50ec 100644
--- a/src/variant/vector2.cpp
+++ b/src/variant/vector2.cpp
@@ -137,12 +137,24 @@ Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const {
 			CLAMP(y, p_min.y, p_max.y));
 }
 
+Vector2 Vector2::clampf(real_t p_min, real_t p_max) const {
+	return Vector2(
+			CLAMP(x, p_min, p_max),
+			CLAMP(y, p_min, p_max));
+}
+
 Vector2 Vector2::snapped(const Vector2 &p_step) const {
 	return Vector2(
 			Math::snapped(x, p_step.x),
 			Math::snapped(y, p_step.y));
 }
 
+Vector2 Vector2::snappedf(real_t p_step) const {
+	return Vector2(
+			Math::snapped(x, p_step),
+			Math::snapped(y, p_step));
+}
+
 Vector2 Vector2::limit_length(const real_t p_len) const {
 	const real_t l = length();
 	Vector2 v = *this;
diff --git a/src/variant/vector2i.cpp b/src/variant/vector2i.cpp
index c1c1ab076..4baff3bb3 100644
--- a/src/variant/vector2i.cpp
+++ b/src/variant/vector2i.cpp
@@ -35,12 +35,30 @@
 
 namespace godot {
 
+Vector2i Vector2i::snapped(const Vector2i &p_step) const {
+	return Vector2i(
+			Math::snapped(x, p_step.x),
+			Math::snapped(y, p_step.y));
+}
+
+Vector2i Vector2i::snappedi(int32_t p_step) const {
+	return Vector2i(
+			Math::snapped(x, p_step),
+			Math::snapped(y, p_step));
+}
+
 Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const {
 	return Vector2i(
 			CLAMP(x, p_min.x, p_max.x),
 			CLAMP(y, p_min.y, p_max.y));
 }
 
+Vector2i Vector2i::clampi(int32_t p_min, int32_t p_max) const {
+	return Vector2i(
+			CLAMP(x, p_min, p_max),
+			CLAMP(y, p_min, p_max));
+}
+
 int64_t Vector2i::length_squared() const {
 	return x * (int64_t)x + y * (int64_t)y;
 }
diff --git a/src/variant/vector3.cpp b/src/variant/vector3.cpp
index 615365802..e66018566 100644
--- a/src/variant/vector3.cpp
+++ b/src/variant/vector3.cpp
@@ -54,18 +54,37 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const {
 			CLAMP(z, p_min.z, p_max.z));
 }
 
+Vector3 Vector3::clampf(real_t p_min, real_t p_max) const {
+	return Vector3(
+			CLAMP(x, p_min, p_max),
+			CLAMP(y, p_min, p_max),
+			CLAMP(z, p_min, p_max));
+}
+
 void Vector3::snap(const Vector3 p_step) {
 	x = Math::snapped(x, p_step.x);
 	y = Math::snapped(y, p_step.y);
 	z = Math::snapped(z, p_step.z);
 }
 
+void Vector3::snapf(real_t p_step) {
+	x = Math::snapped(x, p_step);
+	y = Math::snapped(y, p_step);
+	z = Math::snapped(z, p_step);
+}
+
 Vector3 Vector3::snapped(const Vector3 p_step) const {
 	Vector3 v = *this;
 	v.snap(p_step);
 	return v;
 }
 
+Vector3 Vector3::snappedf(real_t p_step) const {
+	Vector3 v = *this;
+	v.snapf(p_step);
+	return v;
+}
+
 Vector3 Vector3::limit_length(const real_t p_len) const {
 	const real_t l = length();
 	Vector3 v = *this;
diff --git a/src/variant/vector3i.cpp b/src/variant/vector3i.cpp
index eef05b873..7b25d8979 100644
--- a/src/variant/vector3i.cpp
+++ b/src/variant/vector3i.cpp
@@ -35,6 +35,20 @@
 
 namespace godot {
 
+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 Vector3i::snappedi(int32_t p_step) const {
+	return Vector3i(
+			Math::snapped(x, p_step),
+			Math::snapped(y, p_step),
+			Math::snapped(z, p_step));
+}
+
 Vector3i::Axis Vector3i::min_axis_index() const {
 	return x < y ? (x < z ? Vector3i::AXIS_X : Vector3i::AXIS_Z) : (y < z ? Vector3i::AXIS_Y : Vector3i::AXIS_Z);
 }
@@ -50,6 +64,13 @@ Vector3i Vector3i::clamp(const Vector3i &p_min, const Vector3i &p_max) const {
 			CLAMP(z, p_min.z, p_max.z));
 }
 
+Vector3i Vector3i::clampi(int32_t p_min, int32_t p_max) const {
+	return Vector3i(
+			CLAMP(x, p_min, p_max),
+			CLAMP(y, p_min, p_max),
+			CLAMP(z, p_min, p_max));
+}
+
 Vector3i::operator String() const {
 	return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
 }
diff --git a/src/variant/vector4.cpp b/src/variant/vector4.cpp
index 72c79d1e5..641c69680 100644
--- a/src/variant/vector4.cpp
+++ b/src/variant/vector4.cpp
@@ -169,12 +169,25 @@ void Vector4::snap(const Vector4 &p_step) {
 	w = Math::snapped(w, p_step.w);
 }
 
+void Vector4::snapf(real_t p_step) {
+	x = Math::snapped(x, p_step);
+	y = Math::snapped(y, p_step);
+	z = Math::snapped(z, p_step);
+	w = Math::snapped(w, p_step);
+}
+
 Vector4 Vector4::snapped(const Vector4 &p_step) const {
 	Vector4 v = *this;
 	v.snap(p_step);
 	return v;
 }
 
+Vector4 Vector4::snappedf(real_t p_step) const {
+	Vector4 v = *this;
+	v.snapf(p_step);
+	return v;
+}
+
 Vector4 Vector4::inverse() const {
 	return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w);
 }
@@ -187,6 +200,14 @@ Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const {
 			CLAMP(w, p_min.w, p_max.w));
 }
 
+Vector4 Vector4::clampf(real_t p_min, real_t p_max) const {
+	return Vector4(
+			CLAMP(x, p_min, p_max),
+			CLAMP(y, p_min, p_max),
+			CLAMP(z, p_min, p_max),
+			CLAMP(w, p_min, p_max));
+}
+
 Vector4::operator String() const {
 	return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")";
 }
diff --git a/src/variant/vector4i.cpp b/src/variant/vector4i.cpp
index f1817dc85..b0e330ca2 100644
--- a/src/variant/vector4i.cpp
+++ b/src/variant/vector4i.cpp
@@ -35,6 +35,22 @@
 
 namespace godot {
 
+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 Vector4i::snappedi(int32_t p_step) const {
+	return Vector4i(
+			Math::snapped(x, p_step),
+			Math::snapped(y, p_step),
+			Math::snapped(z, p_step),
+			Math::snapped(w, p_step));
+}
+
 Vector4i::Axis Vector4i::min_axis_index() const {
 	uint32_t min_index = 0;
 	int32_t min_value = x;
@@ -67,6 +83,14 @@ Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const {
 			CLAMP(w, p_min.w, p_max.w));
 }
 
+Vector4i Vector4i::clampi(int32_t p_min, int32_t p_max) const {
+	return Vector4i(
+			CLAMP(x, p_min, p_max),
+			CLAMP(y, p_min, p_max),
+			CLAMP(z, p_min, p_max),
+			CLAMP(w, p_min, p_max));
+}
+
 Vector4i::operator String() const {
 	return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
 }
