Honeycomb  0.1
Component-Model Framework
Quat.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2013 Daniel Carter. Distributed under the Boost Software License v1.0.
2 #ifdef HONEY_DX9
3 #ifdef Section_Header
4 
5 namespace honey
6 {
7 
8 template<> Quat_<Float>& Quat_<Float>::fromAxisAngle(const Vec3& axis, Real angle);
9 template<> Quat_<Float>& Quat_<Float>::fromMatrix(const Matrix4& rot);
10 template<> Quat_<Float> Quat_<Float>::operator*(const Quat_& rhs) const;
11 template<> Quat_<Float> Quat_<Float>::exp() const;
12 template<> Quat_<Float> Quat_<Float>::ln() const;
13 template<> Quat_<Float> Quat_<Float>::normalize(option<Real&> len) const;
14 template<> Quat_<Float> Quat_<Float>::normalize_fast() const { return normalize(); }
15 template<> void Quat_<Float>::axisAngle(Vec3& axis, Real& angle) const;
16 template<> Quat_<Float>::Matrix4& Quat_<Float>::toMatrix(Matrix4& rot, bool b3x3) const;
17 template<> Quat_<Float> Quat_<Float>::slerp_fast(Real t, const Quat_& q0, const Quat_& q1, Real cosAlpha);
18 
19 template<> void Quat_<Float>::squadSetup( const Quat_& q0, const Quat_& q1, const Quat_& q2, const Quat_& q3,
20  Quat_& a, Quat_& b, Quat_& c);
21 
22 template<> Quat_<Float> Quat_<Float>::squad(Real t, const Quat_& q1, const Quat_& a, const Quat_& b, const Quat_& c);
23 template<> Quat_<Float> Quat_<Float>::baryCentric(Real f, Real g, const Quat_& q0, const Quat_& q1, const Quat_& q2);
24 
25 
26 
27 }
28 
29 #endif
30 
31 #ifdef Section_Source
32 
33 namespace honey
34 {
35 
36 static FLOAT* DX(Float& f) { return reinterpret_cast<FLOAT*>(&f); }
37 static D3DXVECTOR3* DX(Vec3_f& v) { return reinterpret_cast<D3DXVECTOR3*>(&v); }
38 static const D3DXVECTOR3* DX(const Vec3_f& v) { return reinterpret_cast<const D3DXVECTOR3*>(&v); }
39 static D3DXQUATERNION* DX(Quat_f& q) { return reinterpret_cast<D3DXQUATERNION*>(&q); }
40 static const D3DXQUATERNION* DX(const Quat_f& q) { return reinterpret_cast<const D3DXQUATERNION*>(&q); }
41 static D3DXMATRIX* DX(Matrix4_f& m) { return reinterpret_cast<D3DXMATRIX*>(&m); }
42 static const D3DXMATRIX* DX(const Matrix4_f& m) { return reinterpret_cast<const D3DXMATRIX*>(&m); }
43 
44 
45 template<> Quat_<Float>& Quat_<Float>::fromAxisAngle(const Vec3& axis, Real angle)
46 {
47  D3DXQuaternionRotationAxis(DX(*this), DX(axis), angle);
48  return *this;
49 }
50 
51 template<> Quat_<Float>& Quat_<Float>::fromMatrix(const Matrix4& rot)
52 {
53  D3DXQuaternionRotationMatrix(DX(*this), DX(rot));
54  x = -x; y = -y; z = -z; //dx mat is transposed, so quat from dx is inversed
55  return *this;
56 }
57 
58 template<> Quat_<Float> Quat_<Float>::operator*(const Quat_& rhs) const
59 {
60  Quat_ ret;
61  D3DXQuaternionMultiply(DX(ret), DX(rhs), DX(*this));
62  return ret;
63 }
64 
65 template<> Quat_<Float> Quat_<Float>::exp() const
66 {
67  Quat_ ret;
68  D3DXQuaternionExp(DX(ret), DX(*this));
69  return ret;
70 }
71 
72 template<> Quat_<Float> Quat_<Float>::ln() const
73 {
74  Quat_ ret;
75  D3DXQuaternionLn(DX(ret), DX(*this));
76  return ret;
77 }
78 
79 template<> Quat_<Float> Quat_<Float>::normalize(option<Real&> len) const
80 {
81  if (len)
82  {
83  Real l = length();
84  if (l > RealT::zeroTol)
85  {
86  len = l;
87  return *this / l;
88  }
89  len = 0;
90  return zero;
91  }
92 
93  Quat_ ret;
94  D3DXQuaternionNormalize(DX(ret), DX(*this));
95  return ret;
96 }
97 
98 template<> void Quat_<Float>::axisAngle(Vec3& axis, Real& angle) const
99 {
100  D3DXQuaternionToAxisAngle(DX(*this), DX(axis), DX(angle));
101  axis = axis.normalize();
102 }
103 
104 template<> Quat_<Float> Quat_<Float>::slerp_fast(Real t, const Quat_& q0, const Quat_& q1, Real /*cosAlpha*/)
105 {
106  Quat_ ret;
107  D3DXQuaternionSlerp(DX(ret), DX(q0), DX(q1), t);
108  return ret;
109 }
110 
111 template<> Quat_<Float>::Matrix4& Quat_<Float>::toMatrix(Matrix4& rot, bool b3x3) const
112 {
113  Quat_ inv = inverse(); //Dx mat is transposed, must use inverse
114 
115  if (!b3x3)
116  {
117  D3DXMatrixRotationQuaternion(DX(rot), DX(inv));
118  return rot;
119  }
120 
121  //Dx overwrites entire matrix. Save values outside of upper-left 3x3 submatrix.
122  const Real save[] = { rot( 3), rot( 7), rot(11),
123  rot(12), rot(13), rot(14), rot(15)};
124 
125  D3DXMatrixRotationQuaternion(DX(rot), DX(inv));
126 
127  //Restore values
128  rot( 3) = save[0]; rot( 7) = save[1]; rot(11) = save[2];
129  rot(12) = save[3]; rot(13) = save[4]; rot(14) = save[5]; rot(15) = save[6];
130 
131  return rot;
132 }
133 
134 template<> void Quat_<Float>::squadSetup( const Quat_& q0, const Quat_& q1, const Quat_& q2, const Quat_& q3,
135  Quat_& a, Quat_& b, Quat_& c)
136 {
137  D3DXQuaternionSquadSetup(DX(a), DX(b), DX(c), DX(q0), DX(q1), DX(q2), DX(q3));
138 }
139 
140 template<> Quat_<Float> Quat_<Float>::squad(Float t, const Quat_& q1, const Quat_& a, const Quat_& b, const Quat_& c)
141 {
142  t = Alge::clamp(t, 0, 1);
143  Quat_ ret;
144  D3DXQuaternionSquad(DX(ret), DX(q1), DX(a), DX(b), DX(c), t);
145  return ret;
146 }
147 
148 template<> Quat_<Float> Quat_<Float>::baryCentric(Float f, Float g, const Quat_& q0, const Quat_& q1, const Quat_& q2)
149 {
150  f = Alge::clamp(f, 0, 1);
151  g = Alge::clamp(g, 0, 1);
152  Quat_ ret;
153  D3DXQuaternionBaryCentric(DX(ret), DX(q0), DX(q1), DX(q2), f, g);
154  return ret;
155 }
156 
157 }
158 
159 #endif
160 #endif
Quat_ normalize_fast() const
Fast normalization, only accurate when quaternion is close to unit length.
Definition: Quat.h:226
Float_::Real Float
float type
Definition: Float.h:61
Vec< 3, Float > Vec3_f
Definition: Vec3.h:357
Quat_ operator*(const Quat_ &rhs) const
Definition: Quat.h:151
Matrix4 & toMatrix(Matrix4 &rot, bool b3x3=false) const
Convert quaternion to 4x4 homogeneous rotation matrix. Set b3x3 to true to store the result only in t...
Definition: Quat.cpp:422
Quat_ ln() const
Definition: Quat.cpp:237
Quat_ normalize(optional< Real & > len=optnull) const
Get unit quaternion. The pre-normalized length will be returned in len if specified.
Definition: Quat.h:213
Quat_ & fromMatrix(const Matrix4 &rot)
Construct from 4x4 homogeneous matrix. Rotation is extracted from upper-left 3x3 submatrix.
Definition: Quat.cpp:91
static Quat_ squad(Real t, const Quat_ &q1, const Quat_ &a, const Quat_ &b, const Quat_ &c)
Spherical quadratic interpolation between q1 and c. t ranges from [0,1].
Definition: Quat.cpp:487
static std::common_type< Num, Num2, Num3 >::type clamp(Num val, Num2 min, Num3 max)
Ensure that a number is within a range.
Definition: Alge.h:99
float Real
Real number type. See Real_ for real number operations and constants.
Definition: Real.h:21
Quat_ & fromAxisAngle(const Vec3 &axis, Real angle)
Construct from axis and angle in radians.
Definition: Quat.cpp:14
Vec< 3 > Vec3
3D column vector types
Definition: Vec3.h:356
Matrix< 4, 4, Real > Matrix4
Definition: Matrix4.h:513
Quat_< Float > Quat_f
Definition: Quat.h:354
void axisAngle(Vec3 &axis, Real &angle) const
Get quaternion axis and angle in radians.
Definition: Quat.cpp:326
Matrix< 4, 4, Float > Matrix4_f
Definition: Matrix4.h:514
static void squadSetup(const Quat_ &q0, const Quat_ &q1, const Quat_ &q2, const Quat_ &q3, Quat_ &a, Quat_ &b, Quat_ &c)
Calc intermediate quats required for Squad. Ex. To interpolate between q1 and q2: setup(q0...
Definition: Quat.cpp:472
Global Honeycomb namespace.
Quat_ exp() const
Definition: Quat.cpp:205
static Quat_ baryCentric(Real f, Real g, const Quat_ &q0, const Quat_ &q1, const Quat_ &q2)
Triangular bary-centric interpolation.
Definition: Quat.cpp:496