18bf80f4bSopenharmony_ci/* 28bf80f4bSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 38bf80f4bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48bf80f4bSopenharmony_ci * you may not use this file except in compliance with the License. 58bf80f4bSopenharmony_ci * You may obtain a copy of the License at 68bf80f4bSopenharmony_ci * 78bf80f4bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88bf80f4bSopenharmony_ci * 98bf80f4bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108bf80f4bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118bf80f4bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128bf80f4bSopenharmony_ci * See the License for the specific language governing permissions and 138bf80f4bSopenharmony_ci * limitations under the License. 148bf80f4bSopenharmony_ci */ 158bf80f4bSopenharmony_ci 168bf80f4bSopenharmony_ci#ifndef API_BASE_MATH_QUATERNION_H 178bf80f4bSopenharmony_ci#define API_BASE_MATH_QUATERNION_H 188bf80f4bSopenharmony_ci 198bf80f4bSopenharmony_ci#include <cmath> 208bf80f4bSopenharmony_ci#include <cstddef> 218bf80f4bSopenharmony_ci 228bf80f4bSopenharmony_ci#include <base/math/mathf.h> 238bf80f4bSopenharmony_ci#include <base/namespace.h> 248bf80f4bSopenharmony_ci 258bf80f4bSopenharmony_ciBASE_BEGIN_NAMESPACE() 268bf80f4bSopenharmony_cinamespace Math { 278bf80f4bSopenharmony_ci#include <base/math/disable_warning_4201_heading.h> 288bf80f4bSopenharmony_ci 298bf80f4bSopenharmony_ci/** @ingroup group_math_quaternion */ 308bf80f4bSopenharmony_ci/** Quaternion */ 318bf80f4bSopenharmony_ciclass Quat final { 328bf80f4bSopenharmony_cipublic: 338bf80f4bSopenharmony_ci union { 348bf80f4bSopenharmony_ci struct { 358bf80f4bSopenharmony_ci float x; 368bf80f4bSopenharmony_ci float y; 378bf80f4bSopenharmony_ci float z; 388bf80f4bSopenharmony_ci float w; 398bf80f4bSopenharmony_ci }; 408bf80f4bSopenharmony_ci float data[4]; 418bf80f4bSopenharmony_ci }; 428bf80f4bSopenharmony_ci 438bf80f4bSopenharmony_ci /** Subscript operator */ 448bf80f4bSopenharmony_ci constexpr float& operator[](size_t aIndex) 458bf80f4bSopenharmony_ci { 468bf80f4bSopenharmony_ci return data[aIndex]; 478bf80f4bSopenharmony_ci } 488bf80f4bSopenharmony_ci 498bf80f4bSopenharmony_ci /** Subscript operator */ 508bf80f4bSopenharmony_ci constexpr const float& operator[](size_t aIndex) const 518bf80f4bSopenharmony_ci { 528bf80f4bSopenharmony_ci return data[aIndex]; 538bf80f4bSopenharmony_ci } 548bf80f4bSopenharmony_ci 558bf80f4bSopenharmony_ci // Constructors 568bf80f4bSopenharmony_ci /** Default constructor */ 578bf80f4bSopenharmony_ci inline constexpr Quat() noexcept : data {} {} 588bf80f4bSopenharmony_ci 598bf80f4bSopenharmony_ci /** Constructor for floats */ 608bf80f4bSopenharmony_ci inline constexpr Quat(float xParameter, float yParameter, float zParameter, float wParameter) noexcept 618bf80f4bSopenharmony_ci : x(xParameter), y(yParameter), z(zParameter), w(wParameter) 628bf80f4bSopenharmony_ci {} 638bf80f4bSopenharmony_ci 648bf80f4bSopenharmony_ci /** Constructor for float array */ 658bf80f4bSopenharmony_ci inline constexpr Quat(const float d[]) noexcept : x(d[0]), y(d[1]), z(d[2]), w(d[3]) {} 668bf80f4bSopenharmony_ci 678bf80f4bSopenharmony_ci // Quaternion to quaternion operations 688bf80f4bSopenharmony_ci /** Multiply quaternion by quaternion */ 698bf80f4bSopenharmony_ci inline constexpr Quat operator*(const Quat& quat) const 708bf80f4bSopenharmony_ci { 718bf80f4bSopenharmony_ci return Quat(w * quat.x + x * quat.w + y * quat.z - z * quat.y, 728bf80f4bSopenharmony_ci w * quat.y + y * quat.w + z * quat.x - x * quat.z, w * quat.z + z * quat.w + x * quat.y - y * quat.x, 738bf80f4bSopenharmony_ci w * quat.w - x * quat.x - y * quat.y - z * quat.z); 748bf80f4bSopenharmony_ci } // Add 758bf80f4bSopenharmony_ci 768bf80f4bSopenharmony_ci inline ~Quat() = default; 778bf80f4bSopenharmony_ci 788bf80f4bSopenharmony_ci /** Divide quaternion by float */ 798bf80f4bSopenharmony_ci inline constexpr Quat operator/(float d) const 808bf80f4bSopenharmony_ci { 818bf80f4bSopenharmony_ci return Quat(x / d, y / d, z / d, w / d); 828bf80f4bSopenharmony_ci } 838bf80f4bSopenharmony_ci 848bf80f4bSopenharmony_ci /** Divide quaternion by float */ 858bf80f4bSopenharmony_ci inline constexpr Quat& operator/=(float d) 868bf80f4bSopenharmony_ci { 878bf80f4bSopenharmony_ci if (d != 0.f) { 888bf80f4bSopenharmony_ci x /= d; 898bf80f4bSopenharmony_ci y /= d; 908bf80f4bSopenharmony_ci z /= d; 918bf80f4bSopenharmony_ci w /= d; 928bf80f4bSopenharmony_ci } else { 938bf80f4bSopenharmony_ci x = y = z = w = HUGE_VALF; 948bf80f4bSopenharmony_ci } 958bf80f4bSopenharmony_ci return *this; 968bf80f4bSopenharmony_ci } 978bf80f4bSopenharmony_ci 988bf80f4bSopenharmony_ci // Returns true if the quaternions are equal. 998bf80f4bSopenharmony_ci /** Equality operator */ 1008bf80f4bSopenharmony_ci inline constexpr bool operator==(const Quat& rhs) const 1018bf80f4bSopenharmony_ci { 1028bf80f4bSopenharmony_ci auto const temp = Quat(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); 1038bf80f4bSopenharmony_ci const float sqmgt = temp.x * temp.x + temp.y * temp.y + temp.z * temp.z + temp.w * temp.w; 1048bf80f4bSopenharmony_ci 1058bf80f4bSopenharmony_ci // Returns false in the presence of NaN values 1068bf80f4bSopenharmony_ci return sqmgt < Math::EPSILON * Math::EPSILON; 1078bf80f4bSopenharmony_ci } 1088bf80f4bSopenharmony_ci 1098bf80f4bSopenharmony_ci // Returns true if quaternions are different. 1108bf80f4bSopenharmony_ci /** Inequality operator */ 1118bf80f4bSopenharmony_ci inline constexpr bool operator!=(const Quat& rhs) const 1128bf80f4bSopenharmony_ci { 1138bf80f4bSopenharmony_ci // Returns true in the presence of NaN values 1148bf80f4bSopenharmony_ci return !(*this == rhs); 1158bf80f4bSopenharmony_ci } 1168bf80f4bSopenharmony_ci}; 1178bf80f4bSopenharmony_ci 1188bf80f4bSopenharmony_ci// Assert that Quat is the same as 4 floats 1198bf80f4bSopenharmony_cistatic_assert(sizeof(Quat) == 4 * sizeof(float)); 1208bf80f4bSopenharmony_ci 1218bf80f4bSopenharmony_ci#include <base/math/disable_warning_4201_footer.h> 1228bf80f4bSopenharmony_ci} // namespace Math 1238bf80f4bSopenharmony_ciBASE_END_NAMESPACE() 1248bf80f4bSopenharmony_ci 1258bf80f4bSopenharmony_ci#endif // API_BASE_MATH_QUATERNION_H 126