1 #ifndef DALI_QUATERNION_H
2 #define DALI_QUATERNION_H
5 * Copyright (c) 2020 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.
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>
34 * @addtogroup dali_core_math
38 // Forward declaration
42 * @brief The Quaternion class encapsulates the mathematics of the quaternion.
45 class DALI_CORE_API Quaternion
50 * @brief Default Constructor.
56 * @brief Constructs from a quaternion represented by floats.
59 * @param[in] cosThetaBy2
60 * @param[in] iBySineTheta
61 * @param[in] jBySineTheta
62 * @param[in] kBySineTheta
64 Quaternion( float cosThetaBy2, float iBySineTheta, float jBySineTheta, float kBySineTheta );
67 * @brief Constructs from a quaternion represented by a vector.
70 * @param[in] vector x,y,z fields represent i,j,k coefficients, w represents cos(theta/2)
72 explicit Quaternion( const Vector4& vector );
75 * @brief Constructor from an axis and angle.
78 * @param[in] angle The angle around the axis
79 * @param[in] axis The vector of the axis
81 Quaternion( Radian angle, const Vector3& axis );
84 * @brief Constructs from Euler angles.
91 Quaternion( Radian pitch, Radian yaw, Radian roll );
94 * @brief Constructs from a matrix.
99 explicit Quaternion(const Matrix& matrix);
102 * @brief Constructs from 3 orthonormal axes.
105 * @param[in] xAxis The X axis
106 * @param[in] yAxis The Y axis
107 * @param[in] zAxis The Z axis
109 explicit Quaternion( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
112 * @brief Constructs quaternion which describes minimum rotation to align v0 with v1.
114 * @param[in] v0 First normalized vector
115 * @param[in] v1 Second normalized vector
116 * @pre v0 and v1 should be normalized
119 explicit Quaternion( const Vector3& v0, const Vector3& v1 );
122 * @brief Destructor, nonvirtual as this is not a base class.
130 static const Quaternion IDENTITY; ///< (0.0f,0.0f,0.0f,1.0f)
133 * @brief Helper to check if this is an identity quaternion.
136 * @return True if this is identity quaternion
138 bool IsIdentity() const;
141 * @brief Converts the quaternion to an axis/angle pair.
145 * @param[out] angle Angle in radians
146 * @return True if converted correctly
148 bool ToAxisAngle( Vector3& axis, Radian& angle ) const;
151 * @brief Returns the quaternion as a vector.
154 * @return The vector representation of the quaternion
156 const Vector4& AsVector() const;
159 * @brief SetEuler sets the quaternion from the Euler angles applied in x, y, z order.
166 void SetEuler( Radian pitch, Radian yaw, Radian roll );
169 * @brief Returns the Euler angles from a rotation Quaternion.
172 * @return A vector of Euler angles (x == pitch, y == yaw, z == roll)
174 Vector4 EulerAngles() const;
177 * @brief Addition operator.
180 * @param[in] other The quaternion to add
181 * @return A quaternion containing the result of the addition
183 const Quaternion operator+( const Quaternion& other ) const;
186 * @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.
198 * @param[in] other The quaternion to multiply
199 * @return A quaternion containing the result
201 const Quaternion operator*( const Quaternion& other ) const;
204 * @brief Multiplication operator.
207 * @param[in] other The vector to multiply
208 * @return A vector containing the result of the multiplication
210 Vector3 operator*( const Vector3& other ) const;
213 * @brief Division operator.
216 * @param[in] other A quaternion to divide by
217 * @return A quaternion containing the result
219 const Quaternion operator/( const Quaternion& other ) const;
222 * @brief Scale operator.
225 * @param[in] scale A value to scale by
226 * @return A quaternion containing the result
228 const Quaternion operator*( float scale ) const;
231 * @brief Scale operator.
234 * @param[in] scale A value to scale by
235 * @return A quaternion containing the result
237 const Quaternion operator/( float scale ) const;
240 * @brief Unary Negation operator.
243 * @return A quaternion containing the negated result
245 Quaternion operator-() const;
248 * @brief Addition with Assignment operator.
251 * @param[in] other The quaternion to add
252 * @return A reference to this
254 const Quaternion& operator+=( const Quaternion& other );
257 * @brief Subtraction with Assignment operator.
260 * @param[in] other The quaternion to subtract
261 * @return A reference to this
263 const Quaternion& operator-=( const Quaternion& other );
266 * @brief Multiplication with Assignment operator.
269 * @param[in] other The quaternion to multiply
270 * @return A reference to this
272 const Quaternion& operator*=( const Quaternion& other );
275 * @brief Scale with Assignment operator.
278 * @param[in] scale the value to scale by
279 * @return A reference to this
281 const Quaternion& operator*=( float scale );
284 * @brief Scale with Assignment operator.
287 * @param[in] scale The value to scale by
288 * @return A reference to this
290 const Quaternion& operator/=( float scale );
293 * @brief Equality operator.
296 * @param[in] rhs The quaternion to compare with
297 * @return True if the quaternions are equal
299 bool operator==( const Quaternion& rhs ) const;
302 * @brief Inequality operator.
305 * @param[in] rhs The quaternion to compare with
306 * @return True if the quaternions are not equal
308 bool operator!=( const Quaternion& rhs ) const;
311 * @brief Returns the length of the quaternion.
314 * @return The length of the quaternion
316 float Length() const;
319 * @brief Returns the squared length of the quaternion.
322 * @return The squared length of the quaternion
324 float LengthSquared() const;
327 * @brief Normalizes this to unit length.
337 * @return A normalized version of this quaternion
339 Quaternion Normalized() const;
342 * @brief Conjugates this quaternion.
349 * @brief Inverts this quaternion.
356 * @brief Performs the logarithm of a Quaternion = v*a where q = (cos(a),v*sin(a)).
359 * @return A quaternion representing the logarithm
361 Quaternion Log() const;
364 * @brief Performs an exponent e^Quaternion = Exp(v*a) = (cos(a),vsin(a)).
367 * @return A quaternion representing the exponent
369 Quaternion Exp() const;
372 * @brief Returns the dot product of two quaternions.
375 * @param[in] q1 The first quaternion
376 * @param[in] q2 The second quaternion
377 * @return The dot product of the two quaternions
379 static float Dot( const Quaternion &q1, const Quaternion &q2 );
382 * @brief Linear Interpolation (using a straight line between the two quaternions).
385 * @param[in] q1 The start quaternion
386 * @param[in] q2 The end quaternion
387 * @param[in] t A progress value between 0 and 1
388 * @return The interpolated quaternion
390 static Quaternion Lerp( const Quaternion &q1, const Quaternion &q2, float t );
393 * @brief Spherical Linear Interpolation (using the shortest arc of a great circle between
394 * the two quaternions).
397 * @param[in] q1 The start quaternion
398 * @param[in] q2 The end quaternion
399 * @param[in] progress A progress value between 0 and 1
400 * @return The interpolated quaternion
402 static Quaternion Slerp( const Quaternion &q1, const Quaternion &q2, float progress );
405 * @brief This version of Slerp, used by Squad, does not check for theta > 90.
408 * @param[in] q1 The start quaternion
409 * @param[in] q2 The end quaternion
410 * @param[in] t A progress value between 0 and 1
411 * @return The interpolated quaternion
413 static Quaternion SlerpNoInvert( const Quaternion &q1, const Quaternion &q2, float t );
416 * @brief Spherical Cubic Interpolation.
419 * @param[in] start The start quaternion
420 * @param[in] end The end quaternion
421 * @param[in] ctrl1 The control quaternion for q1
422 * @param[in] ctrl2 The control quaternion for q2
423 * @param[in] t A progress value between 0 and 1
424 * @return The interpolated quaternion
426 static Quaternion Squad( const Quaternion& start, const Quaternion& end, const Quaternion& ctrl1, const Quaternion& ctrl2, float t );
429 * @brief Returns the shortest angle between two quaternions in Radians.
432 * @param[in] q1 The first quaternion
433 * @param[in] q2 The second quaternion
434 * @return The angle between the two quaternions
436 static float AngleBetween( const Quaternion& q1, const Quaternion& q2 );
439 * @brief Rotates v by this Quaternion (Quaternion must be unit).
442 * @param[in] vector A vector to rotate
443 * @return The rotated vector
445 Vector4 Rotate( const Vector4& vector ) const;
448 * @brief Rotates v by this Quaternion (Quaternion must be unit).
451 * @param[in] vector A vector to rotate
452 * @return The rotated vector
454 Vector3 Rotate( const Vector3& vector ) const;
460 * @brief Sets the quaternion from 3 orthonormal axes.
463 * @param[in] xAxis The X axis
464 * @param[in] yAxis The Y axis
465 * @param[in] zAxis The Z axis
467 DALI_INTERNAL void SetFromAxes( const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis );
472 Quaternion( const Quaternion& ) = default; ///< Default copy constructor
473 Quaternion( Quaternion&& ) = default; ///< Default move constructor
474 Quaternion& operator=( const Quaternion& ) = default; ///< Default copy assignment operator
475 Quaternion& operator=( Quaternion&& ) = default; ///< Default move assignment operator
479 Vector4 mVector; ///< w component is s ( = cos(theta/2.0) )
483 * @brief Prints a Quaternion.
486 * @param[in] o The output stream operator
487 * @param[in] quaternion The quaternion to print
488 * @return The output stream operator
490 DALI_CORE_API std::ostream& operator<< (std::ostream& o, const Quaternion& quaternion);
492 // Allow Quaternion to be treated as a POD type
493 template <> struct TypeTraits< Quaternion > : public BasicTypes< Quaternion > { enum { IS_TRIVIAL_TYPE = true }; };
500 #endif // DALI_QUATERNION_H