// Copyright Epic Games, Inc. All Rights Reserved. #include "MassVisualizationLODProcessor.h" #include "MassCommonFragments.h" #include "MassRepresentationDebug.h" #include "MassExecutionContext.h" UMassVisualizationLODProcessor::UMassVisualizationLODProcessor() { bAutoRegisterWithProcessingPhases = false; ExecutionOrder.ExecuteInGroup = UE::Mass::ProcessorGroupNames::LOD; ExecutionOrder.ExecuteAfter.Add(UE::Mass::ProcessorGroupNames::LODCollector); } void UMassVisualizationLODProcessor::ConfigureQueries(const TSharedRef& EntityManager) { FMassEntityQuery BaseQuery(EntityManager); BaseQuery.AddTagRequirement(EMassFragmentPresence::All); BaseQuery.AddRequirement(EMassFragmentAccess::ReadOnly); BaseQuery.AddRequirement(EMassFragmentAccess::ReadWrite); BaseQuery.AddRequirement(EMassFragmentAccess::ReadOnly); BaseQuery.AddConstSharedRequirement(); BaseQuery.AddSharedRequirement(EMassFragmentAccess::ReadWrite); CloseEntityQuery = BaseQuery; CloseEntityQuery.AddTagRequirement(EMassFragmentPresence::None); CloseEntityQuery.RegisterWithProcessor(*this); CloseEntityAdjustDistanceQuery = CloseEntityQuery; CloseEntityAdjustDistanceQuery.SetChunkFilter([](const FMassExecutionContext& Context) { const FMassVisualizationLODSharedFragment& LODSharedFragment = Context.GetSharedFragment(); return LODSharedFragment.bHasAdjustedDistancesFromCount; }); CloseEntityAdjustDistanceQuery.RegisterWithProcessor(*this); FarEntityQuery = BaseQuery; FarEntityQuery.AddTagRequirement(EMassFragmentPresence::All); FarEntityQuery.AddChunkRequirement(EMassFragmentAccess::ReadOnly); FarEntityQuery.SetChunkFilter(&FMassVisualizationChunkFragment::ShouldUpdateVisualizationForChunk); FarEntityQuery.RegisterWithProcessor(*this); DebugEntityQuery = BaseQuery; DebugEntityQuery.RegisterWithProcessor(*this); ProcessorRequirements.AddSubsystemRequirement(EMassFragmentAccess::ReadOnly); } void UMassVisualizationLODProcessor::Execute(FMassEntityManager& EntityManager, FMassExecutionContext& Context) { if (bForceOFFLOD) { CloseEntityQuery.ForEachEntityChunk(Context, [this](FMassExecutionContext& Context) { FMassVisualizationLODSharedFragment& LODSharedFragment = Context.GetMutableSharedFragment(); TArrayView RepresentationLODList = Context.GetMutableFragmentView(); LODSharedFragment.LODCalculator.ForceOffLOD(Context, RepresentationLODList); }); return; } { TRACE_CPUPROFILER_EVENT_SCOPE(PrepareExecution) const UMassLODSubsystem& LODSubsystem = Context.GetSubsystemChecked(); const TArray& Viewers = LODSubsystem.GetViewers(); EntityManager.ForEachSharedFragment([this, &Viewers](FMassVisualizationLODSharedFragment& LODSharedFragment) { if (FilterTag == LODSharedFragment.FilterTag) { LODSharedFragment.LODCalculator.PrepareExecution(Viewers); } }); } { TRACE_CPUPROFILER_EVENT_SCOPE(CalculateLOD) auto CalculateLOD = [this](FMassExecutionContext& Context) { FMassVisualizationLODSharedFragment& LODSharedFragment = Context.GetMutableSharedFragment(); TArrayView RepresentationLODList = Context.GetMutableFragmentView(); TConstArrayView ViewerInfoList = Context.GetFragmentView(); LODSharedFragment.LODCalculator.CalculateLOD(Context, ViewerInfoList, RepresentationLODList); }; CloseEntityQuery.ForEachEntityChunk(Context, CalculateLOD); FarEntityQuery.ForEachEntityChunk(Context, CalculateLOD); } if (bDoAdjustmentFromCount) { TRACE_CPUPROFILER_EVENT_SCOPE(AdjustDistanceAndLODFromCount) EntityManager.ForEachSharedFragment([this](FMassVisualizationLODSharedFragment& LODSharedFragment) { if (FilterTag == LODSharedFragment.FilterTag) { LODSharedFragment.bHasAdjustedDistancesFromCount = LODSharedFragment.LODCalculator.AdjustDistancesFromCount(); } }); CloseEntityAdjustDistanceQuery.ForEachEntityChunk(Context, [this](FMassExecutionContext& Context) { FMassVisualizationLODSharedFragment& LODSharedFragment = Context.GetMutableSharedFragment(); TConstArrayView ViewerInfoList = Context.GetFragmentView(); TArrayView RepresentationLODList = Context.GetMutableFragmentView(); LODSharedFragment.LODCalculator.AdjustLODFromCount(Context, ViewerInfoList, RepresentationLODList); }); // Far entities do not need to maximize count } #if WITH_MASSGAMEPLAY_DEBUG // Optional debug display if (UE::Mass::Representation::Debug::DebugRepresentationLOD == 1 || UE::Mass::Representation::Debug::DebugRepresentationLOD >= 3) { TRACE_CPUPROFILER_EVENT_SCOPE(DebugDisplayLOD) UWorld* World = EntityManager.GetWorld(); DebugEntityQuery.ForEachEntityChunk(Context, [World](FMassExecutionContext& Context) { FMassVisualizationLODSharedFragment& LODSharedFragment = Context.GetMutableSharedFragment(); TConstArrayView RepresentationLODList = Context.GetFragmentView(); TConstArrayView TransformList = Context.GetFragmentView(); LODSharedFragment.LODCalculator.DebugDisplaySignificantLOD(Context, RepresentationLODList, TransformList, World, UE::Mass::Representation::Debug::DebugRepresentationLODMaxSignificance); }); } // Optional vislog if (UE::Mass::Representation::Debug::DebugRepresentationLOD >= 2) { TRACE_CPUPROFILER_EVENT_SCOPE(VisLogLOD) DebugEntityQuery.ForEachEntityChunk(Context, [this](FMassExecutionContext& Context) { FMassVisualizationLODSharedFragment& LODSharedFragment = Context.GetMutableSharedFragment(); TConstArrayView RepresentationLODList = Context.GetFragmentView(); TConstArrayView TransformList = Context.GetFragmentView(); LODSharedFragment.LODCalculator.VisLogSignificantLOD(Context, RepresentationLODList, TransformList, this, UE::Mass::Representation::Debug::DebugRepresentationLODMaxSignificance); }); } #endif // WITH_MASSGAMEPLAY_DEBUG }