diff --git a/Source/Engine/Core/Math/Quaternion.cpp b/Source/Engine/Core/Math/Quaternion.cpp index 93c218d76..b1a6597f5 100644 --- a/Source/Engine/Core/Math/Quaternion.cpp +++ b/Source/Engine/Core/Math/Quaternion.cpp @@ -227,6 +227,23 @@ void Quaternion::Billboard(const Vector3& objectPosition, const Vector3& cameraP RotationMatrix(matrix, result); } +Quaternion Quaternion::FromDirection(const Vector3& direction) +{ + Quaternion orientation; + if (Vector3::Dot(direction, Vector3::Up) >= 0.999f) + { + RotationAxis(Vector3::Left, PI_OVER_2, orientation); + } + else + { + Vector3 right, up; + Vector3::Cross(direction, Vector3::Up, right); + Vector3::Cross(right, direction, up); + LookRotation(direction, up, orientation); + } + return orientation; +} + void Quaternion::LookRotation(const Vector3& forward, const Vector3& up, Quaternion& result) { Vector3 forwardNorm = forward; diff --git a/Source/Engine/Core/Math/Quaternion.h b/Source/Engine/Core/Math/Quaternion.h index d3eeb4f32..c712ad34a 100644 --- a/Source/Engine/Core/Math/Quaternion.h +++ b/Source/Engine/Core/Math/Quaternion.h @@ -587,6 +587,13 @@ public: // @param result When the method completes, contains the created billboard quaternion static void Billboard(const Vector3& objectPosition, const Vector3& cameraPosition, const Vector3& cameraUpVector, const Vector3& cameraForwardVector, Quaternion& result); + /// + /// Calculates the orientation from the direction vector. + /// + /// The direction vector (normalized). + /// The orientation. + static Quaternion FromDirection(const Vector3& direction); + /// /// Creates a rotation with the specified forward and upwards directions. ///