From b3f60e90fd05b6f05cf6a3c043e91372b31825d0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 30 May 2013 02:56:58 +0200 Subject: [PATCH] Fixed Quaternion::(Make)RotationBetween Could not handle parallel vectors Former-commit-id: 3fed3a46d443b208dc95a5bcd29dd43fb7960114 --- include/Nazara/Math/Quaternion.inl | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 4432eee21..ab843d4a1 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -132,13 +132,27 @@ NzQuaternion& NzQuaternion::MakeIdentity() template NzQuaternion& NzQuaternion::MakeRotationBetween(const NzVector3& from, const NzVector3& to) { - NzVector3f a = from.CrossProduct(to); - x = a.x; - y = a.y; - z = a.z; - w = std::sqrt(std::pow(from.GetLength(), 2.f) * std::pow(to.GetLength(), 2.f)) + from.DotProduct(to); + T dot = from.DotProduct(to); + if (NzNumberEquals(dot, F(-1.0))) + { + NzVector3 cross = NzVector3::CrossProduct(NzVector3::UnitX(), from); + if (NzNumberEquals(cross.GetLength(), F(0.0))) + cross = NzVector3::CrossProduct(NzVector3::UnitY(), from); - return Normalize(); + return Set(F(180.0), cross); + } + else if (NzNumberEquals(dot, F(1.0))) + return MakeIdentity(); + else + { + NzVector3 a = from.CrossProduct(to); + x = a.x; + y = a.y; + z = a.z; + w = T(1.0) + dot; + + return Normalize(); + } } template @@ -195,12 +209,12 @@ NzQuaternion& NzQuaternion::Set(const T quat[4]) template NzQuaternion& NzQuaternion::Set(T angle, const NzVector3& axis) { - angle *= F(0.5); - #if !NAZARA_MATH_ANGLE_RADIAN angle = NzDegreeToRadian(angle); #endif + angle *= F(0.5); + NzVector3 normalizedAxis = axis.GetNormal(); T sinAngle = std::sin(angle);