[dali_1.0.15] Merge branch 'tizen'
[platform/core/uifw/dali-core.git] / dali / public-api / math / quaternion.h
1 #ifndef __DALI_QUATERNION_H__
2 #define __DALI_QUATERNION_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <iostream>
23 #include <math.h>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/math/vector4.h>
29
30 namespace Dali
31 {
32
33 // Forward declaration
34 class Matrix;
35
36 /**
37  * @brief The Quaternion class encapsulates the mathematics of the quaternion.
38  */
39 class DALI_IMPORT_API Quaternion
40 {
41 public:
42
43   /**
44    * @brief Default Constructor
45    */
46   Quaternion();
47
48   /**
49    * @brief Construct from a quaternion represented by floats.
50    *
51    * @param[in] cosThetaBy2
52    * @param[in] iBySineTheta
53    * @param[in] jBySineTheta
54    * @param[in] kBySineTheta
55    */
56   Quaternion(float cosThetaBy2, float iBySineTheta, float jBySineTheta, float kBySineTheta);
57
58   /**
59    * @brief Construct from a quaternion represented by a vector.
60    *
61    * @param[in] vector - x,y,z fields represent i,j,k coefficients, w represents cos(theta/2)
62    */
63   explicit Quaternion(const Vector4& vector);
64
65   /**
66    * @brief Constructor from an axis and angle.
67    *
68    * @param[in] angle - the angle around the axis
69    * @param[in] axis  - the vector of the axis
70    */
71   Quaternion(float angle, const Vector3 &axis);
72
73   /**
74    * @brief Constructor from an axis and angle.
75    *
76    * @param[in] theta - the angle of the axis
77    * @param[in] axis  - the unit vector of the axis
78    */
79   Quaternion(float theta, const Vector4 &axis);
80
81   /**
82    * @brief Construct from Euler angles.
83    *
84    * @param[in] x - the X axis euler angle (pitch)
85    * @param[in] y - the Y axis euler angle (yaw)
86    * @param[in] z - the Z axis euler angle (roll)
87    */
88   Quaternion(float x, float y, float z);
89
90   /**
91    * @brief Construct from a matrix.
92    *
93    * @param[in] matrix
94    */
95   explicit Quaternion(const Matrix& matrix);
96
97   /**
98    * @brief Construct from 3 orthonormal axes.
99    *
100    * @param[in] xAxis The X axis
101    * @param[in] yAxis The Y axis
102    * @param[in] zAxis The Z axis
103    */
104   explicit Quaternion( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
105
106   /**
107    * @brief Converts an axis + angle pair rotation to a Quaternion.
108    *
109    * @param[in] axis
110    * @param[in] angle
111    * @return the represented quaternion
112    */
113   static Quaternion FromAxisAngle(const Vector4 &axis, float angle);
114
115   /**
116    * @brief Destructor, nonvirtual as this is not a base class.
117    *
118    */
119   ~Quaternion();
120
121 // Constants
122
123   static const Quaternion IDENTITY; ///< (0.0f,0.0f,0.0f,1.0f)
124
125   /**
126    * @brief Helper to check if this is an identity quaternion
127    *
128    * @return true if this is identity quaternion
129    */
130   bool IsIdentity() const
131   {
132     // start from w as its unlikely that any real rotation has w == 1
133     // Uses a relaxed epsilon, as composition of rotation introduces error
134     return ( ( fabsf( mVector.w - 1.0f ) < Math::MACHINE_EPSILON_10 )&&
135              ( fabsf( mVector.x ) < Math::MACHINE_EPSILON_10 )&&
136              ( fabsf( mVector.y ) < Math::MACHINE_EPSILON_10 )&&
137              ( fabsf( mVector.z ) < Math::MACHINE_EPSILON_10 ) );
138   }
139
140   /**
141    * @brief Convert the quaternion to an axis/angle pair.
142    *
143    * @param[out] axis
144    * @param[out] angle
145    * @return true if converted correctly
146    */
147   bool ToAxisAngle(Vector3 &axis, float &angle) const;
148
149   /**
150    * @brief Convert the quaternion to an axis/angle pair.
151    *
152    * @param[out] axis
153    * @param[out] angle
154    * @return true if converted correctly
155    */
156   bool ToAxisAngle(Vector4 &axis, float &angle) const;
157
158   /**
159    * @brief Return the quaternion as a vector.
160    *
161    * @return the vector representation of the quaternion
162    */
163   const Vector4& AsVector() const;
164
165   /**
166    * @brief SetEuler sets the quaternion from the Euler angles applied in x, y, z order.
167    *
168    * @param[in] x - the X axis euler angle (pitch)
169    * @param[in] y - the Y axis euler angle (yaw)
170    * @param[in] z - the Z axis euler angle (roll)
171    */
172   void SetEuler(float x, float y, float z);
173
174   /**
175    * @brief returns the Euler angles from a rotation Quaternion.
176    *
177    * @return a vector of Euler angles (x == pitch, y == yaw, z == roll)
178    */
179   Vector4 EulerAngles() const;
180
181   /**
182    * @brief Addition operator.
183    *
184    * @param[in] other The quaternion to add
185    * @return A quaternion containing the result of the addition
186    */
187   const Quaternion operator +(const Quaternion &other) const;
188
189   /**
190    * @brief Subtraction operator.
191    *
192    * @param[in] other The quaternion to subtract
193    * @return A quaternion containing the result of the subtract
194    */
195   const Quaternion operator -(const Quaternion &other) const;
196
197   /**
198    * @brief Multiplication operator.
199    *
200    * @param[in] other The quaternion to multiply
201    * @return A quaternion containing the result
202    */
203   const Quaternion operator *(const Quaternion &other) const;
204
205   /**
206    * @brief Multiplication operator.
207    *
208    * @param[in] v The vector to multiply
209    * @return A vector containing the result of the multiplication
210    */
211   Vector3 operator *(const Vector3& v) const;
212
213   /**
214    * @brief Division operator.
215    *
216    * @param[in] other a quaternion to divide by
217    * @return A quaternion containing the result
218    */
219   const Quaternion operator /(const Quaternion &other) const;
220
221   /**
222    * @brief Scale operator.
223    *
224    * @param[in] scale A value to scale by
225    * @return A quaternion containing the result
226    */
227   const Quaternion operator *(float scale) const;
228
229   /**
230    * @brief Scale operator.
231    *
232    * @param[in] scale A value to scale by
233    * @return A quaternion containing the result
234    */
235   const Quaternion operator /(float scale) const;
236
237   /**
238    * @brief Unary Negation operator.
239    *
240    * @return A quaternion containing the negated result
241    */
242   Quaternion operator -() const;
243
244   /**
245    * @brief Addition with Assignment operator.
246    *
247    * @param[in] other The quaternion to add
248    * @return itself
249    */
250   const Quaternion &operator +=(const Quaternion &other);
251
252   /**
253    * @brief Subtraction with Assignment operator.
254    *
255    * @param[in] other The quaternion to subtract
256    * @return itself
257    */
258   const Quaternion &operator -=(const Quaternion &other);
259
260   /**
261    * @brief Multiplication with Assignment operator.
262    *
263    * @param[in] other The quaternion to multiply
264    * @return itself
265    */
266   const Quaternion &operator *=(const Quaternion &other);
267
268   /**
269    * @brief Scale with Assignment operator.
270    *
271    * @param[in] scale the value to scale by
272    * @return itself
273    */
274   const Quaternion &operator *= (float scale);
275
276   /**
277    * @brief Scale with Assignment operator.
278    *
279    * @param[in] scale the value to scale by
280    * @return itself
281    */
282   const Quaternion &operator /= (float scale);
283
284   /**
285    * @brief Equality operator.
286    *
287    * @param[in] rhs The quaterion to compare with.
288    * @return True if the quaternions are equal.
289    */
290   bool operator== (const Quaternion& rhs) const;
291
292   /**
293    * @brief Inequality operator.
294    *
295    * @param[in] rhs The quaterion to compare with.
296    * @return True if the quaternions are not equal.
297    */
298   bool operator!= (const Quaternion& rhs) const;
299
300   /**
301    * @brief Return the length of the quaternion.
302    *
303    * @return the length of the quaternion
304    */
305   float Length() const;
306
307   /**
308    * @brief Return the squared length of the quaternion.
309    *
310    * @return the squared length of the quaternion
311    */
312   float LengthSquared() const;
313
314   /**
315    * @brief Normalize this to unit length.
316    *
317    */
318   void Normalize();
319
320   /**
321    * @brief Normalized.
322    *
323    * @return a normalized version of this quaternion
324    */
325   Quaternion Normalized() const;
326
327   /**
328    * @brief Conjugate this quaternion.
329    *
330    */
331   void Conjugate();
332
333   /**
334    * @brief Invert this quaternion.
335    *
336    */
337   void Invert();
338
339   /**
340    * @brief Performs the logarithm of a Quaternion = v*a where q = (cos(a),v*sin(a)).
341    *
342    * @return a quaternion representing the logarithm
343    */
344   Quaternion Log() const;
345
346   /**
347    * @brief Performs an exponent e^Quaternion = Exp(v*a) = (cos(a),vsin(a)).
348    *
349    * @return a quaternion representing the exponent
350    */
351   Quaternion Exp() const;
352
353   /**
354    * @brief Return the dot product of two quaternions.
355    *
356    * @param[in] q1 - the first quaternion
357    * @param[in] q2 - the second quaternion
358    * @return the dot product of the two quaternions
359    */
360   static float Dot(const Quaternion &q1, const Quaternion &q2);
361
362   /**
363    * @brief Linear Interpolation (using a straight line between the two quaternions).
364    *
365    * @param[in] q1 - the start quaternion
366    * @param[in] q2 - the end quaternion
367    * @param[in] t  - a progress value between 0 and 1
368    * @return the interpolated quaternion
369    */
370   static Quaternion Lerp(const Quaternion &q1, const Quaternion &q2, float t);
371
372   /**
373    * @brief Spherical Linear Interpolation (using the shortest arc of a great circle between
374    * the two quaternions).
375    *
376    * @param[in] q1 - the start quaternion
377    * @param[in] q2 - the end quaternion
378    * @param[in] progress  - a progress value between 0 and 1
379    * @return the interpolated quaternion
380    */
381   static Quaternion Slerp(const Quaternion &q1, const Quaternion &q2, float progress);
382
383   /**
384    * @brief This version of Slerp, used by Squad, does not check for theta > 90.
385    *
386    * @param[in] q1 - the start quaternion
387    * @param[in] q2 - the end quaternion
388    * @param[in] t  - a progress value between 0 and 1
389    * @return the interpolated quaternion
390    */
391   static Quaternion SlerpNoInvert(const Quaternion &q1, const Quaternion &q2, float t);
392
393   /**
394    * @brief Spherical Cubic Interpolation.
395    *
396    * @param[in] q1 - the start quaternion
397    * @param[in] q2 - the end quaternion
398    * @param[in] a  - the control quaternion for q1
399    * @param[in] b  - the control quaternion for q2
400    * @param[in] t  - a progress value between 0 and 1
401    * @return the interpolated quaternion
402    */
403   static Quaternion Squad(const Quaternion &q1,const Quaternion &q2,const Quaternion &a,const Quaternion &b,float t);
404
405   /**
406    * @brief Returns the shortest angle between two quaternions in Radians.
407    *
408    * @param[in] q1 - the first quaternion
409    * @param[in] q2 - the second quaternion
410    * @return the angle between the two quaternions.
411    */
412   static float AngleBetween(const Quaternion &q1, const Quaternion &q2);
413
414   /**
415    * @brief Rotate v by this Quaternion (Quaternion must be unit).
416    *
417    * @param[in] v - a vector to rotate
418    * @return the rotated vector
419    */
420   Vector4 Rotate(const Vector4 &v) const;
421
422   /**
423    * @brief Rotate v by this Quaternion (Quaternion must be unit).
424    *
425    * @param[in] v - a vector to rotate
426    * @return the rotated vector
427    */
428   Vector3 Rotate(const Vector3 &v) const;
429
430 private:
431
432   /**
433    * @brief Set the quaternion from 3 orthonormal axes.
434    *
435    * @param[in] xAxis The X axis
436    * @param[in] yAxis The Y axis
437    * @param[in] zAxis The Z axis
438    */
439   DALI_INTERNAL void SetFromAxes( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
440
441 public:
442
443   Vector4 mVector;   ///< w component is s ( = cos(theta/2.0) )
444 };
445
446 /**
447  * @brief Print a Quaternion.
448  *
449  * @param [in] o The output stream operator.
450  * @param [in] quaternion The quaternion to print.
451  * @return The output stream operator.
452  */
453 DALI_IMPORT_API std::ostream& operator<< (std::ostream& o, const Quaternion& quaternion);
454
455 } // namespace Dali
456
457 #endif // __DALI_QUATERNION_H__