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 
BASE_BEGIN_NAMESPACE()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 */
44     constexpr float& operator[](size_t aIndex)
45     {
46         return data[aIndex];
47     }
48 
49     /** Subscript operator */
50     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
61         : x(xParameter), y(yParameter), z(zParameter), w(wParameter)
62     {}
63 
64     /** Constructor for float array */
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 */
69     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 */
79     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 */
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 */
100     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 */
111     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