1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef API_BASE_MATH_QUATERNION_H 17 #define API_BASE_MATH_QUATERNION_H 18 19 #include <cmath> 20 #include <cstddef> 21 22 #include <base/math/mathf.h> 23 #include <base/namespace.h> 24 25 BASE_BEGIN_NAMESPACE() 26 namespace Math { 27 #include <base/math/disable_warning_4201_heading.h> 28 29 /** @ingroup group_math_quaternion */ 30 /** Quaternion */ 31 class Quat final { 32 public: 33 union { 34 struct { 35 float x; 36 float y; 37 float z; 38 float w; 39 }; 40 float data[4]; 41 }; 42 43 /** Subscript operator */ operator [](size_t aIndex)44 constexpr float& operator[](size_t aIndex) 45 { 46 return data[aIndex]; 47 } 48 49 /** Subscript operator */ operator [](size_t aIndex) const50 constexpr const float& operator[](size_t aIndex) const 51 { 52 return data[aIndex]; 53 } 54 55 // Constructors 56 /** Default constructor */ 57 inline constexpr Quat() noexcept : data {} {} 58 59 /** Constructor for floats */ 60 inline constexpr Quat(float xParameter, float yParameter, float zParameter, float wParameter) noexcept w(wParameter)61 : x(xParameter), y(yParameter), z(zParameter), w(wParameter) 62 {} 63 64 /** Constructor for float array */ w(d[3])65 inline constexpr Quat(const float d[]) noexcept : x(d[0]), y(d[1]), z(d[2]), w(d[3]) {} 66 67 // Quaternion to quaternion operations 68 /** Multiply quaternion by quaternion */ operator *(const Quat& quat) const69 inline constexpr Quat operator*(const Quat& quat) const 70 { 71 return Quat(w * quat.x + x * quat.w + y * quat.z - z * quat.y, 72 w * quat.y + y * quat.w + z * quat.x - x * quat.z, w * quat.z + z * quat.w + x * quat.y - y * quat.x, 73 w * quat.w - x * quat.x - y * quat.y - z * quat.z); 74 } // Add 75 76 inline ~Quat() = default; 77 78 /** Divide quaternion by float */ operator /(float d) const79 inline constexpr Quat operator/(float d) const 80 { 81 return Quat(x / d, y / d, z / d, w / d); 82 } 83 84 /** Divide quaternion by float */ operator /=(float d)85 inline constexpr Quat& operator/=(float d) 86 { 87 if (d != 0.f) { 88 x /= d; 89 y /= d; 90 z /= d; 91 w /= d; 92 } else { 93 x = y = z = w = HUGE_VALF; 94 } 95 return *this; 96 } 97 98 // Returns true if the quaternions are equal. 99 /** Equality operator */ operator ==(const Quat& rhs) const100 inline constexpr bool operator==(const Quat& rhs) const 101 { 102 auto const temp = Quat(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); 103 const float sqmgt = temp.x * temp.x + temp.y * temp.y + temp.z * temp.z + temp.w * temp.w; 104 105 // Returns false in the presence of NaN values 106 return sqmgt < Math::EPSILON * Math::EPSILON; 107 } 108 109 // Returns true if quaternions are different. 110 /** Inequality operator */ operator !=(const Quat& rhs) const111 inline constexpr bool operator!=(const Quat& rhs) const 112 { 113 // Returns true in the presence of NaN values 114 return !(*this == rhs); 115 } 116 }; 117 118 // Assert that Quat is the same as 4 floats 119 static_assert(sizeof(Quat) == 4 * sizeof(float)); 120 121 #include <base/math/disable_warning_4201_footer.h> 122 } // namespace Math 123 BASE_END_NAMESPACE() 124 125 #endif // API_BASE_MATH_QUATERNION_H 126