ralpha-assets/Plugins/CesiumForUnreal/Source/CesiumRuntime/Private/GenerateMaterialUtility.cpp

187 lines
5.9 KiB
C++

#include "GenerateMaterialUtility.h"
#include "CesiumMetadataEncodingDetails.h"
#include "Containers/Map.h"
#include "EncodedFeaturesMetadata.h"
#if WITH_EDITOR
#include "AssetRegistry/AssetData.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "ComponentReregisterContext.h"
#include "ContentBrowserModule.h"
#include "Factories/MaterialFunctionMaterialLayerFactory.h"
#include "IContentBrowserSingleton.h"
#include "IMaterialEditor.h"
#include "Materials/Material.h"
#include "Materials/MaterialExpressionCustom.h"
#include "Materials/MaterialExpressionFunctionInput.h"
#include "Materials/MaterialExpressionFunctionOutput.h"
#include "Materials/MaterialExpressionScalarParameter.h"
#include "Materials/MaterialExpressionTextureObjectParameter.h"
#include "Materials/MaterialExpressionTextureProperty.h"
#include "Materials/MaterialExpressionVectorParameter.h"
#include "Misc/PackageName.h"
#include "Modules/ModuleManager.h"
#include "Subsystems/AssetEditorSubsystem.h"
#include "UObject/Package.h"
extern UNREALED_API class UEditorEngine* GEditor;
namespace GenerateMaterialUtility {
UMaterialFunctionMaterialLayer*
CreateMaterialLayer(const FString& PackageName, const FString& MaterialName) {
UPackage* Package = CreatePackage(*PackageName);
UMaterialFunctionMaterialLayerFactory* MaterialFactory =
NewObject<UMaterialFunctionMaterialLayerFactory>();
UMaterialFunctionMaterialLayer* pMaterialLayer =
(UMaterialFunctionMaterialLayer*)MaterialFactory->FactoryCreateNew(
UMaterialFunctionMaterialLayer::StaticClass(),
Package,
*MaterialName,
RF_Public | RF_Standalone | RF_Transactional,
NULL,
GWarn);
FAssetRegistryModule::AssetCreated(pMaterialLayer);
Package->FullyLoad();
Package->SetDirtyFlag(true);
return pMaterialLayer;
}
void MoveNodesToMaterialLayer(
MaterialGenerationState& MaterialState,
UMaterialFunctionMaterialLayer* pMaterialLayer) {
for (UMaterialExpression* Node : MaterialState.AutoGeneratedNodes) {
// Mark as auto-generated. If the material is regenerated, we will look
// for this exact description.
Node->Desc = AutogeneratedMessage;
// Don't clutter the material editor with autogenerated messages.
Node->bCommentBubbleVisible = false;
pMaterialLayer->GetExpressionCollection().AddExpression(Node);
}
for (UMaterialExpression* Node : MaterialState.OneTimeGeneratedNodes) {
pMaterialLayer->GetExpressionCollection().AddExpression(Node);
}
MaterialState.AutoGeneratedNodes.Empty();
MaterialState.OneTimeGeneratedNodes.Empty();
}
float GetNameLengthScalar(const FName& Name) {
return FMath::Max(static_cast<float>(Name.GetStringLength()) / 24, 1.0f);
}
float GetNameLengthScalar(const FString& Name) {
return FMath::Max(static_cast<float>(Name.Len()) / 24, 1.0f);
}
ECustomMaterialOutputType
GetOutputTypeForEncodedType(ECesiumEncodedMetadataType Type) {
switch (Type) {
case ECesiumEncodedMetadataType::Vec2:
return ECustomMaterialOutputType::CMOT_Float2;
case ECesiumEncodedMetadataType::Vec3:
return ECustomMaterialOutputType::CMOT_Float3;
case ECesiumEncodedMetadataType::Vec4:
return ECustomMaterialOutputType::CMOT_Float4;
case ECesiumEncodedMetadataType::Scalar:
default:
return ECustomMaterialOutputType::CMOT_Float1;
};
}
FString GetHlslTypeForEncodedType(
ECesiumEncodedMetadataType Type,
ECesiumEncodedMetadataComponentType ComponentType) {
if (ComponentType == ECesiumEncodedMetadataComponentType::Uint8) {
switch (Type) {
case ECesiumEncodedMetadataType::Scalar:
return "uint";
case ECesiumEncodedMetadataType::Vec2:
return "uint2";
case ECesiumEncodedMetadataType::Vec3:
return "uint3";
case ECesiumEncodedMetadataType::Vec4:
return "uint4";
default:
break;
}
}
if (ComponentType == ECesiumEncodedMetadataComponentType::Float) {
switch (Type) {
case ECesiumEncodedMetadataType::Scalar:
return "float";
case ECesiumEncodedMetadataType::Vec2:
return "float2";
case ECesiumEncodedMetadataType::Vec3:
return "float3";
case ECesiumEncodedMetadataType::Vec4:
return "float4";
default:
break;
}
}
return FString();
}
FString GetSwizzleForEncodedType(ECesiumEncodedMetadataType Type) {
switch (Type) {
case ECesiumEncodedMetadataType::Scalar:
return ".r";
case ECesiumEncodedMetadataType::Vec2:
return ".rg";
case ECesiumEncodedMetadataType::Vec3:
return ".rgb";
case ECesiumEncodedMetadataType::Vec4:
return ".rgba";
default:
return FString();
};
}
UMaterialExpressionParameter* GenerateParameterNode(
UMaterialFunctionMaterialLayer* TargetMaterialLayer,
const ECesiumEncodedMetadataType Type,
const FString& Name,
int32 NodeX,
int32 NodeY) {
UMaterialExpressionParameter* Parameter = nullptr;
int32 NodeHeight = 0;
if (Type == ECesiumEncodedMetadataType::Scalar) {
UMaterialExpressionScalarParameter* ScalarParameter =
NewObject<UMaterialExpressionScalarParameter>(TargetMaterialLayer);
ScalarParameter->DefaultValue = 0.0f;
Parameter = ScalarParameter;
}
if (Type == ECesiumEncodedMetadataType::Vec2 ||
Type == ECesiumEncodedMetadataType::Vec3 ||
Type == ECesiumEncodedMetadataType::Vec4) {
UMaterialExpressionVectorParameter* VectorParameter =
NewObject<UMaterialExpressionVectorParameter>(TargetMaterialLayer);
VectorParameter->DefaultValue = FLinearColor(0.0f, 0.0f, 0.0f, 0.0f);
Parameter = VectorParameter;
}
if (!Parameter) {
return nullptr;
}
Parameter->ParameterName = FName(Name);
Parameter->MaterialExpressionEditorX = NodeX;
Parameter->MaterialExpressionEditorY = NodeY;
return Parameter;
}
} // namespace GenerateMaterialUtility
#endif