瀏覽代碼

[3.x] Add Quat angle_to method

Aaron Franke 4 年之前
父節點
當前提交
85a0345d57
共有 5 個文件被更改,包括 35 次插入0 次删除
  1. 5 0
      core/math/quat.cpp
  2. 1 0
      core/math/quat.h
  3. 2 0
      core/variant_call.cpp
  4. 10 0
      doc/classes/Quat.xml
  5. 17 0
      modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs

+ 5 - 0
core/math/quat.cpp

@@ -33,6 +33,11 @@
 #include "core/math/basis.h"
 #include "core/print_string.h"
 
+real_t Quat::angle_to(const Quat &p_to) const {
+	real_t d = dot(p_to);
+	return Math::acos(CLAMP(d * d * 2 - 1, -1, 1));
+}
+
 // set_euler_xyz expects a vector containing the Euler angles in the format
 // (ax,ay,az), where ax is the angle of rotation around x axis,
 // and similar for other axes.

+ 1 - 0
core/math/quat.h

@@ -48,6 +48,7 @@ public:
 	bool is_normalized() const;
 	Quat inverse() const;
 	_FORCE_INLINE_ real_t dot(const Quat &p_q) const;
+	real_t angle_to(const Quat &p_to) const;
 
 	void set_euler_xyz(const Vector3 &p_euler);
 	Vector3 get_euler_xyz() const;

+ 2 - 0
core/variant_call.cpp

@@ -497,6 +497,7 @@ struct _VariantCall {
 	VCALL_LOCALMEM0R(Quat, is_normalized);
 	VCALL_LOCALMEM1R(Quat, is_equal_approx);
 	VCALL_LOCALMEM0R(Quat, inverse);
+	VCALL_LOCALMEM1R(Quat, angle_to);
 	VCALL_LOCALMEM1R(Quat, dot);
 	VCALL_LOCALMEM1R(Quat, xform);
 	VCALL_LOCALMEM2R(Quat, slerp);
@@ -1816,6 +1817,7 @@ void register_variant_methods() {
 	ADDFUNC0R(QUAT, BOOL, Quat, is_normalized, varray());
 	ADDFUNC1R(QUAT, BOOL, Quat, is_equal_approx, QUAT, "quat", varray());
 	ADDFUNC0R(QUAT, QUAT, Quat, inverse, varray());
+	ADDFUNC1R(QUAT, REAL, Quat, angle_to, QUAT, "to", varray());
 	ADDFUNC1R(QUAT, REAL, Quat, dot, QUAT, "b", varray());
 	ADDFUNC1R(QUAT, VECTOR3, Quat, xform, VECTOR3, "v", varray());
 	ADDFUNC2R(QUAT, QUAT, Quat, slerp, QUAT, "to", REAL, "weight", varray());

+ 10 - 0
doc/classes/Quat.xml

@@ -57,6 +57,16 @@
 				Constructs a quaternion defined by the given values.
 			</description>
 		</method>
+		<method name="angle_to">
+			<return type="float">
+			</return>
+			<argument index="0" name="to" type="Quat">
+			</argument>
+			<description>
+				Returns the angle between this quaternion and [code]to[/code]. This is the magnitude of the angle you would need to rotate by to get from one to the other.
+				[b]Note:[/b] This method has an abnormally high amount of floating-point error, so methods such as [method @GDScript.is_zero_approx] will not work reliably.
+			</description>
+		</method>
 		<method name="cubic_slerp">
 			<return type="Quat">
 			</return>

+ 17 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/Quat.cs

@@ -113,6 +113,23 @@ namespace Godot
             get { return Dot(this); }
         }
 
+        /// <summary>
+        /// Returns the angle between this quaternion and `to`.
+        /// This is the magnitude of the angle you would need to rotate
+        /// by to get from one to the other.
+        ///
+        /// Note: This method has an abnormally high amount
+        /// of floating-point error, so methods such as
+        /// <see cref="Mathf.IsZeroApprox"/> will not work reliably.
+        /// </summary>
+        /// <param name="to">The other quaternion.</param>
+        /// <returns>The angle between the quaternions.</returns>
+        public real_t AngleTo(Quat to)
+        {
+            real_t dot = Dot(to);
+            return Mathf.Acos(Mathf.Clamp(dot * dot * 2 - 1, -1, 1));
+        }
+
         /// <summary>
         /// Performs a cubic spherical interpolation between quaternions `preA`,
         /// this vector, `b`, and `postB`, by the given amount `t`.