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#include "frustum_util.h" 178bf80f4bSopenharmony_ci 188bf80f4bSopenharmony_ci#include <cstdint> 198bf80f4bSopenharmony_ci 208bf80f4bSopenharmony_ci#include <base/containers/string_view.h> 218bf80f4bSopenharmony_ci#include <base/math/matrix.h> 228bf80f4bSopenharmony_ci#include <base/math/vector.h> 238bf80f4bSopenharmony_ci#include <base/math/vector_util.h> 248bf80f4bSopenharmony_ci#include <base/namespace.h> 258bf80f4bSopenharmony_ci#include <base/util/uid.h> 268bf80f4bSopenharmony_ci#include <core/namespace.h> 278bf80f4bSopenharmony_ci 288bf80f4bSopenharmony_ciCORE_BEGIN_NAMESPACE() 298bf80f4bSopenharmony_ciusing BASE_NS::string_view; 308bf80f4bSopenharmony_ciusing BASE_NS::Uid; 318bf80f4bSopenharmony_ciusing BASE_NS::Math::Mat4X4; 328bf80f4bSopenharmony_ciusing BASE_NS::Math::Vec3; 338bf80f4bSopenharmony_ci 348bf80f4bSopenharmony_ciFrustum FrustumUtil::CreateFrustum(const Mat4X4& matrix) const 358bf80f4bSopenharmony_ci{ 368bf80f4bSopenharmony_ci Frustum frustum; 378bf80f4bSopenharmony_ci 388bf80f4bSopenharmony_ci auto& planes = frustum.planes; 398bf80f4bSopenharmony_ci planes[Frustum::PLANE_LEFT].x = matrix[0].w + matrix[0].x; 408bf80f4bSopenharmony_ci planes[Frustum::PLANE_LEFT].y = matrix[1].w + matrix[1].x; 418bf80f4bSopenharmony_ci planes[Frustum::PLANE_LEFT].z = matrix[2].w + matrix[2].x; 428bf80f4bSopenharmony_ci planes[Frustum::PLANE_LEFT].w = matrix[3].w + matrix[3].x; 438bf80f4bSopenharmony_ci 448bf80f4bSopenharmony_ci planes[Frustum::PLANE_RIGHT].x = matrix[0].w - matrix[0].x; 458bf80f4bSopenharmony_ci planes[Frustum::PLANE_RIGHT].y = matrix[1].w - matrix[1].x; 468bf80f4bSopenharmony_ci planes[Frustum::PLANE_RIGHT].z = matrix[2].w - matrix[2].x; 478bf80f4bSopenharmony_ci planes[Frustum::PLANE_RIGHT].w = matrix[3].w - matrix[3].x; 488bf80f4bSopenharmony_ci 498bf80f4bSopenharmony_ci planes[Frustum::PLANE_BOTTOM].x = matrix[0].w - matrix[0].y; 508bf80f4bSopenharmony_ci planes[Frustum::PLANE_BOTTOM].y = matrix[1].w - matrix[1].y; 518bf80f4bSopenharmony_ci planes[Frustum::PLANE_BOTTOM].z = matrix[2].w - matrix[2].y; 528bf80f4bSopenharmony_ci planes[Frustum::PLANE_BOTTOM].w = matrix[3].w - matrix[3].y; 538bf80f4bSopenharmony_ci 548bf80f4bSopenharmony_ci planes[Frustum::PLANE_TOP].x = matrix[0].w + matrix[0].y; 558bf80f4bSopenharmony_ci planes[Frustum::PLANE_TOP].y = matrix[1].w + matrix[1].y; 568bf80f4bSopenharmony_ci planes[Frustum::PLANE_TOP].z = matrix[2].w + matrix[2].y; 578bf80f4bSopenharmony_ci planes[Frustum::PLANE_TOP].w = matrix[3].w + matrix[3].y; 588bf80f4bSopenharmony_ci 598bf80f4bSopenharmony_ci planes[Frustum::PLANE_NEAR].x = matrix[0].w + matrix[0].z; 608bf80f4bSopenharmony_ci planes[Frustum::PLANE_NEAR].y = matrix[1].w + matrix[1].z; 618bf80f4bSopenharmony_ci planes[Frustum::PLANE_NEAR].z = matrix[2].w + matrix[2].z; 628bf80f4bSopenharmony_ci planes[Frustum::PLANE_NEAR].w = matrix[3].w + matrix[3].z; 638bf80f4bSopenharmony_ci 648bf80f4bSopenharmony_ci planes[Frustum::PLANE_FAR].x = matrix[0].w - matrix[0].z; 658bf80f4bSopenharmony_ci planes[Frustum::PLANE_FAR].y = matrix[1].w - matrix[1].z; 668bf80f4bSopenharmony_ci planes[Frustum::PLANE_FAR].z = matrix[2].w - matrix[2].z; 678bf80f4bSopenharmony_ci planes[Frustum::PLANE_FAR].w = matrix[3].w - matrix[3].z; 688bf80f4bSopenharmony_ci 698bf80f4bSopenharmony_ci for (uint32_t idx = 0; idx < Frustum::PLANE_COUNT; ++idx) { 708bf80f4bSopenharmony_ci const float rcpLength = 1.0f / Magnitude(Vec3(planes[idx])); 718bf80f4bSopenharmony_ci planes[idx] *= rcpLength; 728bf80f4bSopenharmony_ci } 738bf80f4bSopenharmony_ci return frustum; 748bf80f4bSopenharmony_ci} 758bf80f4bSopenharmony_ci 768bf80f4bSopenharmony_cibool FrustumUtil::SphereFrustumCollision(const Frustum& frustum, const Vec3 pos, const float radius) const 778bf80f4bSopenharmony_ci{ 788bf80f4bSopenharmony_ci for (auto const& plane : frustum.planes) { 798bf80f4bSopenharmony_ci const float d = (plane.x * pos.x) + (plane.y * pos.y) + (plane.z * pos.z) + plane.w; 808bf80f4bSopenharmony_ci if (d <= -radius) { 818bf80f4bSopenharmony_ci return false; 828bf80f4bSopenharmony_ci } 838bf80f4bSopenharmony_ci } 848bf80f4bSopenharmony_ci return true; 858bf80f4bSopenharmony_ci} 868bf80f4bSopenharmony_ci 878bf80f4bSopenharmony_ciconst IInterface* FrustumUtil::GetInterface(const Uid& uid) const 888bf80f4bSopenharmony_ci{ 898bf80f4bSopenharmony_ci if ((uid == IFrustumUtil::UID) || (uid == IInterface::UID)) { 908bf80f4bSopenharmony_ci return this; 918bf80f4bSopenharmony_ci } 928bf80f4bSopenharmony_ci return nullptr; 938bf80f4bSopenharmony_ci} 948bf80f4bSopenharmony_ci 958bf80f4bSopenharmony_ciIInterface* FrustumUtil::GetInterface(const Uid& uid) 968bf80f4bSopenharmony_ci{ 978bf80f4bSopenharmony_ci if ((uid == IFrustumUtil::UID) || (uid == IInterface::UID)) { 988bf80f4bSopenharmony_ci return this; 998bf80f4bSopenharmony_ci } 1008bf80f4bSopenharmony_ci return nullptr; 1018bf80f4bSopenharmony_ci} 1028bf80f4bSopenharmony_ci 1038bf80f4bSopenharmony_civoid FrustumUtil::Ref() {} 1048bf80f4bSopenharmony_ci 1058bf80f4bSopenharmony_civoid FrustumUtil::Unref() {} 1068bf80f4bSopenharmony_ciCORE_END_NAMESPACE() 107