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