diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index ca963cbf4f8e..36f5d8e2abf5 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -612,6 +612,43 @@ namespace Godot return b; } + /// + /// Creates a with a rotation such that the forward + /// axis (-Z) points towards the position. + /// The up axis (+Y) points as close to the vector + /// as possible while staying perpendicular to the forward axis. + /// The resulting Basis is orthonormalized. + /// The and vectors + /// cannot be zero, and cannot be parallel to each other. + /// + /// The position to look at. + /// The relative up direction. + /// The resulting basis matrix. + 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); + } + /// /// Returns the orthonormalized version of the basis matrix (useful to /// call occasionally to avoid rounding errors for orthogonal matrices). diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform3D.cs index b34e95c04df6..1e2aaa299f07 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 } /// - /// Returns a copy of the transform rotated such that its - /// -Z axis (forward) points towards the position. - /// - /// The transform will first be rotated around the given vector, - /// and then fully aligned to the by a further rotation around - /// an axis perpendicular to both the and vectors. - /// - /// Operations take place in global space. + /// Returns a copy of the transform rotated such that the forward axis (-Z) + /// points towards the position. + /// The up axis (+Y) points as close to the 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 and vectors cannot be zero, + /// cannot be parallel to each other, and are defined in global/parent space. /// /// The object to look at. /// The relative up direction. @@ -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; }