1 /* 2 * Copyright (c) 2022 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 #include "frustum_util.h" 17 18 #include <base/containers/string_view.h> 19 #include <base/math/matrix.h> 20 #include <base/math/vector.h> 21 #include <base/math/vector_util.h> 22 #include <base/namespace.h> 23 #include <base/util/uid.h> 24 #include <core/namespace.h> 25 26 CORE_BEGIN_NAMESPACE() 27 using BASE_NS::string_view; 28 using BASE_NS::Uid; 29 using BASE_NS::Math::Mat4X4; 30 using BASE_NS::Math::Vec3; 31 CreateFrustum(const Mat4X4 & matrix) const32Frustum FrustumUtil::CreateFrustum(const Mat4X4& matrix) const 33 { 34 Frustum frustum; 35 36 auto& planes = frustum.planes; 37 planes[Frustum::PLANE_LEFT].x = matrix[0U].w + matrix[0U].x; 38 planes[Frustum::PLANE_LEFT].y = matrix[1U].w + matrix[1U].x; 39 planes[Frustum::PLANE_LEFT].z = matrix[2U].w + matrix[2U].x; 40 planes[Frustum::PLANE_LEFT].w = matrix[3U].w + matrix[3U].x; 41 42 planes[Frustum::PLANE_RIGHT].x = matrix[0U].w - matrix[0U].x; 43 planes[Frustum::PLANE_RIGHT].y = matrix[1U].w - matrix[1U].x; 44 planes[Frustum::PLANE_RIGHT].z = matrix[2U].w - matrix[2U].x; 45 planes[Frustum::PLANE_RIGHT].w = matrix[3U].w - matrix[3U].x; 46 47 planes[Frustum::PLANE_BOTTOM].x = matrix[0U].w - matrix[0U].y; 48 planes[Frustum::PLANE_BOTTOM].y = matrix[1U].w - matrix[1U].y; 49 planes[Frustum::PLANE_BOTTOM].z = matrix[2U].w - matrix[2U].y; 50 planes[Frustum::PLANE_BOTTOM].w = matrix[3U].w - matrix[3U].y; 51 52 planes[Frustum::PLANE_TOP].x = matrix[0U].w + matrix[0U].y; 53 planes[Frustum::PLANE_TOP].y = matrix[1U].w + matrix[1U].y; 54 planes[Frustum::PLANE_TOP].z = matrix[2U].w + matrix[2U].y; 55 planes[Frustum::PLANE_TOP].w = matrix[3U].w + matrix[3U].y; 56 57 planes[Frustum::PLANE_NEAR].x = matrix[0U].w + matrix[0U].z; 58 planes[Frustum::PLANE_NEAR].y = matrix[1U].w + matrix[1U].z; 59 planes[Frustum::PLANE_NEAR].z = matrix[2U].w + matrix[2U].z; 60 planes[Frustum::PLANE_NEAR].w = matrix[3U].w + matrix[3U].z; 61 62 planes[Frustum::PLANE_FAR].x = matrix[0U].w - matrix[0U].z; 63 planes[Frustum::PLANE_FAR].y = matrix[1U].w - matrix[1U].z; 64 planes[Frustum::PLANE_FAR].z = matrix[2U].w - matrix[2U].z; 65 planes[Frustum::PLANE_FAR].w = matrix[3U].w - matrix[3U].z; 66 67 for (auto& plane : planes) { 68 const float rcpLength = 1.0f / Magnitude(Vec3(plane)); 69 plane *= rcpLength; 70 } 71 return frustum; 72 } 73 SphereFrustumCollision(const Frustum & frustum,const Vec3 pos,const float radius) const74bool FrustumUtil::SphereFrustumCollision(const Frustum& frustum, const Vec3 pos, const float radius) const 75 { 76 for (auto const& plane : frustum.planes) { 77 const float d = (plane.x * pos.x) + (plane.y * pos.y) + (plane.z * pos.z) + plane.w; 78 if (d <= -radius) { 79 return false; 80 } 81 } 82 return true; 83 } 84 GetInterface(const Uid & uid) const85const IInterface* FrustumUtil::GetInterface(const Uid& uid) const 86 { 87 if ((uid == IFrustumUtil::UID) || (uid == IInterface::UID)) { 88 return this; 89 } 90 return nullptr; 91 } 92 GetInterface(const Uid & uid)93IInterface* FrustumUtil::GetInterface(const Uid& uid) 94 { 95 if ((uid == IFrustumUtil::UID) || (uid == IInterface::UID)) { 96 return this; 97 } 98 return nullptr; 99 } 100 Ref()101void FrustumUtil::Ref() {} 102 Unref()103void FrustumUtil::Unref() {} 104 CORE_END_NAMESPACE() 105