Browse Source

Merge pull request #75662 from goncalo/basis_looking_at

C#: Add Basis.LookingAt
Rémi Verschelde 2 years ago
parent
commit
f26a2dbb1b

+ 37 - 0
modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs

@@ -612,6 +612,43 @@ namespace Godot
             return b;
             return b;
         }
         }
 
 
+        /// <summary>
+        /// Creates a <see cref="Basis"/> with a rotation such that the forward
+        /// axis (-Z) points towards the <paramref name="target"/> position.
+        /// The up axis (+Y) points as close to the <paramref name="up"/> vector
+        /// as possible while staying perpendicular to the forward axis.
+        /// The resulting Basis is orthonormalized.
+        /// The <paramref name="target"/> and <paramref name="up"/> vectors
+        /// cannot be zero, and cannot be parallel to each other.
+        /// </summary>
+        /// <param name="target">The position to look at.</param>
+        /// <param name="up">The relative up direction.</param>
+        /// <returns>The resulting basis matrix.</returns>
+        public static Basis LookingAt(Vector3 target, Vector3 up)
+        {
+#if DEBUG
+            if (target.IsZeroApprox())
+            {
+                throw new ArgumentException("The vector can't be zero.", nameof(target));
+            }
+            if (up.IsZeroApprox())
+            {
+                throw new ArgumentException("The vector can't be zero.", nameof(up));
+            }
+#endif
+            Vector3 column2 = -target.Normalized();
+            Vector3 column0 = up.Cross(column2);
+#if DEBUG
+            if (column0.IsZeroApprox())
+            {
+                throw new ArgumentException("The target vector and up vector can't be parallel to each other.");
+            }
+#endif
+            column0.Normalize();
+            Vector3 column1 = column2.Cross(column0);
+            return new Basis(column0, column1, column2);
+        }
+
         /// <summary>
         /// <summary>
         /// Returns the orthonormalized version of the basis matrix (useful to
         /// Returns the orthonormalized version of the basis matrix (useful to
         /// call occasionally to avoid rounding errors for orthogonal matrices).
         /// call occasionally to avoid rounding errors for orthogonal matrices).

+ 9 - 26
modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs

@@ -164,14 +164,14 @@ namespace Godot
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// Returns a copy of the transform rotated such that its
-        /// -Z axis (forward) points towards the <paramref name="target"/> position.
-        ///
-        /// The transform will first be rotated around the given <paramref name="up"/> vector,
-        /// and then fully aligned to the <paramref name="target"/> by a further rotation around
-        /// an axis perpendicular to both the <paramref name="target"/> and <paramref name="up"/> vectors.
-        ///
-        /// Operations take place in global space.
+        /// Returns a copy of the transform rotated such that the forward axis (-Z)
+        /// points towards the <paramref name="target"/> position.
+        /// The up axis (+Y) points as close to the <paramref name="up"/> vector
+        /// as possible while staying perpendicular to the forward axis.
+        /// The resulting transform is orthonormalized.
+        /// The existing rotation, scale, and skew information from the original transform is discarded.
+        /// The <paramref name="target"/> and <paramref name="up"/> vectors cannot be zero,
+        /// cannot be parallel to each other, and are defined in global/parent space.
         /// </summary>
         /// </summary>
         /// <param name="target">The object to look at.</param>
         /// <param name="target">The object to look at.</param>
         /// <param name="up">The relative up direction.</param>
         /// <param name="up">The relative up direction.</param>
@@ -249,24 +249,7 @@ namespace Godot
 
 
         private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up)
         private void SetLookAt(Vector3 eye, Vector3 target, Vector3 up)
         {
         {
-            // Make rotation matrix
-            // Z vector
-            Vector3 column2 = eye - target;
-
-            column2.Normalize();
-
-            Vector3 column1 = up;
-
-            Vector3 column0 = column1.Cross(column2);
-
-            // Recompute Y = Z cross X
-            column1 = column2.Cross(column0);
-
-            column0.Normalize();
-            column1.Normalize();
-
-            Basis = new Basis(column0, column1, column2);
-
+            Basis = Basis.LookingAt(target - eye, up);
             Origin = eye;
             Origin = eye;
         }
         }