108 lines
3.3 KiB
C++
108 lines
3.3 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#ifndef __NQUATERNION__
|
|
#define __NQUATERNION__
|
|
|
|
|
|
#include "math/nmath.h"
|
|
|
|
|
|
namespace GS {
|
|
struct Vector4;
|
|
class Matrix3;
|
|
|
|
namespace NML {
|
|
class File;
|
|
class Tag;
|
|
}
|
|
|
|
/*!
|
|
@short Quaternion.
|
|
@author Emmanuel Julien (ejulien@gsworks.fr)
|
|
*/
|
|
struct Quaternion
|
|
{
|
|
float x, y, z, w;
|
|
|
|
void operator += (const Quaternion &b) { x += b.x; y += b.y; z += b.z; w += b.w; };
|
|
void operator += (float k) { x += k; y += k; z += k; w += k; };
|
|
void operator -= (const Quaternion &b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; };
|
|
void operator -= (float k) { x -= k; y -= k; z -= k; w -= k; };
|
|
void operator *= (const Quaternion &b)
|
|
{
|
|
Quaternion t = *this;
|
|
w = t.w * b.w - (t.x * b.x + t.y * b.y + t.z * b.z);
|
|
x = t.w * b.x + b.w * t.x + t.y * b.z - t.z * b.y;
|
|
y = t.w * b.y + b.w * t.y + t.z * b.x - t.x * b.z;
|
|
z = t.w * b.z + b.w * t.z + t.x * b.y - t.y * b.x;
|
|
};
|
|
void operator *= (float k) { x *= k; y *= k; z *= k; w *= k; };
|
|
void operator /= (float k) { k = 1.f / k; x *= k; y *= k; z *= k; w *= k; };
|
|
|
|
Quaternion operator + (const Quaternion &b) const
|
|
{ return Quaternion(x + b.x, y + b.y, z + b.z, w + b.w); }
|
|
Quaternion operator + (float v) const
|
|
{ return Quaternion(x + v, y + v, z + v, w + v); }
|
|
Quaternion operator - (const Quaternion &b) const
|
|
{ return Quaternion(x - b.x, y - b.y, z - b.z, w - b.w); }
|
|
Quaternion operator - (float v) const
|
|
{ return Quaternion(x - v, y - v, z - v, w - v); }
|
|
Quaternion operator * (const Quaternion &b) const
|
|
{
|
|
return Quaternion (
|
|
w * b.x + b.w * x + y * b.z - z * b.y,
|
|
w * b.y + b.w * y + z * b.x - x * b.z,
|
|
w * b.z + b.w * z + x * b.y - y * b.x,
|
|
w * b.w - (x * b.x + y * b.y + z * b.z)
|
|
);
|
|
}
|
|
Quaternion operator * (float v) const
|
|
{ return Quaternion(x * v, y * v, z * v, w * v); }
|
|
Quaternion operator / (float v) const
|
|
{ v = 1.f / v; return Quaternion(x * v, y * v, z * v, w * v); }
|
|
|
|
/// Dot product.
|
|
float Dot(const Quaternion &b) const
|
|
{ return x * b.x + y * b.y + z * b.z + w * b.w; }
|
|
|
|
/// Normalize quaternion.
|
|
Quaternion Normalize() const;
|
|
/// Inverse quaternion.
|
|
Quaternion Inverse() const;
|
|
/// To rotation matrix.
|
|
Matrix3 AsMatrix3() const;
|
|
|
|
/// Distance to quaternion.
|
|
static float Distance(const Quaternion &a, const Quaternion &b);
|
|
/// Slerp.
|
|
static Quaternion Slerp(float t, const Quaternion &a, const Quaternion &b);
|
|
|
|
/// From Euler angle.
|
|
static Quaternion FromEuler(float x, float y, float z, Math::rOrder rorder = Math::rOrder_Default);
|
|
/// Get an orientation from a 'look at' vector (look_at = to - from).
|
|
static Quaternion LookAt(const Vector4 &at);
|
|
/// From matrix3.
|
|
static Quaternion FromMatrix3(const Matrix3 &m);
|
|
/// From axis-angle.
|
|
static Quaternion FromAxisAngle(float angle, float x, float y, float z);
|
|
|
|
/// Set quaternion values.
|
|
void Set(float _x = 0, float _y = 0, float _z = 0, float _w = 1.f)
|
|
{ x = _x; y = _y; z = _z; w = _w; }
|
|
|
|
NML::Tag *AsMetaTag(const char *id) const;
|
|
bool FromMetaTag(NML::Tag &tag);
|
|
|
|
Quaternion(float _x = 0, float _y = 0, float _z = 0, float _w = 1.f)
|
|
{ Set(_x, _y, _z, _w); }
|
|
};
|
|
|
|
} // GS
|
|
|
|
|
|
#endif // __NQUATERNION__
|