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