Files
UnrealEngineUWP/Engine/Source/Runtime/Landscape/Private/LandscapeNaniteComponent.cpp
graham wihlidal 739c468154 Build fix
#preflight skip

#ROBOMERGE-AUTHOR: graham.wihlidal
#ROBOMERGE-SOURCE: CL 20660720 via CL 20660858 via CL 20661130
#ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v955-20579017)

[CL 20663269 by graham wihlidal in ue5-main branch]
2022-06-14 21:21:07 -04:00

174 lines
4.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "LandscapeNaniteComponent.h"
#include "LandscapeEdit.h"
#include "LandscapeRender.h"
#include "NaniteSceneProxy.h"
#include "Materials/MaterialInstanceConstant.h"
#include "Engine/StaticMesh.h"
#include "Engine/StaticMeshSourceData.h"
#if WITH_EDITOR
#include "StaticMeshAttributes.h"
#include "StaticMeshDescription.h"
#include "StaticMeshOperations.h"
#include "MeshUtilitiesCommon.h"
#include "OverlappingCorners.h"
#include "MeshBuild.h"
#include "StaticMeshBuilder.h"
#include "NaniteBuilder.h"
#include "Rendering/NaniteResources.h"
#include "PhysicsEngine/BodySetup.h"
#endif
ULandscapeNaniteComponent::ULandscapeNaniteComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, bEnabled(true)
{
}
void ULandscapeNaniteComponent::PostLoad()
{
Super::PostLoad();
ALandscapeProxy* LandscapeProxy = GetLandscapeProxy();
if (ensure(LandscapeProxy))
{
// Ensure that the component lighting and shadow settings matches the actor
UpdatedSharedPropertiesFromActor();
}
}
ALandscapeProxy* ULandscapeNaniteComponent::GetLandscapeProxy() const
{
return CastChecked<ALandscapeProxy>(GetOuter());
}
ALandscape* ULandscapeNaniteComponent::GetLandscapeActor() const
{
ALandscapeProxy* Landscape = GetLandscapeProxy();
if (Landscape)
{
return Landscape->GetLandscapeActor();
}
return nullptr;
}
void ULandscapeNaniteComponent::UpdatedSharedPropertiesFromActor()
{
ALandscapeProxy* LandscapeProxy = GetLandscapeProxy();
CastShadow = LandscapeProxy->CastShadow;
bCastDynamicShadow = LandscapeProxy->bCastDynamicShadow;
bCastStaticShadow = LandscapeProxy->bCastStaticShadow;
bCastContactShadow = LandscapeProxy->bCastContactShadow;
bCastFarShadow = LandscapeProxy->bCastFarShadow;
bCastHiddenShadow = LandscapeProxy->bCastHiddenShadow;
bCastShadowAsTwoSided = LandscapeProxy->bCastShadowAsTwoSided;
bAffectDistanceFieldLighting = LandscapeProxy->bAffectDistanceFieldLighting;
bRenderCustomDepth = LandscapeProxy->bRenderCustomDepth;
CustomDepthStencilWriteMask = LandscapeProxy->CustomDepthStencilWriteMask;
CustomDepthStencilValue = LandscapeProxy->CustomDepthStencilValue;
SetCullDistance(LandscapeProxy->LDMaxDrawDistance);
LightingChannels = LandscapeProxy->LightingChannels;
// We don't want Nanite representation in ray tracing
bVisibleInRayTracing = false;
}
void ULandscapeNaniteComponent::SetEnabled(bool bValue)
{
if (bValue != bEnabled)
{
bEnabled = bValue;
MarkRenderStateDirty();
}
}
#if WITH_EDITOR
void ULandscapeNaniteComponent::InitializeForLandscape(ALandscapeProxy* Landscape, const FGuid& NewProxyContentId)
{
UStaticMesh* NaniteStaticMesh = NewObject<UStaticMesh>(this /* Outer */, TEXT("LandscapeNaniteMesh"), RF_Transactional);
FMeshDescription* MeshDescription = nullptr;
// Mesh
{
FStaticMeshSourceModel& SrcModel = NaniteStaticMesh->AddSourceModel();
// Don't allow the engine to recalculate normals
SrcModel.BuildSettings.bRecomputeNormals = false;
SrcModel.BuildSettings.bRecomputeTangents = false;
SrcModel.BuildSettings.bRemoveDegenerates = false;
SrcModel.BuildSettings.bUseHighPrecisionTangentBasis = false;
SrcModel.BuildSettings.bUseFullPrecisionUVs = false;
FMeshNaniteSettings& NaniteSettings = NaniteStaticMesh->NaniteSettings;
NaniteSettings.bEnabled = true;
NaniteSettings.FallbackPercentTriangles = 0.01f; // Keep effectively no fallback mesh triangles
NaniteSettings.FallbackRelativeError = 1.0f;
const int32 LOD = 0; // Always uses high quality LOD
MeshDescription = NaniteStaticMesh->CreateMeshDescription(LOD);
{
TArray<UMaterialInterface*, TInlineAllocator<4>> InputMaterials;
TInlineComponentArray<ULandscapeComponent*> InputComponents;
for (ULandscapeComponent* Component : Landscape->LandscapeComponents)
{
if (Component)
{
InputMaterials.Add(Component->GetLandscapeMaterial(LOD));
InputComponents.Add(Component);
}
}
if (InputComponents.Num() == 0)
{
// TODO: Error
return;
}
FBoxSphereBounds UnusedBounds;
if (!Landscape->ExportToRawMesh(
MakeArrayView(InputComponents.GetData(), InputComponents.Num()),
LOD,
*MeshDescription,
UnusedBounds,
true /* Ignore Bounds */
))
{
// TODO: Error
return;
}
for (UMaterialInterface* Material : InputMaterials)
{
if (Material == nullptr)
{
Material = UMaterial::GetDefaultMaterial(MD_Surface);
}
NaniteStaticMesh->GetStaticMaterials().Add(FStaticMaterial(Material));
}
}
NaniteStaticMesh->CommitMeshDescription(0);
NaniteStaticMesh->ImportVersion = EImportStaticMeshVersion::LastVersion;
}
// Disable collisions
if (UBodySetup* BodySetup = NaniteStaticMesh->GetBodySetup())
{
BodySetup->DefaultInstance.SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
BodySetup->CollisionTraceFlag = CTF_UseSimpleAsComplex;
}
SetStaticMesh(NaniteStaticMesh);
UStaticMesh::BatchBuild({ NaniteStaticMesh });
ProxyContentId = NewProxyContentId;
}
#endif