|
|
|
|
@@ -2,36 +2,69 @@
|
|
|
|
|
#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;
|
|
|
|
|
InfoMetaMap Temp;
|
|
|
|
|
for (int32 i = 0; i < (int32)EMaterialParameterType::NumRuntime; i++)
|
|
|
|
|
TMap<FMaterialParameterInfo, Metadata> Temp;
|
|
|
|
|
for (int I = 0; I < int(EMaterialParameterType::NumRuntime); I++)
|
|
|
|
|
{
|
|
|
|
|
Material->GetAllParametersOfType((EMaterialParameterType)i, Temp);
|
|
|
|
|
Result.Append(Temp);
|
|
|
|
|
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 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)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FString WingMaterialParameter::StringID(const FMaterialParameterInfo &ID)
|
|
|
|
|
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:%d:%s"), Prefix, ID.Index, *Ext);
|
|
|
|
|
return FString::Printf(TEXT("%s:%s:%d:%s"), Type, Prefix, ID.Index, *Ext);
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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.TokenIs(TEXT("Layer"), ':') || Tok.TokenIs(TEXT("Blend"), ':'))
|
|
|
|
|
{
|
|
|
|
|
if (Tok.NextName() == TEXT("Layer"))
|
|
|
|
|
ID.Association = EMaterialParameterAssociation::LayerParameter;
|
|
|
|
|
else
|
|
|
|
|
ID.Association = EMaterialParameterAssociation::BlendParameter;
|
|
|
|
|
Tok.Advance();
|
|
|
|
|
|
|
|
|
|
if (!Tok.TokenIs(':'))
|
|
|
|
|
{ ReportBadToken(Tok, TEXT("colon"), Errors); return false; }
|
|
|
|
|
Tok.Advance();
|
|
|
|
|
|
|
|
|
|
if ((!Tok.TokenIs(Tok.Identifier)) ||
|
|
|
|
|
@@ -104,20 +150,20 @@ bool WingMaterialParameter::ParseID(const FString& IDString, FMaterialParameterI
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FMaterialParameterMetadata *WingMaterialParameter::FindParameter(
|
|
|
|
|
InfoMetaMap &Map, const FMaterialParameterInfo &ID, WingOut Errors)
|
|
|
|
|
WingMaterialParameter::Metadata *WingMaterialParameter::FindParameter(
|
|
|
|
|
InfoMetaMap &Map, const Info &ID, WingOut Errors)
|
|
|
|
|
{
|
|
|
|
|
FMaterialParameterMetadata* Found = Map.Find(ID);
|
|
|
|
|
Metadata* Found = Map.Find(ID);
|
|
|
|
|
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 Found;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool WingMaterialParameter::CheckNoCustomPrimitiveData(
|
|
|
|
|
const FMaterialParameterInfo &ID, const FMaterialParameterMetadata &Data, WingOut Errors)
|
|
|
|
|
const Info &ID, const Metadata &Data, WingOut Errors)
|
|
|
|
|
{
|
|
|
|
|
if (Data.PrimitiveDataIndex != INDEX_NONE)
|
|
|
|
|
{
|
|
|
|
|
@@ -134,30 +180,98 @@ FString WingMaterialParameter::FormatValue(const FMaterialParameterValue& Value)
|
|
|
|
|
switch (Value.Type)
|
|
|
|
|
{
|
|
|
|
|
case EMaterialParameterType::Scalar: {
|
|
|
|
|
return FString::Printf(TEXT("scalar(%g)"), Value.AsScalar());
|
|
|
|
|
return FString::Printf(TEXT("%g"), Value.AsScalar());
|
|
|
|
|
}
|
|
|
|
|
case EMaterialParameterType::Vector: {
|
|
|
|
|
return FString::Printf(TEXT("vector(%s)"), *Value.AsLinearColor().ToString());
|
|
|
|
|
return Value.AsLinearColor().ToString();
|
|
|
|
|
}
|
|
|
|
|
case EMaterialParameterType::DoubleVector: {
|
|
|
|
|
return FString::Printf(TEXT("doublevector(%s)"), *Value.AsLinearColor().ToString());
|
|
|
|
|
return Value.AsVector4d().ToString();
|
|
|
|
|
}
|
|
|
|
|
case EMaterialParameterType::Texture: {
|
|
|
|
|
UTexture* Tex = Cast<UTexture>(Value.AsTextureObject());
|
|
|
|
|
return FString::Printf(TEXT("texture(%s)"), *Tex->GetPathName());
|
|
|
|
|
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: {
|
|
|
|
|
const TCHAR *Str = Value.AsStaticSwitch() ? TEXT("true") : TEXT("false");
|
|
|
|
|
return FString::Printf(TEXT("staticswitch(%s)"), Str);
|
|
|
|
|
return Value.AsStaticSwitch() ? TEXT("true") : TEXT("false");
|
|
|
|
|
}
|
|
|
|
|
default: {
|
|
|
|
|
return FString::Printf(TEXT("unknown(%d)"), (int)Value.Type);
|
|
|
|
|
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 FMaterialParameterInfo &ID, UMaterialInstanceConstant *MI, WingOut Errors)
|
|
|
|
|
const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors)
|
|
|
|
|
{
|
|
|
|
|
// Remove the override from all parameter arrays.
|
|
|
|
|
auto RemoveFrom = [&](auto& Arr) {
|
|
|
|
|
@@ -165,14 +279,21 @@ bool WingMaterialParameter::RemoveOverride(
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int32 Removed = 0;
|
|
|
|
|
Removed += RemoveFrom(MI->ScalarParameterValues);
|
|
|
|
|
Removed += RemoveFrom(MI->VectorParameterValues);
|
|
|
|
|
Removed += RemoveFrom(MI->DoubleVectorParameterValues);
|
|
|
|
|
Removed += RemoveFrom(MI->TextureParameterValues);
|
|
|
|
|
Removed += RemoveFrom(MI->TextureCollectionParameterValues);
|
|
|
|
|
Removed += RemoveFrom(MI->RuntimeVirtualTextureParameterValues);
|
|
|
|
|
Removed += RemoveFrom(MI->SparseVolumeTextureParameterValues);
|
|
|
|
|
Removed += RemoveFrom(MI->FontParameterValues);
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
@@ -184,7 +305,7 @@ bool WingMaterialParameter::RemoveOverride(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void WingMaterialParameter::Print(
|
|
|
|
|
const FMaterialParameterInfo &Info, const FMaterialParameterMetadata &Meta)
|
|
|
|
|
const Info &Info, const Metadata &Meta)
|
|
|
|
|
{
|
|
|
|
|
WingOut::Stdout.Printf(TEXT(" %s %s\n"),
|
|
|
|
|
*WingMaterialParameter::StringID(Info), *WingMaterialParameter::FormatValue(Meta.Value));
|
|
|
|
|
|