Switched CQuaternion from XYZW to WXYZ, added new conversion functions (Quats->Eulers, Degs<->Rads)
This commit is contained in:
parent
3542759c74
commit
f0cb6169ae
|
@ -1,21 +1,22 @@
|
||||||
#include "CQuaternion.h"
|
#include "CQuaternion.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <Common/Math.h>
|
||||||
|
|
||||||
CQuaternion::CQuaternion()
|
CQuaternion::CQuaternion()
|
||||||
{
|
{
|
||||||
x = 0;
|
w = 0.f;
|
||||||
y = 0;
|
x = 0.f;
|
||||||
z = 0;
|
y = 0.f;
|
||||||
w = 0;
|
z = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
CQuaternion::CQuaternion(float _x, float _y, float _z, float _w)
|
CQuaternion::CQuaternion(float _w, float _x, float _y, float _z)
|
||||||
{
|
{
|
||||||
|
w = _w;
|
||||||
x = _x;
|
x = _x;
|
||||||
y = _y;
|
y = _y;
|
||||||
z = _z;
|
z = _z;
|
||||||
w = _w;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector3f CQuaternion::XAxis()
|
CVector3f CQuaternion::XAxis()
|
||||||
|
@ -40,12 +41,25 @@ CQuaternion CQuaternion::Inverse()
|
||||||
if (fNorm > 0.f)
|
if (fNorm > 0.f)
|
||||||
{
|
{
|
||||||
float fInvNorm = 1.f / fNorm;
|
float fInvNorm = 1.f / fNorm;
|
||||||
return CQuaternion(-x * fInvNorm, -y * fInvNorm, -z * fInvNorm, w * fInvNorm);
|
return CQuaternion( w * fInvNorm, -x * fInvNorm, -y * fInvNorm, -z * fInvNorm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return CQuaternion::skZero;
|
return CQuaternion::skZero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CVector3f CQuaternion::ToEuler()
|
||||||
|
{
|
||||||
|
// There is more than one way to do this conversion, based on rotation order.
|
||||||
|
// But since we only care about the rotation order used in Retro games, which is consistent,
|
||||||
|
// we can just have a single conversion function. Handy!
|
||||||
|
// https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
|
||||||
|
|
||||||
|
float ex = atan2f(2 * (w*x + y*z), 1 - (2 * (Math::Pow(x,2) + Math::Pow(y,2))));
|
||||||
|
float ey = asinf(2 * (w*y - z*x));
|
||||||
|
float ez = atan2f(2 * (w*z + x*y), 1 - (2 * (Math::Pow(y,2) + Math::Pow(z,2))));
|
||||||
|
return CVector3f(Math::RadiansToDegrees(ex), Math::RadiansToDegrees(ey), Math::RadiansToDegrees(ez));
|
||||||
|
}
|
||||||
|
|
||||||
// ************ OPERATORS ************
|
// ************ OPERATORS ************
|
||||||
CVector3f CQuaternion::operator*(const CVector3f& vec) const
|
CVector3f CQuaternion::operator*(const CVector3f& vec) const
|
||||||
{
|
{
|
||||||
|
@ -62,10 +76,10 @@ CVector3f CQuaternion::operator*(const CVector3f& vec) const
|
||||||
CQuaternion CQuaternion::operator*(const CQuaternion& other) const
|
CQuaternion CQuaternion::operator*(const CQuaternion& other) const
|
||||||
{
|
{
|
||||||
CQuaternion out;
|
CQuaternion out;
|
||||||
|
out.w = (-x * other.x) - (y * other.y) - (z * other.z) + (w * other.w);
|
||||||
out.x = ( x * other.w) + (y * other.z) - (z * other.y) + (w * other.x);
|
out.x = ( x * other.w) + (y * other.z) - (z * other.y) + (w * other.x);
|
||||||
out.y = (-x * other.z) + (y * other.w) + (z * other.x) + (w * other.y);
|
out.y = (-x * other.z) + (y * other.w) + (z * other.x) + (w * other.y);
|
||||||
out.z = ( x * other.y) - (y * other.x) + (z * other.w) + (w * other.z);
|
out.z = ( x * other.y) - (y * other.x) + (z * other.w) + (w * other.z);
|
||||||
out.w = (-x * other.x) - (y * other.y) - (z * other.z) + (w * other.w);
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,16 +127,16 @@ CQuaternion CQuaternion::FromAxisAngle(float angle, CVector3f axis)
|
||||||
{
|
{
|
||||||
CQuaternion quat;
|
CQuaternion quat;
|
||||||
axis = axis.Normalized();
|
axis = axis.Normalized();
|
||||||
angle = angle * 3.14159265358979323846f / 180;
|
angle = Math::DegreesToRadians(angle);
|
||||||
|
|
||||||
float sa = sin(angle / 2);
|
float sa = sinf(angle / 2);
|
||||||
|
quat.w = cosf(angle / 2);
|
||||||
quat.x = axis.x * sa;
|
quat.x = axis.x * sa;
|
||||||
quat.y = axis.y * sa;
|
quat.y = axis.y * sa;
|
||||||
quat.z = axis.z * sa;
|
quat.z = axis.z * sa;
|
||||||
quat.w = cos(angle / 2);
|
|
||||||
return quat;
|
return quat;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CQuaternion CQuaternion::skIdentity = CQuaternion(0.f, 0.f, 0.f, 1.f);
|
CQuaternion CQuaternion::skIdentity = CQuaternion(1.f, 0.f, 0.f, 0.f);
|
||||||
CQuaternion CQuaternion::skZero = CQuaternion(0.f, 0.f, 0.f, 0.f);
|
CQuaternion CQuaternion::skZero = CQuaternion(0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
|
@ -6,15 +6,16 @@
|
||||||
class CQuaternion
|
class CQuaternion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
float x, y, z, w;
|
float w, x, y, z;
|
||||||
|
|
||||||
CQuaternion();
|
CQuaternion();
|
||||||
CQuaternion(float _x, float _y, float _z, float _w);
|
CQuaternion(float _w, float _x, float _y, float _z);
|
||||||
|
|
||||||
CVector3f XAxis();
|
CVector3f XAxis();
|
||||||
CVector3f YAxis();
|
CVector3f YAxis();
|
||||||
CVector3f ZAxis();
|
CVector3f ZAxis();
|
||||||
CQuaternion Inverse();
|
CQuaternion Inverse();
|
||||||
|
CVector3f ToEuler();
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
CVector3f operator*(const CVector3f& vec) const;
|
CVector3f operator*(const CVector3f& vec) const;
|
||||||
|
|
|
@ -20,6 +20,16 @@ float Distance(const CVector3f& A, const CVector3f& B)
|
||||||
Pow(B.z - A.z, 2.f) );
|
Pow(B.z - A.z, 2.f) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float DegreesToRadians(float deg)
|
||||||
|
{
|
||||||
|
return deg * skPi / 180.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float RadiansToDegrees(float rad)
|
||||||
|
{
|
||||||
|
return rad * 180.f / skPi;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<bool,float> RayPlaneIntersecton(const CRay& ray, const CPlane& plane)
|
std::pair<bool,float> RayPlaneIntersecton(const CRay& ray, const CPlane& plane)
|
||||||
{
|
{
|
||||||
// Code based on ray/plane intersect code from Ogre
|
// Code based on ray/plane intersect code from Ogre
|
||||||
|
|
|
@ -17,6 +17,10 @@ float Pow(float Base, float Exponent);
|
||||||
|
|
||||||
float Distance(const CVector3f& A, const CVector3f& B);
|
float Distance(const CVector3f& A, const CVector3f& B);
|
||||||
|
|
||||||
|
float DegreesToRadians(float deg);
|
||||||
|
|
||||||
|
float RadiansToDegrees(float rad);
|
||||||
|
|
||||||
std::pair<bool,float> RayPlaneIntersecton(const CRay& ray, const CPlane& plane);
|
std::pair<bool,float> RayPlaneIntersecton(const CRay& ray, const CPlane& plane);
|
||||||
|
|
||||||
std::pair<bool,float> RayBoxIntersection(const CRay& Ray, const CAABox& Box);
|
std::pair<bool,float> RayBoxIntersection(const CRay& Ray, const CAABox& Box);
|
||||||
|
@ -27,6 +31,10 @@ std::pair<bool,float> RayLineIntersection(const CRay& ray, const CVector3f& poin
|
||||||
std::pair<bool,float> RayTriangleIntersection(const CRay& Ray, const CVector3f& PointA,
|
std::pair<bool,float> RayTriangleIntersection(const CRay& Ray, const CVector3f& PointA,
|
||||||
const CVector3f& PointB, const CVector3f& PointC,
|
const CVector3f& PointB, const CVector3f& PointC,
|
||||||
bool AllowBackfaces = false);
|
bool AllowBackfaces = false);
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
static const float skPi = 3.14159265358979323846f;
|
||||||
|
static const float skHalfPi = skPi / 2.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MATH
|
#endif // MATH
|
||||||
|
|
Loading…
Reference in New Issue