2
0
Эх сурвалжийг харах

Merge pull request #31094 from aaronfranke/vector-sign-mod-etc

Add Vector2/3 sign and posmod functions, axis, docs, misc additions
Rémi Verschelde 6 жил өмнө
parent
commit
51d50e167d

+ 13 - 0
core/math/vector2.cpp

@@ -98,6 +98,11 @@ real_t Vector2::cross(const Vector2 &p_other) const {
 	return x * p_other.y - y * p_other.x;
 }
 
+Vector2 Vector2::sign() const {
+
+	return Vector2(SGN(x), SGN(y));
+}
+
 Vector2 Vector2::floor() const {
 
 	return Vector2(Math::floor(x), Math::floor(y));
@@ -121,6 +126,14 @@ Vector2 Vector2::rotated(real_t p_by) const {
 	return v;
 }
 
+Vector2 Vector2::posmod(const real_t p_mod) const {
+	return Vector2(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod));
+}
+
+Vector2 Vector2::posmodv(const Vector2 &p_modv) const {
+	return Vector2(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y));
+}
+
 Vector2 Vector2::project(const Vector2 &p_b) const {
 	return p_b * (dot(p_b) / p_b.length_squared());
 }

+ 18 - 6
core/math/vector2.h

@@ -38,6 +38,11 @@ struct Vector2i;
 
 struct Vector2 {
 
+	enum Axis {
+		AXIS_X,
+		AXIS_Y,
+	};
+
 	union {
 		real_t x;
 		real_t width;
@@ -69,6 +74,8 @@ struct Vector2 {
 
 	real_t dot(const Vector2 &p_other) const;
 	real_t cross(const Vector2 &p_other) const;
+	Vector2 posmod(const real_t p_mod) const;
+	Vector2 posmodv(const Vector2 &p_modv) const;
 	Vector2 project(const Vector2 &p_b) const;
 
 	Vector2 plane_project(real_t p_d, const Vector2 &p_vec) const;
@@ -107,8 +114,10 @@ struct Vector2 {
 	bool operator==(const Vector2 &p_vec2) const;
 	bool operator!=(const Vector2 &p_vec2) const;
 
-	bool operator<(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y < p_vec2.y) : (x < p_vec2.x); }
-	bool operator<=(const Vector2 &p_vec2) const { return (Math::is_equal_approx(x, p_vec2.x)) ? (y <= p_vec2.y) : (x < p_vec2.x); }
+	bool operator<(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y < p_vec2.y) : (x < p_vec2.x); }
+	bool operator>(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y > p_vec2.y) : (x > p_vec2.x); }
+	bool operator<=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y <= p_vec2.y) : (x < p_vec2.x); }
+	bool operator>=(const Vector2 &p_vec2) const { return Math::is_equal_approx(x, p_vec2.x) ? (y >= p_vec2.y) : (x > p_vec2.x); }
 
 	real_t angle() const;
 
@@ -129,6 +138,7 @@ struct Vector2 {
 		return Vector2(y, -x);
 	}
 
+	Vector2 sign() const;
 	Vector2 floor() const;
 	Vector2 ceil() const;
 	Vector2 round() const;
@@ -141,10 +151,7 @@ struct Vector2 {
 		x = p_x;
 		y = p_y;
 	}
-	_FORCE_INLINE_ Vector2() {
-		x = 0;
-		y = 0;
-	}
+	_FORCE_INLINE_ Vector2() { x = y = 0; }
 };
 
 _FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2 &p_vec) const {
@@ -262,6 +269,11 @@ typedef Vector2 Point2;
 
 struct Vector2i {
 
+	enum Axis {
+		AXIS_X,
+		AXIS_Y,
+	};
+
 	union {
 		int x;
 		int width;

+ 37 - 3
core/math/vector3.h

@@ -31,9 +31,7 @@
 #ifndef VECTOR3_H
 #define VECTOR3_H
 
-#include "core/math/math_defs.h"
 #include "core/math/math_funcs.h"
-#include "core/typedefs.h"
 #include "core/ustring.h"
 
 class Basis;
@@ -110,6 +108,8 @@ struct Vector3 {
 	_FORCE_INLINE_ real_t distance_to(const Vector3 &p_b) const;
 	_FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_b) const;
 
+	_FORCE_INLINE_ Vector3 posmod(const real_t p_mod) const;
+	_FORCE_INLINE_ Vector3 posmodv(const Vector3 &p_modv) const;
 	_FORCE_INLINE_ Vector3 project(const Vector3 &p_b) const;
 
 	_FORCE_INLINE_ real_t angle_to(const Vector3 &p_b) const;
@@ -141,15 +141,17 @@ struct Vector3 {
 	_FORCE_INLINE_ bool operator!=(const Vector3 &p_v) const;
 	_FORCE_INLINE_ bool operator<(const Vector3 &p_v) const;
 	_FORCE_INLINE_ bool operator<=(const Vector3 &p_v) const;
+	_FORCE_INLINE_ bool operator>(const Vector3 &p_v) const;
+	_FORCE_INLINE_ bool operator>=(const Vector3 &p_v) const;
 
 	operator String() const;
 
-	_FORCE_INLINE_ Vector3() { x = y = z = 0; }
 	_FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) {
 		x = p_x;
 		y = p_y;
 		z = p_z;
 	}
+	_FORCE_INLINE_ Vector3() { x = y = z = 0; }
 };
 
 // Should be included after class definition, otherwise we get circular refs
@@ -233,6 +235,14 @@ real_t Vector3::distance_squared_to(const Vector3 &p_b) const {
 	return (p_b - *this).length_squared();
 }
 
+Vector3 Vector3::posmod(const real_t p_mod) const {
+	return Vector3(Math::fposmod(x, p_mod), Math::fposmod(y, p_mod), Math::fposmod(z, p_mod));
+}
+
+Vector3 Vector3::posmodv(const Vector3 &p_modv) const {
+	return Vector3(Math::fposmod(x, p_modv.x), Math::fposmod(y, p_modv.y), Math::fposmod(z, p_modv.z));
+}
+
 Vector3 Vector3::project(const Vector3 &p_b) const {
 	return p_b * (dot(p_b) / p_b.length_squared());
 }
@@ -357,6 +367,18 @@ bool Vector3::operator<(const Vector3 &p_v) const {
 	}
 }
 
+bool Vector3::operator>(const Vector3 &p_v) const {
+
+	if (x == p_v.x) {
+		if (y == p_v.y)
+			return z > p_v.z;
+		else
+			return y > p_v.y;
+	} else {
+		return x > p_v.x;
+	}
+}
+
 bool Vector3::operator<=(const Vector3 &p_v) const {
 
 	if (Math::is_equal_approx(x, p_v.x)) {
@@ -369,6 +391,18 @@ bool Vector3::operator<=(const Vector3 &p_v) const {
 	}
 }
 
+bool Vector3::operator>=(const Vector3 &p_v) const {
+
+	if (x == p_v.x) {
+		if (y == p_v.y)
+			return z >= p_v.z;
+		else
+			return y > p_v.y;
+	} else {
+		return x > p_v.x;
+	}
+}
+
 _FORCE_INLINE_ Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {
 
 	return p_a.cross(p_b);

+ 15 - 0
core/variant_call.cpp

@@ -347,6 +347,8 @@ struct _VariantCall {
 	VCALL_LOCALMEM0R(Vector2, is_normalized);
 	VCALL_LOCALMEM1R(Vector2, distance_to);
 	VCALL_LOCALMEM1R(Vector2, distance_squared_to);
+	VCALL_LOCALMEM1R(Vector2, posmod);
+	VCALL_LOCALMEM1R(Vector2, posmodv);
 	VCALL_LOCALMEM1R(Vector2, project);
 	VCALL_LOCALMEM1R(Vector2, angle_to);
 	VCALL_LOCALMEM1R(Vector2, angle_to_point);
@@ -370,6 +372,7 @@ struct _VariantCall {
 	VCALL_LOCALMEM1R(Vector2, cross);
 	VCALL_LOCALMEM0R(Vector2, abs);
 	VCALL_LOCALMEM1R(Vector2, clamped);
+	VCALL_LOCALMEM0R(Vector2, sign);
 
 	VCALL_LOCALMEM0R(Rect2, get_area);
 	VCALL_LOCALMEM1R(Rect2, intersects);
@@ -407,12 +410,15 @@ struct _VariantCall {
 	VCALL_LOCALMEM0R(Vector3, round);
 	VCALL_LOCALMEM1R(Vector3, distance_to);
 	VCALL_LOCALMEM1R(Vector3, distance_squared_to);
+	VCALL_LOCALMEM1R(Vector3, posmod);
+	VCALL_LOCALMEM1R(Vector3, posmodv);
 	VCALL_LOCALMEM1R(Vector3, project);
 	VCALL_LOCALMEM1R(Vector3, angle_to);
 	VCALL_LOCALMEM1R(Vector3, direction_to);
 	VCALL_LOCALMEM1R(Vector3, slide);
 	VCALL_LOCALMEM1R(Vector3, bounce);
 	VCALL_LOCALMEM1R(Vector3, reflect);
+	VCALL_LOCALMEM0R(Vector3, sign);
 
 	VCALL_LOCALMEM0R(Plane, normalized);
 	VCALL_LOCALMEM0R(Plane, center);
@@ -1587,6 +1593,8 @@ void register_variant_methods() {
 	ADDFUNC1R(VECTOR2, VECTOR2, Vector2, direction_to, VECTOR2, "b", varray());
 	ADDFUNC1R(VECTOR2, REAL, Vector2, distance_to, VECTOR2, "to", varray());
 	ADDFUNC1R(VECTOR2, REAL, Vector2, distance_squared_to, VECTOR2, "to", varray());
+	ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmod, REAL, "mod", varray());
+	ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmodv, VECTOR2, "modv", varray());
 	ADDFUNC1R(VECTOR2, VECTOR2, Vector2, project, VECTOR2, "b", varray());
 	ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to, VECTOR2, "to", varray());
 	ADDFUNC1R(VECTOR2, REAL, Vector2, angle_to_point, VECTOR2, "to", varray());
@@ -1608,6 +1616,7 @@ void register_variant_methods() {
 	ADDFUNC1R(VECTOR2, REAL, Vector2, cross, VECTOR2, "with", varray());
 	ADDFUNC0R(VECTOR2, VECTOR2, Vector2, abs, varray());
 	ADDFUNC1R(VECTOR2, VECTOR2, Vector2, clamped, REAL, "length", varray());
+	ADDFUNC0R(VECTOR2, VECTOR2, Vector2, sign, varray());
 
 	ADDFUNC0R(RECT2, REAL, Rect2, get_area, varray());
 	ADDFUNC1R(RECT2, BOOL, Rect2, intersects, RECT2, "b", varray());
@@ -1646,11 +1655,14 @@ void register_variant_methods() {
 	ADDFUNC0R(VECTOR3, VECTOR3, Vector3, round, varray());
 	ADDFUNC1R(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
 	ADDFUNC1R(VECTOR3, REAL, Vector3, distance_squared_to, VECTOR3, "b", varray());
+	ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmod, REAL, "mod", varray());
+	ADDFUNC1R(VECTOR3, VECTOR3, Vector3, posmodv, VECTOR3, "modv", varray());
 	ADDFUNC1R(VECTOR3, VECTOR3, Vector3, project, VECTOR3, "b", varray());
 	ADDFUNC1R(VECTOR3, REAL, Vector3, angle_to, VECTOR3, "to", varray());
 	ADDFUNC1R(VECTOR3, VECTOR3, Vector3, slide, VECTOR3, "n", varray());
 	ADDFUNC1R(VECTOR3, VECTOR3, Vector3, bounce, VECTOR3, "n", varray());
 	ADDFUNC1R(VECTOR3, VECTOR3, Vector3, reflect, VECTOR3, "n", varray());
+	ADDFUNC0R(VECTOR3, VECTOR3, Vector3, sign, varray());
 
 	ADDFUNC0R(PLANE, PLANE, Plane, normalized, varray());
 	ADDFUNC0R(PLANE, VECTOR3, Plane, center, varray());
@@ -1943,6 +1955,9 @@ void register_variant_methods() {
 	_VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1));
 	_VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1));
 
+	_VariantCall::add_constant(Variant::VECTOR2, "AXIS_X", Vector2::AXIS_X);
+	_VariantCall::add_constant(Variant::VECTOR2, "AXIS_Y", Vector2::AXIS_Y);
+
 	_VariantCall::add_variant_constant(Variant::VECTOR2, "ZERO", Vector2(0, 0));
 	_VariantCall::add_variant_constant(Variant::VECTOR2, "ONE", Vector2(1, 1));
 	_VariantCall::add_variant_constant(Variant::VECTOR2, "INF", Vector2(Math_INF, Math_INF));

+ 32 - 1
doc/classes/Vector2.xml

@@ -203,6 +203,24 @@
 				Returns the vector scaled to unit length. Equivalent to [code]v / v.length()[/code].
 			</description>
 		</method>
+		<method name="posmod">
+			<return type="Vector2">
+			</return>
+			<argument index="0" name="mod" type="float">
+			</argument>
+			<description>
+				Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]mod[/code].
+			</description>
+		</method>
+		<method name="posmodv">
+			<return type="Vector2">
+			</return>
+			<argument index="0" name="mod" type="float">
+			</argument>
+			<description>
+				Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]modv[/code]'s components.
+			</description>
+		</method>
 		<method name="project">
 			<return type="Vector2">
 			</return>
@@ -237,6 +255,13 @@
 				Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
 			</description>
 		</method>
+		<method name="sign">
+			<return type="Vector2">
+			</return>
+			<description>
+				Returns the vector with each component set to one or negative one, depending on the signs of the components.
+			</description>
+		</method>
 		<method name="slerp">
 			<return type="Vector2">
 			</return>
@@ -284,6 +309,12 @@
 		</member>
 	</members>
 	<constants>
+		<constant name="AXIS_X" value="0">
+			Enumerated value for the X axis. Returned by [method max_axis] and [method min_axis].
+		</constant>
+		<constant name="AXIS_Y" value="1">
+			Enumerated value for the Y axis.
+		</constant>
 		<constant name="ZERO" value="Vector2( 0, 0 )">
 			Zero vector.
 		</constant>
@@ -291,7 +322,7 @@
 			One vector.
 		</constant>
 		<constant name="INF" value="Vector2( inf, inf )">
-			Infinite vector.
+			Infinity vector.
 		</constant>
 		<constant name="LEFT" value="Vector2( -1, 0 )">
 			Left unit vector.

+ 28 - 3
doc/classes/Vector3.xml

@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <class name="Vector3" category="Built-In Types" version="3.2">
 	<brief_description>
-		Vector class, which performs basic 3D vector math operations.
+		Vector used for 3D math.
 	</brief_description>
 	<description>
-		Vector3 is one of the core classes of the engine, and includes several built-in helper functions to perform basic vector math operations.
+		3-element structure that can be used to represent positions in 3D space or any other pair of numeric values.
 	</description>
 	<tutorials>
 		<link>https://docs.godotengine.org/en/latest/tutorials/math/index.html</link>
@@ -202,6 +202,24 @@
 				Returns the outer product with [code]b[/code].
 			</description>
 		</method>
+		<method name="posmod">
+			<return type="Vector3">
+			</return>
+			<argument index="0" name="mod" type="float">
+			</argument>
+			<description>
+				Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]mod[/code].
+			</description>
+		</method>
+		<method name="posmodv">
+			<return type="Vector3">
+			</return>
+			<argument index="0" name="mod" type="float">
+			</argument>
+			<description>
+				Returns a vector composed of the [code]fposmod[/code] of this vector's components and [code]modv[/code]'s components.
+			</description>
+		</method>
 		<method name="project">
 			<return type="Vector3">
 			</return>
@@ -238,6 +256,13 @@
 				Returns the vector with all components rounded to the nearest integer, with halfway cases rounded away from zero.
 			</description>
 		</method>
+		<method name="sign">
+			<return type="Vector3">
+			</return>
+			<description>
+				Returns the vector with each component set to one or negative one, depending on the signs of the components.
+			</description>
+		</method>
 		<method name="slerp">
 			<return type="Vector3">
 			</return>
@@ -304,7 +329,7 @@
 			One vector.
 		</constant>
 		<constant name="INF" value="Vector3( inf, inf, inf )">
-			Infinite vector.
+			Infinity vector.
 		</constant>
 		<constant name="LEFT" value="Vector3( -1, 0, 0 )">
 			Left unit vector.

+ 48 - 1
modules/mono/glue/Managed/Files/Vector2.cs

@@ -14,10 +14,19 @@ using real_t = System.Single;
 
 namespace Godot
 {
+    /// <summary>
+    /// 2-element structure that can be used to represent positions in 2D space or any other pair of numeric values.
+    /// </summary>
     [Serializable]
     [StructLayout(LayoutKind.Sequential)]
     public struct Vector2 : IEquatable<Vector2>
     {
+        public enum Axis
+        {
+            X = 0,
+            Y
+        }
+
         public real_t x;
         public real_t y;
 
@@ -202,6 +211,22 @@ namespace Godot
             return v;
         }
 
+        public Vector2 PosMod(real_t mod)
+        {
+            Vector2 v;
+            v.x = Mathf.PosMod(x, mod);
+            v.y = Mathf.PosMod(y, mod);
+            return v;
+        }
+
+        public Vector2 PosMod(Vector2 modv)
+        {
+            Vector2 v;
+            v.x = Mathf.PosMod(x, modv.x);
+            v.y = Mathf.PosMod(y, modv.y);
+            return v;
+        }
+
         public Vector2 Project(Vector2 onNormal)
         {
             return onNormal * (Dot(onNormal) / onNormal.LengthSquared());
@@ -236,6 +261,14 @@ namespace Godot
             y = v.y;
         }
 
+        public Vector2 Sign()
+        {
+            Vector2 v;
+            v.x = Mathf.Sign(x);
+            v.y = Mathf.Sign(y);
+            return v;
+        }
+
         public Vector2 Slerp(Vector2 b, real_t t)
         {
             real_t theta = AngleTo(b);
@@ -265,7 +298,7 @@ namespace Godot
 
         private static readonly Vector2 _up = new Vector2(0, -1);
         private static readonly Vector2 _down = new Vector2(0, 1);
-        private static readonly Vector2 _right  = new Vector2(1, 0);
+        private static readonly Vector2 _right = new Vector2(1, 0);
         private static readonly Vector2 _left = new Vector2(-1, 0);
 
         public static Vector2 Zero { get { return _zero; } }
@@ -346,6 +379,20 @@ namespace Godot
             return left;
         }
 
+        public static Vector2 operator %(Vector2 vec, real_t divisor)
+        {
+            vec.x %= divisor;
+            vec.y %= divisor;
+            return vec;
+        }
+
+        public static Vector2 operator %(Vector2 vec, Vector2 divisorv)
+        {
+            vec.x %= divisorv.x;
+            vec.y %= divisorv.y;
+            return vec;
+        }
+
         public static bool operator ==(Vector2 left, Vector2 right)
         {
             return left.Equals(right);

+ 46 - 0
modules/mono/glue/Managed/Files/Vector3.cs

@@ -14,6 +14,9 @@ using real_t = System.Single;
 
 namespace Godot
 {
+    /// <summary>
+    /// 3-element structure that can be used to represent positions in 3D space or any other pair of numeric values.
+    /// </summary>
     [Serializable]
     [StructLayout(LayoutKind.Sequential)]
     public struct Vector3 : IEquatable<Vector3>
@@ -225,6 +228,24 @@ namespace Godot
             );
         }
 
+        public Vector3 PosMod(real_t mod)
+        {
+            Vector3 v;
+            v.x = Mathf.PosMod(x, mod);
+            v.y = Mathf.PosMod(y, mod);
+            v.z = Mathf.PosMod(z, mod);
+            return v;
+        }
+
+        public Vector3 PosMod(Vector3 modv)
+        {
+            Vector3 v;
+            v.x = Mathf.PosMod(x, modv.x);
+            v.y = Mathf.PosMod(y, modv.y);
+            v.z = Mathf.PosMod(z, modv.z);
+            return v;
+        }
+
         public Vector3 Project(Vector3 onNormal)
         {
             return onNormal * (Dot(onNormal) / onNormal.LengthSquared());
@@ -264,6 +285,15 @@ namespace Godot
             z = v.z;
         }
 
+        public Vector3 Sign()
+        {
+            Vector3 v;
+            v.x = Mathf.Sign(x);
+            v.y = Mathf.Sign(y);
+            v.z = Mathf.Sign(z);
+            return v;
+        }
+
         public Vector3 Slerp(Vector3 b, real_t t)
         {
             real_t theta = AngleTo(b);
@@ -397,6 +427,22 @@ namespace Godot
             return left;
         }
 
+        public static Vector3 operator %(Vector3 vec, real_t divisor)
+        {
+            vec.x %= divisor;
+            vec.y %= divisor;
+            vec.z %= divisor;
+            return vec;
+        }
+
+        public static Vector3 operator %(Vector3 vec, Vector3 divisorv)
+        {
+            vec.x %= divisorv.x;
+            vec.y %= divisorv.y;
+            vec.z %= divisorv.z;
+            return vec;
+        }
+
         public static bool operator ==(Vector3 left, Vector3 right)
         {
             return left.Equals(right);