#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; // 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; using SetterFunc = TFunction; struct GetterAndSetter { FProperty *Property; GetterFunc Getter; SetterFunc Setter; GetterAndSetter(FName N, GetterFunc G, SetterFunc S); }; using GetterAndSetterMap = TMap; 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); };