From 672e28d44fbe125d123314727cfcac2196b5bdb9 Mon Sep 17 00:00:00 2001 From: otto Date: Tue, 31 Aug 2021 11:19:31 +0800 Subject: [PATCH] fix bug: Quaternion::LookAt --- include/mathfu/quaternion.h | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/include/mathfu/quaternion.h b/include/mathfu/quaternion.h index 7e2e6f4..00f04a3 100644 --- a/include/mathfu/quaternion.h +++ b/include/mathfu/quaternion.h @@ -572,24 +572,41 @@ class Quaternion { .Normalized(); } - /// @brief Returns a quaternion looking at forward vector with an up vector. + /// @cond MATHFU_INTERNAL + /// Create a 3-dimensional look-at matrix. + static inline Matrix LookAtHelper(const Vector& forward, + const Vector& up, + T handedness) { + Matrix m; + m.GetColumn(2) = -handedness * forward; + const Vector& right = Vector::CrossProduct(up, m.GetColumn(2)); + + // avoid division by zero errors. + T inverse = 1 / sqrt(std::max(static_cast(0.00001), Vector::DotProduct(right, right))); + m.GetColumn(0) = right * inverse; + m.GetColumn(1) = Vector::CrossProduct(m.GetColumn(2), m.GetColumn(0)); + return m; + } + /// @endcond + + /// @brief Returns a quaternion looking at forward vector with an up vector based on the default handedness. /// /// @param forward The forward vector (Vector to face). /// @param up The up vector. /// @param Forward and up do not have to be orthogonal. /// @param Forward and up cannot be parallel. /// @param Forward and up cannot be zero vectors. - /// + /// @param handedness 1.0f for RH, -1.0f for LH(default). /// @return A Quaternion looking at forward vector with an up vector. /// - /// Uses Matrix::LookAt to get the Rotation Matrix, then convert it to Quat. - /// Matrix::LookAt takes destination and source as first and second param. - /// The params can be represented with zero-vector as source and - /// forward-vector as destination. + /// Uses Quaternion::LookAtHelper to get the Rotation Matrix, then convert it to Quat. + /// Quaternion::LookAtHelper takes forward direction and Up vector as first and second param. + /// The forward vector needs to be normalized. + /// Up vector, how the camera is oriented. Typically (0, 1, 0). static inline Quaternion LookAt(const Vector& forward, - const Vector& up) { - return FromMatrix( - Matrix::LookAt(forward, Vector(static_cast(0)), up)); + const Vector& up, + T handedness = -1) { + return FromMatrix(LookAtHelper(forward, up, handedness)); } /// @brief Contains a quaternion doing the identity transform.