Files
UnrealEngineUWP/Engine/Source/Runtime/Landscape/Private/Materials/MaterialExpressionLandscapeLayerSwitch.cpp
jeremy moore 75dbbdbdf5 #jira FORT-476711
Landscape: Default Preview to false on LandscapeLayerSwitch material node. When true the behavior is to always show the Used branch, which is almost never what we want.
It would be better to have Preview path only taken on non-landscape mesh, but current static parameter set doesn't distinguish between non-landscape and landscape with no layers.
#preflight 627c5f0bf3326dc708b663ae

[CL 20156372 by jeremy moore in ue5-main branch]
2022-05-11 21:17:41 -04:00

139 lines
3.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Materials/MaterialExpressionLandscapeLayerSwitch.h"
#include "Engine/Engine.h"
#include "Engine/Texture.h"
#include "EngineGlobals.h"
#include "MaterialCompiler.h"
#include "Materials/Material.h"
#define LOCTEXT_NAMESPACE "Landscape"
///////////////////////////////////////////////////////////////////////////////
// UMaterialExpressionLandscapeLayerSwitch
///////////////////////////////////////////////////////////////////////////////
UMaterialExpressionLandscapeLayerSwitch::UMaterialExpressionLandscapeLayerSwitch(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
// Structure to hold one-time initialization
struct FConstructorStatics
{
FText NAME_Landscape;
FConstructorStatics()
: NAME_Landscape(LOCTEXT("Landscape", "Landscape"))
{
}
};
static FConstructorStatics ConstructorStatics;
#if WITH_EDITORONLY_DATA
MenuCategories.Add(ConstructorStatics.NAME_Landscape);
bCollapsed = false;
#endif
PreviewUsed = false;
}
#if WITH_EDITOR
bool UMaterialExpressionLandscapeLayerSwitch::IsResultMaterialAttributes(int32 OutputIndex)
{
if (ContainsInputLoop())
{
// If there is a loop anywhere in this expression's inputs then we can't risk checking them
return false;
}
bool bLayerUsedIsMaterialAttributes = LayerUsed.Expression != nullptr && LayerUsed.Expression->IsResultMaterialAttributes(LayerUsed.OutputIndex);
bool bLayerNotUsedIsMaterialAttributes = LayerNotUsed.Expression != nullptr && LayerNotUsed.Expression->IsResultMaterialAttributes(LayerNotUsed.OutputIndex);
return bLayerUsedIsMaterialAttributes || bLayerNotUsedIsMaterialAttributes;
}
int32 UMaterialExpressionLandscapeLayerSwitch::Compile(class FMaterialCompiler* Compiler, int32 OutputIndex)
{
const int32 WeightCode = Compiler->StaticTerrainLayerWeight(
ParameterName,
PreviewUsed ? Compiler->Constant(1.0f) : INDEX_NONE
);
int32 ReturnCode = INDEX_NONE;
if (WeightCode != INDEX_NONE)
{
ReturnCode = LayerUsed.Compile(Compiler);
}
else
{
ReturnCode = LayerNotUsed.Compile(Compiler);
}
if (ReturnCode != INDEX_NONE && //If we've already failed for some other reason don't bother with this check. It could have been the reentrant check causing this to loop infinitely!
LayerUsed.Expression != nullptr && LayerNotUsed.Expression != nullptr &&
LayerUsed.Expression->IsResultMaterialAttributes(LayerUsed.OutputIndex) != LayerNotUsed.Expression->IsResultMaterialAttributes(LayerNotUsed.OutputIndex))
{
Compiler->Error(TEXT("Cannot mix MaterialAttributes and non MaterialAttributes nodes"));
}
return ReturnCode;
}
#endif // WITH_EDITOR
UObject* UMaterialExpressionLandscapeLayerSwitch::GetReferencedTexture() const
{
return GEngine->WeightMapPlaceholderTexture;
}
#if WITH_EDITOR
void UMaterialExpressionLandscapeLayerSwitch::GetCaption(TArray<FString>& OutCaptions) const
{
OutCaptions.Add(TEXT("Layer Switch"));
OutCaptions.Add(FString::Printf(TEXT("'%s'"), *ParameterName.ToString()));
}
bool UMaterialExpressionLandscapeLayerSwitch::MatchesSearchQuery(const TCHAR* SearchQuery)
{
TArray<FString> Captions;
GetCaption(Captions);
for (const FString& Caption : Captions)
{
if (Caption.Contains(SearchQuery))
{
return true;
}
}
return Super::MatchesSearchQuery(SearchQuery);
}
#endif // WITH_EDITOR
void UMaterialExpressionLandscapeLayerSwitch::Serialize(FStructuredArchive::FRecord Record)
{
Super::Serialize(Record);
if (Record.GetUnderlyingArchive().UEVer() < VER_UE4_FIX_TERRAIN_LAYER_SWITCH_ORDER)
{
Swap(LayerUsed, LayerNotUsed);
}
}
void UMaterialExpressionLandscapeLayerSwitch::PostLoad()
{
Super::PostLoad();
if (GetLinkerUEVersion() < VER_UE4_FIXUP_TERRAIN_LAYER_NODES)
{
UpdateParameterGuid(true, true);
}
}
#if WITH_EDITOR
void UMaterialExpressionLandscapeLayerSwitch::GetLandscapeLayerNames(TArray<FName>& OutLayers) const
{
OutLayers.AddUnique(ParameterName);
}
#endif // WITH_EDITOR
#undef LOCTEXT_NAMESPACE