1 /************************************************************************
2 This file is part of NE.
4 NE is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 NE is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with NE. If not, see <http://www.gnu.org/licenses/>.
16 ************************************************************************/
28 #define SLERP_DELTA 0.001
35 Quat(T w
, const Vec
<T
> &v
) : m_v(v
), m_w(w
) {}
36 Quat(T w
, T x
, T y
, T z
) : m_v(x
, y
, z
), m_w(w
) {}
38 ///////////////////////
39 // Set/Get functions //
40 ///////////////////////
41 inline const Quat
<T
> set(T w
, const Vec
<T
> &v
)
47 inline const Quat
<T
> set(T x
, T y
, T z
, T w
)
49 m_v
= Vec
<T
>(x
, y
, z
);
54 inline void get(T v
[4]) const
62 inline const Vec
<T
> v() const {return m_v
;}
63 inline T
x() const {return m_v
.x();}
64 inline T
y() const {return m_v
.y();}
65 inline T
z() const {return m_v
.z();}
66 inline T
w() const {return m_w
;}
71 inline T
angle() const
76 inline static const Quat
<T
> FromAxis(T angle
, const Vec
<T
> &v
)
80 return Quat
<T
>(cos(a
), v
* sin(a
));
83 inline static const Quat
<T
> FromODE(const dReal
*q
)
85 return Quat
<T
>(q
[0], q
[1], q
[2], q
[3]);
88 inline const dReal
*toODE()
98 inline void toMatrixGL(T m
[16])
117 m
[ 0] = 1.0 - (yy
+ zz
);
123 m
[ 5] = 1.0 - (xx
+ zz
);
129 m
[10] = 1.0 - (xx
+ yy
);
138 inline const Vec
<T
> toEuler() const
141 double test
= x() * y() + z() * w();
143 if (test
> 0.5 - SLERP_DELTA
) {
144 nx
= 2.0 * atan2(x(), w());
148 else if (test
< -0.5 + SLERP_DELTA
) {
149 nx
= -2.0 * atan2(x(), w());
154 T xx
, yy
, zz
, x2
, y2
, z2
, w2
;
165 nx
= atan2(y2
* w() - x2
* z(), 1.0 - yy
- zz
);
166 ny
= asin(2.0 * test
);
167 nz
= atan2(x2
* w() - y2
* z(), 1.0 - xx
- zz
);
170 return Vec
<T
>(nx
, ny
, nz
);
177 inline T
norm() const
179 return w() * w() + v().dot(v());
182 inline const Quat
<T
> unit() const
184 return Quat
<T
>(*this / norm());
187 inline const Quat
<T
> inverse() const
189 return conjugate() / norm();
192 inline const Quat
<T
> conjugate() const
194 return Quat
<T
>(w(), -v());
197 inline const Quat
<T
> operator * (const Quat
<T
> &q
) const
199 //T w = m_w * q.m_w - m_v.dot(q.m_v);
200 //Vec<T> v(m_v.cross(q.m_v) + m_w * q.m_v + q.m_w * m_v);
201 //return Quat<T>(w, v);
203 return Quat
<T
>(*this) *= q
;
206 inline const Quat
<T
> &operator *= (const Quat
<T
> &q
)
208 T a
, b
, c
, d
, e
, f
, g
, h
;
209 a
= (w() + x()) * (q
.w() + q
.x());
210 b
= (z() - y()) * (q
.y() - q
.z());
211 c
= (w() - x()) * (q
.y() + q
.z());
212 d
= (y() + z()) * (q
.w() - q
.x());
213 e
= (x() + z()) * (q
.x() + q
.y());
214 f
= (x() - z()) * (q
.x() - q
.y());
215 g
= (w() + y()) * (q
.w() - q
.z());
216 h
= (w() - y()) * (q
.w() + q
.z());
218 T w
= b
+ (-e
- f
+ g
+ h
) * 0.5;
219 T x
= a
- ( e
+ f
+ g
+ h
) * 0.5;
220 T y
= c
+ ( e
- f
+ g
- h
) * 0.5;
221 T z
= d
+ ( e
- f
- g
+ h
) * 0.5;
224 m_v
= Vec
<T
>(x
, y
, z
);
229 inline const Quat
<T
> slerp(const Quat
<T
> &to
, T t
)
231 double om
, cosom
, sinom
, s1
, s2
;
235 cosom
= v().dot(to
.v()) + w() * to
.w();
243 if ((1.0 - cosom
) > SLERP_DELTA
) {
246 s1
= sin((1.0 - t
) * om
) / sinom
;
247 s2
= sin(t
* om
) / sinom
;
250 // do linear because they are very close
255 return Quat
<T
>(s1
* x() + s2
* tmp
.x(),
256 s1
* y() + s2
* tmp
.y(),
257 s1
* z() + s2
* tmp
.z(),
258 s1
* w() + s2
* tmp
.w());
261 ///////////////////////
262 // Equality overload //
263 ///////////////////////
265 inline const Quat
<T
> &operator = (const Quat
<T
> &q
)
271 inline bool operator == (const Quat
<T
> &q
) const
273 return m_w
== q
.m_w
&& m_v
== q
.m_v
;
276 /////////////////////
277 // Scalar overload //
278 /////////////////////
280 inline const Quat
<T
> operator / (T s
) const
282 return Quat
<T
> (m_w
/ s
, m_v
/ s
);
291 typedef Quat
<float> Quatf
;
292 typedef Quat
<double> Quatd
;