Broad rearrangement of handlers
This commit is contained in:
228
Plugins/BlueprintMCP/Deprecated/UMCPHandler_DumpMaterial.h
Normal file
228
Plugins/BlueprintMCP/Deprecated/UMCPHandler_DumpMaterial.h
Normal file
@@ -0,0 +1,228 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MCPHandler.h"
|
||||
#include "MCPAssetFinder.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "MaterialDomain.h"
|
||||
#include "Materials/MaterialInstanceConstant.h"
|
||||
#include "Materials/MaterialExpression.h"
|
||||
#include "Materials/MaterialExpressionScalarParameter.h"
|
||||
#include "Materials/MaterialExpressionVectorParameter.h"
|
||||
#include "Materials/MaterialExpressionTextureSampleParameter2D.h"
|
||||
#include "Materials/MaterialExpressionStaticSwitchParameter.h"
|
||||
#include "Materials/MaterialExpressionTextureSample.h"
|
||||
#include "Engine/Texture.h"
|
||||
#include "UMCPHandler_DumpMaterial.generated.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
UCLASS(meta=(Group="Unclassified"))
|
||||
class UMCPHandler_DumpMaterial : public UObject, public IMCPHandler
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(meta=(Description="Material or MaterialInstance name or package path"))
|
||||
FString Material;
|
||||
|
||||
virtual FString GetDescription() const override
|
||||
{
|
||||
return TEXT("Get detailed info about a material or material instance, including parameters, usage flags, and referenced textures.");
|
||||
}
|
||||
|
||||
virtual void Handle(const FJsonObject* Json, FStringBuilderBase& Result) override
|
||||
{
|
||||
MCPAssets<UMaterialInterface> Assets;
|
||||
Assets.NoScans();
|
||||
Assets.Scan<UMaterial>();
|
||||
Assets.Scan<UMaterialInstanceConstant>();
|
||||
if (!Assets.Exact(Material).Errors(Result).ENone().ETwo().Load()) return;
|
||||
UMaterialInterface* LoadedObj = Assets.Object();
|
||||
|
||||
if (UMaterial* Mat = Cast<UMaterial>(LoadedObj))
|
||||
{
|
||||
EmitMaterial(Mat, Result);
|
||||
return;
|
||||
}
|
||||
|
||||
if (UMaterialInstanceConstant* MI = Cast<UMaterialInstanceConstant>(LoadedObj))
|
||||
{
|
||||
EmitMaterialInstance(MI, Result);
|
||||
return;
|
||||
}
|
||||
|
||||
Result.Appendf(TEXT("ERROR: Loaded object is %s, expected Material or MaterialInstance.\n"),
|
||||
*LoadedObj->GetClass()->GetName());
|
||||
}
|
||||
|
||||
private:
|
||||
void EmitMaterial(UMaterial* Mat, FStringBuilderBase& Result)
|
||||
{
|
||||
Result.Appendf(TEXT("Material: %s\n"), *MCPUtils::FormatName(Mat));
|
||||
Result.Appendf(TEXT("Domain: %s\n"), *MCPUtils::EnumToString(Mat->MaterialDomain, TEXT("MD_")));
|
||||
Result.Appendf(TEXT("BlendMode: %s\n"), *MCPUtils::EnumToString(Mat->BlendMode, TEXT("BLEND_")));
|
||||
Result.Appendf(TEXT("TwoSided: %s\n"), Mat->IsTwoSided() ? TEXT("true") : TEXT("false"));
|
||||
|
||||
// Shading models
|
||||
FMaterialShadingModelField SMField = Mat->GetShadingModels();
|
||||
const UEnum* SMEnum = StaticEnum<EMaterialShadingModel>();
|
||||
TArray<FString> SMNames;
|
||||
for (int32 i = 0; i < SMEnum->NumEnums() - 1; ++i)
|
||||
{
|
||||
EMaterialShadingModel SM = (EMaterialShadingModel)SMEnum->GetValueByIndex(i);
|
||||
if (SMField.HasShadingModel(SM))
|
||||
SMNames.Add(SMEnum->GetNameStringByIndex(i));
|
||||
}
|
||||
Result.Appendf(TEXT("ShadingModels: %s\n"), *FString::Join(SMNames, TEXT(", ")));
|
||||
|
||||
// Parameters
|
||||
auto Expressions = Mat->GetExpressions();
|
||||
bool bHasParams = false;
|
||||
for (UMaterialExpression* Expr : Expressions)
|
||||
{
|
||||
if (!Expr) continue;
|
||||
|
||||
if (auto* SP = Cast<UMaterialExpressionScalarParameter>(Expr))
|
||||
{
|
||||
if (!bHasParams) { Result.Append(TEXT("\nParameters:\n")); bHasParams = true; }
|
||||
Result.Appendf(TEXT(" Scalar \"%s\" = %g"), *SP->ParameterName.ToString(), SP->DefaultValue);
|
||||
if (!SP->Group.IsNone()) Result.Appendf(TEXT(" [%s]"), *SP->Group.ToString());
|
||||
Result.Append(TEXT("\n"));
|
||||
}
|
||||
else if (auto* VP = Cast<UMaterialExpressionVectorParameter>(Expr))
|
||||
{
|
||||
if (!bHasParams) { Result.Append(TEXT("\nParameters:\n")); bHasParams = true; }
|
||||
Result.Appendf(TEXT(" Vector \"%s\" = (%.3f, %.3f, %.3f, %.3f)"),
|
||||
*VP->ParameterName.ToString(),
|
||||
VP->DefaultValue.R, VP->DefaultValue.G, VP->DefaultValue.B, VP->DefaultValue.A);
|
||||
if (!VP->Group.IsNone()) Result.Appendf(TEXT(" [%s]"), *VP->Group.ToString());
|
||||
Result.Append(TEXT("\n"));
|
||||
}
|
||||
else if (auto* TP = Cast<UMaterialExpressionTextureSampleParameter2D>(Expr))
|
||||
{
|
||||
if (!bHasParams) { Result.Append(TEXT("\nParameters:\n")); bHasParams = true; }
|
||||
Result.Appendf(TEXT(" Texture \"%s\" = %s"),
|
||||
*TP->ParameterName.ToString(),
|
||||
TP->Texture ? *MCPUtils::FormatName(TP->Texture) : TEXT("None"));
|
||||
if (!TP->Group.IsNone()) Result.Appendf(TEXT(" [%s]"), *TP->Group.ToString());
|
||||
Result.Append(TEXT("\n"));
|
||||
}
|
||||
else if (auto* SSP = Cast<UMaterialExpressionStaticSwitchParameter>(Expr))
|
||||
{
|
||||
if (!bHasParams) { Result.Append(TEXT("\nParameters:\n")); bHasParams = true; }
|
||||
Result.Appendf(TEXT(" StaticSwitch \"%s\" = %s"),
|
||||
*SSP->ParameterName.ToString(),
|
||||
SSP->DefaultValue ? TEXT("true") : TEXT("false"));
|
||||
if (!SSP->Group.IsNone()) Result.Appendf(TEXT(" [%s]"), *SSP->Group.ToString());
|
||||
Result.Append(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
// Referenced textures
|
||||
auto RefTexObjs = Mat->GetReferencedTextures();
|
||||
bool bHasTextures = false;
|
||||
for (const TObjectPtr<UObject>& TexObj : RefTexObjs)
|
||||
{
|
||||
if (!TexObj) continue;
|
||||
if (!bHasTextures) { Result.Append(TEXT("\nReferenced Textures:\n")); bHasTextures = true; }
|
||||
if (UTexture* Tex = Cast<UTexture>(TexObj.Get()))
|
||||
Result.Appendf(TEXT(" %s\n"), *MCPUtils::FormatName(Tex));
|
||||
else
|
||||
Result.Appendf(TEXT(" %s\n"), *TexObj->GetPathName());
|
||||
}
|
||||
|
||||
// Usage flags — only print enabled ones
|
||||
Result.Append(TEXT("\nUsage Flags:"));
|
||||
bool bAnyUsage = false;
|
||||
auto EmitFlag = [&](bool bSet, const TCHAR* Name) {
|
||||
if (bSet) { Result.Appendf(TEXT(" %s"), Name); bAnyUsage = true; }
|
||||
};
|
||||
EmitFlag(Mat->bUsedWithSkeletalMesh, TEXT("SkeletalMesh"));
|
||||
EmitFlag(Mat->bUsedWithMorphTargets, TEXT("MorphTargets"));
|
||||
EmitFlag(Mat->bUsedWithNiagaraSprites, TEXT("NiagaraSprites"));
|
||||
EmitFlag(Mat->bUsedWithParticleSprites, TEXT("ParticleSprites"));
|
||||
EmitFlag(Mat->bUsedWithStaticLighting, TEXT("StaticLighting"));
|
||||
if (!bAnyUsage) Result.Append(TEXT(" (none)"));
|
||||
Result.Append(TEXT("\n"));
|
||||
|
||||
// Stats
|
||||
Result.Appendf(TEXT("Expressions: %d\n"), Expressions.Num());
|
||||
int32 TextureSampleCount = 0;
|
||||
for (UMaterialExpression* Expr : Expressions)
|
||||
if (Expr && Expr->IsA<UMaterialExpressionTextureSample>())
|
||||
TextureSampleCount++;
|
||||
Result.Appendf(TEXT("TextureSamples: %d\n"), TextureSampleCount);
|
||||
if (Mat->MaterialGraph)
|
||||
Result.Appendf(TEXT("GraphNodes: %d\n"), Mat->MaterialGraph->Nodes.Num());
|
||||
|
||||
// Additional settings — only print non-default values
|
||||
if (Mat->OpacityMaskClipValue != 0.3333f)
|
||||
Result.Appendf(TEXT("OpacityMaskClipValue: %g\n"), Mat->OpacityMaskClipValue);
|
||||
if (Mat->DitheredLODTransition)
|
||||
Result.Append(TEXT("DitheredLODTransition: true\n"));
|
||||
if (Mat->bAllowNegativeEmissiveColor)
|
||||
Result.Append(TEXT("AllowNegativeEmissiveColor: true\n"));
|
||||
}
|
||||
|
||||
void EmitMaterialInstance(UMaterialInstanceConstant* MI, FStringBuilderBase& Result)
|
||||
{
|
||||
Result.Appendf(TEXT("MaterialInstance: %s\n"), *MCPUtils::FormatName(MI));
|
||||
if (MI->Parent)
|
||||
{
|
||||
if (UMaterial* ParentMat = Cast<UMaterial>(MI->Parent))
|
||||
Result.Appendf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMat));
|
||||
else if (UMaterialInstance* ParentMI = Cast<UMaterialInstance>(MI->Parent))
|
||||
Result.Appendf(TEXT("Parent: %s\n"), *MCPUtils::FormatName(ParentMI));
|
||||
else
|
||||
Result.Appendf(TEXT("Parent: %s\n"), *MI->Parent->GetPathName());
|
||||
}
|
||||
|
||||
// Overridden parameters
|
||||
bool bHasParams = false;
|
||||
auto EnsureHeader = [&]() {
|
||||
if (!bHasParams) { Result.Append(TEXT("\nOverridden Parameters:\n")); bHasParams = true; }
|
||||
};
|
||||
|
||||
for (const FScalarParameterValue& P : MI->ScalarParameterValues)
|
||||
{
|
||||
EnsureHeader();
|
||||
Result.Appendf(TEXT(" Scalar \"%s\" = %g\n"), *P.ParameterInfo.Name.ToString(), P.ParameterValue);
|
||||
}
|
||||
|
||||
for (const FVectorParameterValue& P : MI->VectorParameterValues)
|
||||
{
|
||||
EnsureHeader();
|
||||
Result.Appendf(TEXT(" Vector \"%s\" = (%.3f, %.3f, %.3f, %.3f)\n"),
|
||||
*P.ParameterInfo.Name.ToString(),
|
||||
P.ParameterValue.R, P.ParameterValue.G, P.ParameterValue.B, P.ParameterValue.A);
|
||||
}
|
||||
|
||||
for (const FTextureParameterValue& P : MI->TextureParameterValues)
|
||||
{
|
||||
EnsureHeader();
|
||||
if (P.ParameterValue)
|
||||
{
|
||||
Result.Appendf(TEXT(" Texture \"%s\" = %s\n"),
|
||||
*P.ParameterInfo.Name.ToString(), *MCPUtils::FormatName(P.ParameterValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.Appendf(TEXT(" Texture \"%s\" = None\n"), *P.ParameterInfo.Name.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
for (const FStaticSwitchParameter& P : MI->GetStaticParameters().StaticSwitchParameters)
|
||||
{
|
||||
EnsureHeader();
|
||||
Result.Appendf(TEXT(" StaticSwitch \"%s\" = %s%s\n"),
|
||||
*P.ParameterInfo.Name.ToString(),
|
||||
P.Value ? TEXT("true") : TEXT("false"),
|
||||
P.bOverride ? TEXT("") : TEXT(" (not overridden)"));
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user