Fixed Quaternion::(Make)RotationBetween

Could not handle parallel vectors


Former-commit-id: 3fed3a46d443b208dc95a5bcd29dd43fb7960114
This commit is contained in:
Lynix 2013-05-30 02:56:58 +02:00
parent 355d52324a
commit b3f60e90fd
1 changed files with 22 additions and 8 deletions

View File

@ -132,13 +132,27 @@ NzQuaternion<T>& NzQuaternion<T>::MakeIdentity()
template<typename T> template<typename T>
NzQuaternion<T>& NzQuaternion<T>::MakeRotationBetween(const NzVector3<T>& from, const NzVector3<T>& to) NzQuaternion<T>& NzQuaternion<T>::MakeRotationBetween(const NzVector3<T>& from, const NzVector3<T>& to)
{ {
NzVector3f a = from.CrossProduct(to); T dot = from.DotProduct(to);
if (NzNumberEquals(dot, F(-1.0)))
{
NzVector3<T> cross = NzVector3<T>::CrossProduct(NzVector3<T>::UnitX(), from);
if (NzNumberEquals(cross.GetLength(), F(0.0)))
cross = NzVector3<T>::CrossProduct(NzVector3<T>::UnitY(), from);
return Set(F(180.0), cross);
}
else if (NzNumberEquals(dot, F(1.0)))
return MakeIdentity();
else
{
NzVector3<T> a = from.CrossProduct(to);
x = a.x; x = a.x;
y = a.y; y = a.y;
z = a.z; z = a.z;
w = std::sqrt(std::pow(from.GetLength(), 2.f) * std::pow(to.GetLength(), 2.f)) + from.DotProduct(to); w = T(1.0) + dot;
return Normalize(); return Normalize();
}
} }
template<typename T> template<typename T>
@ -195,12 +209,12 @@ NzQuaternion<T>& NzQuaternion<T>::Set(const T quat[4])
template<typename T> template<typename T>
NzQuaternion<T>& NzQuaternion<T>::Set(T angle, const NzVector3<T>& axis) NzQuaternion<T>& NzQuaternion<T>::Set(T angle, const NzVector3<T>& axis)
{ {
angle *= F(0.5);
#if !NAZARA_MATH_ANGLE_RADIAN #if !NAZARA_MATH_ANGLE_RADIAN
angle = NzDegreeToRadian(angle); angle = NzDegreeToRadian(angle);
#endif #endif
angle *= F(0.5);
NzVector3<T> normalizedAxis = axis.GetNormal(); NzVector3<T> normalizedAxis = axis.GetNormal();
T sinAngle = std::sin(angle); T sinAngle = std::sin(angle);