Trying to get material parameters into a polished state.

This commit is contained in:
2026-04-06 18:55:17 -04:00
parent 8951065670
commit e7fd6c2f70
6 changed files with 226 additions and 102 deletions

0
.codex Normal file
View File

BIN
Content/Testing/M_Test.uasset LFS Normal file

Binary file not shown.

View File

@@ -40,7 +40,7 @@ public:
if (!MI) return; if (!MI) return;
// Parse the parameter ID. // Parse the parameter ID.
FMaterialParameterInfo ID; WingMaterialParameter::Info ID;
if (!WingMaterialParameter::ParseID(Parameter, ID, WingOut::Stdout)) if (!WingMaterialParameter::ParseID(Parameter, ID, WingOut::Stdout))
return; return;

View File

@@ -8,7 +8,6 @@
#include "WingMaterialParameter.h" #include "WingMaterialParameter.h"
#include "Materials/MaterialInstanceConstant.h" #include "Materials/MaterialInstanceConstant.h"
#include "MaterialTypes.h" #include "MaterialTypes.h"
#include "Misc/DefaultValueHelper.h"
#include "MaterialInstance_SetParameter.generated.h" #include "MaterialInstance_SetParameter.generated.h"
@@ -43,47 +42,19 @@ public:
if (!MI) return; if (!MI) return;
// Parse the parameter ID. // Parse the parameter ID.
FMaterialParameterInfo ID; WingMaterialParameter::Info ID;
if (!WingMaterialParameter::ParseID(Parameter, ID, WingOut::Stdout)) if (!WingMaterialParameter::ParseID(Parameter, ID, WingOut::Stdout))
return; return;
// Find it in the material's parameter map. // Make sure the parameter actually exists.
auto AllParams = WingMaterialParameter::GetMaterialParameters(MI); auto AllParams = WingMaterialParameter::GetMaterialParameters(MI);
FMaterialParameterMetadata* Meta = FMaterialParameterMetadata* Meta =
WingMaterialParameter::FindParameter(AllParams, ID, WingOut::Stdout); WingMaterialParameter::FindParameter(AllParams, ID, WingOut::Stdout);
if (!Meta) return; if (!Meta) return;
if (!WingMaterialParameter::CheckNoCustomPrimitiveData(ID, *Meta, WingOut::Stdout)) return; if (!WingMaterialParameter::CheckNoCustomPrimitiveData(ID, *Meta, WingOut::Stdout)) return;
EMaterialParameterType Type = Meta->Value.Type; // Set the parameter
if (!WingMaterialParameter::AddOverride(ID, MI, Value, WingOut::Stdout)) return;
switch (Type)
{
case EMaterialParameterType::Scalar:
{
float ScalarValue;
if (!FDefaultValueHelper::ParseFloat(Value, ScalarValue))
{
WingOut::Stdout.Printf(TEXT("Failed to parse '%s' as a float"), *Value);
return;
}
MI->SetScalarParameterValueEditorOnly(ID, ScalarValue);
break;
}
case EMaterialParameterType::Vector:
{
FLinearColor Color;
if (!Color.InitFromString(Value))
{
WingOut::Stdout.Printf(TEXT("Failed to parse '%s' as a color/vector (expected format: '(R=1,G=0,B=0,A=1)')"), *Value);
return;
}
MI->SetVectorParameterValueEditorOnly(ID, Color);
break;
}
default:
WingOut::Stdout.Printf(TEXT("Parameters of type %d (see EMaterialParameterType) are not implemented"), (int)Type);
return;
}
WingOut::Stdout.Printf(TEXT("Assigned.\n")); WingOut::Stdout.Printf(TEXT("Assigned.\n"));
} }
}; };

View File

@@ -2,36 +2,69 @@
#include "WingUtils.h" #include "WingUtils.h"
#include "WingTokenizer.h" #include "WingTokenizer.h"
#include "WingServer.h" #include "WingServer.h"
#include "Engine/Font.h"
#include "Engine/TextureCollection.h"
#include "Misc/DefaultValueHelper.h"
#include "SparseVolumeTexture/SparseVolumeTexture.h"
#include "VT/RuntimeVirtualTexture.h"
const TCHAR *WingMaterialParameter::EMaterialParameterTypeToString(EMaterialParameterType Type)
{
switch (Type)
{
case EMaterialParameterType::Scalar: return TEXT("Scalar");
case EMaterialParameterType::Vector: return TEXT("Vector");
case EMaterialParameterType::DoubleVector: return TEXT("DoubleVector");
case EMaterialParameterType::Texture: return TEXT("Texture");
case EMaterialParameterType::TextureCollection: return TEXT("TextureCollection");
case EMaterialParameterType::Font: return TEXT("Font");
case EMaterialParameterType::RuntimeVirtualTexture: return TEXT("RuntimeVirtualTexture");
case EMaterialParameterType::SparseVolumeTexture: return TEXT("SparseVolumeTexture");
case EMaterialParameterType::StaticSwitch: return TEXT("StaticSwitch");
case EMaterialParameterType::StaticComponentMask: return TEXT("StaticComponentMask");
case EMaterialParameterType::Num: return TEXT("Num");
case EMaterialParameterType::None: return TEXT("None");
}
return TEXT("None");
}
bool WingMaterialParameter::EMaterialParameterTypeFromName(FName Name, EMaterialParameterType &Result, WingOut Errors)
{
if (Name == TEXT("Scalar")) { Result = EMaterialParameterType::Scalar; return true; }
if (Name == TEXT("Vector")) { Result = EMaterialParameterType::Vector; return true; }
if (Name == TEXT("DoubleVector")) { Result = EMaterialParameterType::DoubleVector; return true; }
if (Name == TEXT("Texture")) { Result = EMaterialParameterType::Texture; return true; }
if (Name == TEXT("TextureCollection")) { Result = EMaterialParameterType::TextureCollection; return true; }
if (Name == TEXT("Font")) { Result = EMaterialParameterType::Font; return true; }
if (Name == TEXT("RuntimeVirtualTexture")) { Result = EMaterialParameterType::RuntimeVirtualTexture; return true; }
if (Name == TEXT("SparseVolumeTexture")) { Result = EMaterialParameterType::SparseVolumeTexture; return true; }
if (Name == TEXT("StaticSwitch")) { Result = EMaterialParameterType::StaticSwitch; return true; }
if (Name == TEXT("StaticComponentMask")) { Result = EMaterialParameterType::StaticComponentMask; return true; }
if (Name == TEXT("Num")) { Result = EMaterialParameterType::Num; return true; }
if (Name == TEXT("None")) { Result = EMaterialParameterType::None; return true; }
Errors.Printf(TEXT("ERROR: '%s' is not a valid EMaterialParameterType\n"), *Name.ToString());
Result = EMaterialParameterType::None;
return false;
}
WingMaterialParameter::InfoMetaMap WingMaterialParameter::GetMaterialParameters(UMaterialInterface* Material) WingMaterialParameter::InfoMetaMap WingMaterialParameter::GetMaterialParameters(UMaterialInterface* Material)
{ {
InfoMetaMap Result; InfoMetaMap Result;
if (!Material) return Result; if (!Material) return Result;
InfoMetaMap Temp; TMap<FMaterialParameterInfo, Metadata> Temp;
for (int32 i = 0; i < (int32)EMaterialParameterType::NumRuntime; i++) for (int I = 0; I < int(EMaterialParameterType::NumRuntime); I++)
{ {
Material->GetAllParametersOfType((EMaterialParameterType)i, Temp); EMaterialParameterType T = (EMaterialParameterType)I;
Result.Append(Temp); Material->GetAllParametersOfType(T, Temp);
for (const auto &KV : Temp)
{
check(KV.Value.Value.Type == T);
Result.Add(Info(KV.Key, T), KV.Value);
}
} }
return Result; return Result;
} }
bool WingMaterialParameter::ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation, WingOut Errors)
{
if (Str.Equals(TEXT("Global"), ESearchCase::IgnoreCase))
OutAssociation = GlobalParameter;
else if (Str.Equals(TEXT("Layer"), ESearchCase::IgnoreCase))
OutAssociation = LayerParameter;
else if (Str.Equals(TEXT("Blend"), ESearchCase::IgnoreCase))
OutAssociation = BlendParameter;
else
{
Errors.Printf(TEXT("ERROR: Invalid ParameterAssociation '%s' (expected 'Global', 'Layer', or 'Blend')\n"), *Str);
return false;
}
return true;
}
void WingMaterialParameter::ReportBadToken(WingTokenizer &Tok, const TCHAR *Expected, WingOut Errors) void WingMaterialParameter::ReportBadToken(WingTokenizer &Tok, const TCHAR *Expected, WingOut Errors)
{ {
FString Whole = Tok.GetRange(FName(), 1000); FString Whole = Tok.GetRange(FName(), 1000);
@@ -40,41 +73,54 @@ void WingMaterialParameter::ReportBadToken(WingTokenizer &Tok, const TCHAR *Expe
Errors.Printf(TEXT("Parsing %s, near %s: expected %s"), *Whole, *Next, Expected); Errors.Printf(TEXT("Parsing %s, near %s: expected %s"), *Whole, *Next, Expected);
} }
FString WingMaterialParameter::StringID(const FMaterialParameterInfo &ID) FString WingMaterialParameter::StringID(const Info &ID)
{ {
const TCHAR *Type = EMaterialParameterTypeToString(ID.Type);
FString Ext = WingUtils::ExternalizeID(ID.Name); FString Ext = WingUtils::ExternalizeID(ID.Name);
if (ID.Association != EMaterialParameterAssociation::GlobalParameter) if (ID.Association != EMaterialParameterAssociation::GlobalParameter)
{ {
const TCHAR *Prefix = TEXT("Layer"); const TCHAR *Prefix = TEXT("Layer");
if (ID.Association == EMaterialParameterAssociation::BlendParameter) if (ID.Association == EMaterialParameterAssociation::BlendParameter)
Prefix = TEXT("Blend"); Prefix = TEXT("Blend");
return FString::Printf(TEXT("%s:%d:%s"), Prefix, ID.Index, *Ext); return FString::Printf(TEXT("%s:%s:%d:%s"), Type, Prefix, ID.Index, *Ext);
} }
else else
{ {
return Ext; return FString::Printf(TEXT("%s:%s"), Type, *Ext);
} }
} }
bool WingMaterialParameter::ParseID(const FString& IDString, FMaterialParameterInfo& ID, WingOut Errors) bool WingMaterialParameter::ParseID(const FString& IDString, Info& ID, WingOut Errors)
{ {
WingTokenizer Tok(IDString); WingTokenizer Tok(IDString);
ID.Type = EMaterialParameterType::None;
ID.Association = EMaterialParameterAssociation::GlobalParameter; ID.Association = EMaterialParameterAssociation::GlobalParameter;
ID.Index = 0; ID.Index = 0;
ID.Name = FName(); ID.Name = FName();
// Parse the type.
const TCHAR *GoodTypes = TEXT("Vector, DoubleVector, Texture, TextureCollection, Font, RuntimeVirtualTexture, SparseVolumeTexture, or StaticSwitch");
if (!Tok.TokenIs(Tok.Identifier))
{ ReportBadToken(Tok, GoodTypes, Errors); return false; }
EMaterialParameterType TypeValue;
if (!EMaterialParameterTypeFromName(Tok.NextName(), TypeValue, Errors)) return false;
if (TypeValue >= EMaterialParameterType::NumRuntime)
{ ReportBadToken(Tok, GoodTypes, Errors); return false; }
ID.Type = TypeValue;
Tok.Advance();
// A colon after the type.
if (!Tok.TokenIs(':')) { ReportBadToken(Tok, TEXT("colon"), Errors); return false; }
// Parse the Layer or blend prefix. // Parse the Layer or blend prefix.
if (Tok.TokenIs(TEXT("Layer")) || Tok.TokenIs(TEXT("Blend"))) if (Tok.TokenIs(TEXT("Layer"), ':') || Tok.TokenIs(TEXT("Blend"), ':'))
{ {
if (Tok.NextName() == TEXT("Layer")) if (Tok.NextName() == TEXT("Layer"))
ID.Association = EMaterialParameterAssociation::LayerParameter; ID.Association = EMaterialParameterAssociation::LayerParameter;
else else
ID.Association = EMaterialParameterAssociation::BlendParameter; ID.Association = EMaterialParameterAssociation::BlendParameter;
Tok.Advance(); Tok.Advance();
if (!Tok.TokenIs(':'))
{ ReportBadToken(Tok, TEXT("colon"), Errors); return false; }
Tok.Advance(); Tok.Advance();
if ((!Tok.TokenIs(Tok.Identifier)) || if ((!Tok.TokenIs(Tok.Identifier)) ||
@@ -104,20 +150,20 @@ bool WingMaterialParameter::ParseID(const FString& IDString, FMaterialParameterI
return true; return true;
} }
FMaterialParameterMetadata *WingMaterialParameter::FindParameter( WingMaterialParameter::Metadata *WingMaterialParameter::FindParameter(
InfoMetaMap &Map, const FMaterialParameterInfo &ID, WingOut Errors) InfoMetaMap &Map, const Info &ID, WingOut Errors)
{ {
FMaterialParameterMetadata* Found = Map.Find(ID); Metadata* Found = Map.Find(ID);
if (!Found) if (!Found)
{ {
Errors.Printf(TEXT("No parameter named '%s' in this material"), *StringID(ID)); Errors.Printf(TEXT("No parameter '%s' in this material"), *StringID(ID));
return nullptr; return nullptr;
} }
return Found; return Found;
} }
bool WingMaterialParameter::CheckNoCustomPrimitiveData( bool WingMaterialParameter::CheckNoCustomPrimitiveData(
const FMaterialParameterInfo &ID, const FMaterialParameterMetadata &Data, WingOut Errors) const Info &ID, const Metadata &Data, WingOut Errors)
{ {
if (Data.PrimitiveDataIndex != INDEX_NONE) if (Data.PrimitiveDataIndex != INDEX_NONE)
{ {
@@ -134,30 +180,98 @@ FString WingMaterialParameter::FormatValue(const FMaterialParameterValue& Value)
switch (Value.Type) switch (Value.Type)
{ {
case EMaterialParameterType::Scalar: { case EMaterialParameterType::Scalar: {
return FString::Printf(TEXT("scalar(%g)"), Value.AsScalar()); return FString::Printf(TEXT("%g"), Value.AsScalar());
} }
case EMaterialParameterType::Vector: { case EMaterialParameterType::Vector: {
return FString::Printf(TEXT("vector(%s)"), *Value.AsLinearColor().ToString()); return Value.AsLinearColor().ToString();
} }
case EMaterialParameterType::DoubleVector: { case EMaterialParameterType::DoubleVector: {
return FString::Printf(TEXT("doublevector(%s)"), *Value.AsLinearColor().ToString()); return Value.AsVector4d().ToString();
} }
case EMaterialParameterType::Texture: { case EMaterialParameterType::Texture: {
UTexture* Tex = Cast<UTexture>(Value.AsTextureObject()); return PathNameOrNone(Value.Texture);
return FString::Printf(TEXT("texture(%s)"), *Tex->GetPathName()); }
case EMaterialParameterType::TextureCollection: {
return PathNameOrNone(Value.TextureCollection);
}
case EMaterialParameterType::Font: {
return FString::Printf(TEXT("%s:%d"), *PathNameOrNone(Value.Font.Value), Value.Font.Page);
}
case EMaterialParameterType::RuntimeVirtualTexture: {
return PathNameOrNone(Value.RuntimeVirtualTexture);
}
case EMaterialParameterType::SparseVolumeTexture: {
return PathNameOrNone(Value.SparseVolumeTexture);
} }
case EMaterialParameterType::StaticSwitch: { case EMaterialParameterType::StaticSwitch: {
const TCHAR *Str = Value.AsStaticSwitch() ? TEXT("true") : TEXT("false"); return Value.AsStaticSwitch() ? TEXT("true") : TEXT("false");
return FString::Printf(TEXT("staticswitch(%s)"), Str);
} }
default: { case EMaterialParameterType::StaticComponentMask: {
return FString::Printf(TEXT("unknown(%d)"), (int)Value.Type); const FStaticComponentMaskValue Mask = Value.AsStaticComponentMask();
return FString::Printf(
TEXT("(R=%s,G=%s,B=%s,A=%s)"),
Mask.R ? TEXT("true") : TEXT("false"),
Mask.G ? TEXT("true") : TEXT("false"),
Mask.B ? TEXT("true") : TEXT("false"),
Mask.A ? TEXT("true") : TEXT("false"));
}
case EMaterialParameterType::Num: {
return TEXT("invalid-parameter-type");
}
case EMaterialParameterType::None: {
return TEXT("invalid-parameter-type");
} }
} }
return TEXT("invalid-parameter-type");
}
bool WingMaterialParameter::AddOverride(
const Info &ID, UMaterialInstanceConstant *MI, const FString &Value, WingOut Errors)
{
switch (ID.Type)
{
case EMaterialParameterType::Scalar:
{
float ScalarValue;
if (!FDefaultValueHelper::ParseFloat(Value, ScalarValue))
{
Errors.Printf(TEXT("Failed to parse '%s' as a float"), *Value);
return false;
}
MI->SetScalarParameterValueEditorOnly(ID, ScalarValue);
return true;
}
case EMaterialParameterType::Vector:
{
FLinearColor Color;
if (!Color.InitFromString(Value))
{
Errors.Printf(TEXT("Failed to parse '%s' as a color/vector (expected format: '(R=1,G=0,B=0,A=1)')"), *Value);
return false;
}
MI->SetVectorParameterValueEditorOnly(ID, Color);
return true;
}
case EMaterialParameterType::DoubleVector:
case EMaterialParameterType::Texture:
case EMaterialParameterType::TextureCollection:
case EMaterialParameterType::Font:
case EMaterialParameterType::RuntimeVirtualTexture:
case EMaterialParameterType::SparseVolumeTexture:
case EMaterialParameterType::StaticSwitch:
case EMaterialParameterType::StaticComponentMask:
Errors.Printf(TEXT("Parameters of type %s are not implemented"), EMaterialParameterTypeToString(ID.Type));
return false;
case EMaterialParameterType::Num:
case EMaterialParameterType::None:
Errors.Printf(TEXT("Parameter Type is not valid"));
return false;
}
return false;
} }
bool WingMaterialParameter::RemoveOverride( bool WingMaterialParameter::RemoveOverride(
const FMaterialParameterInfo &ID, UMaterialInstanceConstant *MI, WingOut Errors) const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors)
{ {
// Remove the override from all parameter arrays. // Remove the override from all parameter arrays.
auto RemoveFrom = [&](auto& Arr) { auto RemoveFrom = [&](auto& Arr) {
@@ -165,14 +279,21 @@ bool WingMaterialParameter::RemoveOverride(
}; };
int32 Removed = 0; int32 Removed = 0;
Removed += RemoveFrom(MI->ScalarParameterValues); switch (ID.Type)
Removed += RemoveFrom(MI->VectorParameterValues); {
Removed += RemoveFrom(MI->DoubleVectorParameterValues); case EMaterialParameterType::Scalar: Removed += RemoveFrom(MI->ScalarParameterValues); break;
Removed += RemoveFrom(MI->TextureParameterValues); case EMaterialParameterType::Vector: Removed += RemoveFrom(MI->VectorParameterValues); break;
Removed += RemoveFrom(MI->TextureCollectionParameterValues); case EMaterialParameterType::DoubleVector: Removed += RemoveFrom(MI->DoubleVectorParameterValues); break;
Removed += RemoveFrom(MI->RuntimeVirtualTextureParameterValues); case EMaterialParameterType::Texture: Removed += RemoveFrom(MI->TextureParameterValues); break;
Removed += RemoveFrom(MI->SparseVolumeTextureParameterValues); case EMaterialParameterType::TextureCollection: Removed += RemoveFrom(MI->TextureCollectionParameterValues); break;
Removed += RemoveFrom(MI->FontParameterValues); case EMaterialParameterType::Font: Removed += RemoveFrom(MI->FontParameterValues); break;
case EMaterialParameterType::RuntimeVirtualTexture: Removed += RemoveFrom(MI->RuntimeVirtualTextureParameterValues); break;
case EMaterialParameterType::SparseVolumeTexture: Removed += RemoveFrom(MI->SparseVolumeTextureParameterValues); break;
case EMaterialParameterType::StaticSwitch: Errors.Printf(TEXT("Removal of static switches not implemented")); return false;
case EMaterialParameterType::StaticComponentMask: Errors.Printf(TEXT("Removal of static component masks not implemented")); return false;
case EMaterialParameterType::Num: Errors.Printf(TEXT("Parameter Type is not valid")); return false;
case EMaterialParameterType::None: Errors.Printf(TEXT("Parameter Type is not valid")); return false;
}
if (Removed == 0) if (Removed == 0)
{ {
@@ -184,7 +305,7 @@ bool WingMaterialParameter::RemoveOverride(
void WingMaterialParameter::Print( void WingMaterialParameter::Print(
const FMaterialParameterInfo &Info, const FMaterialParameterMetadata &Meta) const Info &Info, const Metadata &Meta)
{ {
WingOut::Stdout.Printf(TEXT(" %s %s\n"), WingOut::Stdout.Printf(TEXT(" %s %s\n"),
*WingMaterialParameter::StringID(Info), *WingMaterialParameter::FormatValue(Meta.Value)); *WingMaterialParameter::StringID(Info), *WingMaterialParameter::FormatValue(Meta.Value));

View File

@@ -6,10 +6,37 @@
#include "Materials/MaterialInstanceConstant.h" #include "Materials/MaterialInstanceConstant.h"
#include "WingHandler.h" #include "WingHandler.h"
class WingMaterialParameter class WingMaterialParameter
{ {
public: public:
using InfoMetaMap = TMap<FMaterialParameterInfo, FMaterialParameterMetadata>; // Info struct is a FMaterialParameterInfo plus a type field.
struct Info : public FMaterialParameterInfo
{
EMaterialParameterType Type;
Info() : FMaterialParameterInfo(), Type(EMaterialParameterType::None) {}
Info(const FMaterialParameterInfo &I, EMaterialParameterType T) : FMaterialParameterInfo(I), Type(T) {}
friend FORCEINLINE bool operator==(const Info& Lhs, const Info& Rhs)
{
return Lhs.Name.IsEqual(Rhs.Name) && Lhs.Association == Rhs.Association && Lhs.Index == Rhs.Index && Lhs.Type == Rhs.Type;
}
friend FORCEINLINE bool operator!=(const Info& Lhs, const Info& Rhs)
{
return !operator==(Lhs, Rhs);
}
friend FORCEINLINE uint32 GetTypeHash(const Info& Value)
{
return HashCombine(HashCombine(HashCombine(GetTypeHash(NameToScriptName(Value.Name)), Value.Index), (uint32)Value.Association), (uint32)Value.Type);
}
};
using Type = EMaterialParameterType;
using Metadata = FMaterialParameterMetadata;
using Value = FMaterialParameterValue;
using InfoMetaMap = TMap<Info, Metadata>;
// Get all the material parameters of the specified material including // Get all the material parameters of the specified material including
// both parameters that have been overridden and those that haven't. // both parameters that have been overridden and those that haven't.
@@ -19,46 +46,48 @@ public:
// Find a material parameter in the InfoMap. // Find a material parameter in the InfoMap.
// If it doesn't exist, or report an error and return nullptr. // If it doesn't exist, or report an error and return nullptr.
// //
static FMaterialParameterMetadata *FindParameter( static Metadata *FindParameter(InfoMetaMap &Map, const Info &ID, WingOut Errors);
InfoMetaMap &Map, const FMaterialParameterInfo &ID, WingOut Errors);
// If the material uses custom primitive data, print an error // If the material uses custom primitive data, print an error
// and return false. // and return false.
// //
static bool CheckNoCustomPrimitiveData( static bool CheckNoCustomPrimitiveData(const Info &ID, const Metadata &Data, WingOut Errors);
const FMaterialParameterInfo &ID, const FMaterialParameterMetadata &Data, WingOut Errors);
// Convert a parameter ID into an ID string. // Convert an ID in string form into an ID in info form.
// //
static bool ParseID(const FString& Str, FMaterialParameterInfo& ID, WingOut Errors); static bool ParseID(const FString& Str, Info& ID, WingOut Errors);
// Parse a parameter ID String into a parameter ID. // Convert an ID in Info form into an ID in string form.
// //
static FString StringID(const FMaterialParameterInfo& ID); static FString StringID(const Info& ID);
// Add a material parameter override to a material instance.
//
static bool AddOverride(
const Info &ID, UMaterialInstanceConstant *MI, const FString &Value, WingOut Errors);
// Remove a material parameter override from a material instance. // Remove a material parameter override from a material instance.
// If there is no override, print an error and return false. // If there is no override, print an error and return false.
// //
static bool RemoveOverride( static bool RemoveOverride(const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors);
const FMaterialParameterInfo &ID, UMaterialInstanceConstant *MI, WingOut Errors);
// Format a material parameter value. // Format a material parameter value.
// //
static FString FormatValue(const FMaterialParameterValue& Value); static FString FormatValue(const Value& Value);
// Print out a material parameter with ID. // Print out a material parameter with ID.
// //
static void Print(const FMaterialParameterInfo &Info, const FMaterialParameterMetadata &Meta); static void Print(const Info &Info, const Metadata &Meta);
// Print out a map full of material parameters. If Headings is // Print out a map full of material parameters. If Headings is
// true, the parameters are grouped by inherited/overridden. // true, the parameters are grouped by inherited/overridden.
// //
static void PrintAll(const InfoMetaMap &Params, bool Headings); static void PrintAll(const InfoMetaMap &Params, bool Headings);
static bool ParseMaterialParameterAssociation(const FString& Str, EMaterialParameterAssociation& OutAssociation, WingOut Errors);
private: private:
static void ReportBadToken(WingTokenizer &Tok, const TCHAR *Expected, WingOut Errors); static void ReportBadToken(WingTokenizer &Tok, const TCHAR *Expected, WingOut Errors);
static const TCHAR *EMaterialParameterTypeToString(EMaterialParameterType Type);
static bool EMaterialParameterTypeFromName(FName Name, EMaterialParameterType &Result, WingOut Errors);
static FString PathNameOrNone(UObject *Obj) { return Obj ? Obj->GetPathName() : FString(TEXT("None")); }
}; };