1 /*
2 * Copyright (C) 2023 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 <base/math/mathf.h>
20 #include <base/namespace.h>
21
BASE_BEGIN_NAMESPACE()22 BASE_BEGIN_NAMESPACE()
23 namespace Math {
24 #include <base/math/disable_warning_4201_heading.h>
25
26 /** @ingroup group_math_quaternion */
27 /** Quaternion */
28 class Quat final {
29 public:
30 union {
31 struct {
32 float x;
33 float y;
34 float z;
35 float w;
36 };
37 float data[4];
38 };
39
40 /** Subscript operator */
41 constexpr float& operator[](size_t aIndex)
42 {
43 return data[aIndex];
44 }
45
46 /** Subscript operator */
47 constexpr const float& operator[](size_t aIndex) const
48 {
49 return data[aIndex];
50 }
51
52 // Constructors
53 /** Default constructor */
54 inline constexpr Quat() noexcept : data {} {}
55
56 /** Constructor for floats */
57 inline constexpr Quat(float xParameter, float yParameter, float zParameter, float wParameter) noexcept
58 : x(xParameter), y(yParameter), z(zParameter), w(wParameter)
59 {}
60
61 /** Constructor for float array */
62 inline constexpr Quat(const float d[]) noexcept : x(d[0]), y(d[1]), z(d[2]), w(d[3]) {}
63
64 // Quaternion to quaternion operations
65 /** Multiply quaternion by quaternion */
66 inline constexpr Quat operator*(const Quat& quat) const
67 {
68 return Quat(w * quat.x + x * quat.w + y * quat.z - z * quat.y,
69 w * quat.y + y * quat.w + z * quat.x - x * quat.z, w * quat.z + z * quat.w + x * quat.y - y * quat.x,
70 w * quat.w - x * quat.x - y * quat.y - z * quat.z);
71 } // Add
72
73 inline ~Quat() = default;
74
75 /** Divide quaternion by float */
76 inline constexpr Quat operator/(float d) const
77 {
78 return Quat(x / d, y / d, z / d, w / d);
79 }
80
81 /** Divide quaternion by float */
82 inline constexpr Quat& operator/=(float d)
83 {
84 if (d != 0.f) {
85 x /= d;
86 y /= d;
87 z /= d;
88 w /= d;
89 } else {
90 x = y = z = w = HUGE_VALF;
91 }
92 return *this;
93 }
94
95 // Returns true if the quaternions are equal.
96 /** Equality operator */
97 inline constexpr bool operator==(const Quat& rhs) const
98 {
99 auto const temp = Quat(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w);
100 const float sqmgt = temp.x * temp.x + temp.y * temp.y + temp.z * temp.z + temp.w * temp.w;
101
102 // Returns false in the presence of NaN values
103 return sqmgt < Math::EPSILON * Math::EPSILON;
104 }
105
106 // Returns true if quaternions are different.
107 /** Inequality operator */
108 inline constexpr bool operator!=(const Quat& rhs) const
109 {
110 // Returns true in the presence of NaN values
111 return !(*this == rhs);
112 }
113 };
114
115 // Assert that Quat is the same as 4 floats
116 static_assert(sizeof(Quat) == 4 * sizeof(float));
117
118 #include <base/math/disable_warning_4201_footer.h>
119 } // namespace Math
120 BASE_END_NAMESPACE()
121
122 #endif // API_BASE_MATH_QUATERNION_H
123