You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#rb richard.malo, jeanfrancois.dube #preflight 6214e114a97c2c3348cb166d #rnx [CL 19071881 by Patrick Enfedaque in ue5-main branch]
264 lines
7.1 KiB
C++
264 lines
7.1 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "LandscapeSubsystem.h"
|
|
#include "UObject/UObjectGlobals.h"
|
|
#include "Engine/EngineBaseTypes.h"
|
|
#include "Engine/World.h"
|
|
#include "ContentStreaming.h"
|
|
#include "Landscape.h"
|
|
#include "LandscapeProxy.h"
|
|
#include "LandscapeStreamingProxy.h"
|
|
#include "LandscapeInfo.h"
|
|
#include "ProfilingDebugging/CsvProfiler.h"
|
|
#include "WorldPartition/WorldPartitionSubsystem.h"
|
|
#include "ActorPartition/ActorPartitionSubsystem.h"
|
|
#include "Engine/World.h"
|
|
#include "Math/IntRect.h"
|
|
#include "LandscapeConfigHelper.h"
|
|
#include "Engine/Canvas.h"
|
|
|
|
static int32 GUseStreamingManagerForCameras = 1;
|
|
static FAutoConsoleVariableRef CVarUseStreamingManagerForCameras(
|
|
TEXT("grass.UseStreamingManagerForCameras"),
|
|
GUseStreamingManagerForCameras,
|
|
TEXT("1: Use Streaming Manager; 0: Use ViewLocationsRenderedLastFrame"));
|
|
|
|
DECLARE_CYCLE_STAT(TEXT("LandscapeSubsystem Tick"), STAT_LandscapeSubsystemTick, STATGROUP_Landscape);
|
|
|
|
#define LOCTEXT_NAMESPACE "LandscapeSubsystem"
|
|
|
|
ULandscapeSubsystem::ULandscapeSubsystem()
|
|
{
|
|
}
|
|
|
|
ULandscapeSubsystem::~ULandscapeSubsystem()
|
|
{
|
|
}
|
|
|
|
void ULandscapeSubsystem::RegisterActor(ALandscapeProxy* Proxy)
|
|
{
|
|
Proxies.AddUnique(Proxy);
|
|
}
|
|
|
|
void ULandscapeSubsystem::UnregisterActor(ALandscapeProxy* Proxy)
|
|
{
|
|
Proxies.Remove(Proxy);
|
|
}
|
|
|
|
void ULandscapeSubsystem::Initialize(FSubsystemCollectionBase& Collection)
|
|
{
|
|
Super::Initialize(Collection);
|
|
|
|
#if WITH_EDITOR
|
|
GrassMapsBuilder = new FLandscapeGrassMapsBuilder(GetWorld());
|
|
GIBakedTextureBuilder = new FLandscapeGIBakedTextureBuilder(GetWorld());
|
|
PhysicalMaterialBuilder = new FLandscapePhysicalMaterialBuilder(GetWorld());
|
|
#endif
|
|
}
|
|
|
|
void ULandscapeSubsystem::Deinitialize()
|
|
{
|
|
#if WITH_EDITOR
|
|
if (GrassMapsBuilder)
|
|
{
|
|
delete GrassMapsBuilder;
|
|
}
|
|
if (GIBakedTextureBuilder)
|
|
{
|
|
delete GIBakedTextureBuilder;
|
|
}
|
|
if (PhysicalMaterialBuilder)
|
|
{
|
|
delete PhysicalMaterialBuilder;
|
|
}
|
|
#endif
|
|
Proxies.Empty();
|
|
|
|
Super::Deinitialize();
|
|
}
|
|
|
|
TStatId ULandscapeSubsystem::GetStatId() const
|
|
{
|
|
RETURN_QUICK_DECLARE_CYCLE_STAT(ULandscapeSubsystem, STATGROUP_Tickables);
|
|
}
|
|
|
|
ETickableTickType ULandscapeSubsystem::GetTickableTickType() const
|
|
{
|
|
return HasAnyFlags(RF_ClassDefaultObject) || !GetWorld() || GetWorld()->IsNetMode(NM_DedicatedServer) ? ETickableTickType::Never : ETickableTickType::Always;
|
|
}
|
|
|
|
void ULandscapeSubsystem::Tick(float DeltaTime)
|
|
{
|
|
SCOPE_CYCLE_COUNTER(STAT_LandscapeSubsystemTick);
|
|
TRACE_CPUPROFILER_EVENT_SCOPE(ULandscapeSubsystem::Tick);
|
|
CSV_SCOPED_TIMING_STAT_EXCLUSIVE(Landscape);
|
|
LLM_SCOPE(ELLMTag::Landscape);
|
|
|
|
Super::Tick(DeltaTime);
|
|
|
|
UWorld* World = GetWorld();
|
|
|
|
static TArray<FVector> OldCameras;
|
|
TArray<FVector>* Cameras = nullptr;
|
|
if (GUseStreamingManagerForCameras == 0)
|
|
{
|
|
if (OldCameras.Num() || World->ViewLocationsRenderedLastFrame.Num())
|
|
{
|
|
Cameras = &OldCameras;
|
|
// there is a bug here, which often leaves us with no cameras in the editor
|
|
if (World->ViewLocationsRenderedLastFrame.Num())
|
|
{
|
|
check(IsInGameThread());
|
|
Cameras = &World->ViewLocationsRenderedLastFrame;
|
|
OldCameras = *Cameras;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int32 Num = IStreamingManager::Get().GetNumViews();
|
|
if (Num)
|
|
{
|
|
OldCameras.Reset(Num);
|
|
for (int32 Index = 0; Index < Num; Index++)
|
|
{
|
|
auto& ViewInfo = IStreamingManager::Get().GetViewInformation(Index);
|
|
OldCameras.Add(ViewInfo.ViewOrigin);
|
|
}
|
|
Cameras = &OldCameras;
|
|
}
|
|
}
|
|
|
|
int32 InOutNumComponentsCreated = 0;
|
|
for (ALandscapeProxy* Proxy : Proxies)
|
|
{
|
|
#if WITH_EDITOR
|
|
if (GIsEditor)
|
|
{
|
|
if (ALandscape* Landscape = Cast<ALandscape>(Proxy))
|
|
{
|
|
Landscape->TickLayers(DeltaTime);
|
|
}
|
|
|
|
// editor-only
|
|
if (!World->IsPlayInEditor())
|
|
{
|
|
Proxy->UpdateGIBakedTextures();
|
|
Proxy->UpdatePhysicalMaterialTasks();
|
|
}
|
|
}
|
|
#endif
|
|
if (Cameras && Proxy->ShouldTickGrass())
|
|
{
|
|
Proxy->TickGrass(*Cameras, InOutNumComponentsCreated);
|
|
}
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
if (GIsEditor && !World->IsPlayInEditor())
|
|
{
|
|
LandscapePhysicalMaterial::GarbageCollectTasks();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if WITH_EDITOR
|
|
void ULandscapeSubsystem::BuildAll()
|
|
{
|
|
BuildGrassMaps();
|
|
BuildGIBakedTextures();
|
|
BuildPhysicalMaterial();
|
|
}
|
|
|
|
void ULandscapeSubsystem::BuildGrassMaps()
|
|
{
|
|
GrassMapsBuilder->Build();
|
|
}
|
|
|
|
int32 ULandscapeSubsystem::GetOutdatedGrassMapCount()
|
|
{
|
|
return GrassMapsBuilder->GetOutdatedGrassMapCount(/*bInForceUpdate*/false);
|
|
}
|
|
|
|
void ULandscapeSubsystem::BuildGIBakedTextures()
|
|
{
|
|
GIBakedTextureBuilder->Build();
|
|
}
|
|
|
|
int32 ULandscapeSubsystem::GetOutdatedGIBakedTextureComponentsCount()
|
|
{
|
|
return GIBakedTextureBuilder->GetOutdatedGIBakedTextureComponentsCount(/*bInForceUpdate*/false);
|
|
}
|
|
|
|
void ULandscapeSubsystem::BuildPhysicalMaterial()
|
|
{
|
|
PhysicalMaterialBuilder->Build();
|
|
}
|
|
|
|
int32 ULandscapeSubsystem::GetOudatedPhysicalMaterialComponentsCount()
|
|
{
|
|
return PhysicalMaterialBuilder->GetOudatedPhysicalMaterialComponentsCount();
|
|
}
|
|
|
|
bool ULandscapeSubsystem::IsGridBased() const
|
|
{
|
|
return UWorld::IsPartitionedWorld(GetWorld());
|
|
}
|
|
|
|
void ULandscapeSubsystem::ChangeGridSize(ULandscapeInfo* LandscapeInfo, uint32 GridSizeInComponents)
|
|
{
|
|
if (!IsGridBased())
|
|
{
|
|
return;
|
|
}
|
|
|
|
TSet<AActor*> ActorsToDelete;
|
|
FLandscapeConfigHelper::ChangeGridSize(LandscapeInfo, GridSizeInComponents, ActorsToDelete);
|
|
// This code path is used for converting a non grid based Landscape to a gridbased so it shouldn't delete any actors
|
|
check(!ActorsToDelete.Num());
|
|
}
|
|
|
|
ALandscapeProxy* ULandscapeSubsystem::FindOrAddLandscapeProxy(ULandscapeInfo* LandscapeInfo, const FIntPoint& SectionBase)
|
|
{
|
|
if (!IsGridBased())
|
|
{
|
|
return LandscapeInfo->GetCurrentLevelLandscapeProxy(true);
|
|
}
|
|
|
|
return FLandscapeConfigHelper::FindOrAddLandscapeStreamingProxy(LandscapeInfo, SectionBase);
|
|
}
|
|
|
|
void ULandscapeSubsystem::DisplayBuildMessages(FCanvas* Canvas, float& XPos, float& YPos)
|
|
{
|
|
const int32 FontSizeY = 20;
|
|
FCanvasTextItem SmallTextItem(FVector2D(0, 0), FText::GetEmpty(), GEngine->GetSmallFont(), FLinearColor::White);
|
|
SmallTextItem.EnableShadow(FLinearColor::Black);
|
|
|
|
if (int32 OutdatedGrassMapCount = GetOutdatedGrassMapCount())
|
|
{
|
|
SmallTextItem.SetColor(FLinearColor::Red);
|
|
SmallTextItem.Text = FText::Format(LOCTEXT("GRASS_MAPS_NEED_TO_BE_REBUILT_FMT", "GRASS MAPS NEEDS TO BE REBUILT ({0} {0}|plural(one=object,other=objects))"), OutdatedGrassMapCount);
|
|
Canvas->DrawItem(SmallTextItem, FVector2D(XPos, YPos));
|
|
YPos += FontSizeY;
|
|
}
|
|
|
|
if (int32 ComponentsNeedingGITextureBaking = GetOutdatedGIBakedTextureComponentsCount())
|
|
{
|
|
SmallTextItem.SetColor(FLinearColor::Red);
|
|
SmallTextItem.Text = FText::Format(LOCTEXT("LANDSCAPE_TEXTURES_NEED_TO_BE_REBUILT_FMT", "LANDSCAPE BAKED TEXTURES NEEDS TO BE REBUILT ({0} {0}|plural(one=object,other=objects))"), ComponentsNeedingGITextureBaking);
|
|
Canvas->DrawItem(SmallTextItem, FVector2D(XPos, YPos));
|
|
YPos += FontSizeY;
|
|
}
|
|
|
|
if (int32 ComponentsWithOudatedPhysicalMaterial = GetOudatedPhysicalMaterialComponentsCount())
|
|
{
|
|
SmallTextItem.SetColor(FLinearColor::Red);
|
|
SmallTextItem.Text = FText::Format(LOCTEXT("LANDSCAPE_PHYSICALMATERIAL_NEED_TO_BE_REBUILT_FMT", "LANDSCAPE PHYSICAL MATERIAL NEEDS TO BE REBUILT ({0} {0}|plural(one=object,other=objects))"), ComponentsWithOudatedPhysicalMaterial);
|
|
Canvas->DrawItem(SmallTextItem, FVector2D(XPos, YPos));
|
|
YPos += FontSizeY;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
#undef LOCTEXT_NAMESPACE |