1 #ifndef DALI_QUATERNION_H
2 #define DALI_QUATERNION_H
5 * Copyright (c) 2022 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
49 * @brief Default Constructor.
55 * @brief Constructs from a quaternion represented by floats.
58 * @param[in] cosThetaBy2
59 * @param[in] iBySineTheta
60 * @param[in] jBySineTheta
61 * @param[in] kBySineTheta
63 Quaternion(float cosThetaBy2, float iBySineTheta, float jBySineTheta, float kBySineTheta);
66 * @brief Constructs from a quaternion represented by a vector.
69 * @param[in] vector x,y,z fields represent i,j,k coefficients, w represents cos(theta/2)
71 explicit Quaternion(const Vector4& vector);
74 * @brief Constructor from an axis and angle.
77 * @param[in] angle The angle around the axis
78 * @param[in] axis The vector of the axis
80 Quaternion(Radian angle, const Vector3& axis);
83 * @brief Constructs from Euler angles.
90 Quaternion(Radian pitch, Radian yaw, Radian roll);
93 * @brief Constructs from a matrix.
98 explicit Quaternion(const Matrix& matrix);
101 * @brief Constructs from 3 orthonormal axes.
104 * @param[in] xAxis The X axis
105 * @param[in] yAxis The Y axis
106 * @param[in] zAxis The Z axis
108 explicit Quaternion(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
111 * @brief Constructs quaternion which describes minimum rotation to align v0 with v1.
113 * @param[in] v0 First normalized vector
114 * @param[in] v1 Second normalized vector
115 * @pre v0 and v1 should be normalized
118 explicit Quaternion(const Vector3& v0, const Vector3& v1);
121 * @brief Destructor, nonvirtual as this is not a base class.
129 static const Quaternion IDENTITY; ///< (0.0f,0.0f,0.0f,1.0f)
132 * @brief Helper to check if this is an identity quaternion.
135 * @return True if this is identity quaternion
137 bool IsIdentity() const;
140 * @brief Converts the quaternion to an axis/angle pair.
144 * @param[out] angle Angle in radians
145 * @return True if converted correctly
147 bool ToAxisAngle(Vector3& axis, Radian& angle) const;
150 * @brief Returns the quaternion as a vector.
153 * @return The vector representation of the quaternion
155 const Vector4& AsVector() const;
158 * @brief SetEuler sets the quaternion from the Euler angles applied in x, y, z order.
165 void SetEuler(Radian pitch, Radian yaw, Radian roll);
168 * @brief Returns the Euler angles from a rotation Quaternion.
171 * @return A vector of Euler angles (x == pitch, y == yaw, z == roll)
173 Vector4 EulerAngles() const;
176 * @brief Addition operator.
179 * @param[in] other The quaternion to add
180 * @return A quaternion containing the result of the addition
182 const Quaternion operator+(const Quaternion& other) const;
185 * @brief Subtraction operator.
188 * @param[in] other The quaternion to subtract
189 * @return A quaternion containing the result of the subtract
191 const Quaternion operator-(const Quaternion& other) const;
194 * @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.
206 * @param[in] other The vector to multiply
207 * @return A vector containing the result of the multiplication
209 Vector3 operator*(const Vector3& other) const;
212 * @brief Division operator.
215 * @param[in] other A quaternion to divide by
216 * @return A quaternion containing the result
218 const Quaternion operator/(const Quaternion& other) const;
221 * @brief Scale operator.
224 * @param[in] scale A value to scale by
225 * @return A quaternion containing the result
227 const Quaternion operator*(float scale) const;
230 * @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 Unary Negation operator.
242 * @return A quaternion containing the negated result
244 Quaternion operator-() const;
247 * @brief Addition with Assignment operator.
250 * @param[in] other The quaternion to add
251 * @return A reference to this
253 const Quaternion& operator+=(const Quaternion& other);
256 * @brief Subtraction with Assignment operator.
259 * @param[in] other The quaternion to subtract
260 * @return A reference to this
262 const Quaternion& operator-=(const Quaternion& other);
265 * @brief Multiplication with Assignment operator.
268 * @param[in] other The quaternion to multiply
269 * @return A reference to this
271 const Quaternion& operator*=(const Quaternion& other);
274 * @brief Scale with Assignment operator.
277 * @param[in] scale the value to scale by
278 * @return A reference to this
280 const Quaternion& operator*=(float scale);
283 * @brief Scale with Assignment operator.
286 * @param[in] scale The value to scale by
287 * @return A reference to this
289 const Quaternion& operator/=(float scale);
292 * @brief Equality operator.
295 * @param[in] rhs The quaternion to compare with
296 * @return True if the quaternions are equal
298 bool operator==(const Quaternion& rhs) const;
301 * @brief Inequality operator.
304 * @param[in] rhs The quaternion to compare with
305 * @return True if the quaternions are not equal
307 bool operator!=(const Quaternion& rhs) const;
310 * @brief Returns the length of the quaternion.
313 * @return The length of the quaternion
315 float Length() const;
318 * @brief Returns the squared length of the quaternion.
321 * @return The squared length of the quaternion
323 float LengthSquared() const;
326 * @brief Normalizes this to unit length.
336 * @return A normalized version of this quaternion
338 Quaternion Normalized() const;
341 * @brief Conjugates this quaternion.
348 * @brief Inverts this quaternion.
355 * @brief Performs the logarithm of a Quaternion = v*a where q = (cos(a),v*sin(a)).
358 * @return A quaternion representing the logarithm
360 Quaternion Log() const;
363 * @brief Performs an exponent e^Quaternion = Exp(v*a) = (cos(a),vsin(a)).
366 * @return A quaternion representing the exponent
368 Quaternion Exp() const;
371 * @brief Returns the dot product of two quaternions.
374 * @param[in] q1 The first quaternion
375 * @param[in] q2 The second quaternion
376 * @return The dot product of the two quaternions
378 static float Dot(const Quaternion& q1, const Quaternion& q2);
381 * @brief Linear Interpolation (using a straight line between the two quaternions).
384 * @param[in] q1 The start quaternion
385 * @param[in] q2 The end quaternion
386 * @param[in] t A progress value between 0 and 1
387 * @return The interpolated quaternion
389 static Quaternion Lerp(const Quaternion& q1, const Quaternion& q2, float t);
392 * @brief Spherical Linear Interpolation (using the shortest arc of a great circle between
393 * the two quaternions).
396 * @param[in] q1 The start quaternion
397 * @param[in] q2 The end quaternion
398 * @param[in] progress A progress value between 0 and 1
399 * @return The interpolated quaternion
401 static Quaternion Slerp(const Quaternion& q1, const Quaternion& q2, float progress);
404 * @brief This version of Slerp, used by Squad, does not check for theta > 90.
407 * @param[in] q1 The start quaternion
408 * @param[in] q2 The end quaternion
409 * @param[in] t A progress value between 0 and 1
410 * @return The interpolated quaternion
412 static Quaternion SlerpNoInvert(const Quaternion& q1, const Quaternion& q2, float t);
415 * @brief Spherical Cubic Interpolation.
418 * @param[in] start The start quaternion
419 * @param[in] end The end quaternion
420 * @param[in] ctrl1 The control quaternion for q1
421 * @param[in] ctrl2 The control quaternion for q2
422 * @param[in] t A progress value between 0 and 1
423 * @return The interpolated quaternion
425 static Quaternion Squad(const Quaternion& start, const Quaternion& end, const Quaternion& ctrl1, const Quaternion& ctrl2, float t);
428 * @brief Returns the shortest angle between two quaternions in Radians.
431 * @param[in] q1 The first quaternion
432 * @param[in] q2 The second quaternion
433 * @return The angle between the two quaternions
435 static float AngleBetween(const Quaternion& q1, const Quaternion& q2);
438 * @brief Rotates v by this Quaternion (Quaternion must be unit).
441 * @param[in] vector A vector to rotate
442 * @return The rotated vector
444 Vector4 Rotate(const Vector4& vector) const;
447 * @brief Rotates v by this Quaternion (Quaternion must be unit).
450 * @param[in] vector A vector to rotate
451 * @return The rotated vector
453 Vector3 Rotate(const Vector3& vector) const;
458 * @brief Sets the quaternion from 3 orthonormal axes.
461 * @param[in] xAxis The X axis
462 * @param[in] yAxis The Y axis
463 * @param[in] zAxis The Z axis
465 DALI_INTERNAL void SetFromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis);
469 Quaternion(const Quaternion&) = default; ///< Default copy constructor
470 Quaternion(Quaternion&&) noexcept = default; ///< Default move constructor
471 Quaternion& operator=(const Quaternion&) = default; ///< Default copy assignment operator
472 Quaternion& operator=(Quaternion&&) noexcept = default; ///< Default move assignment operator
475 Vector4 mVector; ///< w component is s ( = cos(theta/2.0) )
479 * @brief Prints a Quaternion.
482 * @param[in] o The output stream operator
483 * @param[in] quaternion The quaternion to print
484 * @return The output stream operator
486 DALI_CORE_API std::ostream& operator<<(std::ostream& o, const Quaternion& quaternion);
488 // Allow Quaternion to be treated as a POD type
490 struct TypeTraits<Quaternion> : public BasicTypes<Quaternion>
494 IS_TRIVIAL_TYPE = true
503 #endif // DALI_QUATERNION_H