Files
integration/Plugins/UEWingman/Source/UEWingman/Public/WingParameterEditor.h

164 lines
4.6 KiB
C++

#pragma once
#include "CoreMinimal.h"
#include "Materials/Material.h"
#include "Materials/MaterialInstanceConstant.h"
#include "WingBasics.h"
#include "WingParameterEditor.generated.h"
struct WingTokenizer;
USTRUCT()
struct FWingFontAndPage
{
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:
// 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 Metadata = FMaterialParameterMetadata;
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
// both parameters that have been overridden and those that haven't.
//
static InfoMetaMap GetMaterialParameters(UMaterialInterface* Material);
// Find a material parameter in the InfoMap.
// If it doesn't exist, or report an error and return nullptr.
//
static Metadata *FindParameter(InfoMetaMap &Map, const Info &ID, WingOut Errors);
// If the material uses custom primitive data, print an error
// and return false.
//
static bool CheckNoCustomPrimitiveData(const Info &ID, const Metadata &Data, WingOut Errors);
// Convert an ID in string form into an ID in info form.
//
static bool ParseID(const FString& Str, Info& ID, WingOut Errors);
// Convert an ID in Info form into an ID in string form.
//
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 &StrVal, WingOut Errors);
// Remove a material parameter override from a material instance.
// If there is no override, print an error and return false.
//
static bool RemoveOverride(const Info &ID, UMaterialInstanceConstant *MI, WingOut Errors);
// Print out a material parameter with ID.
//
static void Print(const Info &Info, const Metadata &Meta);
// Print out a map full of material parameters. If Headings is
// true, the parameters are grouped by inherited/overridden.
//
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:
static void ReportBadToken(WingTokenizer &Tok, const TCHAR *Expected, WingOut Errors);
static bool ReportBadType(EMaterialParameterType Type, WingOut Errors);
};