/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include #include #include #include namespace AZ { namespace Render { void OcclusionCullingPlaneFeatureProcessor::Reflect(ReflectContext* context) { if (auto* serializeContext = azrtti_cast(context)) { serializeContext ->Class() ->Version(0); } } void OcclusionCullingPlaneFeatureProcessor::Activate() { m_occlusionCullingPlanes.reserve(InitialOcclusionCullingPlanesAllocationSize); m_rpiOcclusionPlanes.reserve(InitialOcclusionCullingPlanesAllocationSize); EnableSceneNotification(); } void OcclusionCullingPlaneFeatureProcessor::Deactivate() { AZ_Warning("OcclusionCullingPlaneFeatureProcessor", m_occlusionCullingPlanes.size() == 0, "Deactivating the OcclusionCullingPlaneFeatureProcessor, but there are still outstanding occlusion planes. Components\n" "using OcclusionCullingPlaneHandles should free them before the OcclusionCullingPlaneFeatureProcessor is deactivated.\n" ); DisableSceneNotification(); } void OcclusionCullingPlaneFeatureProcessor::OnBeginPrepareRender() { if (m_rpiListNeedsUpdate) { // rebuild the RPI occlusion list m_rpiOcclusionPlanes.clear(); for (auto& occlusionCullingPlane : m_occlusionCullingPlanes) { if (!occlusionCullingPlane->GetEnabled()) { continue; } RPI::CullingScene::OcclusionPlane rpiOcclusionPlane; static const Vector3 BL = Vector3(-0.5f, 0.0f, -0.5f); static const Vector3 TL = Vector3(-0.5f, 0.0f, 0.5f); static const Vector3 TR = Vector3( 0.5f, 0.0f, 0.5f); static const Vector3 BR = Vector3( 0.5f, 0.0f, -0.5f); const AZ::Transform& transform = occlusionCullingPlane->GetTransform(); // convert corners to world space rpiOcclusionPlane.m_cornerBL = transform.TransformPoint(BL); rpiOcclusionPlane.m_cornerTL = transform.TransformPoint(TL); rpiOcclusionPlane.m_cornerTR = transform.TransformPoint(TR); rpiOcclusionPlane.m_cornerBR = transform.TransformPoint(BR); // build world space AABB AZ::Vector3 aabbMin = rpiOcclusionPlane.m_cornerBL.GetMin(rpiOcclusionPlane.m_cornerTR); AZ::Vector3 aabbMax = rpiOcclusionPlane.m_cornerBL.GetMax(rpiOcclusionPlane.m_cornerTR); rpiOcclusionPlane.m_aabb = Aabb::CreateFromMinMax(aabbMin, aabbMax); m_rpiOcclusionPlanes.push_back(rpiOcclusionPlane); } GetParentScene()->GetCullingScene()->SetOcclusionPlanes(m_rpiOcclusionPlanes); m_rpiListNeedsUpdate = false; } } OcclusionCullingPlaneHandle OcclusionCullingPlaneFeatureProcessor::AddOcclusionCullingPlane(const AZ::Transform& transform) { AZStd::shared_ptr occlusionCullingPlane = AZStd::make_shared(); occlusionCullingPlane->Init(GetParentScene()); occlusionCullingPlane->SetTransform(transform); m_occlusionCullingPlanes.push_back(occlusionCullingPlane); m_rpiListNeedsUpdate = true; return occlusionCullingPlane; } void OcclusionCullingPlaneFeatureProcessor::RemoveOcclusionCullingPlane(OcclusionCullingPlaneHandle& occlusionCullingPlane) { AZ_Assert(occlusionCullingPlane.get(), "RemoveOcclusionCullingPlane called with an invalid handle"); auto itEntry = AZStd::find_if(m_occlusionCullingPlanes.begin(), m_occlusionCullingPlanes.end(), [&](AZStd::shared_ptr const& entry) { return (entry == occlusionCullingPlane); }); AZ_Assert(itEntry != m_occlusionCullingPlanes.end(), "RemoveOcclusionCullingPlane called with an occlusion plane that is not in the occlusion plane list"); m_occlusionCullingPlanes.erase(itEntry); occlusionCullingPlane = nullptr; m_rpiListNeedsUpdate = true; } void OcclusionCullingPlaneFeatureProcessor::SetTransform(const OcclusionCullingPlaneHandle& occlusionCullingPlane, const AZ::Transform& transform) { AZ_Assert(occlusionCullingPlane.get(), "SetTransform called with an invalid handle"); occlusionCullingPlane->SetTransform(transform); m_rpiListNeedsUpdate = true; } void OcclusionCullingPlaneFeatureProcessor::SetEnabled(const OcclusionCullingPlaneHandle& occlusionCullingPlane, bool enabled) { AZ_Assert(occlusionCullingPlane.get(), "Enable called with an invalid handle"); occlusionCullingPlane->SetEnabled(enabled); m_rpiListNeedsUpdate = true; } void OcclusionCullingPlaneFeatureProcessor::ShowVisualization(const OcclusionCullingPlaneHandle& occlusionCullingPlane, bool showVisualization) { AZ_Assert(occlusionCullingPlane.get(), "ShowVisualization called with an invalid handle"); occlusionCullingPlane->ShowVisualization(showVisualization); } void OcclusionCullingPlaneFeatureProcessor::SetTransparentVisualization(const OcclusionCullingPlaneHandle& occlusionCullingPlane, bool transparentVisualization) { AZ_Assert(occlusionCullingPlane.get(), "SetTransparentVisualization called with an invalid handle"); occlusionCullingPlane->SetTransparentVisualization(transparentVisualization); } } // namespace Render } // namespace AZ