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.
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>
33 // Forward declaration
37 * @brief The Quaternion class encapsulates the mathematics of the quaternion.
39 class DALI_IMPORT_API Quaternion
44 * @brief Default Constructor
49 * @brief Construct from a quaternion represented by floats.
51 * @param[in] cosThetaBy2
52 * @param[in] iBySineTheta
53 * @param[in] jBySineTheta
54 * @param[in] kBySineTheta
56 Quaternion(float cosThetaBy2, float iBySineTheta, float jBySineTheta, float kBySineTheta);
59 * @brief Construct from a quaternion represented by a vector.
61 * @param[in] vector - x,y,z fields represent i,j,k coefficients, w represents cos(theta/2)
63 explicit Quaternion(const Vector4& vector);
66 * @brief Constructor from an axis and angle.
68 * @param[in] angle - the angle around the axis
69 * @param[in] axis - the vector of the axis
71 Quaternion(float angle, const Vector3 &axis);
74 * @brief Constructor from an axis and angle.
76 * @param[in] theta - the angle of the axis
77 * @param[in] axis - the unit vector of the axis
79 Quaternion(float theta, const Vector4 &axis);
82 * @brief Construct from Euler angles.
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)
88 Quaternion(float x, float y, float z);
91 * @brief Construct from a matrix.
95 explicit Quaternion(const Matrix& matrix);
98 * @brief Construct from 3 orthonormal axes.
100 * @param[in] xAxis The X axis
101 * @param[in] yAxis The Y axis
102 * @param[in] zAxis The Z axis
104 explicit Quaternion( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
107 * @brief Construct quaternion which describes minimum rotation to align v0 with v1
108 * @pre v0 and v1 should be normalized
110 * @param[in] v0 First normalized vector
111 * @param[in] v1 Second normalized vector
113 explicit Quaternion( const Vector3& v0, const Vector3& v1 );
116 * @brief Converts an axis + angle pair rotation to a Quaternion.
120 * @return the represented quaternion
122 static Quaternion FromAxisAngle(const Vector4 &axis, float angle);
125 * @brief Destructor, nonvirtual as this is not a base class.
132 static const Quaternion IDENTITY; ///< (0.0f,0.0f,0.0f,1.0f)
135 * @brief Helper to check if this is an identity quaternion
137 * @return true if this is identity quaternion
139 bool IsIdentity() const
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 ) );
150 * @brief Convert the quaternion to an axis/angle pair.
154 * @return true if converted correctly
156 bool ToAxisAngle(Vector3 &axis, float &angle) const;
159 * @brief Convert the quaternion to an axis/angle pair.
163 * @return true if converted correctly
165 bool ToAxisAngle(Vector4 &axis, float &angle) const;
168 * @brief Return the quaternion as a vector.
170 * @return the vector representation of the quaternion
172 const Vector4& AsVector() const;
175 * @brief SetEuler sets the quaternion from the Euler angles applied in x, y, z order.
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)
181 void SetEuler(float x, float y, float z);
184 * @brief returns the Euler angles from a rotation Quaternion.
186 * @return a vector of Euler angles (x == pitch, y == yaw, z == roll)
188 Vector4 EulerAngles() const;
191 * @brief Addition operator.
193 * @param[in] other The quaternion to add
194 * @return A quaternion containing the result of the addition
196 const Quaternion operator +(const Quaternion &other) const;
199 * @brief Subtraction operator.
201 * @param[in] other The quaternion to subtract
202 * @return A quaternion containing the result of the subtract
204 const Quaternion operator -(const Quaternion &other) const;
207 * @brief Multiplication operator.
209 * @param[in] other The quaternion to multiply
210 * @return A quaternion containing the result
212 const Quaternion operator *(const Quaternion &other) const;
215 * @brief Multiplication operator.
217 * @param[in] v The vector to multiply
218 * @return A vector containing the result of the multiplication
220 Vector3 operator *(const Vector3& v) const;
223 * @brief Division operator.
225 * @param[in] other a quaternion to divide by
226 * @return A quaternion containing the result
228 const Quaternion operator /(const Quaternion &other) const;
231 * @brief Scale operator.
233 * @param[in] scale A value to scale by
234 * @return A quaternion containing the result
236 const Quaternion operator *(float scale) const;
239 * @brief Scale operator.
241 * @param[in] scale A value to scale by
242 * @return A quaternion containing the result
244 const Quaternion operator /(float scale) const;
247 * @brief Unary Negation operator.
249 * @return A quaternion containing the negated result
251 Quaternion operator -() const;
254 * @brief Addition with Assignment operator.
256 * @param[in] other The quaternion to add
259 const Quaternion &operator +=(const Quaternion &other);
262 * @brief Subtraction with Assignment operator.
264 * @param[in] other The quaternion to subtract
267 const Quaternion &operator -=(const Quaternion &other);
270 * @brief Multiplication with Assignment operator.
272 * @param[in] other The quaternion to multiply
275 const Quaternion &operator *=(const Quaternion &other);
278 * @brief Scale with Assignment operator.
280 * @param[in] scale the value to scale by
283 const Quaternion &operator *= (float scale);
286 * @brief Scale with Assignment operator.
288 * @param[in] scale the value to scale by
291 const Quaternion &operator /= (float scale);
294 * @brief Equality operator.
296 * @param[in] rhs The quaterion to compare with.
297 * @return True if the quaternions are equal.
299 bool operator== (const Quaternion& rhs) const;
302 * @brief Inequality operator.
304 * @param[in] rhs The quaterion to compare with.
305 * @return True if the quaternions are not equal.
307 bool operator!= (const Quaternion& rhs) const;
310 * @brief Return the length of the quaternion.
312 * @return the length of the quaternion
314 float Length() const;
317 * @brief Return the squared length of the quaternion.
319 * @return the squared length of the quaternion
321 float LengthSquared() const;
324 * @brief Normalize this to unit length.
332 * @return a normalized version of this quaternion
334 Quaternion Normalized() const;
337 * @brief Conjugate this quaternion.
343 * @brief Invert this quaternion.
349 * @brief Performs the logarithm of a Quaternion = v*a where q = (cos(a),v*sin(a)).
351 * @return a quaternion representing the logarithm
353 Quaternion Log() const;
356 * @brief Performs an exponent e^Quaternion = Exp(v*a) = (cos(a),vsin(a)).
358 * @return a quaternion representing the exponent
360 Quaternion Exp() const;
363 * @brief Return the dot product of two quaternions.
365 * @param[in] q1 - the first quaternion
366 * @param[in] q2 - the second quaternion
367 * @return the dot product of the two quaternions
369 static float Dot(const Quaternion &q1, const Quaternion &q2);
372 * @brief Linear Interpolation (using a straight line between the two quaternions).
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
379 static Quaternion Lerp(const Quaternion &q1, const Quaternion &q2, float t);
382 * @brief Spherical Linear Interpolation (using the shortest arc of a great circle between
383 * the two quaternions).
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
390 static Quaternion Slerp(const Quaternion &q1, const Quaternion &q2, float progress);
393 * @brief This version of Slerp, used by Squad, does not check for theta > 90.
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
400 static Quaternion SlerpNoInvert(const Quaternion &q1, const Quaternion &q2, float t);
403 * @brief Spherical Cubic Interpolation.
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
412 static Quaternion Squad(const Quaternion &q1,const Quaternion &q2,const Quaternion &a,const Quaternion &b,float t);
415 * @brief Returns the shortest angle between two quaternions in Radians.
417 * @param[in] q1 - the first quaternion
418 * @param[in] q2 - the second quaternion
419 * @return the angle between the two quaternions.
421 static float AngleBetween(const Quaternion &q1, const Quaternion &q2);
424 * @brief Rotate v by this Quaternion (Quaternion must be unit).
426 * @param[in] v - a vector to rotate
427 * @return the rotated vector
429 Vector4 Rotate(const Vector4 &v) const;
432 * @brief Rotate v by this Quaternion (Quaternion must be unit).
434 * @param[in] v - a vector to rotate
435 * @return the rotated vector
437 Vector3 Rotate(const Vector3 &v) const;
442 * @brief Set the quaternion from 3 orthonormal axes.
444 * @param[in] xAxis The X axis
445 * @param[in] yAxis The Y axis
446 * @param[in] zAxis The Z axis
448 DALI_INTERNAL void SetFromAxes( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
452 Vector4 mVector; ///< w component is s ( = cos(theta/2.0) )
456 * @brief Print a Quaternion.
458 * @param [in] o The output stream operator.
459 * @param [in] quaternion The quaternion to print.
460 * @return The output stream operator.
462 DALI_IMPORT_API std::ostream& operator<< (std::ostream& o, const Quaternion& quaternion);
466 #endif // __DALI_QUATERNION_H__