1// tQuaternion.h 
2// 
3// A quaternion class for representing rotations along with expected functionality such as spherical and 
4// normalized linear interpolation. Ability to construct unit quaternions (rotations) from axis-angle as 
5// well as from rotation matrices. 
6// 
7// Copyright (c) 2004-2006, 2015, 2017 Tristan Grimmer. 
8// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
9// granted, provided that the above copyright notice and this permission notice appear in all copies. 
10// 
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
12// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
13// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
14// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
15// PERFORMANCE OF THIS SOFTWARE. 
16 
17#pragma once 
18#include "Math/tLinearAlgebra.h" 
19namespace tMath 
20
21 
22 
23struct tQuaternion : public tQuat 
24
25 tQuaternion() { } 
26 tQuaternion(const tQuat& s) { tSet(*this, s); } 
27 tQuaternion(float x, float y, float z, float w) { tSet(*this, x, y, z, w); } 
28 tQuaternion(const float* a) { tSet(*this, a); } 
29 tQuaternion(const tMat4& orientation) /* Unit quaternion from a 4x4 rotation matrix. */ { tSet(*this, orientation); } 
30 tQuaternion(float r, tVec3 v) /* r,v is used in textbooks. This is not axis-angle. */ { tSet(*this, r, v); } 
31 tQuaternion(const tVec3& axis, float angle) /* Assumes axis vector is normalized. */ { tSet(*this, axis, angle); } 
32 tQuaternion(const tVec3& v) /* r (w) gets set to 0.0f. */ { tSet(*this, v); } 
33 const tQuat& Pod() const { return *this; } 
34 
35 void Set(const tQuat& s) { tSet(*this, s); } 
36 void Set(float x, float y, float z, float w) { tSet(*this, x, y, z, w); } 
37 void Set(const float* a) { tSet(*this, a); } 
38 void Set(const tMat4& orientation) { tSet(*this, orientation); } 
39 void Set(float r, tVec3 v) { tSet(*this, r, v); } 
40 void Set(const tVec3& axis, float angle) { tSet(*this, axis, angle); } 
41 void Set(const tVec3& v) { tSet(*this, v); } 
42 void Get(float& x, float& y, float& z, float& w) const { tGet(x, y, z, w, *this); } 
43 void Get(float* a) const { tGet(a, *this); } 
44 void Get(tVec3& axis, float& angle) const { tGet(axis, angle, *this); } 
45 
46 void Zero() { tZero(*this); } 
47 void Zero(tComponents c) { tZero(*this, c); } 
48 bool IsZero() const { return tIsZero(*this); } 
49 bool IsZero(tComponents c) const { return tIsZero(*this, c); } 
50 bool ApproxEqual(const tQuat& q, float e = Epsilon) const { return tApproxEqual(*this, q, e); } 
51 bool ApproxEqual(const tQuat& q, tComponents c, float e = Epsilon) const { return tApproxEqual(*this, q, c, e); } 
52 
53 float LengthSq() const { return tLengthSq(*this); } 
54 float Length() const { return tLength(*this); } 
55 float LengthFast() const { return tLengthFast(*this); } 
56 float NormSq() const /* Returns the norm (length) squared. */ { return tLengthSq(*this); } 
57 float Norm() const /* Returns the norm (length). */ { return tLength(*this); } 
58 float NormFast() const /* Less accurate but faster. */ { return tLengthFast(*this); } 
59 
60 void Normalize() { tNormalize(*this); } 
61 float NormalizeGetLength() /* Returns pre-normalized length. */ { return tNormalizeGetLength(*this); } 
62 bool NormalizeSafe() /* Returns success. */ { return tNormalizeSafe(*this); } 
63 float NormalizeSafeGetLength() /* Returns pre-normalized length. 0.0f if no go. */ { return tNormalizeSafeGetLength(*this); } 
64 void NormalizeFast() { tNormalizeFast(*this); } 
65 bool NormalizeSafeFast() { return tNormalizeSafeFast(*this); } 
66 
67 // The lack of invert functions is intentional. For unit quaternion just use the conjugate functions. 
68 tQuat Conjugate() const { tQuat d; tConjugate(d, *this); return d; } 
69 tQuat& MakeConjugate() { tConjugate(*this); return *this; } 
70 void Slerp(const tQuat& a, const tQuat& b, float t) /* Spherical linear interpolation between a and b. */ { tSlerp(*this, a, b, t); } 
71 void Nlerp(const tQuat& a, const tQuat& b, float t) /* Normalized linear interpolation between a and b. */ { tNlerp(*this, a, b, t); } 
72 float RotationAngle() const { return tRotationAngle(*this); } 
73 void Rotate(tVec3& v) const /* Rotates the vector. */ { tRotate(v, *this); } 
74 void Rotate(tVec4& v) const /* Rotates the vector. Needs testing. */ { tRotate(v, *this); } 
75 inline static int GetNumComponents() { return 4; } 
76 
77 // Don't add extra operators without first checking the math. 
78 tQuaternion& operator=(const tQuat& q) { tSet(*this, q); return *this; } 
79 
80 tQuaternion& operator+=(const tQuat& a) { tAdd(*this, a); return *this; } 
81 const tQuaternion operator+(const tQuat& a) const { tQuaternion d; tAdd(d, *this, a); return d; } 
82 
83 tQuaternion& operator-=(const tQuat& a) { tSub(*this, a); return *this; } 
84 const tQuaternion operator-(const tQuat& a) const { tQuaternion d; tSub(d, *this, a); return d; } 
85 const tQuaternion operator-() const { tQuaternion d; tNeg(d, *this); return d; } 
86 
87 tQuaternion& operator*=(float a) { tMul(*this, a); return *this; } 
88 tQuaternion& operator*=(const tQuat& a) { tMul(*this, a); return *this; } 
89 tQuaternion& operator*=(const tVec3& a) /* Treats 'a' as an augmented (pure) quaternion. w = 0. */ { tMul(*this, a); return *this; } 
90 const tQuaternion operator*(const tQuat& a) const { tQuaternion d; tMul(d, *this, a); return d; } 
91 const tQuaternion operator*(const tVec3& a) const /* Treats 'a' as an augmented (pure) quaternion. w = 0. */ { tQuaternion d; tMul(d, *this, a); return d; } 
92 friend const tQuaternion operator*(const tQuat& a, float b) { tQuaternion d; tMul(d, a, b); return d; } 
93 friend const tQuaternion operator*(float a, const tQuat& b) { tQuaternion d; tMul(d, a, b); return d; } 
94 
95 tQuaternion& operator/=(float a) { tDiv(*this, a); return *this; } 
96 const tQuaternion operator/(float a) const { tQuaternion d; tDiv(d, *this, a); return d; } 
97 
98 bool operator==(const tQuat& a) const { return tEqual(*this, a); } 
99 bool operator!=(const tQuat& a) const { return tNotEqual(*this, a); } 
100 operator const float*() { return E; } 
101 operator const float*() const { return E; } 
102 float& operator[](int i) { return E[i]; } 
103 float operator[](int i) const { return E[i]; } 
104 
105 const static tQuaternion zero; // Zero quaternion (0, 0, 0, 0). 
106 const static tQuaternion unit; // Unit quaternion (0, 0, 0, 1). 
107}; 
108 
109 
110
111