Merge "Added api to animate an actor (position and orientation) through a path" into...
[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 Construct quaternion which describes minimum rotation to align v0 with v1
108    * @pre v0 and v1 should be normalized
109    *
110    * @param[in] v0 First normalized vector
111    * @param[in] v1 Second normalized vector
112    */
113   explicit Quaternion( const Vector3& v0, const Vector3& v1 );
114
115   /**
116    * @brief Converts an axis + angle pair rotation to a Quaternion.
117    *
118    * @param[in] axis
119    * @param[in] angle
120    * @return the represented quaternion
121    */
122   static Quaternion FromAxisAngle(const Vector4 &axis, float angle);
123
124   /**
125    * @brief Destructor, nonvirtual as this is not a base class.
126    *
127    */
128   ~Quaternion();
129
130 // Constants
131
132   static const Quaternion IDENTITY; ///< (0.0f,0.0f,0.0f,1.0f)
133
134   /**
135    * @brief Helper to check if this is an identity quaternion
136    *
137    * @return true if this is identity quaternion
138    */
139   bool IsIdentity() const
140   {
141     // start from w as its unlikely that any real rotation has w == 1
142     // Uses a relaxed epsilon, as composition of rotation introduces error
143     return ( ( fabsf( mVector.w - 1.0f ) < Math::MACHINE_EPSILON_10 )&&
144              ( fabsf( mVector.x ) < Math::MACHINE_EPSILON_10 )&&
145              ( fabsf( mVector.y ) < Math::MACHINE_EPSILON_10 )&&
146              ( fabsf( mVector.z ) < Math::MACHINE_EPSILON_10 ) );
147   }
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(Vector3 &axis, float &angle) const;
157
158   /**
159    * @brief Convert the quaternion to an axis/angle pair.
160    *
161    * @param[out] axis
162    * @param[out] angle
163    * @return true if converted correctly
164    */
165   bool ToAxisAngle(Vector4 &axis, float &angle) const;
166
167   /**
168    * @brief Return the quaternion as a vector.
169    *
170    * @return the vector representation of the quaternion
171    */
172   const Vector4& AsVector() const;
173
174   /**
175    * @brief SetEuler sets the quaternion from the Euler angles applied in x, y, z order.
176    *
177    * @param[in] x - the X axis euler angle (pitch)
178    * @param[in] y - the Y axis euler angle (yaw)
179    * @param[in] z - the Z axis euler angle (roll)
180    */
181   void SetEuler(float x, float y, float z);
182
183   /**
184    * @brief returns the Euler angles from a rotation Quaternion.
185    *
186    * @return a vector of Euler angles (x == pitch, y == yaw, z == roll)
187    */
188   Vector4 EulerAngles() const;
189
190   /**
191    * @brief Addition operator.
192    *
193    * @param[in] other The quaternion to add
194    * @return A quaternion containing the result of the addition
195    */
196   const Quaternion operator +(const Quaternion &other) const;
197
198   /**
199    * @brief Subtraction operator.
200    *
201    * @param[in] other The quaternion to subtract
202    * @return A quaternion containing the result of the subtract
203    */
204   const Quaternion operator -(const Quaternion &other) const;
205
206   /**
207    * @brief Multiplication operator.
208    *
209    * @param[in] other The quaternion to multiply
210    * @return A quaternion containing the result
211    */
212   const Quaternion operator *(const Quaternion &other) const;
213
214   /**
215    * @brief Multiplication operator.
216    *
217    * @param[in] v The vector to multiply
218    * @return A vector containing the result of the multiplication
219    */
220   Vector3 operator *(const Vector3& v) const;
221
222   /**
223    * @brief Division operator.
224    *
225    * @param[in] other a quaternion to divide by
226    * @return A quaternion containing the result
227    */
228   const Quaternion operator /(const Quaternion &other) const;
229
230   /**
231    * @brief Scale operator.
232    *
233    * @param[in] scale A value to scale by
234    * @return A quaternion containing the result
235    */
236   const Quaternion operator *(float scale) const;
237
238   /**
239    * @brief Scale operator.
240    *
241    * @param[in] scale A value to scale by
242    * @return A quaternion containing the result
243    */
244   const Quaternion operator /(float scale) const;
245
246   /**
247    * @brief Unary Negation operator.
248    *
249    * @return A quaternion containing the negated result
250    */
251   Quaternion operator -() const;
252
253   /**
254    * @brief Addition with Assignment operator.
255    *
256    * @param[in] other The quaternion to add
257    * @return itself
258    */
259   const Quaternion &operator +=(const Quaternion &other);
260
261   /**
262    * @brief Subtraction with Assignment operator.
263    *
264    * @param[in] other The quaternion to subtract
265    * @return itself
266    */
267   const Quaternion &operator -=(const Quaternion &other);
268
269   /**
270    * @brief Multiplication with Assignment operator.
271    *
272    * @param[in] other The quaternion to multiply
273    * @return itself
274    */
275   const Quaternion &operator *=(const Quaternion &other);
276
277   /**
278    * @brief Scale with Assignment operator.
279    *
280    * @param[in] scale the value to scale by
281    * @return itself
282    */
283   const Quaternion &operator *= (float scale);
284
285   /**
286    * @brief Scale with Assignment operator.
287    *
288    * @param[in] scale the value to scale by
289    * @return itself
290    */
291   const Quaternion &operator /= (float scale);
292
293   /**
294    * @brief Equality operator.
295    *
296    * @param[in] rhs The quaterion to compare with.
297    * @return True if the quaternions are equal.
298    */
299   bool operator== (const Quaternion& rhs) const;
300
301   /**
302    * @brief Inequality operator.
303    *
304    * @param[in] rhs The quaterion to compare with.
305    * @return True if the quaternions are not equal.
306    */
307   bool operator!= (const Quaternion& rhs) const;
308
309   /**
310    * @brief Return the length of the quaternion.
311    *
312    * @return the length of the quaternion
313    */
314   float Length() const;
315
316   /**
317    * @brief Return the squared length of the quaternion.
318    *
319    * @return the squared length of the quaternion
320    */
321   float LengthSquared() const;
322
323   /**
324    * @brief Normalize this to unit length.
325    *
326    */
327   void Normalize();
328
329   /**
330    * @brief Normalized.
331    *
332    * @return a normalized version of this quaternion
333    */
334   Quaternion Normalized() const;
335
336   /**
337    * @brief Conjugate this quaternion.
338    *
339    */
340   void Conjugate();
341
342   /**
343    * @brief Invert this quaternion.
344    *
345    */
346   void Invert();
347
348   /**
349    * @brief Performs the logarithm of a Quaternion = v*a where q = (cos(a),v*sin(a)).
350    *
351    * @return a quaternion representing the logarithm
352    */
353   Quaternion Log() const;
354
355   /**
356    * @brief Performs an exponent e^Quaternion = Exp(v*a) = (cos(a),vsin(a)).
357    *
358    * @return a quaternion representing the exponent
359    */
360   Quaternion Exp() const;
361
362   /**
363    * @brief Return the dot product of two quaternions.
364    *
365    * @param[in] q1 - the first quaternion
366    * @param[in] q2 - the second quaternion
367    * @return the dot product of the two quaternions
368    */
369   static float Dot(const Quaternion &q1, const Quaternion &q2);
370
371   /**
372    * @brief Linear Interpolation (using a straight line between the two quaternions).
373    *
374    * @param[in] q1 - the start quaternion
375    * @param[in] q2 - the end quaternion
376    * @param[in] t  - a progress value between 0 and 1
377    * @return the interpolated quaternion
378    */
379   static Quaternion Lerp(const Quaternion &q1, const Quaternion &q2, float t);
380
381   /**
382    * @brief Spherical Linear Interpolation (using the shortest arc of a great circle between
383    * the two quaternions).
384    *
385    * @param[in] q1 - the start quaternion
386    * @param[in] q2 - the end quaternion
387    * @param[in] progress  - a progress value between 0 and 1
388    * @return the interpolated quaternion
389    */
390   static Quaternion Slerp(const Quaternion &q1, const Quaternion &q2, float progress);
391
392   /**
393    * @brief This version of Slerp, used by Squad, does not check for theta > 90.
394    *
395    * @param[in] q1 - the start quaternion
396    * @param[in] q2 - the end quaternion
397    * @param[in] t  - a progress value between 0 and 1
398    * @return the interpolated quaternion
399    */
400   static Quaternion SlerpNoInvert(const Quaternion &q1, const Quaternion &q2, float t);
401
402   /**
403    * @brief Spherical Cubic Interpolation.
404    *
405    * @param[in] q1 - the start quaternion
406    * @param[in] q2 - the end quaternion
407    * @param[in] a  - the control quaternion for q1
408    * @param[in] b  - the control quaternion for q2
409    * @param[in] t  - a progress value between 0 and 1
410    * @return the interpolated quaternion
411    */
412   static Quaternion Squad(const Quaternion &q1,const Quaternion &q2,const Quaternion &a,const Quaternion &b,float t);
413
414   /**
415    * @brief Returns the shortest angle between two quaternions in Radians.
416    *
417    * @param[in] q1 - the first quaternion
418    * @param[in] q2 - the second quaternion
419    * @return the angle between the two quaternions.
420    */
421   static float AngleBetween(const Quaternion &q1, const Quaternion &q2);
422
423   /**
424    * @brief Rotate v by this Quaternion (Quaternion must be unit).
425    *
426    * @param[in] v - a vector to rotate
427    * @return the rotated vector
428    */
429   Vector4 Rotate(const Vector4 &v) const;
430
431   /**
432    * @brief Rotate v by this Quaternion (Quaternion must be unit).
433    *
434    * @param[in] v - a vector to rotate
435    * @return the rotated vector
436    */
437   Vector3 Rotate(const Vector3 &v) const;
438
439 private:
440
441   /**
442    * @brief Set the quaternion from 3 orthonormal axes.
443    *
444    * @param[in] xAxis The X axis
445    * @param[in] yAxis The Y axis
446    * @param[in] zAxis The Z axis
447    */
448   DALI_INTERNAL void SetFromAxes( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
449
450 public:
451
452   Vector4 mVector;   ///< w component is s ( = cos(theta/2.0) )
453 };
454
455 /**
456  * @brief Print a Quaternion.
457  *
458  * @param [in] o The output stream operator.
459  * @param [in] quaternion The quaternion to print.
460  * @return The output stream operator.
461  */
462 DALI_IMPORT_API std::ostream& operator<< (std::ostream& o, const Quaternion& quaternion);
463
464 } // namespace Dali
465
466 #endif // __DALI_QUATERNION_H__