Browse Source

[Core] Add scalar versions of `Vector*` `min/max/clamp/snap(ped)`

Convenience for a number of cases operating on single values
A Thousand Ships 1 year ago
parent
commit
308dbb8c63
73 changed files with 588 additions and 105 deletions
  1. 1 1
      core/math/aabb.h
  2. 3 3
      core/math/delaunay_3d.h
  3. 1 1
      core/math/quick_hull.cpp
  4. 1 1
      core/math/rect2.h
  5. 1 1
      core/math/rect2i.h
  6. 1 1
      core/math/triangle_mesh.cpp
  7. 12 0
      core/math/vector2.cpp
  8. 10 0
      core/math/vector2.h
  9. 12 0
      core/math/vector2i.cpp
  10. 10 0
      core/math/vector2i.h
  11. 19 0
      core/math/vector3.cpp
  12. 11 0
      core/math/vector3.h
  13. 14 0
      core/math/vector3i.cpp
  14. 10 0
      core/math/vector3i.h
  15. 21 0
      core/math/vector4.cpp
  16. 11 0
      core/math/vector4.h
  17. 16 0
      core/math/vector4i.cpp
  18. 10 0
      core/math/vector4i.h
  19. 12 0
      core/variant/variant_call.cpp
  20. 15 0
      doc/classes/Vector2.xml
  21. 15 0
      doc/classes/Vector2i.xml
  22. 15 0
      doc/classes/Vector3.xml
  23. 15 0
      doc/classes/Vector3i.xml
  24. 15 0
      doc/classes/Vector4.xml
  25. 15 0
      doc/classes/Vector4i.xml
  26. 2 4
      drivers/gles3/effects/copy_effects.cpp
  27. 1 2
      drivers/gles3/storage/render_scene_buffers_gles3.cpp
  28. 1 1
      drivers/gles3/storage/texture_storage.cpp
  29. 2 2
      editor/plugins/canvas_item_editor_plugin.cpp
  30. 1 1
      editor/plugins/editor_preview_plugins.cpp
  31. 1 1
      editor/plugins/gizmos/navigation_link_3d_gizmo_plugin.cpp
  32. 2 2
      editor/plugins/gizmos/navigation_region_3d_gizmo_plugin.cpp
  33. 2 2
      editor/plugins/gizmos/occluder_instance_3d_gizmo_plugin.cpp
  34. 3 3
      editor/plugins/gradient_texture_2d_editor_plugin.cpp
  35. 1 3
      editor/plugins/navigation_obstacle_3d_editor_plugin.cpp
  36. 5 5
      editor/plugins/node_3d_editor_plugin.cpp
  37. 2 2
      editor/plugins/path_3d_editor_plugin.cpp
  38. 1 3
      editor/plugins/polygon_3d_editor_plugin.cpp
  39. 2 2
      editor/plugins/texture_region_editor_plugin.cpp
  40. 1 1
      editor/plugins/tiles/tile_data_editors.cpp
  41. 2 2
      editor/plugins/tiles/tile_proxies_manager_dialog.cpp
  42. 7 7
      editor/plugins/tiles/tile_set_atlas_source_editor.cpp
  43. 3 3
      editor/plugins/visual_shader_editor_plugin.cpp
  44. 29 1
      modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
  45. 45 0
      modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs
  46. 35 1
      modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
  47. 48 0
      modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs
  48. 36 1
      modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs
  49. 49 0
      modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs
  50. 1 1
      platform/linuxbsd/wayland/wayland_thread.cpp
  51. 1 1
      platform/linuxbsd/x11/display_server_x11.cpp
  52. 1 1
      platform/macos/display_server_macos.mm
  53. 1 1
      scene/2d/parallax_2d.cpp
  54. 1 1
      scene/3d/decal.cpp
  55. 1 1
      scene/3d/fog_volume.cpp
  56. 2 2
      scene/3d/gpu_particles_collision_3d.cpp
  57. 2 2
      scene/3d/occluder_instance_3d.cpp
  58. 1 1
      scene/3d/voxel_gi.cpp
  59. 2 2
      scene/gui/control.cpp
  60. 3 3
      scene/gui/graph_edit.cpp
  61. 1 1
      scene/gui/graph_edit_arranger.cpp
  62. 1 1
      scene/gui/progress_bar.cpp
  63. 1 1
      scene/gui/texture_button.cpp
  64. 1 1
      scene/gui/texture_progress_bar.cpp
  65. 1 1
      scene/gui/tree.cpp
  66. 3 3
      scene/main/viewport.cpp
  67. 2 2
      scene/main/window.cpp
  68. 3 3
      scene/resources/2d/tile_set.cpp
  69. 1 2
      servers/rendering/renderer_rd/effects/ss_effects.cpp
  70. 2 2
      servers/rendering/renderer_rd/environment/fog.cpp
  71. 1 2
      servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
  72. 6 11
      servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
  73. 2 2
      servers/rendering/renderer_scene_occlusion_cull.h

+ 1 - 1
core/math/aabb.h

@@ -101,7 +101,7 @@ struct _NO_DISCARD_ AABB {
 	_FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */
 	_FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */
 
 
 	_FORCE_INLINE_ AABB abs() const {
 	_FORCE_INLINE_ AABB abs() const {
-		return AABB(position + size.min(Vector3()), size.abs());
+		return AABB(position + size.minf(0), size.abs());
 	}
 	}
 
 
 	Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;
 	Variant intersects_segment_bind(const Vector3 &p_from, const Vector3 &p_to) const;

+ 3 - 3
core/math/delaunay_3d.h

@@ -278,7 +278,7 @@ public:
 			}
 			}
 
 
 			Vector3i grid_pos = Vector3i(points[i] * proportions * ACCEL_GRID_SIZE);
 			Vector3i grid_pos = Vector3i(points[i] * proportions * ACCEL_GRID_SIZE);
-			grid_pos = grid_pos.clamp(Vector3i(), Vector3i(ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1));
+			grid_pos = grid_pos.clampi(0, ACCEL_GRID_SIZE - 1);
 
 
 			for (List<Simplex *>::Element *E = acceleration_grid[grid_pos.x][grid_pos.y][grid_pos.z].front(); E;) {
 			for (List<Simplex *>::Element *E = acceleration_grid[grid_pos.x][grid_pos.y][grid_pos.z].front(); E;) {
 				List<Simplex *>::Element *N = E->next(); //may be deleted
 				List<Simplex *>::Element *N = E->next(); //may be deleted
@@ -335,8 +335,8 @@ public:
 					Vector3 extents = Vector3(radius2, radius2, radius2);
 					Vector3 extents = Vector3(radius2, radius2, radius2);
 					Vector3i from = Vector3i((center - extents) * proportions * ACCEL_GRID_SIZE);
 					Vector3i from = Vector3i((center - extents) * proportions * ACCEL_GRID_SIZE);
 					Vector3i to = Vector3i((center + extents) * proportions * ACCEL_GRID_SIZE);
 					Vector3i to = Vector3i((center + extents) * proportions * ACCEL_GRID_SIZE);
-					from = from.clamp(Vector3i(), Vector3i(ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1));
-					to = to.clamp(Vector3i(), Vector3i(ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1, ACCEL_GRID_SIZE - 1));
+					from = from.clampi(0, ACCEL_GRID_SIZE - 1);
+					to = to.clampi(0, ACCEL_GRID_SIZE - 1);
 
 
 					for (int32_t x = from.x; x <= to.x; x++) {
 					for (int32_t x = from.x; x <= to.x; x++) {
 						for (int32_t y = from.y; y <= to.y; y++) {
 						for (int32_t y = from.y; y <= to.y; y++) {

+ 1 - 1
core/math/quick_hull.cpp

@@ -55,7 +55,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry3D::MeshData &r_
 	HashSet<Vector3> valid_cache;
 	HashSet<Vector3> valid_cache;
 
 
 	for (int i = 0; i < p_points.size(); i++) {
 	for (int i = 0; i < p_points.size(); i++) {
-		Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001));
+		Vector3 sp = p_points[i].snappedf(0.0001);
 		if (valid_cache.has(sp)) {
 		if (valid_cache.has(sp)) {
 			valid_points.write[i] = false;
 			valid_points.write[i] = false;
 		} else {
 		} else {

+ 1 - 1
core/math/rect2.h

@@ -278,7 +278,7 @@ struct _NO_DISCARD_ Rect2 {
 	}
 	}
 
 
 	_FORCE_INLINE_ Rect2 abs() const {
 	_FORCE_INLINE_ Rect2 abs() const {
-		return Rect2(position + size.min(Point2()), size.abs());
+		return Rect2(position + size.minf(0), size.abs());
 	}
 	}
 
 
 	_FORCE_INLINE_ Rect2 round() const {
 	_FORCE_INLINE_ Rect2 round() const {

+ 1 - 1
core/math/rect2i.h

@@ -213,7 +213,7 @@ struct _NO_DISCARD_ Rect2i {
 	}
 	}
 
 
 	_FORCE_INLINE_ Rect2i abs() const {
 	_FORCE_INLINE_ Rect2i abs() const {
-		return Rect2i(position + size.min(Point2i()), size.abs());
+		return Rect2i(position + size.mini(0), size.abs());
 	}
 	}
 
 
 	_FORCE_INLINE_ void set_end(const Vector2i &p_end) {
 	_FORCE_INLINE_ void set_end(const Vector2i &p_end) {

+ 1 - 1
core/math/triangle_mesh.cpp

@@ -133,7 +133,7 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces, const Vector<int32_t>
 
 
 			for (int j = 0; j < 3; j++) {
 			for (int j = 0; j < 3; j++) {
 				int vidx = -1;
 				int vidx = -1;
-				Vector3 vs = v[j].snapped(Vector3(0.0001, 0.0001, 0.0001));
+				Vector3 vs = v[j].snappedf(0.0001);
 				HashMap<Vector3, int>::Iterator E = db.find(vs);
 				HashMap<Vector3, int>::Iterator E = db.find(vs);
 				if (E) {
 				if (E) {
 					vidx = E->value;
 					vidx = E->value;

+ 12 - 0
core/math/vector2.cpp

@@ -135,12 +135,24 @@ Vector2 Vector2::clamp(const Vector2 &p_min, const Vector2 &p_max) const {
 			CLAMP(y, p_min.y, p_max.y));
 			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 {
 Vector2 Vector2::snapped(const Vector2 &p_step) const {
 	return Vector2(
 	return Vector2(
 			Math::snapped(x, p_step.x),
 			Math::snapped(x, p_step.x),
 			Math::snapped(y, p_step.y));
 			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(real_t p_len) const {
 Vector2 Vector2::limit_length(real_t p_len) const {
 	const real_t l = length();
 	const real_t l = length();
 	Vector2 v = *this;
 	Vector2 v = *this;

+ 10 - 0
core/math/vector2.h

@@ -89,10 +89,18 @@ struct _NO_DISCARD_ Vector2 {
 		return Vector2(MIN(x, p_vector2.x), MIN(y, p_vector2.y));
 		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 {
 	Vector2 max(const Vector2 &p_vector2) const {
 		return Vector2(MAX(x, p_vector2.x), MAX(y, p_vector2.y));
 		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_to(const Vector2 &p_vector2) const;
 	real_t distance_squared_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;
 	real_t angle_to(const Vector2 &p_vector2) const;
@@ -168,7 +176,9 @@ struct _NO_DISCARD_ Vector2 {
 	Vector2 ceil() const;
 	Vector2 ceil() const;
 	Vector2 round() const;
 	Vector2 round() const;
 	Vector2 snapped(const Vector2 &p_by) 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 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; }
 	real_t aspect() const { return width / height; }
 
 
 	operator String() const;
 	operator String() const;

+ 12 - 0
core/math/vector2i.cpp

@@ -39,12 +39,24 @@ Vector2i Vector2i::clamp(const Vector2i &p_min, const Vector2i &p_max) const {
 			CLAMP(y, p_min.y, p_max.y));
 			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));
+}
+
 Vector2i Vector2i::snapped(const Vector2i &p_step) const {
 Vector2i Vector2i::snapped(const Vector2i &p_step) const {
 	return Vector2i(
 	return Vector2i(
 			Math::snapped(x, p_step.x),
 			Math::snapped(x, p_step.x),
 			Math::snapped(y, p_step.y));
 			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));
+}
+
 int64_t Vector2i::length_squared() const {
 int64_t Vector2i::length_squared() const {
 	return x * (int64_t)x + y * (int64_t)y;
 	return x * (int64_t)x + y * (int64_t)y;
 }
 }

+ 10 - 0
core/math/vector2i.h

@@ -81,10 +81,18 @@ struct _NO_DISCARD_ Vector2i {
 		return Vector2i(MIN(x, p_vector2i.x), MIN(y, p_vector2i.y));
 		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 {
 	Vector2i max(const Vector2i &p_vector2i) const {
 		return Vector2i(MAX(x, p_vector2i.x), MAX(y, p_vector2i.y));
 		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));
+	}
+
 	double distance_to(const Vector2i &p_to) const {
 	double distance_to(const Vector2i &p_to) const {
 		return (p_to - *this).length();
 		return (p_to - *this).length();
 	}
 	}
@@ -127,7 +135,9 @@ struct _NO_DISCARD_ Vector2i {
 	Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
 	Vector2i sign() const { return Vector2i(SIGN(x), SIGN(y)); }
 	Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
 	Vector2i abs() const { return Vector2i(Math::abs(x), Math::abs(y)); }
 	Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
 	Vector2i clamp(const Vector2i &p_min, const Vector2i &p_max) const;
+	Vector2i clampi(int32_t p_min, int32_t p_max) const;
 	Vector2i snapped(const Vector2i &p_step) const;
 	Vector2i snapped(const Vector2i &p_step) const;
+	Vector2i snappedi(int32_t p_step) const;
 
 
 	operator String() const;
 	operator String() const;
 	operator Vector2() const;
 	operator Vector2() const;

+ 19 - 0
core/math/vector3.cpp

@@ -52,6 +52,13 @@ Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const {
 			CLAMP(z, p_min.z, p_max.z));
 			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) {
 void Vector3::snap(const Vector3 &p_step) {
 	x = Math::snapped(x, p_step.x);
 	x = Math::snapped(x, p_step.x);
 	y = Math::snapped(y, p_step.y);
 	y = Math::snapped(y, p_step.y);
@@ -64,6 +71,18 @@ Vector3 Vector3::snapped(const Vector3 &p_step) const {
 	return v;
 	return v;
 }
 }
 
 
+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::snappedf(real_t p_step) const {
+	Vector3 v = *this;
+	v.snapf(p_step);
+	return v;
+}
+
 Vector3 Vector3::limit_length(real_t p_len) const {
 Vector3 Vector3::limit_length(real_t p_len) const {
 	const real_t l = length();
 	const real_t l = length();
 	Vector3 v = *this;
 	Vector3 v = *this;

+ 11 - 0
core/math/vector3.h

@@ -80,10 +80,18 @@ struct _NO_DISCARD_ Vector3 {
 		return Vector3(MIN(x, p_vector3.x), MIN(y, p_vector3.y), MIN(z, p_vector3.z));
 		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 {
 	Vector3 max(const Vector3 &p_vector3) const {
 		return Vector3(MAX(x, p_vector3.x), MAX(y, p_vector3.y), MAX(z, p_vector3.z));
 		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() const;
 	_FORCE_INLINE_ real_t length_squared() const;
 	_FORCE_INLINE_ real_t length_squared() const;
 
 
@@ -96,7 +104,9 @@ struct _NO_DISCARD_ Vector3 {
 	_FORCE_INLINE_ void zero();
 	_FORCE_INLINE_ void zero();
 
 
 	void snap(const Vector3 &p_step);
 	void snap(const Vector3 &p_step);
+	void snapf(real_t p_step);
 	Vector3 snapped(const Vector3 &p_step) const;
 	Vector3 snapped(const Vector3 &p_step) const;
+	Vector3 snappedf(real_t p_step) const;
 
 
 	void rotate(const Vector3 &p_axis, real_t p_angle);
 	void rotate(const Vector3 &p_axis, real_t p_angle);
 	Vector3 rotated(const Vector3 &p_axis, real_t p_angle) const;
 	Vector3 rotated(const Vector3 &p_axis, real_t p_angle) const;
@@ -127,6 +137,7 @@ struct _NO_DISCARD_ Vector3 {
 	_FORCE_INLINE_ Vector3 ceil() const;
 	_FORCE_INLINE_ Vector3 ceil() const;
 	_FORCE_INLINE_ Vector3 round() const;
 	_FORCE_INLINE_ Vector3 round() const;
 	Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) 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_to(const Vector3 &p_to) const;
 	_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const;
 	_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const;

+ 14 - 0
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));
 			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 Vector3i::snapped(const Vector3i &p_step) const {
 Vector3i Vector3i::snapped(const Vector3i &p_step) const {
 	return Vector3i(
 	return Vector3i(
 			Math::snapped(x, p_step.x),
 			Math::snapped(x, p_step.x),
@@ -55,6 +62,13 @@ Vector3i Vector3i::snapped(const Vector3i &p_step) const {
 			Math::snapped(z, p_step.z));
 			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::operator String() const {
 Vector3i::operator String() const {
 	return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
 	return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ")";
 }
 }

+ 10 - 0
core/math/vector3i.h

@@ -73,10 +73,18 @@ struct _NO_DISCARD_ Vector3i {
 		return Vector3i(MIN(x, p_vector3i.x), MIN(y, p_vector3i.y), MIN(z, p_vector3i.z));
 		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 {
 	Vector3i max(const Vector3i &p_vector3i) const {
 		return Vector3i(MAX(x, p_vector3i.x), MAX(y, p_vector3i.y), MAX(z, p_vector3i.z));
 		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_ int64_t length_squared() const;
 	_FORCE_INLINE_ double length() const;
 	_FORCE_INLINE_ double length() const;
 
 
@@ -85,7 +93,9 @@ struct _NO_DISCARD_ Vector3i {
 	_FORCE_INLINE_ Vector3i abs() const;
 	_FORCE_INLINE_ Vector3i abs() const;
 	_FORCE_INLINE_ Vector3i sign() const;
 	_FORCE_INLINE_ Vector3i sign() const;
 	Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
 	Vector3i clamp(const Vector3i &p_min, const Vector3i &p_max) const;
+	Vector3i clampi(int32_t p_min, int32_t p_max) const;
 	Vector3i snapped(const Vector3i &p_step) const;
 	Vector3i snapped(const Vector3i &p_step) const;
+	Vector3i snappedi(int32_t p_step) const;
 
 
 	_FORCE_INLINE_ double distance_to(const Vector3i &p_to) const;
 	_FORCE_INLINE_ double distance_to(const Vector3i &p_to) const;
 	_FORCE_INLINE_ int64_t distance_squared_to(const Vector3i &p_to) const;
 	_FORCE_INLINE_ int64_t distance_squared_to(const Vector3i &p_to) const;

+ 21 - 0
core/math/vector4.cpp

@@ -171,12 +171,25 @@ void Vector4::snap(const Vector4 &p_step) {
 	w = Math::snapped(w, p_step.w);
 	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 Vector4::snapped(const Vector4 &p_step) const {
 	Vector4 v = *this;
 	Vector4 v = *this;
 	v.snap(p_step);
 	v.snap(p_step);
 	return v;
 	return v;
 }
 }
 
 
+Vector4 Vector4::snappedf(real_t p_step) const {
+	Vector4 v = *this;
+	v.snapf(p_step);
+	return v;
+}
+
 Vector4 Vector4::inverse() const {
 Vector4 Vector4::inverse() const {
 	return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w);
 	return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w);
 }
 }
@@ -189,6 +202,14 @@ Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const {
 			CLAMP(w, p_min.w, p_max.w));
 			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 {
 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) + ")";
 	return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")";
 }
 }

+ 11 - 0
core/math/vector4.h

@@ -72,10 +72,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));
 		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 {
 	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));
 		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;
 	_FORCE_INLINE_ real_t length_squared() const;
 	bool is_equal_approx(const Vector4 &p_vec4) const;
 	bool is_equal_approx(const Vector4 &p_vec4) const;
 	bool is_zero_approx() const;
 	bool is_zero_approx() const;
@@ -101,8 +109,11 @@ struct _NO_DISCARD_ Vector4 {
 	Vector4 posmod(real_t p_mod) const;
 	Vector4 posmod(real_t p_mod) const;
 	Vector4 posmodv(const Vector4 &p_modv) const;
 	Vector4 posmodv(const Vector4 &p_modv) const;
 	void snap(const Vector4 &p_step);
 	void snap(const Vector4 &p_step);
+	void snapf(real_t p_step);
 	Vector4 snapped(const Vector4 &p_step) const;
 	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 clamp(const Vector4 &p_min, const Vector4 &p_max) const;
+	Vector4 clampf(real_t p_min, real_t p_max) const;
 
 
 	Vector4 inverse() const;
 	Vector4 inverse() const;
 	_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;
 	_FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const;

+ 16 - 0
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));
 			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 Vector4i::snapped(const Vector4i &p_step) const {
 Vector4i Vector4i::snapped(const Vector4i &p_step) const {
 	return Vector4i(
 	return Vector4i(
 			Math::snapped(x, p_step.x),
 			Math::snapped(x, p_step.x),
@@ -73,6 +81,14 @@ Vector4i Vector4i::snapped(const Vector4i &p_step) const {
 			Math::snapped(w, p_step.w));
 			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::operator String() const {
 Vector4i::operator String() const {
 	return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
 	return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")";
 }
 }

+ 10 - 0
core/math/vector4i.h

@@ -75,10 +75,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));
 		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 {
 	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));
 		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_ int64_t length_squared() const;
 	_FORCE_INLINE_ double length() const;
 	_FORCE_INLINE_ double length() const;
 
 
@@ -90,7 +98,9 @@ struct _NO_DISCARD_ Vector4i {
 	_FORCE_INLINE_ Vector4i abs() const;
 	_FORCE_INLINE_ Vector4i abs() const;
 	_FORCE_INLINE_ Vector4i sign() const;
 	_FORCE_INLINE_ Vector4i sign() const;
 	Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const;
 	Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const;
+	Vector4i clampi(int32_t p_min, int32_t p_max) const;
 	Vector4i snapped(const Vector4i &p_step) const;
 	Vector4i snapped(const Vector4i &p_step) const;
+	Vector4i snappedi(int32_t p_step) const;
 
 
 	/* Operators */
 	/* Operators */
 
 

+ 12 - 0
core/variant/variant_call.cpp

@@ -1804,7 +1804,9 @@ static void _register_variant_builtin_methods() {
 	bind_method(Vector2, abs, sarray(), varray());
 	bind_method(Vector2, abs, sarray(), varray());
 	bind_method(Vector2, sign, sarray(), varray());
 	bind_method(Vector2, sign, sarray(), varray());
 	bind_method(Vector2, clamp, sarray("min", "max"), varray());
 	bind_method(Vector2, clamp, sarray("min", "max"), varray());
+	bind_method(Vector2, clampf, sarray("min", "max"), varray());
 	bind_method(Vector2, snapped, sarray("step"), varray());
 	bind_method(Vector2, snapped, sarray("step"), varray());
+	bind_method(Vector2, snappedf, sarray("step"), varray());
 
 
 	bind_static_method(Vector2, from_angle, sarray("angle"), varray());
 	bind_static_method(Vector2, from_angle, sarray("angle"), varray());
 
 
@@ -1820,7 +1822,9 @@ static void _register_variant_builtin_methods() {
 	bind_method(Vector2i, sign, sarray(), varray());
 	bind_method(Vector2i, sign, sarray(), varray());
 	bind_method(Vector2i, abs, sarray(), varray());
 	bind_method(Vector2i, abs, sarray(), varray());
 	bind_method(Vector2i, clamp, sarray("min", "max"), varray());
 	bind_method(Vector2i, clamp, sarray("min", "max"), varray());
+	bind_method(Vector2i, clampi, sarray("min", "max"), varray());
 	bind_method(Vector2i, snapped, sarray("step"), varray());
 	bind_method(Vector2i, snapped, sarray("step"), varray());
+	bind_method(Vector2i, snappedi, sarray("step"), varray());
 
 
 	/* Rect2 */
 	/* Rect2 */
 
 
@@ -1875,7 +1879,9 @@ static void _register_variant_builtin_methods() {
 	bind_method(Vector3, is_finite, sarray(), varray());
 	bind_method(Vector3, is_finite, sarray(), varray());
 	bind_method(Vector3, inverse, sarray(), varray());
 	bind_method(Vector3, inverse, sarray(), varray());
 	bind_method(Vector3, clamp, sarray("min", "max"), varray());
 	bind_method(Vector3, clamp, sarray("min", "max"), varray());
+	bind_method(Vector3, clampf, sarray("min", "max"), varray());
 	bind_method(Vector3, snapped, sarray("step"), varray());
 	bind_method(Vector3, snapped, sarray("step"), varray());
+	bind_method(Vector3, snappedf, sarray("step"), varray());
 	bind_method(Vector3, rotated, sarray("axis", "angle"), varray());
 	bind_method(Vector3, rotated, sarray("axis", "angle"), varray());
 	bind_method(Vector3, lerp, sarray("to", "weight"), varray());
 	bind_method(Vector3, lerp, sarray("to", "weight"), varray());
 	bind_method(Vector3, slerp, sarray("to", "weight"), varray());
 	bind_method(Vector3, slerp, sarray("to", "weight"), varray());
@@ -1912,7 +1918,9 @@ static void _register_variant_builtin_methods() {
 	bind_method(Vector3i, sign, sarray(), varray());
 	bind_method(Vector3i, sign, sarray(), varray());
 	bind_method(Vector3i, abs, sarray(), varray());
 	bind_method(Vector3i, abs, sarray(), varray());
 	bind_method(Vector3i, clamp, sarray("min", "max"), varray());
 	bind_method(Vector3i, clamp, sarray("min", "max"), varray());
+	bind_method(Vector3i, clampi, sarray("min", "max"), varray());
 	bind_method(Vector3i, snapped, sarray("step"), varray());
 	bind_method(Vector3i, snapped, sarray("step"), varray());
+	bind_method(Vector3i, snappedi, sarray("step"), varray());
 
 
 	/* Vector4 */
 	/* Vector4 */
 
 
@@ -1931,7 +1939,9 @@ static void _register_variant_builtin_methods() {
 	bind_method(Vector4, posmod, sarray("mod"), varray());
 	bind_method(Vector4, posmod, sarray("mod"), varray());
 	bind_method(Vector4, posmodv, sarray("modv"), varray());
 	bind_method(Vector4, posmodv, sarray("modv"), varray());
 	bind_method(Vector4, snapped, sarray("step"), varray());
 	bind_method(Vector4, snapped, sarray("step"), varray());
+	bind_method(Vector4, snappedf, sarray("step"), varray());
 	bind_method(Vector4, clamp, sarray("min", "max"), varray());
 	bind_method(Vector4, clamp, sarray("min", "max"), varray());
+	bind_method(Vector4, clampf, sarray("min", "max"), varray());
 	bind_method(Vector4, normalized, sarray(), varray());
 	bind_method(Vector4, normalized, sarray(), varray());
 	bind_method(Vector4, is_normalized, sarray(), varray());
 	bind_method(Vector4, is_normalized, sarray(), varray());
 	bind_method(Vector4, direction_to, sarray("to"), varray());
 	bind_method(Vector4, direction_to, sarray("to"), varray());
@@ -1952,7 +1962,9 @@ static void _register_variant_builtin_methods() {
 	bind_method(Vector4i, sign, sarray(), varray());
 	bind_method(Vector4i, sign, sarray(), varray());
 	bind_method(Vector4i, abs, sarray(), varray());
 	bind_method(Vector4i, abs, sarray(), varray());
 	bind_method(Vector4i, clamp, sarray("min", "max"), varray());
 	bind_method(Vector4i, clamp, sarray("min", "max"), varray());
+	bind_method(Vector4i, clampi, sarray("min", "max"), varray());
 	bind_method(Vector4i, snapped, sarray("step"), varray());
 	bind_method(Vector4i, snapped, sarray("step"), varray());
+	bind_method(Vector4i, snappedi, sarray("step"), varray());
 	bind_method(Vector4i, distance_to, sarray("to"), varray());
 	bind_method(Vector4i, distance_to, sarray("to"), varray());
 	bind_method(Vector4i, distance_squared_to, sarray("to"), varray());
 	bind_method(Vector4i, distance_squared_to, sarray("to"), varray());
 
 

+ 15 - 0
doc/classes/Vector2.xml

@@ -128,6 +128,14 @@
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="clampf" qualifiers="const">
+			<return type="Vector2" />
+			<param index="0" name="min" type="float" />
+			<param index="1" name="max" type="float" />
+			<description>
+				Returns a new vector with all components clamped between [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
+			</description>
+		</method>
 		<method name="cross" qualifiers="const">
 		<method name="cross" qualifiers="const">
 			<return type="float" />
 			<return type="float" />
 			<param index="0" name="with" type="Vector2" />
 			<param index="0" name="with" type="Vector2" />
@@ -371,6 +379,13 @@
 				Returns a new vector with each component snapped to the nearest multiple of the corresponding component in [param step]. This can also be used to round the components to an arbitrary number of decimals.
 				Returns a new vector with each component snapped to the nearest multiple of the corresponding component in [param step]. This can also be used to round the components to an arbitrary number of decimals.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="snappedf" qualifiers="const">
+			<return type="Vector2" />
+			<param index="0" name="step" type="float" />
+			<description>
+				Returns a new vector with each component snapped to the nearest multiple of [param step]. This can also be used to round the components to an arbitrary number of decimals.
+			</description>
+		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
 		<member name="x" type="float" setter="" getter="" default="0.0">
 		<member name="x" type="float" setter="" getter="" default="0.0">

+ 15 - 0
doc/classes/Vector2i.xml

@@ -64,6 +64,14 @@
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="clampi" qualifiers="const">
+			<return type="Vector2i" />
+			<param index="0" name="min" type="int" />
+			<param index="1" name="max" type="int" />
+			<description>
+				Returns a new vector with all components clamped between [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
+			</description>
+		</method>
 		<method name="distance_squared_to" qualifiers="const">
 		<method name="distance_squared_to" qualifiers="const">
 			<return type="int" />
 			<return type="int" />
 			<param index="0" name="to" type="Vector2i" />
 			<param index="0" name="to" type="Vector2i" />
@@ -117,6 +125,13 @@
 				Returns a new vector with each component snapped to the closest multiple of the corresponding component in [param step].
 				Returns a new vector with each component snapped to the closest multiple of the corresponding component in [param step].
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="snappedi" qualifiers="const">
+			<return type="Vector2i" />
+			<param index="0" name="step" type="int" />
+			<description>
+				Returns a new vector with each component snapped to the closest multiple of [param step].
+			</description>
+		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
 		<member name="x" type="int" setter="" getter="" default="0">
 		<member name="x" type="int" setter="" getter="" default="0">

+ 15 - 0
doc/classes/Vector3.xml

@@ -104,6 +104,14 @@
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="clampf" qualifiers="const">
+			<return type="Vector3" />
+			<param index="0" name="min" type="float" />
+			<param index="1" name="max" type="float" />
+			<description>
+				Returns a new vector with all components clamped between [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
+			</description>
+		</method>
 		<method name="cross" qualifiers="const">
 		<method name="cross" qualifiers="const">
 			<return type="Vector3" />
 			<return type="Vector3" />
 			<param index="0" name="with" type="Vector3" />
 			<param index="0" name="with" type="Vector3" />
@@ -365,6 +373,13 @@
 				Returns a new vector with each component snapped to the nearest multiple of the corresponding component in [param step]. This can also be used to round the components to an arbitrary number of decimals.
 				Returns a new vector with each component snapped to the nearest multiple of the corresponding component in [param step]. This can also be used to round the components to an arbitrary number of decimals.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="snappedf" qualifiers="const">
+			<return type="Vector3" />
+			<param index="0" name="step" type="float" />
+			<description>
+				Returns a new vector with each component snapped to the nearest multiple of [param step]. This can also be used to round the components to an arbitrary number of decimals.
+			</description>
+		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
 		<member name="x" type="float" setter="" getter="" default="0.0">
 		<member name="x" type="float" setter="" getter="" default="0.0">

+ 15 - 0
doc/classes/Vector3i.xml

@@ -59,6 +59,14 @@
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="clampi" qualifiers="const">
+			<return type="Vector3i" />
+			<param index="0" name="min" type="int" />
+			<param index="1" name="max" type="int" />
+			<description>
+				Returns a new vector with all components clamped between [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
+			</description>
+		</method>
 		<method name="distance_squared_to" qualifiers="const">
 		<method name="distance_squared_to" qualifiers="const">
 			<return type="int" />
 			<return type="int" />
 			<param index="0" name="to" type="Vector3i" />
 			<param index="0" name="to" type="Vector3i" />
@@ -112,6 +120,13 @@
 				Returns a new vector with each component snapped to the closest multiple of the corresponding component in [param step].
 				Returns a new vector with each component snapped to the closest multiple of the corresponding component in [param step].
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="snappedi" qualifiers="const">
+			<return type="Vector3i" />
+			<param index="0" name="step" type="int" />
+			<description>
+				Returns a new vector with each component snapped to the closest multiple of [param step].
+			</description>
+		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
 		<member name="x" type="int" setter="" getter="" default="0">
 		<member name="x" type="int" setter="" getter="" default="0">

+ 15 - 0
doc/classes/Vector4.xml

@@ -64,6 +64,14 @@
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="clampf" qualifiers="const">
+			<return type="Vector4" />
+			<param index="0" name="min" type="float" />
+			<param index="1" name="max" type="float" />
+			<description>
+				Returns a new vector with all components clamped between [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
+			</description>
+		</method>
 		<method name="cubic_interpolate" qualifiers="const">
 		<method name="cubic_interpolate" qualifiers="const">
 			<return type="Vector4" />
 			<return type="Vector4" />
 			<param index="0" name="b" type="Vector4" />
 			<param index="0" name="b" type="Vector4" />
@@ -228,6 +236,13 @@
 				Returns a new vector with each component snapped to the nearest multiple of the corresponding component in [param step]. This can also be used to round the components to an arbitrary number of decimals.
 				Returns a new vector with each component snapped to the nearest multiple of the corresponding component in [param step]. This can also be used to round the components to an arbitrary number of decimals.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="snappedf" qualifiers="const">
+			<return type="Vector4" />
+			<param index="0" name="step" type="float" />
+			<description>
+				Returns a new vector with each component snapped to the nearest multiple of [param step]. This can also be used to round the components to an arbitrary number of decimals.
+			</description>
+		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
 		<member name="w" type="float" setter="" getter="" default="0.0">
 		<member name="w" type="float" setter="" getter="" default="0.0">

+ 15 - 0
doc/classes/Vector4i.xml

@@ -57,6 +57,14 @@
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 				Returns a new vector with all components clamped between the components of [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="clampi" qualifiers="const">
+			<return type="Vector4i" />
+			<param index="0" name="min" type="int" />
+			<param index="1" name="max" type="int" />
+			<description>
+				Returns a new vector with all components clamped between [param min] and [param max], by running [method @GlobalScope.clamp] on each component.
+			</description>
+		</method>
 		<method name="distance_squared_to" qualifiers="const">
 		<method name="distance_squared_to" qualifiers="const">
 			<return type="int" />
 			<return type="int" />
 			<param index="0" name="to" type="Vector4i" />
 			<param index="0" name="to" type="Vector4i" />
@@ -110,6 +118,13 @@
 				Returns a new vector with each component snapped to the closest multiple of the corresponding component in [param step].
 				Returns a new vector with each component snapped to the closest multiple of the corresponding component in [param step].
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="snappedi" qualifiers="const">
+			<return type="Vector4i" />
+			<param index="0" name="step" type="int" />
+			<description>
+				Returns a new vector with each component snapped to the closest multiple of [param step].
+			</description>
+		</method>
 	</methods>
 	</methods>
 	<members>
 	<members>
 		<member name="w" type="int" setter="" getter="" default="0">
 		<member name="w" type="int" setter="" getter="" default="0">

+ 2 - 4
drivers/gles3/effects/copy_effects.cpp

@@ -198,8 +198,7 @@ void CopyEffects::bilinear_blur(GLuint p_source_texture, int p_mipmap_count, con
 	for (int i = 1; i < p_mipmap_count; i++) {
 	for (int i = 1; i < p_mipmap_count; i++) {
 		dest_region.position.x >>= 1;
 		dest_region.position.x >>= 1;
 		dest_region.position.y >>= 1;
 		dest_region.position.y >>= 1;
-		dest_region.size.x = MAX(1, dest_region.size.x >> 1);
-		dest_region.size.y = MAX(1, dest_region.size.y >> 1);
+		dest_region.size = Size2i(dest_region.size.x >> 1, dest_region.size.y >> 1).maxi(1);
 		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[i % 2]);
 		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[i % 2]);
 		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_source_texture, i);
 		glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_source_texture, i);
 		glBlitFramebuffer(source_region.position.x, source_region.position.y, source_region.position.x + source_region.size.x, source_region.position.y + source_region.size.y,
 		glBlitFramebuffer(source_region.position.x, source_region.position.y, source_region.position.x + source_region.size.x, source_region.position.y + source_region.size.y,
@@ -238,8 +237,7 @@ void CopyEffects::gaussian_blur(GLuint p_source_texture, int p_mipmap_count, con
 	for (int i = 1; i < p_mipmap_count; i++) {
 	for (int i = 1; i < p_mipmap_count; i++) {
 		dest_region.position.x >>= 1;
 		dest_region.position.x >>= 1;
 		dest_region.position.y >>= 1;
 		dest_region.position.y >>= 1;
-		dest_region.size.x = MAX(1, dest_region.size.x >> 1);
-		dest_region.size.y = MAX(1, dest_region.size.y >> 1);
+		dest_region.size = Size2i(dest_region.size.x >> 1, dest_region.size.y >> 1).maxi(1);
 		base_size.x >>= 1;
 		base_size.x >>= 1;
 		base_size.y >>= 1;
 		base_size.y >>= 1;
 
 

+ 1 - 2
drivers/gles3/storage/render_scene_buffers_gles3.cpp

@@ -577,8 +577,7 @@ void RenderSceneBuffersGLES3::check_glow_buffers() {
 	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
 	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
 	Size2i level_size = internal_size;
 	Size2i level_size = internal_size;
 	for (int i = 0; i < 4; i++) {
 	for (int i = 0; i < 4; i++) {
-		level_size.x = MAX(level_size.x >> 1, 4);
-		level_size.y = MAX(level_size.y >> 1, 4);
+		level_size = Size2i(level_size.x >> 1, level_size.y >> 1).maxi(4);
 
 
 		glow.levels[i].size = level_size;
 		glow.levels[i].size = level_size;
 
 

+ 1 - 1
drivers/gles3/storage/texture_storage.cpp

@@ -2812,7 +2812,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
 	}
 	}
 
 
 	rt->process_size = size * scale / 100;
 	rt->process_size = size * scale / 100;
-	rt->process_size = rt->process_size.max(Size2i(1, 1));
+	rt->process_size = rt->process_size.maxi(1);
 
 
 	glGenTextures(2, rt->sdf_texture_process);
 	glGenTextures(2, rt->sdf_texture_process);
 	glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[0]);
 	glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[0]);

+ 2 - 2
editor/plugins/canvas_item_editor_plugin.cpp

@@ -467,7 +467,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig
 
 
 	if (((snap_pixel && (p_modes & SNAP_PIXEL)) || (p_forced_modes & SNAP_PIXEL)) && rotation == 0.0) {
 	if (((snap_pixel && (p_modes & SNAP_PIXEL)) || (p_forced_modes & SNAP_PIXEL)) && rotation == 0.0) {
 		// Pixel
 		// Pixel
-		output = output.snapped(Size2(1, 1));
+		output = output.snappedf(1);
 	}
 	}
 
 
 	snap_transform = Transform2D(rotation, output);
 	snap_transform = Transform2D(rotation, output);
@@ -1625,7 +1625,7 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {
 			previous_anchor = xform.affine_inverse().xform(_anchor_to_position(control, previous_anchor));
 			previous_anchor = xform.affine_inverse().xform(_anchor_to_position(control, previous_anchor));
 
 
 			Vector2 new_anchor = xform.xform(snap_point(previous_anchor + (drag_to - drag_from), SNAP_GRID | SNAP_OTHER_NODES, SNAP_NODE_PARENT | SNAP_NODE_SIDES | SNAP_NODE_CENTER, control));
 			Vector2 new_anchor = xform.xform(snap_point(previous_anchor + (drag_to - drag_from), SNAP_GRID | SNAP_OTHER_NODES, SNAP_NODE_PARENT | SNAP_NODE_SIDES | SNAP_NODE_CENTER, control));
-			new_anchor = _position_to_anchor(control, new_anchor).snapped(Vector2(0.001, 0.001));
+			new_anchor = _position_to_anchor(control, new_anchor).snappedf(0.001);
 
 
 			bool use_single_axis = m->is_shift_pressed();
 			bool use_single_axis = m->is_shift_pressed();
 			Vector2 drag_vector = xform.xform(drag_to) - xform.xform(drag_from);
 			Vector2 drag_vector = xform.xform(drag_to) - xform.xform(drag_from);

+ 1 - 1
editor/plugins/editor_preview_plugins.cpp

@@ -130,7 +130,7 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const Ref<Resource> &p_from,
 	if (new_size.y > p_size.y) {
 	if (new_size.y > p_size.y) {
 		new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
 		new_size = Vector2(new_size.x * p_size.y / new_size.y, p_size.y);
 	}
 	}
-	Vector2i new_size_i = Vector2i(new_size).max(Vector2i(1, 1));
+	Vector2i new_size_i = Vector2i(new_size).maxi(1);
 	img->resize(new_size_i.x, new_size_i.y, Image::INTERPOLATE_CUBIC);
 	img->resize(new_size_i.x, new_size_i.y, Image::INTERPOLATE_CUBIC);
 	post_process_preview(img);
 	post_process_preview(img);
 
 

+ 1 - 1
editor/plugins/gizmos/navigation_link_3d_gizmo_plugin.cpp

@@ -165,7 +165,7 @@ void NavigationLink3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
 
 
 	if (Node3DEditor::get_singleton()->is_snap_enabled()) {
 	if (Node3DEditor::get_singleton()->is_snap_enabled()) {
 		double snap = Node3DEditor::get_singleton()->get_translate_snap();
 		double snap = Node3DEditor::get_singleton()->get_translate_snap();
-		intersection.snap(Vector3(snap, snap, snap));
+		intersection.snapf(snap);
 	}
 	}
 
 
 	position = gi.xform(intersection);
 	position = gi.xform(intersection);

+ 2 - 2
editor/plugins/gizmos/navigation_region_3d_gizmo_plugin.cpp

@@ -108,8 +108,8 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
 			for (int j = 0; j < 3; j++) {
 			for (int j = 0; j < 3; j++) {
 				tw[tidx++] = f.vertex[j];
 				tw[tidx++] = f.vertex[j];
 				_EdgeKey ek;
 				_EdgeKey ek;
-				ek.from = f.vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
-				ek.to = f.vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
+				ek.from = f.vertex[j].snappedf(CMP_EPSILON);
+				ek.to = f.vertex[(j + 1) % 3].snappedf(CMP_EPSILON);
 				if (ek.from < ek.to) {
 				if (ek.from < ek.to) {
 					SWAP(ek.from, ek.to);
 					SWAP(ek.from, ek.to);
 				}
 				}

+ 2 - 2
editor/plugins/gizmos/occluder_instance_3d_gizmo_plugin.cpp

@@ -163,9 +163,9 @@ void OccluderInstance3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo,
 		if (p_id == 2) {
 		if (p_id == 2) {
 			Vector2 s = Vector2(intersection.x, intersection.y) * 2.0f;
 			Vector2 s = Vector2(intersection.x, intersection.y) * 2.0f;
 			if (snap_enabled) {
 			if (snap_enabled) {
-				s = s.snapped(Vector2(snap, snap));
+				s = s.snappedf(snap);
 			}
 			}
-			s = s.max(Vector2(0.001, 0.001));
+			s = s.maxf(0.001);
 			qo->set_size(s);
 			qo->set_size(s);
 		} else {
 		} else {
 			float d = intersection[p_id];
 			float d = intersection[p_id];

+ 3 - 3
editor/plugins/gradient_texture_2d_editor_plugin.cpp

@@ -42,7 +42,7 @@
 
 
 Point2 GradientTexture2DEdit::_get_handle_pos(const Handle p_handle) {
 Point2 GradientTexture2DEdit::_get_handle_pos(const Handle p_handle) {
 	// Get the handle's mouse position in pixels relative to offset.
 	// Get the handle's mouse position in pixels relative to offset.
-	return (p_handle == HANDLE_FROM ? texture->get_fill_from() : texture->get_fill_to()).clamp(Vector2(), Vector2(1, 1)) * size;
+	return (p_handle == HANDLE_FROM ? texture->get_fill_from() : texture->get_fill_to()).clampf(0, 1) * size;
 }
 }
 
 
 GradientTexture2DEdit::Handle GradientTexture2DEdit::get_handle_at(const Vector2 &p_pos) {
 GradientTexture2DEdit::Handle GradientTexture2DEdit::get_handle_at(const Vector2 &p_pos) {
@@ -112,9 +112,9 @@ void GradientTexture2DEdit::gui_input(const Ref<InputEvent> &p_event) {
 			return;
 			return;
 		}
 		}
 
 
-		Vector2 new_pos = (mpos / size).clamp(Vector2(0, 0), Vector2(1, 1));
+		Vector2 new_pos = (mpos / size).clampf(0, 1);
 		if (snap_enabled || mm->is_command_or_control_pressed()) {
 		if (snap_enabled || mm->is_command_or_control_pressed()) {
-			new_pos = new_pos.snapped(Vector2(1.0 / snap_count, 1.0 / snap_count));
+			new_pos = new_pos.snappedf(1.0 / snap_count);
 		}
 		}
 
 
 		// Allow to snap to an axis with Shift.
 		// Allow to snap to an axis with Shift.

+ 1 - 3
editor/plugins/navigation_obstacle_3d_editor_plugin.cpp

@@ -330,9 +330,7 @@ EditorPlugin::AfterGUIInput NavigationObstacle3DEditor::forward_3d_gui_input(Cam
 			}
 			}
 
 
 			if (!snap_ignore && Node3DEditor::get_singleton()->is_snap_enabled()) {
 			if (!snap_ignore && Node3DEditor::get_singleton()->is_snap_enabled()) {
-				cpoint = cpoint.snapped(Vector2(
-						Node3DEditor::get_singleton()->get_translate_snap(),
-						Node3DEditor::get_singleton()->get_translate_snap()));
+				cpoint = cpoint.snappedf(Node3DEditor::get_singleton()->get_translate_snap());
 			}
 			}
 			edited_point_pos = cpoint;
 			edited_point_pos = cpoint;
 
 

+ 5 - 5
editor/plugins/node_3d_editor_plugin.cpp

@@ -1448,7 +1448,7 @@ Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const
 	switch (p_mode) {
 	switch (p_mode) {
 		case TRANSFORM_SCALE: {
 		case TRANSFORM_SCALE: {
 			if (_edit.snap || spatial_editor->is_snap_enabled()) {
 			if (_edit.snap || spatial_editor->is_snap_enabled()) {
-				p_motion.snap(Vector3(p_extra, p_extra, p_extra));
+				p_motion.snapf(p_extra);
 			}
 			}
 			Transform3D s;
 			Transform3D s;
 			if (p_local) {
 			if (p_local) {
@@ -1469,7 +1469,7 @@ Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const
 		}
 		}
 		case TRANSFORM_TRANSLATE: {
 		case TRANSFORM_TRANSLATE: {
 			if (_edit.snap || spatial_editor->is_snap_enabled()) {
 			if (_edit.snap || spatial_editor->is_snap_enabled()) {
-				p_motion.snap(Vector3(p_extra, p_extra, p_extra));
+				p_motion.snapf(p_extra);
 			}
 			}
 
 
 			if (p_local) {
 			if (p_local) {
@@ -4786,7 +4786,7 @@ void Node3DEditorViewport::update_transform(bool p_shift) {
 				snap = spatial_editor->get_scale_snap() / 100;
 				snap = spatial_editor->get_scale_snap() / 100;
 			}
 			}
 			Vector3 motion_snapped = motion;
 			Vector3 motion_snapped = motion;
-			motion_snapped.snap(Vector3(snap, snap, snap));
+			motion_snapped.snapf(snap);
 			// This might not be necessary anymore after issue #288 is solved (in 4.0?).
 			// This might not be necessary anymore after issue #288 is solved (in 4.0?).
 			// TRANSLATORS: Refers to changing the scale of a node in the 3D editor.
 			// TRANSLATORS: Refers to changing the scale of a node in the 3D editor.
 			set_message(TTR("Scaling:") + " (" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
 			set_message(TTR("Scaling:") + " (" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
@@ -4858,7 +4858,7 @@ void Node3DEditorViewport::update_transform(bool p_shift) {
 				snap = spatial_editor->get_translate_snap();
 				snap = spatial_editor->get_translate_snap();
 			}
 			}
 			Vector3 motion_snapped = motion;
 			Vector3 motion_snapped = motion;
-			motion_snapped.snap(Vector3(snap, snap, snap));
+			motion_snapped.snapf(snap);
 			// TRANSLATORS: Refers to changing the position of a node in the 3D editor.
 			// TRANSLATORS: Refers to changing the position of a node in the 3D editor.
 			set_message(TTR("Translating:") + " (" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
 			set_message(TTR("Translating:") + " (" + String::num(motion_snapped.x, snap_step_decimals) + ", " +
 					String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
 					String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
@@ -8997,7 +8997,7 @@ void Node3DEditorPlugin::set_state(const Dictionary &p_state) {
 Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
 Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
 	if (is_snap_enabled()) {
 	if (is_snap_enabled()) {
 		real_t snap = get_translate_snap();
 		real_t snap = get_translate_snap();
-		p_target.snap(Vector3(snap, snap, snap));
+		p_target.snapf(snap);
 	}
 	}
 	return p_target;
 	return p_target;
 }
 }

+ 2 - 2
editor/plugins/path_3d_editor_plugin.cpp

@@ -117,7 +117,7 @@ void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, con
 		if (p.intersects_ray(ray_from, ray_dir, &inters)) {
 		if (p.intersects_ray(ray_from, ray_dir, &inters)) {
 			if (Node3DEditor::get_singleton()->is_snap_enabled()) {
 			if (Node3DEditor::get_singleton()->is_snap_enabled()) {
 				float snap = Node3DEditor::get_singleton()->get_translate_snap();
 				float snap = Node3DEditor::get_singleton()->get_translate_snap();
-				inters.snap(Vector3(snap, snap, snap));
+				inters.snapf(snap);
 			}
 			}
 
 
 			Vector3 local = gi.xform(inters);
 			Vector3 local = gi.xform(inters);
@@ -146,7 +146,7 @@ void Path3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, con
 				Vector3 local = gi.xform(inters) - base;
 				Vector3 local = gi.xform(inters) - base;
 				if (Node3DEditor::get_singleton()->is_snap_enabled()) {
 				if (Node3DEditor::get_singleton()->is_snap_enabled()) {
 					float snap = Node3DEditor::get_singleton()->get_translate_snap();
 					float snap = Node3DEditor::get_singleton()->get_translate_snap();
-					local.snap(Vector3(snap, snap, snap));
+					local.snapf(snap);
 				}
 				}
 
 
 				if (info.type == HandleType::HANDLE_TYPE_IN) {
 				if (info.type == HandleType::HANDLE_TYPE_IN) {

+ 1 - 3
editor/plugins/polygon_3d_editor_plugin.cpp

@@ -334,9 +334,7 @@ EditorPlugin::AfterGUIInput Polygon3DEditor::forward_3d_gui_input(Camera3D *p_ca
 			}
 			}
 
 
 			if (!snap_ignore && Node3DEditor::get_singleton()->is_snap_enabled()) {
 			if (!snap_ignore && Node3DEditor::get_singleton()->is_snap_enabled()) {
-				cpoint = cpoint.snapped(Vector2(
-						Node3DEditor::get_singleton()->get_translate_snap(),
-						Node3DEditor::get_singleton()->get_translate_snap()));
+				cpoint = cpoint.snappedf(Node3DEditor::get_singleton()->get_translate_snap());
 			}
 			}
 			edited_point_pos = cpoint;
 			edited_point_pos = cpoint;
 
 

+ 2 - 2
editor/plugins/texture_region_editor_plugin.cpp

@@ -328,7 +328,7 @@ void TextureRegionEditor::_texture_overlay_input(const Ref<InputEvent> &p_input)
 
 
 					drag_from = mtx.affine_inverse().xform(mb->get_position());
 					drag_from = mtx.affine_inverse().xform(mb->get_position());
 					if (snap_mode == SNAP_PIXEL) {
 					if (snap_mode == SNAP_PIXEL) {
-						drag_from = drag_from.snapped(Vector2(1, 1));
+						drag_from = drag_from.snappedf(1);
 					} else if (snap_mode == SNAP_GRID) {
 					} else if (snap_mode == SNAP_GRID) {
 						drag_from = snap_point(drag_from);
 						drag_from = snap_point(drag_from);
 					}
 					}
@@ -566,7 +566,7 @@ void TextureRegionEditor::_texture_overlay_input(const Ref<InputEvent> &p_input)
 			} else {
 			} else {
 				Vector2 new_pos = mtx.affine_inverse().xform(mm->get_position());
 				Vector2 new_pos = mtx.affine_inverse().xform(mm->get_position());
 				if (snap_mode == SNAP_PIXEL) {
 				if (snap_mode == SNAP_PIXEL) {
-					new_pos = new_pos.snapped(Vector2(1, 1));
+					new_pos = new_pos.snappedf(1);
 				} else if (snap_mode == SNAP_GRID) {
 				} else if (snap_mode == SNAP_GRID) {
 					new_pos = snap_point(new_pos);
 					new_pos = snap_point(new_pos);
 				}
 				}

+ 1 - 1
editor/plugins/tiles/tile_data_editors.cpp

@@ -458,7 +458,7 @@ void GenericTilePolygonEditor::_snap_point(Point2 &r_point) {
 			break;
 			break;
 
 
 		case SNAP_HALF_PIXEL:
 		case SNAP_HALF_PIXEL:
-			r_point = r_point.snapped(Vector2(0.5, 0.5));
+			r_point = r_point.snappedf(0.5);
 			break;
 			break;
 
 
 		case SNAP_GRID: {
 		case SNAP_GRID: {

+ 2 - 2
editor/plugins/tiles/tile_proxies_manager_dialog.cpp

@@ -257,13 +257,13 @@ bool TileProxiesManagerDialog::_set(const StringName &p_name, const Variant &p_v
 	if (p_name == "from_source") {
 	if (p_name == "from_source") {
 		from.source_id = MAX(int(p_value), -1);
 		from.source_id = MAX(int(p_value), -1);
 	} else if (p_name == "from_coords") {
 	} else if (p_name == "from_coords") {
-		from.set_atlas_coords(Vector2i(p_value).max(Vector2i(-1, -1)));
+		from.set_atlas_coords(Vector2i(p_value).maxi(-1));
 	} else if (p_name == "from_alternative") {
 	} else if (p_name == "from_alternative") {
 		from.alternative_tile = MAX(int(p_value), -1);
 		from.alternative_tile = MAX(int(p_value), -1);
 	} else if (p_name == "to_source") {
 	} else if (p_name == "to_source") {
 		to.source_id = MAX(int(p_value), 0);
 		to.source_id = MAX(int(p_value), 0);
 	} else if (p_name == "to_coords") {
 	} else if (p_name == "to_coords") {
-		to.set_atlas_coords(Vector2i(p_value).max(Vector2i(0, 0)));
+		to.set_atlas_coords(Vector2i(p_value).maxi(0));
 	} else if (p_name == "to_alternative") {
 	} else if (p_name == "to_alternative") {
 		to.alternative_tile = MAX(int(p_value), 0);
 		to.alternative_tile = MAX(int(p_value), 0);
 	} else {
 	} else {

+ 7 - 7
editor/plugins/tiles/tile_set_atlas_source_editor.cpp

@@ -1088,7 +1088,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven
 
 
 			if (drag_type == DRAG_TYPE_CREATE_BIG_TILE) {
 			if (drag_type == DRAG_TYPE_CREATE_BIG_TILE) {
 				// Create big tile.
 				// Create big tile.
-				new_base_tiles_coords = new_base_tiles_coords.max(Vector2i(0, 0)).min(grid_size - Vector2i(1, 1));
+				new_base_tiles_coords = new_base_tiles_coords.maxi(0).min(grid_size - Vector2i(1, 1));
 
 
 				Rect2i new_rect = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs();
 				Rect2i new_rect = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs();
 				new_rect.size += Vector2i(1, 1);
 				new_rect.size += Vector2i(1, 1);
@@ -1100,8 +1100,8 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven
 				}
 				}
 			} else if (drag_type == DRAG_TYPE_CREATE_TILES) {
 			} else if (drag_type == DRAG_TYPE_CREATE_TILES) {
 				// Create tiles.
 				// Create tiles.
-				last_base_tiles_coords = last_base_tiles_coords.max(Vector2i(0, 0)).min(grid_size - Vector2i(1, 1));
-				new_base_tiles_coords = new_base_tiles_coords.max(Vector2i(0, 0)).min(grid_size - Vector2i(1, 1));
+				last_base_tiles_coords = last_base_tiles_coords.maxi(0).min(grid_size - Vector2i(1, 1));
+				new_base_tiles_coords = new_base_tiles_coords.maxi(0).min(grid_size - Vector2i(1, 1));
 
 
 				Vector<Point2i> line = Geometry2D::bresenham_line(last_base_tiles_coords, new_base_tiles_coords);
 				Vector<Point2i> line = Geometry2D::bresenham_line(last_base_tiles_coords, new_base_tiles_coords);
 				for (int i = 0; i < line.size(); i++) {
 				for (int i = 0; i < line.size(); i++) {
@@ -1115,8 +1115,8 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref<InputEven
 
 
 			} else if (drag_type == DRAG_TYPE_REMOVE_TILES) {
 			} else if (drag_type == DRAG_TYPE_REMOVE_TILES) {
 				// Remove tiles.
 				// Remove tiles.
-				last_base_tiles_coords = last_base_tiles_coords.max(Vector2i(0, 0)).min(grid_size - Vector2i(1, 1));
-				new_base_tiles_coords = new_base_tiles_coords.max(Vector2i(0, 0)).min(grid_size - Vector2i(1, 1));
+				last_base_tiles_coords = last_base_tiles_coords.maxi(0).min(grid_size - Vector2i(1, 1));
+				new_base_tiles_coords = new_base_tiles_coords.maxi(0).min(grid_size - Vector2i(1, 1));
 
 
 				Vector<Point2i> line = Geometry2D::bresenham_line(last_base_tiles_coords, new_base_tiles_coords);
 				Vector<Point2i> line = Geometry2D::bresenham_line(last_base_tiles_coords, new_base_tiles_coords);
 				for (int i = 0; i < line.size(); i++) {
 				for (int i = 0; i < line.size(); i++) {
@@ -1838,7 +1838,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() {
 		Vector2i separation = tile_set_atlas_source->get_separation();
 		Vector2i separation = tile_set_atlas_source->get_separation();
 		Vector2i tile_size = tile_set_atlas_source->get_texture_region_size();
 		Vector2i tile_size = tile_set_atlas_source->get_texture_region_size();
 		Vector2i origin = margins + (area.position * (tile_size + separation));
 		Vector2i origin = margins + (area.position * (tile_size + separation));
-		Vector2i size = area.size * tile_size + (area.size - Vector2i(1, 1)).max(Vector2i(0, 0)) * separation;
+		Vector2i size = area.size * tile_size + (area.size - Vector2i(1, 1)).maxi(0) * separation;
 		TilesEditorUtils::draw_selection_rect(tile_atlas_control, Rect2i(origin, size));
 		TilesEditorUtils::draw_selection_rect(tile_atlas_control, Rect2i(origin, size));
 	} else {
 	} else {
 		Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size();
 		Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size();
@@ -2157,7 +2157,7 @@ void TileSetAtlasSourceEditor::_undo_redo_inspector_callback(Object *p_undo_redo
 Vector2i TileSetAtlasSourceEditor::_get_drag_offset_tile_coords(const Vector2i &p_offset) const {
 Vector2i TileSetAtlasSourceEditor::_get_drag_offset_tile_coords(const Vector2i &p_offset) const {
 	Vector2i half_tile_size = tile_set->get_tile_size() / 2;
 	Vector2i half_tile_size = tile_set->get_tile_size() / 2;
 	Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position() + half_tile_size * p_offset);
 	Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position() + half_tile_size * p_offset);
-	return new_base_tiles_coords.max(Vector2i(-1, -1)).min(tile_set_atlas_source->get_atlas_grid_size());
+	return new_base_tiles_coords.maxi(-1).min(tile_set_atlas_source->get_atlas_grid_size());
 }
 }
 
 
 void TileSetAtlasSourceEditor::edit(Ref<TileSet> p_tile_set, TileSetAtlasSource *p_tile_set_atlas_source, int p_source_id) {
 void TileSetAtlasSourceEditor::edit(Ref<TileSet> p_tile_set, TileSetAtlasSource *p_tile_set_atlas_source, int p_source_id) {

+ 3 - 3
editor/plugins/visual_shader_editor_plugin.cpp

@@ -4673,7 +4673,7 @@ void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos, VisualShaderNod
 	// Keep dialog within window bounds.
 	// Keep dialog within window bounds.
 	Rect2 window_rect = Rect2(get_window()->get_position(), get_window()->get_size());
 	Rect2 window_rect = Rect2(get_window()->get_position(), get_window()->get_size());
 	Rect2 dialog_rect = Rect2(members_dialog->get_position(), members_dialog->get_size());
 	Rect2 dialog_rect = Rect2(members_dialog->get_position(), members_dialog->get_size());
-	Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).max(Vector2());
+	Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).maxf(0);
 	members_dialog->set_position(members_dialog->get_position() - difference);
 	members_dialog->set_position(members_dialog->get_position() - difference);
 
 
 	callable_mp((Control *)node_filter, &Control::grab_focus).call_deferred(); // Still not visible.
 	callable_mp((Control *)node_filter, &Control::grab_focus).call_deferred(); // Still not visible.
@@ -4702,7 +4702,7 @@ void VisualShaderEditor::_show_add_varying_dialog() {
 	// Keep dialog within window bounds.
 	// Keep dialog within window bounds.
 	Rect2 window_rect = Rect2(DisplayServer::get_singleton()->window_get_position(), DisplayServer::get_singleton()->window_get_size());
 	Rect2 window_rect = Rect2(DisplayServer::get_singleton()->window_get_position(), DisplayServer::get_singleton()->window_get_size());
 	Rect2 dialog_rect = Rect2(add_varying_dialog->get_position(), add_varying_dialog->get_size());
 	Rect2 dialog_rect = Rect2(add_varying_dialog->get_position(), add_varying_dialog->get_size());
-	Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).max(Vector2());
+	Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).maxf(0);
 	add_varying_dialog->set_position(add_varying_dialog->get_position() - difference);
 	add_varying_dialog->set_position(add_varying_dialog->get_position() - difference);
 }
 }
 
 
@@ -4713,7 +4713,7 @@ void VisualShaderEditor::_show_remove_varying_dialog() {
 	// Keep dialog within window bounds.
 	// Keep dialog within window bounds.
 	Rect2 window_rect = Rect2(DisplayServer::get_singleton()->window_get_position(), DisplayServer::get_singleton()->window_get_size());
 	Rect2 window_rect = Rect2(DisplayServer::get_singleton()->window_get_position(), DisplayServer::get_singleton()->window_get_size());
 	Rect2 dialog_rect = Rect2(remove_varying_dialog->get_position(), remove_varying_dialog->get_size());
 	Rect2 dialog_rect = Rect2(remove_varying_dialog->get_position(), remove_varying_dialog->get_size());
-	Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).max(Vector2());
+	Vector2 difference = (dialog_rect.get_end() - window_rect.get_end()).maxf(0);
 	remove_varying_dialog->set_position(remove_varying_dialog->get_position() - difference);
 	remove_varying_dialog->set_position(remove_varying_dialog->get_position() - difference);
 }
 }
 
 

+ 29 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs

@@ -191,6 +191,23 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with all components clamped between the
+        /// <paramref name="min"/> and <paramref name="max"/> using
+        /// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>.
+        /// </summary>
+        /// <param name="min">The minimum allowed value.</param>
+        /// <param name="max">The maximum allowed value.</param>
+        /// <returns>The vector with all components clamped.</returns>
+        public readonly Vector2 Clamp(real_t min, real_t max)
+        {
+            return new Vector2
+            (
+                Mathf.Clamp(X, min, max),
+                Mathf.Clamp(Y, min, max)
+            );
+        }
+
         /// <summary>
         /// <summary>
         /// Returns the cross product of this vector and <paramref name="with"/>.
         /// Returns the cross product of this vector and <paramref name="with"/>.
         /// </summary>
         /// </summary>
@@ -600,7 +617,7 @@ namespace Godot
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Returns this vector with each component snapped to the nearest multiple of <paramref name="step"/>.
+        /// Returns a new vector with each component snapped to the nearest multiple of the corresponding component in <paramref name="step"/>.
         /// This can also be used to round to an arbitrary number of decimals.
         /// This can also be used to round to an arbitrary number of decimals.
         /// </summary>
         /// </summary>
         /// <param name="step">A vector value representing the step size to snap to.</param>
         /// <param name="step">A vector value representing the step size to snap to.</param>
@@ -610,6 +627,17 @@ namespace Godot
             return new Vector2(Mathf.Snapped(X, step.X), Mathf.Snapped(Y, step.Y));
             return new Vector2(Mathf.Snapped(X, step.X), Mathf.Snapped(Y, step.Y));
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with each component snapped to the nearest multiple of <paramref name="step"/>.
+        /// This can also be used to round to an arbitrary number of decimals.
+        /// </summary>
+        /// <param name="step">The step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector2 Snapped(real_t step)
+        {
+            return new Vector2(Mathf.Snapped(X, step), Mathf.Snapped(Y, step));
+        }
+
         /// <summary>
         /// <summary>
         /// Returns a perpendicular vector rotated 90 degrees counter-clockwise
         /// Returns a perpendicular vector rotated 90 degrees counter-clockwise
         /// compared to the original, with the same length.
         /// compared to the original, with the same length.

+ 45 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2I.cs

@@ -124,6 +124,23 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with all components clamped between the
+        /// <paramref name="min"/> and <paramref name="max"/> using
+        /// <see cref="Mathf.Clamp(int, int, int)"/>.
+        /// </summary>
+        /// <param name="min">The minimum allowed value.</param>
+        /// <param name="max">The maximum allowed value.</param>
+        /// <returns>The vector with all components clamped.</returns>
+        public readonly Vector2I Clamp(int min, int max)
+        {
+            return new Vector2I
+            (
+                Mathf.Clamp(X, min, max),
+                Mathf.Clamp(Y, min, max)
+            );
+        }
+
         /// <summary>
         /// <summary>
         /// Returns the squared distance between this vector and <paramref name="to"/>.
         /// Returns the squared distance between this vector and <paramref name="to"/>.
         /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
         /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
@@ -208,6 +225,34 @@ namespace Godot
             return v;
             return v;
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with each component snapped to the closest multiple of the corresponding component in <paramref name="step"/>.
+        /// </summary>
+        /// <param name="step">A vector value representing the step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector2I Snapped(Vector2I step)
+        {
+            return new Vector2I
+            (
+                (int)Mathf.Snapped((double)X, (double)step.X),
+                (int)Mathf.Snapped((double)Y, (double)step.Y)
+            );
+        }
+
+        /// <summary>
+        /// Returns a new vector with each component snapped to the closest multiple of <paramref name="step"/>.
+        /// </summary>
+        /// <param name="step">The step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector2I Snapped(int step)
+        {
+            return new Vector2I
+            (
+                (int)Mathf.Snapped((double)X, (double)step),
+                (int)Mathf.Snapped((double)Y, (double)step)
+            );
+        }
+
         // Constants
         // Constants
         private static readonly Vector2I _minValue = new Vector2I(int.MinValue, int.MinValue);
         private static readonly Vector2I _minValue = new Vector2I(int.MinValue, int.MinValue);
         private static readonly Vector2I _maxValue = new Vector2I(int.MaxValue, int.MaxValue);
         private static readonly Vector2I _maxValue = new Vector2I(int.MaxValue, int.MaxValue);

+ 35 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs

@@ -178,6 +178,24 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with all components clamped between the
+        /// <paramref name="min"/> and <paramref name="max"/> using
+        /// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>.
+        /// </summary>
+        /// <param name="min">The minimum allowed value.</param>
+        /// <param name="max">The maximum allowed value.</param>
+        /// <returns>The vector with all components clamped.</returns>
+        public readonly Vector3 Clamp(real_t min, real_t max)
+        {
+            return new Vector3
+            (
+                Mathf.Clamp(X, min, max),
+                Mathf.Clamp(Y, min, max),
+                Mathf.Clamp(Z, min, max)
+            );
+        }
+
         /// <summary>
         /// <summary>
         /// Returns the cross product of this vector and <paramref name="with"/>.
         /// Returns the cross product of this vector and <paramref name="with"/>.
         /// </summary>
         /// </summary>
@@ -643,7 +661,7 @@ namespace Godot
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Returns this vector with each component snapped to the nearest multiple of <paramref name="step"/>.
+        /// Returns a new vector with each component snapped to the nearest multiple of the corresponding component in <paramref name="step"/>.
         /// This can also be used to round to an arbitrary number of decimals.
         /// This can also be used to round to an arbitrary number of decimals.
         /// </summary>
         /// </summary>
         /// <param name="step">A vector value representing the step size to snap to.</param>
         /// <param name="step">A vector value representing the step size to snap to.</param>
@@ -658,6 +676,22 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with each component snapped to the nearest multiple of <paramref name="step"/>.
+        /// This can also be used to round to an arbitrary number of decimals.
+        /// </summary>
+        /// <param name="step">The step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector3 Snapped(real_t step)
+        {
+            return new Vector3
+            (
+                Mathf.Snapped(X, step),
+                Mathf.Snapped(Y, step),
+                Mathf.Snapped(Z, step)
+            );
+        }
+
         // Constants
         // Constants
         private static readonly Vector3 _zero = new Vector3(0, 0, 0);
         private static readonly Vector3 _zero = new Vector3(0, 0, 0);
         private static readonly Vector3 _one = new Vector3(1, 1, 1);
         private static readonly Vector3 _one = new Vector3(1, 1, 1);

+ 48 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3I.cs

@@ -132,6 +132,24 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with all components clamped between the
+        /// <paramref name="min"/> and <paramref name="max"/> using
+        /// <see cref="Mathf.Clamp(int, int, int)"/>.
+        /// </summary>
+        /// <param name="min">The minimum allowed value.</param>
+        /// <param name="max">The maximum allowed value.</param>
+        /// <returns>The vector with all components clamped.</returns>
+        public readonly Vector3I Clamp(int min, int max)
+        {
+            return new Vector3I
+            (
+                Mathf.Clamp(X, min, max),
+                Mathf.Clamp(Y, min, max),
+                Mathf.Clamp(Z, min, max)
+            );
+        }
+
         /// <summary>
         /// <summary>
         /// Returns the squared distance between this vector and <paramref name="to"/>.
         /// Returns the squared distance between this vector and <paramref name="to"/>.
         /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
         /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
@@ -219,6 +237,36 @@ namespace Godot
             return v;
             return v;
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with each component snapped to the closest multiple of the corresponding component in <paramref name="step"/>.
+        /// </summary>
+        /// <param name="step">A vector value representing the step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector3I Snapped(Vector3I step)
+        {
+            return new Vector3I
+            (
+                (int)Mathf.Snapped((double)X, (double)step.X),
+                (int)Mathf.Snapped((double)Y, (double)step.Y),
+                (int)Mathf.Snapped((double)Z, (double)step.Z)
+            );
+        }
+
+        /// <summary>
+        /// Returns a new vector with each component snapped to the closest multiple of <paramref name="step"/>.
+        /// </summary>
+        /// <param name="step">The step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector3I Snapped(int step)
+        {
+            return new Vector3I
+            (
+                (int)Mathf.Snapped((double)X, (double)step),
+                (int)Mathf.Snapped((double)Y, (double)step),
+                (int)Mathf.Snapped((double)Z, (double)step)
+            );
+        }
+
         // Constants
         // Constants
         private static readonly Vector3I _minValue = new Vector3I(int.MinValue, int.MinValue, int.MinValue);
         private static readonly Vector3I _minValue = new Vector3I(int.MinValue, int.MinValue, int.MinValue);
         private static readonly Vector3I _maxValue = new Vector3I(int.MaxValue, int.MaxValue, int.MaxValue);
         private static readonly Vector3I _maxValue = new Vector3I(int.MaxValue, int.MaxValue, int.MaxValue);

+ 36 - 1
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4.cs

@@ -176,6 +176,25 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with all components clamped between the
+        /// <paramref name="min"/> and <paramref name="max"/> using
+        /// <see cref="Mathf.Clamp(real_t, real_t, real_t)"/>.
+        /// </summary>
+        /// <param name="min">The minimum allowed value.</param>
+        /// <param name="max">The maximum allowed value.</param>
+        /// <returns>The vector with all components clamped.</returns>
+        public readonly Vector4 Clamp(real_t min, real_t max)
+        {
+            return new Vector4
+            (
+                Mathf.Clamp(X, min, max),
+                Mathf.Clamp(Y, min, max),
+                Mathf.Clamp(Z, min, max),
+                Mathf.Clamp(W, min, max)
+            );
+        }
+
         /// <summary>
         /// <summary>
         /// Performs a cubic interpolation between vectors <paramref name="preA"/>, this vector,
         /// Performs a cubic interpolation between vectors <paramref name="preA"/>, this vector,
         /// <paramref name="b"/>, and <paramref name="postB"/>, by the given amount <paramref name="weight"/>.
         /// <paramref name="b"/>, and <paramref name="postB"/>, by the given amount <paramref name="weight"/>.
@@ -465,7 +484,7 @@ namespace Godot
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Returns this vector with each component snapped to the nearest multiple of <paramref name="step"/>.
+        /// Returns a new vector with each component snapped to the nearest multiple of the corresponding component in <paramref name="step"/>.
         /// This can also be used to round to an arbitrary number of decimals.
         /// This can also be used to round to an arbitrary number of decimals.
         /// </summary>
         /// </summary>
         /// <param name="step">A vector value representing the step size to snap to.</param>
         /// <param name="step">A vector value representing the step size to snap to.</param>
@@ -480,6 +499,22 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with each component snapped to the nearest multiple of <paramref name="step"/>.
+        /// This can also be used to round to an arbitrary number of decimals.
+        /// </summary>
+        /// <param name="step">The step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector4 Snapped(real_t step)
+        {
+            return new Vector4(
+                Mathf.Snapped(X, step),
+                Mathf.Snapped(Y, step),
+                Mathf.Snapped(Z, step),
+                Mathf.Snapped(W, step)
+            );
+        }
+
         // Constants
         // Constants
         private static readonly Vector4 _zero = new Vector4(0, 0, 0, 0);
         private static readonly Vector4 _zero = new Vector4(0, 0, 0, 0);
         private static readonly Vector4 _one = new Vector4(1, 1, 1, 1);
         private static readonly Vector4 _one = new Vector4(1, 1, 1, 1);

+ 49 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector4I.cs

@@ -149,6 +149,25 @@ namespace Godot
             );
             );
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with all components clamped between
+        /// <paramref name="min"/> and <paramref name="max"/> using
+        /// <see cref="Mathf.Clamp(int, int, int)"/>.
+        /// </summary>
+        /// <param name="min">The minimum allowed value.</param>
+        /// <param name="max">The maximum allowed value.</param>
+        /// <returns>The vector with all components clamped.</returns>
+        public readonly Vector4I Clamp(int min, int max)
+        {
+            return new Vector4I
+            (
+                Mathf.Clamp(X, min, max),
+                Mathf.Clamp(Y, min, max),
+                Mathf.Clamp(Z, min, max),
+                Mathf.Clamp(W, min, max)
+            );
+        }
+
         /// <summary>
         /// <summary>
         /// Returns the squared distance between this vector and <paramref name="to"/>.
         /// Returns the squared distance between this vector and <paramref name="to"/>.
         /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
         /// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
@@ -254,6 +273,36 @@ namespace Godot
             return new Vector4I(Mathf.Sign(X), Mathf.Sign(Y), Mathf.Sign(Z), Mathf.Sign(W));
             return new Vector4I(Mathf.Sign(X), Mathf.Sign(Y), Mathf.Sign(Z), Mathf.Sign(W));
         }
         }
 
 
+        /// <summary>
+        /// Returns a new vector with each component snapped to the closest multiple of the corresponding component in <paramref name="step"/>.
+        /// </summary>
+        /// <param name="step">A vector value representing the step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector4I Snapped(Vector4I step)
+        {
+            return new Vector4I(
+                (int)Mathf.Snapped((double)X, (double)step.X),
+                (int)Mathf.Snapped((double)Y, (double)step.Y),
+                (int)Mathf.Snapped((double)Z, (double)step.Z),
+                (int)Mathf.Snapped((double)W, (double)step.W)
+            );
+        }
+
+        /// <summary>
+        /// Returns a new vector with each component snapped to the closest multiple of <paramref name="step"/>.
+        /// </summary>
+        /// <param name="step">The step size to snap to.</param>
+        /// <returns>The snapped vector.</returns>
+        public readonly Vector4I Snapped(int step)
+        {
+            return new Vector4I(
+                (int)Mathf.Snapped((double)X, (double)step),
+                (int)Mathf.Snapped((double)Y, (double)step),
+                (int)Mathf.Snapped((double)Z, (double)step),
+                (int)Mathf.Snapped((double)W, (double)step)
+            );
+        }
+
         // Constants
         // Constants
         private static readonly Vector4I _minValue = new Vector4I(int.MinValue, int.MinValue, int.MinValue, int.MinValue);
         private static readonly Vector4I _minValue = new Vector4I(int.MinValue, int.MinValue, int.MinValue, int.MinValue);
         private static readonly Vector4I _maxValue = new Vector4I(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue);
         private static readonly Vector4I _maxValue = new Vector4I(int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue);

+ 1 - 1
platform/linuxbsd/wayland/wayland_thread.cpp

@@ -2461,7 +2461,7 @@ void WaylandThread::_wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_
 		// According to the tablet proto spec, tilt is expressed in degrees relative
 		// According to the tablet proto spec, tilt is expressed in degrees relative
 		// to the Z axis of the tablet, so it shouldn't go over 90 degrees either way,
 		// to the Z axis of the tablet, so it shouldn't go over 90 degrees either way,
 		// I think. We'll clamp it just in case.
 		// I think. We'll clamp it just in case.
-		td.tilt = td.tilt.clamp(Vector2(-90, -90), Vector2(90, 90));
+		td.tilt = td.tilt.clampf(-90, 90);
 
 
 		mm->set_tilt(td.tilt / 90);
 		mm->set_tilt(td.tilt / 90);
 
 

+ 1 - 1
platform/linuxbsd/x11/display_server_x11.cpp

@@ -2225,7 +2225,7 @@ void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
 	ERR_FAIL_COND(!windows.has(p_window));
 	ERR_FAIL_COND(!windows.has(p_window));
 
 
 	Size2i size = p_size;
 	Size2i size = p_size;
-	size = size.max(Size2i(1, 1));
+	size = size.maxi(1);
 
 
 	WindowData &wd = windows[p_window];
 	WindowData &wd = windows[p_window];
 
 

+ 1 - 1
platform/macos/display_server_macos.mm

@@ -2321,7 +2321,7 @@ void DisplayServerMacOS::window_set_window_buttons_offset(const Vector2i &p_offs
 	WindowData &wd = windows[p_window];
 	WindowData &wd = windows[p_window];
 	float scale = screen_get_max_scale();
 	float scale = screen_get_max_scale();
 	wd.wb_offset = p_offset / scale;
 	wd.wb_offset = p_offset / scale;
-	wd.wb_offset = wd.wb_offset.max(Vector2i(12, 12));
+	wd.wb_offset = wd.wb_offset.maxi(12);
 	if (wd.window_button_view) {
 	if (wd.window_button_view) {
 		[wd.window_button_view setOffset:NSMakePoint(wd.wb_offset.x, wd.wb_offset.y)];
 		[wd.window_button_view setOffset:NSMakePoint(wd.wb_offset.x, wd.wb_offset.y)];
 	}
 	}

+ 1 - 1
scene/2d/parallax_2d.cpp

@@ -144,7 +144,7 @@ void Parallax2D::set_repeat_size(const Size2 &p_repeat_size) {
 		return;
 		return;
 	}
 	}
 
 
-	repeat_size = p_repeat_size.max(Vector2(0, 0));
+	repeat_size = p_repeat_size.maxf(0);
 
 
 	_update_process();
 	_update_process();
 	_update_repeat();
 	_update_repeat();

+ 1 - 1
scene/3d/decal.cpp

@@ -31,7 +31,7 @@
 #include "decal.h"
 #include "decal.h"
 
 
 void Decal::set_size(const Vector3 &p_size) {
 void Decal::set_size(const Vector3 &p_size) {
-	size = p_size.max(Vector3(0.001, 0.001, 0.001));
+	size = p_size.maxf(0.001);
 	RS::get_singleton()->decal_set_size(decal, size);
 	RS::get_singleton()->decal_set_size(decal, size);
 	update_gizmos();
 	update_gizmos();
 }
 }

+ 1 - 1
scene/3d/fog_volume.cpp

@@ -73,7 +73,7 @@ bool FogVolume::_get(const StringName &p_name, Variant &r_property) const {
 
 
 void FogVolume::set_size(const Vector3 &p_size) {
 void FogVolume::set_size(const Vector3 &p_size) {
 	size = p_size;
 	size = p_size;
-	size = size.max(Vector3());
+	size = size.maxf(0);
 	RS::get_singleton()->fog_volume_set_size(_get_volume(), size);
 	RS::get_singleton()->fog_volume_set_size(_get_volume(), size);
 	update_gizmos();
 	update_gizmos();
 }
 }

+ 2 - 2
scene/3d/gpu_particles_collision_3d.cpp

@@ -382,7 +382,7 @@ Vector3i GPUParticlesCollisionSDF3D::get_estimated_cell_size() const {
 	float cell_size = aabb.get_longest_axis_size() / float(subdiv);
 	float cell_size = aabb.get_longest_axis_size() / float(subdiv);
 
 
 	Vector3i sdf_size = Vector3i(aabb.size / cell_size);
 	Vector3i sdf_size = Vector3i(aabb.size / cell_size);
-	sdf_size = sdf_size.max(Vector3i(1, 1, 1));
+	sdf_size = sdf_size.maxi(1);
 	return sdf_size;
 	return sdf_size;
 }
 }
 
 
@@ -395,7 +395,7 @@ Ref<Image> GPUParticlesCollisionSDF3D::bake() {
 	float cell_size = aabb.get_longest_axis_size() / float(subdiv);
 	float cell_size = aabb.get_longest_axis_size() / float(subdiv);
 
 
 	Vector3i sdf_size = Vector3i(aabb.size / cell_size);
 	Vector3i sdf_size = Vector3i(aabb.size / cell_size);
-	sdf_size = sdf_size.max(Vector3i(1, 1, 1));
+	sdf_size = sdf_size.maxi(1);
 
 
 	if (bake_begin_function) {
 	if (bake_begin_function) {
 		bake_begin_function(100);
 		bake_begin_function(100);

+ 2 - 2
scene/3d/occluder_instance_3d.cpp

@@ -192,7 +192,7 @@ void QuadOccluder3D::set_size(const Size2 &p_size) {
 		return;
 		return;
 	}
 	}
 
 
-	size = p_size.max(Size2());
+	size = p_size.maxf(0);
 	_update();
 	_update();
 }
 }
 
 
@@ -236,7 +236,7 @@ void BoxOccluder3D::set_size(const Vector3 &p_size) {
 		return;
 		return;
 	}
 	}
 
 
-	size = p_size.max(Vector3());
+	size = p_size.maxf(0);
 	_update();
 	_update();
 }
 }
 
 

+ 1 - 1
scene/3d/voxel_gi.cpp

@@ -294,7 +294,7 @@ VoxelGI::Subdiv VoxelGI::get_subdiv() const {
 
 
 void VoxelGI::set_size(const Vector3 &p_size) {
 void VoxelGI::set_size(const Vector3 &p_size) {
 	// Prevent very small size dimensions as these breaks baking if other size dimensions are set very high.
 	// Prevent very small size dimensions as these breaks baking if other size dimensions are set very high.
-	size = p_size.max(Vector3(1.0, 1.0, 1.0));
+	size = p_size.maxf(1.0);
 	update_gizmos();
 	update_gizmos();
 }
 }
 
 

+ 2 - 2
scene/gui/control.cpp

@@ -142,8 +142,8 @@ Size2 Control::_edit_get_scale() const {
 
 
 void Control::_edit_set_rect(const Rect2 &p_edit_rect) {
 void Control::_edit_set_rect(const Rect2 &p_edit_rect) {
 	ERR_FAIL_COND_MSG(!Engine::get_singleton()->is_editor_hint(), "This function can only be used from editor plugins.");
 	ERR_FAIL_COND_MSG(!Engine::get_singleton()->is_editor_hint(), "This function can only be used from editor plugins.");
-	set_position((get_position() + get_transform().basis_xform(p_edit_rect.position)).snapped(Vector2(1, 1)), ControlEditorToolbar::get_singleton()->is_anchors_mode_enabled());
-	set_size(p_edit_rect.size.snapped(Vector2(1, 1)), ControlEditorToolbar::get_singleton()->is_anchors_mode_enabled());
+	set_position((get_position() + get_transform().basis_xform(p_edit_rect.position)).snappedf(1), ControlEditorToolbar::get_singleton()->is_anchors_mode_enabled());
+	set_size(p_edit_rect.size.snappedf(1), ControlEditorToolbar::get_singleton()->is_anchors_mode_enabled());
 }
 }
 
 
 Rect2 Control::_edit_get_rect() const {
 Rect2 Control::_edit_get_rect() const {

+ 3 - 3
scene/gui/graph_edit.cpp

@@ -501,7 +501,7 @@ void GraphEdit::_graph_element_resize_request(const Vector2 &p_new_minsize, Node
 	// Snap the new size to the grid if snapping is enabled.
 	// Snap the new size to the grid if snapping is enabled.
 	Vector2 new_size = p_new_minsize;
 	Vector2 new_size = p_new_minsize;
 	if (snapping_enabled ^ Input::get_singleton()->is_key_pressed(Key::CTRL)) {
 	if (snapping_enabled ^ Input::get_singleton()->is_key_pressed(Key::CTRL)) {
-		new_size = new_size.snapped(Vector2(snapping_distance, snapping_distance));
+		new_size = new_size.snappedf(snapping_distance);
 	}
 	}
 
 
 	// Disallow resizing the frame to a size smaller than the minimum size of the attached nodes.
 	// Disallow resizing the frame to a size smaller than the minimum size of the attached nodes.
@@ -851,7 +851,7 @@ void GraphEdit::_set_position_of_frame_attached_nodes(GraphFrame *p_frame, const
 
 
 		Vector2 pos = (attached_node->get_drag_from() * zoom + drag_accum) / zoom;
 		Vector2 pos = (attached_node->get_drag_from() * zoom + drag_accum) / zoom;
 		if (snapping_enabled ^ Input::get_singleton()->is_key_pressed(Key::CTRL)) {
 		if (snapping_enabled ^ Input::get_singleton()->is_key_pressed(Key::CTRL)) {
-			pos = pos.snapped(Vector2(snapping_distance, snapping_distance));
+			pos = pos.snappedf(snapping_distance);
 		}
 		}
 
 
 		// Recursively move graph frames.
 		// Recursively move graph frames.
@@ -1678,7 +1678,7 @@ void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
 				// Snapping can be toggled temporarily by holding down Ctrl.
 				// Snapping can be toggled temporarily by holding down Ctrl.
 				// This is done here as to not toggle the grid when holding down Ctrl.
 				// This is done here as to not toggle the grid when holding down Ctrl.
 				if (snapping_enabled ^ Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL)) {
 				if (snapping_enabled ^ Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL)) {
-					pos = pos.snapped(Vector2(snapping_distance, snapping_distance));
+					pos = pos.snappedf(snapping_distance);
 				}
 				}
 
 
 				graph_element->set_position_offset(pos);
 				graph_element->set_position_offset(pos);

+ 1 - 1
scene/gui/graph_edit_arranger.cpp

@@ -180,7 +180,7 @@ void GraphEditArranger::arrange_nodes() {
 
 
 		if (graph_edit->is_snapping_enabled()) {
 		if (graph_edit->is_snapping_enabled()) {
 			float snapping_distance = graph_edit->get_snapping_distance();
 			float snapping_distance = graph_edit->get_snapping_distance();
-			pos = pos.snapped(Vector2(snapping_distance, snapping_distance));
+			pos = pos.snappedf(snapping_distance);
 		}
 		}
 		graph_node->set_position_offset(pos);
 		graph_node->set_position_offset(pos);
 		graph_node->set_drag(false);
 		graph_node->set_drag(false);

+ 1 - 1
scene/gui/progress_bar.cpp

@@ -41,7 +41,7 @@ Size2 ProgressBar::get_minimum_size() const {
 		TextLine tl = TextLine(txt, theme_cache.font, theme_cache.font_size);
 		TextLine tl = TextLine(txt, theme_cache.font, theme_cache.font_size);
 		minimum_size.height = MAX(minimum_size.height, theme_cache.background_style->get_minimum_size().height + tl.get_size().y);
 		minimum_size.height = MAX(minimum_size.height, theme_cache.background_style->get_minimum_size().height + tl.get_size().y);
 	} else { // this is needed, else the progressbar will collapse
 	} else { // this is needed, else the progressbar will collapse
-		minimum_size = minimum_size.max(Size2(1, 1));
+		minimum_size = minimum_size.maxf(1);
 	}
 	}
 	return minimum_size;
 	return minimum_size;
 }
 }

+ 1 - 1
scene/gui/texture_button.cpp

@@ -103,7 +103,7 @@ bool TextureButton::has_point(const Point2 &p_point) const {
 			point *= scale;
 			point *= scale;
 
 
 			// finally, we need to check if the point is inside a rectangle with a position >= 0,0 and a size <= mask_size
 			// finally, we need to check if the point is inside a rectangle with a position >= 0,0 and a size <= mask_size
-			rect.position = Point2().max(_texture_region.position);
+			rect.position = _texture_region.position.maxf(0);
 			rect.size = mask_size.min(_texture_region.size);
 			rect.size = mask_size.min(_texture_region.size);
 		}
 		}
 
 

+ 1 - 1
scene/gui/texture_progress_bar.cpp

@@ -249,7 +249,7 @@ Point2 TextureProgressBar::get_relative_center() {
 	p += rad_center_off;
 	p += rad_center_off;
 	p.x /= progress->get_width();
 	p.x /= progress->get_width();
 	p.y /= progress->get_height();
 	p.y /= progress->get_height();
-	p = p.clamp(Point2(), Point2(1, 1));
+	p = p.clampf(0, 1);
 	return p;
 	return p;
 }
 }
 
 

+ 1 - 1
scene/gui/tree.cpp

@@ -3429,7 +3429,7 @@ Rect2 Tree::_get_content_rect() const {
 	const real_t v_size = v_scroll->is_visible() ? (v_scroll->get_combined_minimum_size().x + theme_cache.scrollbar_h_separation) : 0;
 	const real_t v_size = v_scroll->is_visible() ? (v_scroll->get_combined_minimum_size().x + theme_cache.scrollbar_h_separation) : 0;
 	const real_t h_size = h_scroll->is_visible() ? (h_scroll->get_combined_minimum_size().y + theme_cache.scrollbar_v_separation) : 0;
 	const real_t h_size = h_scroll->is_visible() ? (h_scroll->get_combined_minimum_size().y + theme_cache.scrollbar_v_separation) : 0;
 	const Point2 scroll_begin = _get_scrollbar_layout_rect().get_end() - Vector2(v_size, h_size);
 	const Point2 scroll_begin = _get_scrollbar_layout_rect().get_end() - Vector2(v_size, h_size);
-	const Size2 offset = (content_rect.get_end() - scroll_begin).max(Vector2(0, 0));
+	const Size2 offset = (content_rect.get_end() - scroll_begin).maxf(0);
 
 
 	return content_rect.grow_individual(0, 0, -offset.x, -offset.y);
 	return content_rect.grow_individual(0, 0, -offset.x, -offset.y);
 }
 }

+ 3 - 3
scene/main/viewport.cpp

@@ -983,7 +983,7 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override,
 		stretch_transform_new.scale(scale);
 		stretch_transform_new.scale(scale);
 	}
 	}
 
 
-	Size2i new_size = p_size.max(Size2i(2, 2));
+	Size2i new_size = p_size.maxi(2);
 	if (size == new_size && size_allocated == p_allocated && stretch_transform == stretch_transform_new && p_size_2d_override == size_2d_override) {
 	if (size == new_size && size_allocated == p_allocated && stretch_transform == stretch_transform_new && p_size_2d_override == size_2d_override) {
 		return;
 		return;
 	}
 	}
@@ -2767,7 +2767,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
 				Size2i min_size = gui.currently_dragged_subwindow->get_min_size();
 				Size2i min_size = gui.currently_dragged_subwindow->get_min_size();
 				Size2i min_size_clamped = gui.currently_dragged_subwindow->get_clamped_minimum_size();
 				Size2i min_size_clamped = gui.currently_dragged_subwindow->get_clamped_minimum_size();
 
 
-				min_size_clamped = min_size_clamped.max(Size2i(1, 1));
+				min_size_clamped = min_size_clamped.maxi(1);
 
 
 				Rect2i r = gui.subwindow_resize_from_rect;
 				Rect2i r = gui.subwindow_resize_from_rect;
 
 
@@ -2828,7 +2828,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
 
 
 				Size2i max_size = gui.currently_dragged_subwindow->get_max_size();
 				Size2i max_size = gui.currently_dragged_subwindow->get_max_size();
 				if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) {
 				if ((max_size.x > 0 || max_size.y > 0) && (max_size.x >= min_size.x && max_size.y >= min_size.y)) {
-					max_size = max_size.max(Size2i(1, 1));
+					max_size = max_size.maxi(1);
 
 
 					if (r.size.x > max_size.x) {
 					if (r.size.x > max_size.x) {
 						r.size.x = max_size.x;
 						r.size.x = max_size.x;

+ 2 - 2
scene/main/window.cpp

@@ -415,7 +415,7 @@ Size2i Window::_clamp_limit_size(const Size2i &p_limit_size) {
 	if (max_window_size != Size2i()) {
 	if (max_window_size != Size2i()) {
 		return p_limit_size.clamp(Vector2i(), max_window_size);
 		return p_limit_size.clamp(Vector2i(), max_window_size);
 	} else {
 	} else {
-		return p_limit_size.max(Vector2i());
+		return p_limit_size.maxi(0);
 	}
 	}
 }
 }
 
 
@@ -1036,7 +1036,7 @@ void Window::_update_window_size() {
 	}
 	}
 
 
 	if (embedder) {
 	if (embedder) {
-		size = size.max(Size2i(1, 1));
+		size = size.maxi(1);
 
 
 		embedder->_sub_window_update(this);
 		embedder->_sub_window_update(this);
 	} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
 	} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {

+ 3 - 3
scene/resources/2d/tile_set.cpp

@@ -4650,7 +4650,7 @@ Ref<Texture2D> TileSetAtlasSource::get_texture() const {
 void TileSetAtlasSource::set_margins(Vector2i p_margins) {
 void TileSetAtlasSource::set_margins(Vector2i p_margins) {
 	if (p_margins.x < 0 || p_margins.y < 0) {
 	if (p_margins.x < 0 || p_margins.y < 0) {
 		WARN_PRINT("Atlas source margins should be positive.");
 		WARN_PRINT("Atlas source margins should be positive.");
-		margins = p_margins.max(Vector2i());
+		margins = p_margins.maxi(0);
 	} else {
 	} else {
 		margins = p_margins;
 		margins = p_margins;
 	}
 	}
@@ -4666,7 +4666,7 @@ Vector2i TileSetAtlasSource::get_margins() const {
 void TileSetAtlasSource::set_separation(Vector2i p_separation) {
 void TileSetAtlasSource::set_separation(Vector2i p_separation) {
 	if (p_separation.x < 0 || p_separation.y < 0) {
 	if (p_separation.x < 0 || p_separation.y < 0) {
 		WARN_PRINT("Atlas source separation should be positive.");
 		WARN_PRINT("Atlas source separation should be positive.");
-		separation = p_separation.max(Vector2i());
+		separation = p_separation.maxi(0);
 	} else {
 	} else {
 		separation = p_separation;
 		separation = p_separation;
 	}
 	}
@@ -4682,7 +4682,7 @@ Vector2i TileSetAtlasSource::get_separation() const {
 void TileSetAtlasSource::set_texture_region_size(Vector2i p_tile_size) {
 void TileSetAtlasSource::set_texture_region_size(Vector2i p_tile_size) {
 	if (p_tile_size.x <= 0 || p_tile_size.y <= 0) {
 	if (p_tile_size.x <= 0 || p_tile_size.y <= 0) {
 		WARN_PRINT("Atlas source tile_size should be strictly positive.");
 		WARN_PRINT("Atlas source tile_size should be strictly positive.");
-		texture_region_size = p_tile_size.max(Vector2i(1, 1));
+		texture_region_size = p_tile_size.maxi(1);
 	} else {
 	} else {
 		texture_region_size = p_tile_size;
 		texture_region_size = p_tile_size;
 	}
 	}

+ 1 - 2
servers/rendering/renderer_rd/effects/ss_effects.cpp

@@ -521,8 +521,7 @@ void SSEffects::downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uin
 	RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant));
 	RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant));
 
 
 	if (use_half_size) {
 	if (use_half_size) {
-		size.x = MAX(1, size.x >> 1);
-		size.y = MAX(1, size.y >> 1);
+		size = Size2i(size.x >> 1, size.y >> 1).maxi(1);
 	}
 	}
 
 
 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);

+ 2 - 2
servers/rendering/renderer_rd/environment/fog.cpp

@@ -541,7 +541,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 		if (p_cam_projection.is_orthogonal()) {
 		if (p_cam_projection.is_orthogonal()) {
 			fog_near_size = fog_far_size;
 			fog_near_size = fog_far_size;
 		} else {
 		} else {
-			fog_near_size = frustum_near_size.max(Vector2(0.001, 0.001));
+			fog_near_size = frustum_near_size.maxf(0.001);
 		}
 		}
 
 
 		params.fog_frustum_size_begin[0] = fog_near_size.x;
 		params.fog_frustum_size_begin[0] = fog_near_size.x;
@@ -1001,7 +1001,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 	if (p_cam_projection.is_orthogonal()) {
 	if (p_cam_projection.is_orthogonal()) {
 		fog_near_size = fog_far_size;
 		fog_near_size = fog_far_size;
 	} else {
 	} else {
-		fog_near_size = frustum_near_size.max(Vector2(0.001, 0.001));
+		fog_near_size = frustum_near_size.maxf(0.001);
 	}
 	}
 
 
 	params.fog_frustum_size_begin[0] = fog_near_size.x;
 	params.fog_frustum_size_begin[0] = fog_near_size.x;

+ 1 - 2
servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp

@@ -83,8 +83,7 @@ void RenderSceneBuffersRD::update_sizes(NamedTexture &p_named_texture) {
 	for (uint32_t mipmap = 0; mipmap < p_named_texture.format.mipmaps; mipmap++) {
 	for (uint32_t mipmap = 0; mipmap < p_named_texture.format.mipmaps; mipmap++) {
 		p_named_texture.sizes.ptrw()[mipmap] = mipmap_size;
 		p_named_texture.sizes.ptrw()[mipmap] = mipmap_size;
 
 
-		mipmap_size.width = MAX(1, mipmap_size.width >> 1);
-		mipmap_size.height = MAX(1, mipmap_size.height >> 1);
+		mipmap_size = Size2i(mipmap_size.width >> 1, mipmap_size.height >> 1).maxi(1);
 	}
 	}
 }
 }
 
 

+ 6 - 11
servers/rendering/renderer_rd/storage_rd/texture_storage.cpp

@@ -2681,8 +2681,7 @@ void TextureStorage::update_decal_atlas() {
 			mm.size = s;
 			mm.size = s;
 			decal_atlas.texture_mipmaps.push_back(mm);
 			decal_atlas.texture_mipmaps.push_back(mm);
 
 
-			s.width = MAX(1, s.width >> 1);
-			s.height = MAX(1, s.height >> 1);
+			s = Vector2i(s.width >> 1, s.height >> 1).maxi(1);
 		}
 		}
 		{
 		{
 			//create the SRGB variant
 			//create the SRGB variant
@@ -3637,7 +3636,7 @@ void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
 	}
 	}
 
 
 	rt->process_size = size * scale / 100;
 	rt->process_size = size * scale / 100;
-	rt->process_size = rt->process_size.max(Size2i(1, 1));
+	rt->process_size = rt->process_size.maxi(1);
 
 
 	tformat.format = RD::DATA_FORMAT_R16G16_SINT;
 	tformat.format = RD::DATA_FORMAT_R16G16_SINT;
 	tformat.width = rt->process_size.width;
 	tformat.width = rt->process_size.width;
@@ -3838,10 +3837,8 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons
 	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
 	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
 		region.position.x >>= 1;
 		region.position.x >>= 1;
 		region.position.y >>= 1;
 		region.position.y >>= 1;
-		region.size.x = MAX(1, region.size.x >> 1);
-		region.size.y = MAX(1, region.size.y >> 1);
-		texture_size.x = MAX(1, texture_size.x >> 1);
-		texture_size.y = MAX(1, texture_size.y >> 1);
+		region.size = Size2i(region.size.x >> 1, region.size.y >> 1).maxi(1);
+		texture_size = Size2i(texture_size.x >> 1, texture_size.y >> 1).maxi(1);
 
 
 		RID mipmap = rt->backbuffer_mipmaps[i];
 		RID mipmap = rt->backbuffer_mipmaps[i];
 		if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
 		if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
@@ -3911,10 +3908,8 @@ void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target,
 	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
 	for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
 		region.position.x >>= 1;
 		region.position.x >>= 1;
 		region.position.y >>= 1;
 		region.position.y >>= 1;
-		region.size.x = MAX(1, region.size.x >> 1);
-		region.size.y = MAX(1, region.size.y >> 1);
-		texture_size.x = MAX(1, texture_size.x >> 1);
-		texture_size.y = MAX(1, texture_size.y >> 1);
+		region.size = Size2i(region.size.x >> 1, region.size.y >> 1).maxi(1);
+		texture_size = Size2i(texture_size.x >> 1, texture_size.y >> 1).maxi(1);
 
 
 		RID mipmap = rt->backbuffer_mipmaps[i];
 		RID mipmap = rt->backbuffer_mipmaps[i];
 
 

+ 2 - 2
servers/rendering/renderer_scene_occlusion_cull.h

@@ -98,8 +98,8 @@ public:
 				rect_max = rect_max.max(normalized);
 				rect_max = rect_max.max(normalized);
 			}
 			}
 
 
-			rect_max = rect_max.min(Vector2(1, 1));
-			rect_min = rect_min.max(Vector2(0, 0));
+			rect_max = rect_max.minf(1);
+			rect_min = rect_min.maxf(0);
 
 
 			int mip_count = mips.size();
 			int mip_count = mips.size();