/* ----------------------------------------------------------------------------- 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__