mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
69 lines
2.1 KiB
C#
69 lines
2.1 KiB
C#
using System.Numerics;
|
|
|
|
namespace DotNetScriptingHelper;
|
|
|
|
public static class QuaternionExtensions
|
|
{
|
|
public static (Vector3 Axis, float Angle) ToAxisAngle(this Quaternion quat)
|
|
{
|
|
// scalar part = cos(θ/2)
|
|
// So, we can extract the angle directly.
|
|
float angle = 2.0f * MathF.Acos(quat.W);
|
|
|
|
// vector part = axis * sin(θ/2)
|
|
// In other words, the vector part is the axis, but with length of sin(θ/2).
|
|
// We assume quaternion is unit length, so subtracting w^2 gives us length of just vector part (aka sin(θ/2)).
|
|
float length = MathF.Sqrt(1.0f - (quat.W * quat.W));
|
|
|
|
Vector3 axis;
|
|
|
|
// Normalize vector part to get the axis!
|
|
if (length == 0)
|
|
{
|
|
axis = Vector3.Zero;
|
|
}
|
|
else
|
|
{
|
|
length = 1.0f / length;
|
|
axis.X = quat.X * length;
|
|
axis.Y = quat.Y * length;
|
|
axis.Z = quat.Z * length;
|
|
}
|
|
|
|
return (axis, angle);
|
|
}
|
|
|
|
public static Vector3 ToEulerAngles(this Quaternion q)
|
|
{
|
|
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
|
|
|
|
Vector3 result;
|
|
|
|
float sqw = q.W * q.W;
|
|
float sqx = q.X * q.X;
|
|
float sqy = q.Y * q.Y;
|
|
float sqz = q.Z * q.Z;
|
|
float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
|
|
float test = q.X * q.Y + q.Z * q.W;
|
|
if (test > 0.4999f * unit)
|
|
{ // singularity at north pole
|
|
result.Y = 2.0f * MathF.Atan2(q.X, q.W);
|
|
result.Z = MathF.PI / 2.0f;
|
|
result.X = 0.0f;
|
|
return result;
|
|
}
|
|
if (test < -0.4999f * unit)
|
|
{ // singularity at south pole
|
|
result.Y = -2.0f * MathF.Atan2(q.X, q.W);
|
|
result.Z = -MathF.PI / 2.0f;
|
|
result.X = 0.0f;
|
|
return result;
|
|
}
|
|
result.Y = MathF.Atan2(2 * q.Y * q.W - 2 * q.X * q.Z, sqx - sqy - sqz + sqw);
|
|
result.Z = MathF.Asin(2 * test / unit);
|
|
result.X = MathF.Atan2(2 * q.X * q.W - 2 * q.Y * q.Z, -sqx + sqy - sqz + sqw);
|
|
|
|
return result;
|
|
}
|
|
}
|