|
|
@@ -145,6 +145,23 @@ void Quaternion::FromRotationMatrix(const Matrix3& matrix)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void Quaternion::FromLookRotation(const Vector3& direction, const Vector3& upDirection)
|
|
|
+{
|
|
|
+ Vector3 forward = direction.Normalized();
|
|
|
+ Vector3 v = forward.CrossProduct(upDirection).Normalized();
|
|
|
+ Vector3 up = v.CrossProduct(forward);
|
|
|
+ Vector3 right = up.CrossProduct(forward);
|
|
|
+
|
|
|
+ Quaternion ret;
|
|
|
+ ret.w_ = sqrtf(1.0f + right.x_ + up.y_ + forward.z_) * 0.5f;
|
|
|
+ float w4_recip = 1.0f / (4.0f * ret.w_);
|
|
|
+ ret.x_ = (up.z_ - forward.y_) * w4_recip;
|
|
|
+ ret.y_ = (forward.x_ - right.z_) * w4_recip;
|
|
|
+ ret.z_ = (right.y_ - up.x_) * w4_recip;
|
|
|
+
|
|
|
+ (*this) = ret;
|
|
|
+}
|
|
|
+
|
|
|
Vector3 Quaternion::EulerAngles() const
|
|
|
{
|
|
|
// Derivation from http://www.geometrictools.com/Documentation/EulerAngles.pdf
|
|
|
@@ -236,6 +253,18 @@ Quaternion Quaternion::Slerp(Quaternion rhs, float t) const
|
|
|
return *this * t1 + rhs * t2;
|
|
|
}
|
|
|
|
|
|
+Quaternion Quaternion::Nlerp(Quaternion rhs, float t, bool shortestPath) const
|
|
|
+{
|
|
|
+ Quaternion result;
|
|
|
+ float fCos = DotProduct(rhs);
|
|
|
+ if (fCos < 0.0f && shortestPath)
|
|
|
+ result = (*this) + (((-rhs) - (*this)) * t);
|
|
|
+ else
|
|
|
+ result = (*this) + ((rhs - (*this)) * t);
|
|
|
+ result.Normalize();
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
String Quaternion::ToString() const
|
|
|
{
|
|
|
char tempBuffer[CONVERSION_BUFFER_LENGTH];
|