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