Browse Source

Added signed_angle_to for Vector3

JestemStefan 4 years ago
parent
commit
2c71ff1119

+ 8 - 0
core/math/vector3.h

@@ -110,6 +110,7 @@ struct Vector3 {
 	_FORCE_INLINE_ Vector3 project(const Vector3 &p_to) const;
 
 	_FORCE_INLINE_ real_t angle_to(const Vector3 &p_to) const;
+	_FORCE_INLINE_ real_t signed_angle_to(const Vector3 &p_to, const Vector3 &p_axis) const;
 	_FORCE_INLINE_ Vector3 direction_to(const Vector3 &p_to) const;
 
 	_FORCE_INLINE_ Vector3 slide(const Vector3 &p_normal) const;
@@ -230,6 +231,13 @@ real_t Vector3::angle_to(const Vector3 &p_to) const {
 	return Math::atan2(cross(p_to).length(), dot(p_to));
 }
 
+real_t Vector3::signed_angle_to(const Vector3 &p_to, const Vector3 &p_axis) const {
+	Vector3 cross_to = cross(p_to);
+	real_t unsigned_angle = Math::atan2(cross_to.length(), dot(p_to));
+	real_t sign = cross_to.dot(p_axis);
+	return (sign < 0) ? -unsigned_angle : unsigned_angle;
+}
+
 Vector3 Vector3::direction_to(const Vector3 &p_to) const {
 	Vector3 ret(p_to.x - x, p_to.y - y, p_to.z - z);
 	ret.normalize();

+ 1 - 0
core/variant/variant_call.cpp

@@ -1059,6 +1059,7 @@ static void _register_variant_builtin_methods() {
 	bind_method(Vector3, min_axis, sarray(), varray());
 	bind_method(Vector3, max_axis, sarray(), varray());
 	bind_method(Vector3, angle_to, sarray("to"), varray());
+	bind_method(Vector3, signed_angle_to, sarray("to", "axis"), varray());
 	bind_method(Vector3, direction_to, sarray("b"), varray());
 	bind_method(Vector3, distance_to, sarray("b"), varray());
 	bind_method(Vector3, distance_squared_to, sarray("b"), varray());

+ 12 - 1
doc/classes/Vector3.xml

@@ -68,7 +68,7 @@
 			<argument index="0" name="to" type="Vector3">
 			</argument>
 			<description>
-				Returns the minimum angle to the given vector, in radians.
+				Returns the unsigned minimum angle to the given vector, in radians.
 			</description>
 		</method>
 		<method name="bounce">
@@ -465,6 +465,17 @@
 				Returns a vector with each component set to one or negative one, depending on the signs of this vector's components, or zero if the component is zero, by calling [method @GlobalScope.sign] on each component.
 			</description>
 		</method>
+		<method name="signed_angle_to">
+			<return type="float">
+			</return>
+			<argument index="0" name="to" type="Vector3">
+			</argument>
+			<argument index="1" name="axis" type="Vector3">
+			</argument>
+			<description>
+				Returns the signed angle to the given vector, in radians. The sign of the angle is positive in a counter-clockwise direction and negative in a clockwise direction when viewed from the side specified by the [code]axis[/code].
+			</description>
+		</method>
 		<method name="slerp">
 			<return type="Vector3">
 			</return>

+ 19 - 2
modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs

@@ -111,10 +111,10 @@ namespace Godot
         }
 
         /// <summary>
-        /// Returns the minimum angle to the given vector, in radians.
+        /// Returns the unsigned minimum angle to the given vector, in radians.
         /// </summary>
         /// <param name="to">The other vector to compare this vector to.</param>
-        /// <returns>The angle between the two vectors, in radians.</returns>
+        /// <returns>The unsigned angle between the two vectors, in radians.</returns>
         public real_t AngleTo(Vector3 to)
         {
             return Mathf.Atan2(Cross(to).Length(), Dot(to));
@@ -468,6 +468,23 @@ namespace Godot
             return v;
         }
 
+        /// <summary>
+        /// Returns the signed angle to the given vector, in radians.
+        /// The sign of the angle is positive in a counter-clockwise
+        /// direction and negative in a clockwise direction when viewed
+        /// from the side specified by the `axis`.
+        /// </summary>
+        /// <param name="to">The other vector to compare this vector to.</param>
+        /// <param name="axis">The reference axis to use for the angle sign.</param>
+        /// <returns>The signed angle between the two vectors, in radians.</returns>
+        public real_t SignedAngleTo(Vector3 to, Vector3 axis)
+        {
+            Vector3 crossTo = Cross(to);
+            real_t unsignedAngle = Mathf.Atan2(crossTo.Length(), Dot(to));
+            real_t sign = crossTo.Dot(axis);
+            return (sign < 0) ? -unsignedAngle : unsignedAngle;
+        }
+
         /// <summary>
         /// Returns the result of the spherical linear interpolation between
         /// this vector and `to` by amount `weight`.