1 #ifndef __DALI_QUATERNION_H__
2 #define __DALI_QUATERNION_H__
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/public-api/common/constants.h>
24 #include <dali/public-api/math/vector4.h>
29 // Forward declaration
33 * @brief The Quaternion class encapsulates the mathematics of the quaternion.
35 class DALI_IMPORT_API Quaternion
40 * @brief Default Constructor
45 * @brief Construct from a quaternion represented by floats.
47 * @param[in] cosThetaBy2
48 * @param[in] iBySineTheta
49 * @param[in] jBySineTheta
50 * @param[in] kBySineTheta
52 Quaternion(float cosThetaBy2, float iBySineTheta, float jBySineTheta, float kBySineTheta);
55 * @brief Construct from a quaternion represented by a vector.
57 * @param[in] vector - x,y,z fields represent i,j,k coefficients, w represents cos(theta/2)
59 explicit Quaternion(const Vector4& vector);
62 * @brief Constructor from an axis and angle.
64 * @param[in] angle - the angle around the axis
65 * @param[in] axis - the vector of the axis
67 Quaternion(float angle, const Vector3 &axis);
70 * @brief Constructor from an axis and angle.
72 * @param[in] theta - the angle of the axis
73 * @param[in] axis - the unit vector of the axis
75 Quaternion(float theta, const Vector4 &axis);
78 * @brief Construct from Euler angles.
80 * @param[in] x - the X axis euler angle (pitch)
81 * @param[in] y - the Y axis euler angle (yaw)
82 * @param[in] z - the Z axis euler angle (roll)
84 Quaternion(float x, float y, float z);
87 * @brief Construct from a matrix.
91 explicit Quaternion(const Matrix& matrix);
94 * @brief Construct from 3 orthonormal axes.
96 * @param[in] xAxis The X axis
97 * @param[in] yAxis The Y axis
98 * @param[in] zAxis The Z axis
100 explicit Quaternion( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
103 * @brief Construct quaternion which describes minimum rotation to align v0 with v1
104 * @pre v0 and v1 should be normalized
106 * @param[in] v0 First normalized vector
107 * @param[in] v1 Second normalized vector
109 explicit Quaternion( const Vector3& v0, const Vector3& v1 );
112 * @brief Converts an axis + angle pair rotation to a Quaternion.
116 * @return the represented quaternion
118 static Quaternion FromAxisAngle(const Vector4 &axis, float angle);
121 * @brief Destructor, nonvirtual as this is not a base class.
128 static const Quaternion IDENTITY; ///< (0.0f,0.0f,0.0f,1.0f)
131 * @brief Helper to check if this is an identity quaternion
133 * @return true if this is identity quaternion
135 bool IsIdentity() const;
138 * @brief Convert the quaternion to an axis/angle pair.
142 * @return true if converted correctly
144 bool ToAxisAngle(Vector3 &axis, float &angle) const;
147 * @brief Convert the quaternion to an axis/angle pair.
151 * @return true if converted correctly
153 bool ToAxisAngle(Vector4 &axis, float &angle) const;
156 * @brief Return the quaternion as a vector.
158 * @return the vector representation of the quaternion
160 const Vector4& AsVector() const;
163 * @brief SetEuler sets the quaternion from the Euler angles applied in x, y, z order.
165 * @param[in] x - the X axis euler angle (pitch)
166 * @param[in] y - the Y axis euler angle (yaw)
167 * @param[in] z - the Z axis euler angle (roll)
169 void SetEuler(float x, float y, float z);
172 * @brief returns the Euler angles from a rotation Quaternion.
174 * @return a vector of Euler angles (x == pitch, y == yaw, z == roll)
176 Vector4 EulerAngles() const;
179 * @brief Addition operator.
181 * @param[in] other The quaternion to add
182 * @return A quaternion containing the result of the addition
184 const Quaternion operator +(const Quaternion &other) const;
187 * @brief Subtraction operator.
189 * @param[in] other The quaternion to subtract
190 * @return A quaternion containing the result of the subtract
192 const Quaternion operator -(const Quaternion &other) const;
195 * @brief Multiplication operator.
197 * @param[in] other The quaternion to multiply
198 * @return A quaternion containing the result
200 const Quaternion operator *(const Quaternion &other) const;
203 * @brief Multiplication operator.
205 * @param[in] v The vector to multiply
206 * @return A vector containing the result of the multiplication
208 Vector3 operator *(const Vector3& v) const;
211 * @brief Division operator.
213 * @param[in] other a quaternion to divide by
214 * @return A quaternion containing the result
216 const Quaternion operator /(const Quaternion &other) const;
219 * @brief Scale operator.
221 * @param[in] scale A value to scale by
222 * @return A quaternion containing the result
224 const Quaternion operator *(float scale) const;
227 * @brief Scale operator.
229 * @param[in] scale A value to scale by
230 * @return A quaternion containing the result
232 const Quaternion operator /(float scale) const;
235 * @brief Unary Negation operator.
237 * @return A quaternion containing the negated result
239 Quaternion operator -() const;
242 * @brief Addition with Assignment operator.
244 * @param[in] other The quaternion to add
247 const Quaternion &operator +=(const Quaternion &other);
250 * @brief Subtraction with Assignment operator.
252 * @param[in] other The quaternion to subtract
255 const Quaternion &operator -=(const Quaternion &other);
258 * @brief Multiplication with Assignment operator.
260 * @param[in] other The quaternion to multiply
263 const Quaternion &operator *=(const Quaternion &other);
266 * @brief Scale with Assignment operator.
268 * @param[in] scale the value to scale by
271 const Quaternion &operator *= (float scale);
274 * @brief Scale with Assignment operator.
276 * @param[in] scale the value to scale by
279 const Quaternion &operator /= (float scale);
282 * @brief Equality operator.
284 * @param[in] rhs The quaterion to compare with.
285 * @return True if the quaternions are equal.
287 bool operator== (const Quaternion& rhs) const;
290 * @brief Inequality operator.
292 * @param[in] rhs The quaterion to compare with.
293 * @return True if the quaternions are not equal.
295 bool operator!= (const Quaternion& rhs) const;
298 * @brief Return the length of the quaternion.
300 * @return the length of the quaternion
302 float Length() const;
305 * @brief Return the squared length of the quaternion.
307 * @return the squared length of the quaternion
309 float LengthSquared() const;
312 * @brief Normalize this to unit length.
320 * @return a normalized version of this quaternion
322 Quaternion Normalized() const;
325 * @brief Conjugate this quaternion.
331 * @brief Invert this quaternion.
337 * @brief Performs the logarithm of a Quaternion = v*a where q = (cos(a),v*sin(a)).
339 * @return a quaternion representing the logarithm
341 Quaternion Log() const;
344 * @brief Performs an exponent e^Quaternion = Exp(v*a) = (cos(a),vsin(a)).
346 * @return a quaternion representing the exponent
348 Quaternion Exp() const;
351 * @brief Return the dot product of two quaternions.
353 * @param[in] q1 - the first quaternion
354 * @param[in] q2 - the second quaternion
355 * @return the dot product of the two quaternions
357 static float Dot(const Quaternion &q1, const Quaternion &q2);
360 * @brief Linear Interpolation (using a straight line between the two quaternions).
362 * @param[in] q1 - the start quaternion
363 * @param[in] q2 - the end quaternion
364 * @param[in] t - a progress value between 0 and 1
365 * @return the interpolated quaternion
367 static Quaternion Lerp(const Quaternion &q1, const Quaternion &q2, float t);
370 * @brief Spherical Linear Interpolation (using the shortest arc of a great circle between
371 * the two quaternions).
373 * @param[in] q1 - the start quaternion
374 * @param[in] q2 - the end quaternion
375 * @param[in] progress - a progress value between 0 and 1
376 * @return the interpolated quaternion
378 static Quaternion Slerp(const Quaternion &q1, const Quaternion &q2, float progress);
381 * @brief This version of Slerp, used by Squad, does not check for theta > 90.
383 * @param[in] q1 - the start quaternion
384 * @param[in] q2 - the end quaternion
385 * @param[in] t - a progress value between 0 and 1
386 * @return the interpolated quaternion
388 static Quaternion SlerpNoInvert(const Quaternion &q1, const Quaternion &q2, float t);
391 * @brief Spherical Cubic Interpolation.
393 * @param[in] q1 - the start quaternion
394 * @param[in] q2 - the end quaternion
395 * @param[in] a - the control quaternion for q1
396 * @param[in] b - the control quaternion for q2
397 * @param[in] t - a progress value between 0 and 1
398 * @return the interpolated quaternion
400 static Quaternion Squad(const Quaternion &q1,const Quaternion &q2,const Quaternion &a,const Quaternion &b,float t);
403 * @brief Returns the shortest angle between two quaternions in Radians.
405 * @param[in] q1 - the first quaternion
406 * @param[in] q2 - the second quaternion
407 * @return the angle between the two quaternions.
409 static float AngleBetween(const Quaternion &q1, const Quaternion &q2);
412 * @brief Rotate v by this Quaternion (Quaternion must be unit).
414 * @param[in] v - a vector to rotate
415 * @return the rotated vector
417 Vector4 Rotate(const Vector4 &v) const;
420 * @brief Rotate v by this Quaternion (Quaternion must be unit).
422 * @param[in] v - a vector to rotate
423 * @return the rotated vector
425 Vector3 Rotate(const Vector3 &v) const;
430 * @brief Set the quaternion from 3 orthonormal axes.
432 * @param[in] xAxis The X axis
433 * @param[in] yAxis The Y axis
434 * @param[in] zAxis The Z axis
436 DALI_INTERNAL void SetFromAxes( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
440 Vector4 mVector; ///< w component is s ( = cos(theta/2.0) )
444 * @brief Print a Quaternion.
446 * @param [in] o The output stream operator.
447 * @param [in] quaternion The quaternion to print.
448 * @return The output stream operator.
450 DALI_IMPORT_API std::ostream& operator<< (std::ostream& o, const Quaternion& quaternion);
454 #endif // __DALI_QUATERNION_H__