More work on material instances
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingMaterialParameter.h"
|
#include "WingParameterEditor.h"
|
||||||
#include "Materials/MaterialInstanceConstant.h"
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "MaterialInstance_ClearParameter.generated.h"
|
#include "MaterialInstance_ClearParameter.generated.h"
|
||||||
@@ -40,11 +40,11 @@ public:
|
|||||||
if (!MI) return;
|
if (!MI) return;
|
||||||
|
|
||||||
// Parse the parameter ID.
|
// Parse the parameter ID.
|
||||||
WingMaterialParameter::Info ID;
|
FWingParameterEditor::Info ID;
|
||||||
if (!WingMaterialParameter::ParseID(Parameter, ID, WingOut::Stdout))
|
if (!FWingParameterEditor::ParseID(Parameter, ID, WingOut::Stdout))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!WingMaterialParameter::RemoveOverride(ID, MI, WingOut::Stdout)) return
|
if (!FWingParameterEditor::RemoveOverride(ID, MI, WingOut::Stdout)) return;
|
||||||
WingOut::Stdout.Printf(TEXT("Removed override\n"));
|
WingOut::Stdout.Printf(TEXT("Removed override\n"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingMaterialParameter.h"
|
#include "WingParameterEditor.h"
|
||||||
#include "Materials/MaterialInstanceConstant.h"
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "MaterialInstance_DumpParameters.generated.h"
|
#include "MaterialInstance_DumpParameters.generated.h"
|
||||||
@@ -35,8 +35,8 @@ public:
|
|||||||
UMaterialInstanceConstant* MI = F.Asset(MaterialInstance).Cast<UMaterialInstanceConstant>();
|
UMaterialInstanceConstant* MI = F.Asset(MaterialInstance).Cast<UMaterialInstanceConstant>();
|
||||||
if (!MI) return;
|
if (!MI) return;
|
||||||
|
|
||||||
auto AllParams = WingMaterialParameter::GetMaterialParameters(MI);
|
auto AllParams = FWingParameterEditor::GetMaterialParameters(MI);
|
||||||
WingMaterialParameter::PrintAll(AllParams, true);
|
FWingParameterEditor::PrintAll(AllParams, true);
|
||||||
if (AllParams.IsEmpty()) WingOut::Stdout.Printf(TEXT("No material parameters.\n"));
|
if (AllParams.IsEmpty()) WingOut::Stdout.Printf(TEXT("No material parameters.\n"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingMaterialParameter.h"
|
#include "WingParameterEditor.h"
|
||||||
#include "Materials/MaterialInstanceConstant.h"
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "MaterialInstance_SetParameter.generated.h"
|
#include "MaterialInstance_SetParameter.generated.h"
|
||||||
@@ -42,19 +42,12 @@ public:
|
|||||||
if (!MI) return;
|
if (!MI) return;
|
||||||
|
|
||||||
// Parse the parameter ID.
|
// Parse the parameter ID.
|
||||||
WingMaterialParameter::Info ID;
|
FWingParameterEditor::Info ID;
|
||||||
if (!WingMaterialParameter::ParseID(Parameter, ID, WingOut::Stdout))
|
if (!FWingParameterEditor::ParseID(Parameter, ID, WingOut::Stdout))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Make sure the parameter actually exists.
|
|
||||||
auto AllParams = WingMaterialParameter::GetMaterialParameters(MI);
|
|
||||||
FMaterialParameterMetadata* Meta =
|
|
||||||
WingMaterialParameter::FindParameter(AllParams, ID, WingOut::Stdout);
|
|
||||||
if (!Meta) return;
|
|
||||||
if (!WingMaterialParameter::CheckNoCustomPrimitiveData(ID, *Meta, WingOut::Stdout)) return;
|
|
||||||
|
|
||||||
// Set the parameter
|
// Set the parameter
|
||||||
if (!WingMaterialParameter::AddOverride(ID, MI, Value, WingOut::Stdout)) return;
|
if (!FWingParameterEditor::AddOverride(ID, MI, Value, WingOut::Stdout)) return;
|
||||||
WingOut::Stdout.Printf(TEXT("Assigned.\n"));
|
WingOut::Stdout.Printf(TEXT("Assigned.\n"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "WingFetcher.h"
|
#include "WingFetcher.h"
|
||||||
#include "WingServer.h"
|
#include "WingServer.h"
|
||||||
#include "WingUtils.h"
|
#include "WingUtils.h"
|
||||||
#include "WingMaterialParameter.h"
|
#include "WingParameterEditor.h"
|
||||||
#include "MaterialTypes.h"
|
#include "MaterialTypes.h"
|
||||||
#include "Material_DumpParameters.generated.h"
|
#include "Material_DumpParameters.generated.h"
|
||||||
|
|
||||||
@@ -34,8 +34,8 @@ public:
|
|||||||
UMaterial* Mat = F.Asset(Material).Cast<UMaterial>();
|
UMaterial* Mat = F.Asset(Material).Cast<UMaterial>();
|
||||||
if (!Mat) return;
|
if (!Mat) return;
|
||||||
|
|
||||||
auto AllParams = WingMaterialParameter::GetMaterialParameters(Mat);
|
auto AllParams = FWingParameterEditor::GetMaterialParameters(Mat);
|
||||||
WingMaterialParameter::PrintAll(AllParams, false);
|
FWingParameterEditor::PrintAll(AllParams, false);
|
||||||
if (AllParams.IsEmpty()) WingOut::Stdout.Printf(TEXT("No material parameters.\n"));
|
if (AllParams.IsEmpty()) WingOut::Stdout.Printf(TEXT("No material parameters.\n"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,335 +0,0 @@
|
|||||||
#include "WingMaterialParameter.h"
|
|
||||||
#include "WingUtils.h"
|
|
||||||
#include "WingTokenizer.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)
|
|
||||||
{
|
|
||||||
InfoMetaMap Result;
|
|
||||||
if (!Material) return Result;
|
|
||||||
TMap<FMaterialParameterInfo, Metadata> Temp;
|
|
||||||
for (int I = 0; I < int(EMaterialParameterType::NumRuntime); I++)
|
|
||||||
{
|
|
||||||
EMaterialParameterType T = (EMaterialParameterType)I;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WingMaterialParameter::ReportBadToken(WingTokenizer &Tok, const TCHAR *Expected, WingOut Errors)
|
|
||||||
{
|
|
||||||
FString Whole = Tok.GetRange(FName(), 1000);
|
|
||||||
Tok.SaveCursor(FName());
|
|
||||||
FString Next = Tok.GetRange(FName(), 1);
|
|
||||||
Errors.Printf(TEXT("Parsing %s, near %s: expected %s"), *Whole, *Next, Expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
FString WingMaterialParameter::StringID(const Info &ID)
|
|
||||||
{
|
|
||||||
const TCHAR *Type = EMaterialParameterTypeToString(ID.Type);
|
|
||||||
FString Ext = WingUtils::ExternalizeID(ID.Name);
|
|
||||||
if (ID.Association != EMaterialParameterAssociation::GlobalParameter)
|
|
||||||
{
|
|
||||||
const TCHAR *Prefix = TEXT("Layer");
|
|
||||||
if (ID.Association == EMaterialParameterAssociation::BlendParameter)
|
|
||||||
Prefix = TEXT("Blend");
|
|
||||||
return FString::Printf(TEXT("%s:%s:%d:%s"), Type, Prefix, ID.Index, *Ext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return FString::Printf(TEXT("%s:%s"), Type, *Ext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WingMaterialParameter::ParseID(const FString& IDString, Info& ID, WingOut Errors)
|
|
||||||
{
|
|
||||||
WingTokenizer Tok(IDString);
|
|
||||||
|
|
||||||
ID.Type = EMaterialParameterType::None;
|
|
||||||
ID.Association = EMaterialParameterAssociation::GlobalParameter;
|
|
||||||
ID.Index = 0;
|
|
||||||
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.
|
|
||||||
if (Tok.TokenIs(TEXT("Layer"), ':') || Tok.TokenIs(TEXT("Blend"), ':'))
|
|
||||||
{
|
|
||||||
if (Tok.NextName() == TEXT("Layer"))
|
|
||||||
ID.Association = EMaterialParameterAssociation::LayerParameter;
|
|
||||||
else
|
|
||||||
ID.Association = EMaterialParameterAssociation::BlendParameter;
|
|
||||||
Tok.Advance();
|
|
||||||
Tok.Advance();
|
|
||||||
|
|
||||||
if ((!Tok.TokenIs(Tok.Identifier)) ||
|
|
||||||
(!LexTryParseString(ID.Index, *Tok.NextName().ToString())))
|
|
||||||
{ ReportBadToken(Tok, TEXT("integer"), Errors); return false; }
|
|
||||||
Tok.Advance();
|
|
||||||
|
|
||||||
if ((ID.Index < 0)||(ID.Index > 50))
|
|
||||||
{
|
|
||||||
Errors.Printf(TEXT("Layer/Blend index outside of reasonable range\n"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Tok.TokenIs(':'))
|
|
||||||
{ ReportBadToken(Tok, TEXT("colon"), Errors); return false; }
|
|
||||||
Tok.Advance();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the parameter name
|
|
||||||
if (!Tok.TokenIs(Tok.Identifier))
|
|
||||||
{ ReportBadToken(Tok, TEXT("parameter name"), Errors); return false; }
|
|
||||||
ID.Name = Tok.NextName();
|
|
||||||
Tok.Advance();
|
|
||||||
|
|
||||||
if (!Tok.TokenIs(0))
|
|
||||||
{ ReportBadToken(Tok, TEXT("end of input"), Errors); return false; }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
WingMaterialParameter::Metadata *WingMaterialParameter::FindParameter(
|
|
||||||
InfoMetaMap &Map, const Info &ID, WingOut Errors)
|
|
||||||
{
|
|
||||||
Metadata* Found = Map.Find(ID);
|
|
||||||
if (!Found)
|
|
||||||
{
|
|
||||||
Errors.Printf(TEXT("No parameter '%s' in this material"), *StringID(ID));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return Found;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WingMaterialParameter::CheckNoCustomPrimitiveData(
|
|
||||||
const Info &ID, const Metadata &Data, WingOut Errors)
|
|
||||||
{
|
|
||||||
if (Data.PrimitiveDataIndex != INDEX_NONE)
|
|
||||||
{
|
|
||||||
Errors.Printf(
|
|
||||||
TEXT("Parameter '%s' uses custom primitive data, which cannot be set on a material instance"),
|
|
||||||
*StringID(ID));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString WingMaterialParameter::FormatValue(const FMaterialParameterValue& Value)
|
|
||||||
{
|
|
||||||
switch (Value.Type)
|
|
||||||
{
|
|
||||||
case EMaterialParameterType::Scalar: {
|
|
||||||
return FString::Printf(TEXT("%g"), Value.AsScalar());
|
|
||||||
}
|
|
||||||
case EMaterialParameterType::Vector: {
|
|
||||||
return Value.AsLinearColor().ToString();
|
|
||||||
}
|
|
||||||
case EMaterialParameterType::DoubleVector: {
|
|
||||||
return Value.AsVector4d().ToString();
|
|
||||||
}
|
|
||||||
case EMaterialParameterType::Texture: {
|
|
||||||
return PathNameOrNone(Value.Texture);
|
|
||||||
}
|
|
||||||
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: {
|
|
||||||
return Value.AsStaticSwitch() ? TEXT("true") : TEXT("false");
|
|
||||||
}
|
|
||||||
case EMaterialParameterType::StaticComponentMask: {
|
|
||||||
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(
|
|
||||||
const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors)
|
|
||||||
{
|
|
||||||
// Remove the override from all parameter arrays.
|
|
||||||
auto RemoveFrom = [&](auto& Arr) {
|
|
||||||
return Arr.RemoveAll([&](auto& Entry) { return Entry.ParameterInfo == ID; });
|
|
||||||
};
|
|
||||||
|
|
||||||
int32 Removed = 0;
|
|
||||||
switch (ID.Type)
|
|
||||||
{
|
|
||||||
case EMaterialParameterType::Scalar: Removed += RemoveFrom(MI->ScalarParameterValues); break;
|
|
||||||
case EMaterialParameterType::Vector: Removed += RemoveFrom(MI->VectorParameterValues); break;
|
|
||||||
case EMaterialParameterType::DoubleVector: Removed += RemoveFrom(MI->DoubleVectorParameterValues); break;
|
|
||||||
case EMaterialParameterType::Texture: Removed += RemoveFrom(MI->TextureParameterValues); break;
|
|
||||||
case EMaterialParameterType::TextureCollection: Removed += RemoveFrom(MI->TextureCollectionParameterValues); break;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
Errors.Printf(TEXT("No override found for parameter '%s'"), *StringID(ID));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void WingMaterialParameter::Print(
|
|
||||||
const Info &Info, const Metadata &Meta)
|
|
||||||
{
|
|
||||||
WingOut::Stdout.Printf(TEXT(" %s %s\n"),
|
|
||||||
*WingMaterialParameter::StringID(Info), *WingMaterialParameter::FormatValue(Meta.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WingMaterialParameter::PrintAll(const InfoMetaMap &Params, bool Headings)
|
|
||||||
{
|
|
||||||
// Overridden parameters first.
|
|
||||||
bool bHasOverrides = false;
|
|
||||||
for (auto& [Info, Meta] : Params)
|
|
||||||
{
|
|
||||||
if (!Meta.bOverride) continue;
|
|
||||||
if (Headings && !bHasOverrides)
|
|
||||||
{ WingOut::Stdout.Print(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
|
|
||||||
WingMaterialParameter::Print(Info, Meta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inherited (non-overridden) parameters.
|
|
||||||
bool bHasInherited = false;
|
|
||||||
for (auto& [Info, Meta] : Params)
|
|
||||||
{
|
|
||||||
if (Meta.bOverride) continue;
|
|
||||||
if (Headings && !bHasInherited)
|
|
||||||
{ WingOut::Stdout.Print(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
|
|
||||||
WingMaterialParameter::Print(Info, Meta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,347 @@
|
|||||||
|
#include "WingParameterEditor.h"
|
||||||
|
#include "WingUtils.h"
|
||||||
|
#include "WingTokenizer.h"
|
||||||
|
#include "WingProperty.h"
|
||||||
|
#include "WingServer.h"
|
||||||
|
#include "Engine/Font.h"
|
||||||
|
#include "Engine/TextureCollection.h"
|
||||||
|
#include "Misc/DefaultValueHelper.h"
|
||||||
|
#include "SparseVolumeTexture/SparseVolumeTexture.h"
|
||||||
|
#include "VT/RuntimeVirtualTexture.h"
|
||||||
|
|
||||||
|
FWingParameterEditor::GetterAndSetter::GetterAndSetter(FName N, GetterFunc G, SetterFunc S)
|
||||||
|
{
|
||||||
|
Property = FWingParameterEditor::StaticStruct()->FindPropertyByName(N);
|
||||||
|
Getter = G;
|
||||||
|
Setter = S;
|
||||||
|
}
|
||||||
|
|
||||||
|
FWingParameterEditor::GetterAndSetterMap FWingParameterEditor::CalcGetterAndSetterMap()
|
||||||
|
{
|
||||||
|
using Editor = FWingParameterEditor;
|
||||||
|
using Value = FMaterialParameterValue;
|
||||||
|
using Type = EMaterialParameterType;
|
||||||
|
|
||||||
|
GetterAndSetterMap M;
|
||||||
|
|
||||||
|
M.Add(Type::Scalar, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, Scalar),
|
||||||
|
[](Editor &E)->Value { return Value(E.Scalar); },
|
||||||
|
[](Editor &E, const Value &V) { E.Scalar = V.AsScalar(); }));
|
||||||
|
|
||||||
|
M.Add(Type::Vector, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, Vector),
|
||||||
|
[](Editor &E)->Value { return Value(E.Vector); },
|
||||||
|
[](Editor &E, const Value &V) { E.Vector = V.AsLinearColor(); }));
|
||||||
|
|
||||||
|
M.Add(Type::DoubleVector, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, DoubleVector),
|
||||||
|
[](Editor &E)->Value { return Value(E.DoubleVector); },
|
||||||
|
[](Editor &E, const Value &V) { E.DoubleVector = V.AsVector4d(); }));
|
||||||
|
|
||||||
|
M.Add(Type::Texture, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, Texture),
|
||||||
|
[](Editor &E)->Value { return Value(E.Texture); },
|
||||||
|
[](Editor &E, const Value &V) { E.Texture = V.Texture; }));
|
||||||
|
|
||||||
|
M.Add(Type::TextureCollection, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, TextureCollection),
|
||||||
|
[](Editor &E)->Value { return Value(E.TextureCollection); },
|
||||||
|
[](Editor &E, const Value &V) { E.TextureCollection = V.TextureCollection; }));
|
||||||
|
|
||||||
|
M.Add(Type::Font, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, Font),
|
||||||
|
[](Editor &E)->Value { return Value(E.Font.Font, E.Font.Page); },
|
||||||
|
[](Editor &E, const Value &V) { E.Font.Font = V.Font.Value; E.Font.Page = V.Font.Page; }));
|
||||||
|
|
||||||
|
M.Add(Type::RuntimeVirtualTexture, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, RuntimeVirtualTexture),
|
||||||
|
[](Editor &E)->Value { return Value(E.RuntimeVirtualTexture); },
|
||||||
|
[](Editor &E, const Value &V) { E.RuntimeVirtualTexture = V.RuntimeVirtualTexture; }));
|
||||||
|
|
||||||
|
M.Add(Type::SparseVolumeTexture, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, SparseVolumeTexture),
|
||||||
|
[](Editor &E)->Value { return Value(E.SparseVolumeTexture); },
|
||||||
|
[](Editor &E, const Value &V) { E.SparseVolumeTexture = V.SparseVolumeTexture; }));
|
||||||
|
|
||||||
|
M.Add(Type::StaticSwitch, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, StaticSwitch),
|
||||||
|
[](Editor &E)->Value { return Value(E.StaticSwitch); },
|
||||||
|
[](Editor &E, const Value &V) { E.StaticSwitch = V.AsStaticSwitch(); }));
|
||||||
|
|
||||||
|
M.Add(Type::StaticComponentMask, GetterAndSetter(
|
||||||
|
GET_MEMBER_NAME_CHECKED(FWingParameterEditor, StaticComponentMask),
|
||||||
|
[](Editor &E)->Value { return Value(E.StaticComponentMask); },
|
||||||
|
[](Editor &E, const Value &V) { E.StaticComponentMask = V.AsStaticComponentMask(); }));
|
||||||
|
|
||||||
|
return M;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FWingParameterEditor::GetterAndSetterMap &FWingParameterEditor::GetGetterAndSetterMap()
|
||||||
|
{
|
||||||
|
static GetterAndSetterMap TheMap = CalcGetterAndSetterMap();
|
||||||
|
return TheMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
FName FWingParameterEditor::TypeToName(EMaterialParameterType Type)
|
||||||
|
{
|
||||||
|
const GetterAndSetter *GS = GetGetterAndSetterMap().Find(Type);
|
||||||
|
if (GS == nullptr) return FName(TEXT("unknown"));
|
||||||
|
return GS->Property->GetFName();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FWingParameterEditor::NameToType(FName Name, EMaterialParameterType &Result, WingOut Errors)
|
||||||
|
{
|
||||||
|
for (const auto &Pair : GetGetterAndSetterMap())
|
||||||
|
{
|
||||||
|
if (Pair.Value.Property->GetName() == Name)
|
||||||
|
{
|
||||||
|
Result = Pair.Key; return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Errors.Printf(TEXT("ERROR: '%s' is not a valid EMaterialParameterType\n"), *Name.ToString());
|
||||||
|
Result = EMaterialParameterType::None;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FWingParameterEditor::InfoMetaMap FWingParameterEditor::GetMaterialParameters(UMaterialInterface* Material)
|
||||||
|
{
|
||||||
|
InfoMetaMap Result;
|
||||||
|
if (!Material) return Result;
|
||||||
|
TMap<FMaterialParameterInfo, Metadata> Temp;
|
||||||
|
for (int I = 0; I < int(EMaterialParameterType::Num); I++)
|
||||||
|
{
|
||||||
|
EMaterialParameterType T = (EMaterialParameterType)I;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FWingParameterEditor::ReportBadType(EMaterialParameterType Type, WingOut Errors)
|
||||||
|
{
|
||||||
|
Errors.Printf(TEXT("Material parameter type #%d is not a valid type.\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FWingParameterEditor::ReportBadToken(WingTokenizer &Tok, const TCHAR *Expected, WingOut Errors)
|
||||||
|
{
|
||||||
|
FString Whole = Tok.GetRange(FName(), 1000);
|
||||||
|
Tok.SaveCursor(FName());
|
||||||
|
FString Next = Tok.GetRange(FName(), 1);
|
||||||
|
Errors.Printf(TEXT("Parsing %s, near %s: expected %s"), *Whole, *Next, Expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
FString FWingParameterEditor::StringID(const Info &ID)
|
||||||
|
{
|
||||||
|
FString TypeName = TypeToName(ID.Type).ToString();
|
||||||
|
FString Ext = WingUtils::ExternalizeID(ID.Name);
|
||||||
|
if (ID.Association != EMaterialParameterAssociation::GlobalParameter)
|
||||||
|
{
|
||||||
|
const TCHAR *Prefix = TEXT("Layer");
|
||||||
|
if (ID.Association == EMaterialParameterAssociation::BlendParameter)
|
||||||
|
Prefix = TEXT("Blend");
|
||||||
|
return FString::Printf(TEXT("%s:%s:%d:%s"), *TypeName, Prefix, ID.Index, *Ext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FString::Printf(TEXT("%s:%s"), *TypeName, *Ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FWingParameterEditor::ParseID(const FString& IDString, Info& ID, WingOut Errors)
|
||||||
|
{
|
||||||
|
WingTokenizer Tok(IDString);
|
||||||
|
|
||||||
|
ID.Type = EMaterialParameterType::None;
|
||||||
|
ID.Association = EMaterialParameterAssociation::GlobalParameter;
|
||||||
|
ID.Index = INDEX_NONE;
|
||||||
|
ID.Name = FName();
|
||||||
|
|
||||||
|
// Parse the type.
|
||||||
|
const TCHAR *GoodTypes = TEXT("Scalar, Vector, DoubleVector, Texture, TextureCollection, Font, "
|
||||||
|
"RuntimeVirtualTexture, SparseVolumeTexture, StaticSwitch, or StaticComponentMask");
|
||||||
|
if (!Tok.TokenIs(Tok.Identifier))
|
||||||
|
{ ReportBadToken(Tok, GoodTypes, Errors); return false; }
|
||||||
|
EMaterialParameterType TypeValue;
|
||||||
|
if (!NameToType(Tok.NextName(), TypeValue, Errors)) return false;
|
||||||
|
if (TypeValue >= EMaterialParameterType::Num)
|
||||||
|
{ 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; }
|
||||||
|
Tok.Advance();
|
||||||
|
|
||||||
|
// Parse the Layer or blend prefix.
|
||||||
|
if (Tok.TokenIs(TEXT("Layer"), ':') || Tok.TokenIs(TEXT("Blend"), ':'))
|
||||||
|
{
|
||||||
|
if (Tok.NextName() == TEXT("Layer"))
|
||||||
|
ID.Association = EMaterialParameterAssociation::LayerParameter;
|
||||||
|
else
|
||||||
|
ID.Association = EMaterialParameterAssociation::BlendParameter;
|
||||||
|
Tok.Advance();
|
||||||
|
Tok.Advance();
|
||||||
|
|
||||||
|
if ((!Tok.TokenIs(Tok.Identifier)) ||
|
||||||
|
(!LexTryParseString(ID.Index, *Tok.NextName().ToString())))
|
||||||
|
{ ReportBadToken(Tok, TEXT("integer"), Errors); return false; }
|
||||||
|
Tok.Advance();
|
||||||
|
|
||||||
|
if ((ID.Index < 0)||(ID.Index > 50))
|
||||||
|
{
|
||||||
|
Errors.Printf(TEXT("Layer/Blend index outside of reasonable range\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Tok.TokenIs(':'))
|
||||||
|
{ ReportBadToken(Tok, TEXT("colon"), Errors); return false; }
|
||||||
|
Tok.Advance();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the parameter name
|
||||||
|
if (!Tok.TokenIs(Tok.Identifier))
|
||||||
|
{ ReportBadToken(Tok, TEXT("parameter name"), Errors); return false; }
|
||||||
|
ID.Name = Tok.NextName();
|
||||||
|
Tok.Advance();
|
||||||
|
|
||||||
|
if (!Tok.TokenIs(0))
|
||||||
|
{ ReportBadToken(Tok, TEXT("end of input"), Errors); return false; }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FWingParameterEditor::Metadata *FWingParameterEditor::FindParameter(
|
||||||
|
InfoMetaMap &Map, const Info &ID, WingOut Errors)
|
||||||
|
{
|
||||||
|
Metadata* Found = Map.Find(ID);
|
||||||
|
if (!Found)
|
||||||
|
{
|
||||||
|
Errors.Printf(TEXT("No parameter '%s' in this material"), *StringID(ID));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return Found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FWingParameterEditor::CheckNoCustomPrimitiveData(
|
||||||
|
const Info &ID, const Metadata &Data, WingOut Errors)
|
||||||
|
{
|
||||||
|
if (Data.PrimitiveDataIndex != INDEX_NONE)
|
||||||
|
{
|
||||||
|
Errors.Printf(
|
||||||
|
TEXT("Parameter '%s' uses custom primitive data, which cannot be set on a material instance"),
|
||||||
|
*StringID(ID));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FWingParameterEditor::AddOverride(
|
||||||
|
const Info &ID, UMaterialInstanceConstant *MI, const FString &StrVal, WingOut Errors)
|
||||||
|
{
|
||||||
|
// Verify that the parameter type is valid.
|
||||||
|
const GetterAndSetter *GS = GetGetterAndSetterMap().Find(ID.Type);
|
||||||
|
if (GS == nullptr) return ReportBadType(ID.Type, Errors);
|
||||||
|
|
||||||
|
// Find the existing parameter.
|
||||||
|
TMap<FMaterialParameterInfo, FMaterialParameterMetadata> Lookup;
|
||||||
|
MI->GetAllParametersOfType(ID.Type, Lookup);
|
||||||
|
FMaterialParameterMetadata *Meta = Lookup.Find(ID);
|
||||||
|
if (Meta == nullptr)
|
||||||
|
{
|
||||||
|
Errors.Printf(TEXT("No parameter named %s to override.\n"), *StringID(ID));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
check(Meta->Value.Type == ID.Type);
|
||||||
|
|
||||||
|
// If the parameter involves the use of custom primitive data, we
|
||||||
|
// cannot meaningfully override it.
|
||||||
|
if (!CheckNoCustomPrimitiveData(ID, *Meta, Errors)) return false;
|
||||||
|
|
||||||
|
// Parse the value string.
|
||||||
|
FWingParameterEditor Editor;
|
||||||
|
if (!FWingProperty(GS->Property, &Editor, true).SetText(StrVal, Errors)) return false;
|
||||||
|
Meta->Value = GS->Getter(Editor);
|
||||||
|
|
||||||
|
// Apply the update.
|
||||||
|
FMaterialInstanceParameterUpdateContext Update(MI);
|
||||||
|
Update.SetParameterValueEditorOnly(ID, *Meta);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FWingParameterEditor::RemoveOverride(
|
||||||
|
const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors)
|
||||||
|
{
|
||||||
|
// Remove the override from all parameter arrays.
|
||||||
|
auto RemoveFrom = [&](auto& Arr) {
|
||||||
|
return Arr.RemoveAll([&](auto& Entry) { return Entry.ParameterInfo == ID; });
|
||||||
|
};
|
||||||
|
|
||||||
|
int32 Removed = 0;
|
||||||
|
switch (ID.Type)
|
||||||
|
{
|
||||||
|
case EMaterialParameterType::Scalar: Removed += RemoveFrom(MI->ScalarParameterValues); break;
|
||||||
|
case EMaterialParameterType::Vector: Removed += RemoveFrom(MI->VectorParameterValues); break;
|
||||||
|
case EMaterialParameterType::DoubleVector: Removed += RemoveFrom(MI->DoubleVectorParameterValues); break;
|
||||||
|
case EMaterialParameterType::Texture: Removed += RemoveFrom(MI->TextureParameterValues); break;
|
||||||
|
case EMaterialParameterType::TextureCollection: Removed += RemoveFrom(MI->TextureCollectionParameterValues); break;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Errors.Printf(TEXT("No override found for parameter '%s'"), *StringID(ID));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FWingParameterEditor::Print(const Info &ID, const Metadata &Meta)
|
||||||
|
{
|
||||||
|
const GetterAndSetter *GS = GetGetterAndSetterMap().Find(ID.Type);
|
||||||
|
if ((GS == nullptr) || (ID.Type != Meta.Value.Type))
|
||||||
|
{
|
||||||
|
WingOut::Stdout.Printf(TEXT(" corrupted parameter: %s\n"),
|
||||||
|
*StringID(ID));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FWingParameterEditor Editor;
|
||||||
|
GS->Setter(Editor, Meta.Value);
|
||||||
|
FString StrVal = FWingProperty(GS->Property, &Editor, false).GetText();
|
||||||
|
WingOut::Stdout.Printf(TEXT(" %s %s\n"),
|
||||||
|
*StringID(ID), *StrVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FWingParameterEditor::PrintAll(const InfoMetaMap &Params, bool Headings)
|
||||||
|
{
|
||||||
|
// Overridden parameters first.
|
||||||
|
bool bHasOverrides = false;
|
||||||
|
for (auto& [Info, Meta] : Params)
|
||||||
|
{
|
||||||
|
if (!Meta.bOverride) continue;
|
||||||
|
if (Headings && !bHasOverrides)
|
||||||
|
{ WingOut::Stdout.Print(TEXT("\nOverridden Parameters:\n")); bHasOverrides = true; }
|
||||||
|
FWingParameterEditor::Print(Info, Meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inherited (non-overridden) parameters.
|
||||||
|
bool bHasInherited = false;
|
||||||
|
for (auto& [Info, Meta] : Params)
|
||||||
|
{
|
||||||
|
if (Meta.bOverride) continue;
|
||||||
|
if (Headings && !bHasInherited)
|
||||||
|
{ WingOut::Stdout.Print(TEXT("\nInherited Parameters (not overridden):\n")); bHasInherited = true; }
|
||||||
|
FWingParameterEditor::Print(Info, Meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,11 +5,61 @@
|
|||||||
#include "WingTokenizer.h"
|
#include "WingTokenizer.h"
|
||||||
#include "Materials/MaterialInstanceConstant.h"
|
#include "Materials/MaterialInstanceConstant.h"
|
||||||
#include "WingHandler.h"
|
#include "WingHandler.h"
|
||||||
|
#include "WingParameterEditor.generated.h"
|
||||||
|
|
||||||
|
USTRUCT()
|
||||||
|
struct FWingFontAndPage
|
||||||
class WingMaterialParameter
|
|
||||||
{
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
public:
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
UFont *Font;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
int32 Page;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// FWingParameterEditor is a tool for modifying material
|
||||||
|
// parameters in material instances. Transferring values
|
||||||
|
// into UPROPERTY fields makes it possible to use GetText
|
||||||
|
// and SetText to parse them.
|
||||||
|
//
|
||||||
|
USTRUCT()
|
||||||
|
struct FWingParameterEditor
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
private:
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
float Scalar;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
FLinearColor Vector;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
FVector4d DoubleVector;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
UTexture *Texture;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
UTextureCollection *TextureCollection;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
FWingFontAndPage Font;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
URuntimeVirtualTexture *RuntimeVirtualTexture;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
USparseVolumeTexture *SparseVolumeTexture;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
bool StaticSwitch;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
FStaticComponentMaskValue StaticComponentMask;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Info struct is a FMaterialParameterInfo plus a type field.
|
// Info struct is a FMaterialParameterInfo plus a type field.
|
||||||
struct Info : public FMaterialParameterInfo
|
struct Info : public FMaterialParameterInfo
|
||||||
@@ -32,12 +82,17 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using Type = EMaterialParameterType;
|
|
||||||
using Metadata = FMaterialParameterMetadata;
|
using Metadata = FMaterialParameterMetadata;
|
||||||
using Value = FMaterialParameterValue;
|
|
||||||
using InfoMetaMap = TMap<Info, Metadata>;
|
using InfoMetaMap = TMap<Info, Metadata>;
|
||||||
|
|
||||||
|
// Convert a type to a name.
|
||||||
|
//
|
||||||
|
static FName TypeToName(EMaterialParameterType Type);
|
||||||
|
|
||||||
|
// Convert a name to a type, if possible.
|
||||||
|
//
|
||||||
|
static bool NameToType(FName Name, EMaterialParameterType &Result, WingOut Errors);
|
||||||
|
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
@@ -48,7 +103,7 @@ public:
|
|||||||
//
|
//
|
||||||
static Metadata *FindParameter(InfoMetaMap &Map, const Info &ID, WingOut Errors);
|
static Metadata *FindParameter(InfoMetaMap &Map, const Info &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(const Info &ID, const Metadata &Data, WingOut Errors);
|
static bool CheckNoCustomPrimitiveData(const Info &ID, const Metadata &Data, WingOut Errors);
|
||||||
@@ -64,17 +119,13 @@ public:
|
|||||||
// Add a material parameter override to a material instance.
|
// Add a material parameter override to a material instance.
|
||||||
//
|
//
|
||||||
static bool AddOverride(
|
static bool AddOverride(
|
||||||
const Info &ID, UMaterialInstanceConstant *MI, const FString &Value, WingOut Errors);
|
const Info &ID, UMaterialInstanceConstant *MI, const FString &StrVal, 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(const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors);
|
static bool RemoveOverride(const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors);
|
||||||
|
|
||||||
// Format a material parameter 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 Info &Info, const Metadata &Meta);
|
static void Print(const Info &Info, const Metadata &Meta);
|
||||||
@@ -84,10 +135,28 @@ public:
|
|||||||
//
|
//
|
||||||
static void PrintAll(const InfoMetaMap &Params, bool Headings);
|
static void PrintAll(const InfoMetaMap &Params, bool Headings);
|
||||||
|
|
||||||
|
private:
|
||||||
|
using GetterFunc = TFunction<FMaterialParameterValue(FWingParameterEditor &E)>;
|
||||||
|
using SetterFunc = TFunction<void(FWingParameterEditor &E, const FMaterialParameterValue &V)>;
|
||||||
|
|
||||||
|
struct GetterAndSetter
|
||||||
|
{
|
||||||
|
FProperty *Property;
|
||||||
|
GetterFunc Getter;
|
||||||
|
SetterFunc Setter;
|
||||||
|
|
||||||
|
GetterAndSetter(FName N, GetterFunc G, SetterFunc S);
|
||||||
|
};
|
||||||
|
|
||||||
|
using GetterAndSetterMap = TMap<EMaterialParameterType, GetterAndSetter>;
|
||||||
|
|
||||||
|
static void Add(GetterAndSetterMap &M,
|
||||||
|
EMaterialParameterType Type, FName Name, GetterFunc G, SetterFunc S);
|
||||||
|
|
||||||
|
static GetterAndSetterMap CalcGetterAndSetterMap();
|
||||||
|
static const GetterAndSetterMap &GetGetterAndSetterMap();
|
||||||
|
|
||||||
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 ReportBadType(EMaterialParameterType Type, WingOut Errors);
|
||||||
static bool EMaterialParameterTypeFromName(FName Name, EMaterialParameterType &Result, WingOut Errors);
|
|
||||||
static FString PathNameOrNone(UObject *Obj) { return Obj ? Obj->GetPathName() : FString(TEXT("None")); }
|
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user