Math/Quaternion: Fix RotationBetween not handling parallel vectors

This commit is contained in:
SirLynix 2023-03-17 19:24:57 +01:00
parent 506d3939a8
commit b354f7f87d
1 changed files with 24 additions and 5 deletions

View File

@ -268,11 +268,30 @@ namespace Nz
template<typename T>
Quaternion<T>& Quaternion<T>::MakeRotationBetween(const Vector3<T>& from, const Vector3<T>& to)
{
// Based on: http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors
T norm = std::sqrt(from.GetSquaredLength() * to.GetSquaredLength());
Vector3<T> crossProduct = from.CrossProduct(to);
Set(norm + from.DotProduct(to), crossProduct.x, crossProduct.y, crossProduct.z);
return Normalize();
T dot = from.DotProduct(to);
if (dot < T(-0.999999))
{
Vector3<T> crossProduct;
if (from.DotProduct(Vector3<T>::UnitX()) < T(0.999999))
crossProduct = Vector3<T>::UnitX().CrossProduct(from);
else
crossProduct = Vector3<T>::UnitY().CrossProduct(from);
crossProduct.Normalize();
Set(Pi<T>, crossProduct);
return *this;
}
else if (dot > T(0.999999))
{
Set(T(1.0), T(0.0), T(0.0), T(0.0));
return *this;
}
else
{
Vector3<T> crossProduct = from.CrossProduct(to);
Set(T(1) + dot, crossProduct.x, crossProduct.y, crossProduct.z);
return Normalize();
}
}
/*!