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