Add Quaternion::RotationMatrix from Matrix3x3 rotation

This commit is contained in:
Wojciech Figat
2022-05-16 10:05:15 +02:00
parent f7e48d9b23
commit c74b66f728
2 changed files with 60 additions and 0 deletions

View File

@@ -4,6 +4,7 @@
#include "Vector3.h"
#include "Vector4.h"
#include "Matrix.h"
#include "Matrix3x3.h"
#include "Math.h"
#include "../Types/String.h"
@@ -208,6 +209,59 @@ void Quaternion::RotationMatrix(const Matrix& matrix, Quaternion& result)
result.Normalize();
}
void Quaternion::RotationMatrix(const Matrix3x3& matrix, Quaternion& result)
{
float sqrtV;
float half;
const float scale = matrix.M11 + matrix.M22 + matrix.M33;
if (scale > 0.0f)
{
sqrtV = Math::Sqrt(scale + 1.0f);
result.W = sqrtV * 0.5f;
sqrtV = 0.5f / sqrtV;
result.X = (matrix.M23 - matrix.M32) * sqrtV;
result.Y = (matrix.M31 - matrix.M13) * sqrtV;
result.Z = (matrix.M12 - matrix.M21) * sqrtV;
}
else if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33)
{
sqrtV = Math::Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33);
half = 0.5f / sqrtV;
result = Quaternion(
0.5f * sqrtV,
(matrix.M12 + matrix.M21) * half,
(matrix.M13 + matrix.M31) * half,
(matrix.M23 - matrix.M32) * half);
}
else if (matrix.M22 > matrix.M33)
{
sqrtV = Math::Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
half = 0.5f / sqrtV;
result = Quaternion(
(matrix.M21 + matrix.M12) * half,
0.5f * sqrtV,
(matrix.M32 + matrix.M23) * half,
(matrix.M31 - matrix.M13) * half);
}
else
{
sqrtV = Math::Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22);
half = 0.5f / sqrtV;
result = Quaternion(
(matrix.M31 + matrix.M13) * half,
(matrix.M32 + matrix.M23) * half,
0.5f * sqrtV,
(matrix.M12 - matrix.M21) * half);
}
result.Normalize();
}
void Quaternion::LookAt(const Vector3& eye, const Vector3& target, const Vector3& up, Quaternion& result)
{
Matrix matrix;

View File

@@ -10,6 +10,7 @@ struct Vector2;
struct Vector3;
struct Vector4;
struct Matrix;
struct Matrix3x3;
/// <summary>
/// Represents a four dimensional mathematical quaternion. Euler angles are stored in: pitch, yaw, roll order (x, y, z).
@@ -566,6 +567,11 @@ public:
// @param result When the method completes, contains the newly created quaternion
static void RotationMatrix(const Matrix& matrix, Quaternion& result);
// Creates a quaternion given a rotation matrix
// @param matrix The rotation matrix
// @param result When the method completes, contains the newly created quaternion
static void RotationMatrix(const Matrix3x3& matrix, Quaternion& result);
// Creates a left-handed, look-at quaternion
// @param eye The position of the viewer's eye
// @param target The camera look-at target