summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Verschelde <rverschelde@gmail.com>2023-05-12 23:25:52 +0200
committerRémi Verschelde <rverschelde@gmail.com>2023-05-12 23:25:52 +0200
commitf26a2dbb1b16a8e770a8857e06f9808ea6ddf75d (patch)
tree9844531929da500f905e21c5d3acb7ef8c2ed450
parent964a5353dbf5fc0dca4c4b7b9cfa5631dd5ab568 (diff)
parentb74d4f45bb4b2dfd4acdb0529518b8c0e0d5ebe7 (diff)
downloadredot-engine-f26a2dbb1b16a8e770a8857e06f9808ea6ddf75d.tar.gz
Merge pull request #75662 from goncalo/basis_looking_at
C#: Add Basis.LookingAt
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs37
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs35
2 files changed, 46 insertions, 26 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
index ca963cbf4f..36f5d8e2ab 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs
@@ -613,6 +613,43 @@ namespace Godot
}
/// <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>
/// Returns the orthonormalized version of the basis matrix (useful to
/// call occasionally to avoid rounding errors for orthogonal matrices).
/// This performs a Gram-Schmidt orthonormalization on the basis of the matrix.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
index b34e95c04d..1e2aaa299f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs
@@ -164,14 +164,14 @@ namespace Godot
}
/// <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>
/// <param name="target">The object to look at.</param>
/// <param name="up">The relative up direction.</param>
@@ -249,24 +249,7 @@ namespace Godot
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;
}