HaikuDepot: notify work status from main window
[haiku.git] / src / apps / haiku3d / Quaternion.h
blobd88550e5c7a7019f1da0adca9522d786e056d36a
1 /*
2 * Copyright 2008 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Alexandre Deckner
8 */
12 * This is a refactored and stripped down version of
13 * bullet-2.66 src\LinearMath\btQuaternion.h
14 * The dependancies on base class btQuadWord have been removed for
15 * simplification.
16 * Added gl matrix conversion method.
21 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans
22 http://continuousphysics.com/Bullet/
24 This software is provided 'as-is', without any express or implied warranty.
25 In no event will the authors be held liable for any damages arising from the
26 use of this software.
27 Permission is granted to anyone to use this software for any purpose,
28 including commercial applications, and to alter it and redistribute it freely,
29 subject to the following restrictions:
31 1. The origin of this software must not be misrepresented; you must not claim
32 that you wrote the original software. If you use this software in a product,
33 an acknowledgment in the product documentation would be appreciated but is
34 not required.
35 2. Altered source versions must be plainly marked as such, and must not be
36 misrepresented as being the original software.
37 3. This notice may not be removed or altered from any source distribution.
39 #ifndef __QUATERNION_H__
40 #define __QUATERNION_H__
42 #include "Vector3.h"
43 #include <SupportDefs.h>
45 class Quaternion {
46 protected:
47 float m_x;
48 float m_y;
49 float m_z;
50 float m_w;
51 public:
52 Quaternion() {}
54 Quaternion(const Quaternion& q)
56 *((Quaternion*)this) = q;
59 Quaternion(const float& x, const float& y, const float& z, const float& w)
61 m_x = x, m_y = y, m_z = z, m_w = w;
64 Quaternion(const Vector3& axis, const float& angle)
66 setRotation(axis, angle);
69 Quaternion(const float& yaw, const float& pitch, const float& roll)
71 setEuler(yaw, pitch, roll);
74 inline const float& x() const { return m_x; }
77 inline const float& y() const { return m_y; }
80 inline const float& z() const { return m_z; }
83 inline const float& w() const { return m_w; }
86 void setValue(const float& x, const float& y, const float& z)
88 m_x = x;
89 m_y = y;
90 m_z = z;
91 m_w = 0.f;
95 void setValue(const float& x, const float& y, const float& z, const float& w)
97 m_x = x;
98 m_y = y;
99 m_z = z;
100 m_w = w;
104 void setRotation(const Vector3& axis, const float& angle)
106 float d = axis.length();
107 assert(d != 0.0f);
108 float s = sin(angle * 0.5f) / d;
109 setValue(axis.x() * s, axis.y() * s, axis.z() * s,
110 cos(angle * 0.5f));
114 void setEuler(const float& yaw, const float& pitch, const float& roll)
116 float halfYaw = yaw * 0.5f;
117 float halfPitch = pitch * 0.5f;
118 float halfRoll = roll * 0.5f;
119 float cosYaw = cos(halfYaw);
120 float sinYaw = sin(halfYaw);
121 float cosPitch = cos(halfPitch);
122 float sinPitch = sin(halfPitch);
123 float cosRoll = cos(halfRoll);
124 float sinRoll = sin(halfRoll);
125 setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
126 cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
127 sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
128 cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
132 Quaternion& operator+=(const Quaternion& q)
134 m_x += q.x(); m_y += q.y(); m_z += q.z(); m_w += q.m_w;
135 return *this;
139 Quaternion& operator-=(const Quaternion& q)
141 m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_w -= q.m_w;
142 return *this;
146 Quaternion& operator*=(const float& s)
148 m_x *= s; m_y *= s; m_z *= s; m_w *= s;
149 return *this;
153 Quaternion& operator*=(const Quaternion& q)
155 setValue(m_w * q.x() + m_x * q.m_w + m_y * q.z() - m_z * q.y(),
156 m_w * q.y() + m_y * q.m_w + m_z * q.x() - m_x * q.z(),
157 m_w * q.z() + m_z * q.m_w + m_x * q.y() - m_y * q.x(),
158 m_w * q.m_w - m_x * q.x() - m_y * q.y() - m_z * q.z());
159 return *this;
163 float dot(const Quaternion& q) const
165 return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_w * q.m_w;
169 float length2() const
171 return dot(*this);
175 float length() const
177 return sqrt(length2());
181 Quaternion& normalize()
183 return *this /= length();
187 inline Quaternion
188 operator*(const float& s) const
190 return Quaternion(x() * s, y() * s, z() * s, m_w * s);
194 Quaternion operator/(const float& s) const
196 assert(s != 0.0f);
197 return *this * (1.0f / s);
201 Quaternion& operator/=(const float& s)
203 assert(s != 0.0f);
204 return *this *= 1.0f / s;
208 Quaternion normalized() const
210 return *this / length();
214 float angle(const Quaternion& q) const
216 float s = sqrt(length2() * q.length2());
217 assert(s != 0.0f);
218 return acos(dot(q) / s);
222 float getAngle() const
224 float s = 2.0f * acos(m_w);
225 return s;
229 Quaternion inverse() const
231 return Quaternion(m_x, m_y, m_z, -m_w);
235 inline Quaternion
236 operator+(const Quaternion& q2) const
238 const Quaternion& q1 = *this;
239 return Quaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(),
240 q1.m_w + q2.m_w);
244 inline Quaternion
245 operator-(const Quaternion& q2) const
247 const Quaternion& q1 = *this;
248 return Quaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(),
249 q1.m_w - q2.m_w);
253 inline Quaternion operator-() const
255 const Quaternion& q2 = *this;
256 return Quaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_w);
260 inline Quaternion farthest( const Quaternion& qd) const
262 Quaternion diff, sum;
263 diff = *this - qd;
264 sum = *this + qd;
265 if (diff.dot(diff) > sum.dot(sum))
266 return qd;
267 return (-qd);
271 Quaternion slerp(const Quaternion& q, const float& t) const
273 float theta = angle(q);
274 if (theta != 0.0f) {
275 float d = 1.0f / sin(theta);
276 float s0 = sin((1.0f - t) * theta);
277 float s1 = sin(t * theta);
278 return Quaternion((m_x * s0 + q.x() * s1) * d,
279 (m_y * s0 + q.y() * s1) * d,
280 (m_z * s0 + q.z() * s1) * d,
281 (m_w * s0 + q.m_w * s1) * d);
282 } else {
283 return *this;
288 void toOpenGLMatrix(float m[4][4])
290 float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
292 // calculate coefficients
293 x2 = m_x + m_x; y2 = m_y + m_y;
294 z2 = m_z + m_z;
295 xx = m_x * x2; xy = m_x * y2; xz = m_x * z2;
296 yy = m_y * y2; yz = m_y * z2; zz = m_z * z2;
297 wx = m_w * x2; wy = m_w * y2; wz = m_w * z2;
300 m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;
301 m[2][0] = xz + wy; m[3][0] = 0.0;
303 m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);
304 m[2][1] = yz - wx; m[3][1] = 0.0;
307 m[0][2] = xz - wy; m[1][2] = yz + wx;
308 m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;
311 m[0][3] = 0; m[1][3] = 0;
312 m[2][3] = 0; m[3][3] = 1;
317 inline Quaternion
318 operator-(const Quaternion& q)
320 return Quaternion(-q.x(), -q.y(), -q.z(), -q.w());
324 inline Quaternion
325 operator*(const Quaternion& q1, const Quaternion& q2) {
326 return Quaternion(
327 q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
328 q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
329 q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
330 q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z());
334 inline Quaternion
335 operator*(const Quaternion& q, const Vector3& w)
337 return Quaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
338 q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
339 q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
340 -q.x() * w.x() - q.y() * w.y() - q.z() * w.z());
344 inline Quaternion
345 operator*(const Vector3& w, const Quaternion& q)
347 return Quaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(),
348 w.y() * q.w() + w.z() * q.x() - w.x() * q.z(),
349 w.z() * q.w() + w.x() * q.y() - w.y() * q.x(),
350 -w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
354 inline float
355 dot(const Quaternion& q1, const Quaternion& q2)
357 return q1.dot(q2);
361 inline float
362 length(const Quaternion& q)
364 return q.length();
368 inline float
369 angle(const Quaternion& q1, const Quaternion& q2)
371 return q1.angle(q2);
375 inline Quaternion
376 inverse(const Quaternion& q)
378 return q.inverse();
382 inline Quaternion
383 slerp(const Quaternion& q1, const Quaternion& q2, const float& t)
385 return q1.slerp(q2, t);
389 // Game Programming Gems 2.10. make sure v0,v1 are normalized
390 inline Quaternion
391 shortestArcQuat(const Vector3& v0, const Vector3& v1)
393 Vector3 c = v0.cross(v1);
394 float d = v0.dot(v1);
396 if (d < -1.0 + FLT_EPSILON)
397 return Quaternion(0.0f, 1.0f, 0.0f, 0.0f); // just pick any vector
399 float s = sqrt((1.0f + d) * 2.0f);
400 float rs = 1.0f / s;
402 return Quaternion(c.x() * rs, c.y() * rs, c.z() * rs, s * 0.5f);
406 inline Quaternion
407 shortestArcQuatNormalize2(Vector3& v0, Vector3& v1)
409 v0.normalize();
410 v1.normalize();
411 return shortestArcQuat(v0, v1);
413 #endif