// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "IMeshMergeUtilities.h" #include "SceneTypes.h" #include "StaticMeshComponentAdapter.h" #include "MaterialShared.h" class FMeshMergeDataTracker; class FMaterialUpdateContext; struct FMeshLODKey; typedef TPair MaterialRemapPair; /** * Mesh Merge Utilities */ class FMeshMergeUtilities : public IMeshMergeUtilities { public: friend class FProxyGenerationProcessor; FMeshMergeUtilities(); virtual ~FMeshMergeUtilities() override; virtual void BakeMaterialsForComponent(TArray>& OptionObjects, IMaterialBakingAdapter* Adapter) const override; virtual void BakeMaterialsForComponent(UStaticMeshComponent* StaticMeshComponent) const override; virtual void BakeMaterialsForComponent(USkeletalMeshComponent* SkeletalMeshComponent) const override; virtual void BakeMaterialsForMesh(UStaticMesh* Mesh) const override; virtual void MergeComponentsToStaticMesh(const TArray& ComponentsToMerge, UWorld* World, const FMeshMergingSettings& InSettings, UMaterialInterface* InBaseMaterial, UPackage* InOuter, const FString& InBasePackageName, TArray& OutAssetsToSync, FVector& OutMergedActorLocation, const float ScreenSize, bool bSilent /*= false*/) const; virtual void MergeComponentsToInstances(const TArray& ComponentsToMerge, UWorld* World, ULevel* Level, const FMeshInstancingSettings& InSettings, bool bActuallyMerge = true, bool bReplaceSourceActors = false, FText* OutResultsText = nullptr) const override; virtual void CreateProxyMesh(const TArray& InActors, const struct FMeshProxySettings& InMeshProxySettings, UMaterialInterface* InBaseMaterial, UPackage* InOuter, const FString& InProxyBasePackageName, const FGuid InGuid, const FCreateProxyDelegate& InProxyCreatedDelegate, const bool bAllowAsync = false, const float ScreenSize = 1.0f) const override; virtual void CreateProxyMesh(const TArray& InStaticMeshComps, const struct FMeshProxySettings& InMeshProxySettings, UMaterialInterface* InBaseMaterial, UPackage* InOuter, const FString& InProxyBasePackageName, const FGuid InGuid, const FCreateProxyDelegate& InProxyCreatedDelegate, const bool bAllowAsync = false, const float ScreenSize = 1.0f) const override; virtual void CreateProxyMesh(const TArray& InActors, const struct FMeshProxySettings& InMeshProxySettings, UPackage* InOuter, const FString& InProxyBasePackageName, const FGuid InGuid, const FCreateProxyDelegate& InProxyCreatedDelegate, const bool bAllowAsync = false, const float ScreenSize = 1.0f) const override; virtual void CreateProxyMesh(const TArray& InStaticMeshComps, const struct FMeshProxySettings& InMeshProxySettings, UPackage* InOuter, const FString& InProxyBasePackageName, const FGuid InGuid, const FCreateProxyDelegate& InProxyCreatedDelegate, const bool bAllowAsync = false, const float ScreenSize = 1.0f) const override; virtual void RetrieveMeshDescription(const UStaticMeshComponent* InStaticMeshComponent, int32 LODIndex, FMeshDescription& InOutMeshDescription, bool bPropagateVertexColours) const override; virtual void RetrieveMeshDescription(const USkeletalMeshComponent* InSkeletalMeshComponent, int32 LODIndex, FMeshDescription& InOutMeshDescription, bool bPropagateVertexColours) const override; virtual void RetrieveMeshDescription(const UStaticMesh* InStaticMesh, int32 LODIndex, FMeshDescription& InOutMeshDescription) const override; virtual void RetrievePhysicsData(const TArray& InComponents, TArray& InOutPhysicsGeometry, UBodySetup*& OutBodySetupSource) const override; virtual void RegisterExtension(IMeshMergeExtension* InExtension) override; virtual void UnregisterExtension(IMeshMergeExtension* InExtension) override; protected: /** Creates a proxy material instance at givne path and name */ UMaterialInterface* CreateProxyMaterial(const FString &InBasePackageName, FString MergedAssetPackageName, UMaterialInterface* InBaseMaterial, UPackage* InOuter, const FMeshMergingSettings &InSettings, const FFlattenMaterial& OutMaterial, TArray& OutAssetsToSync, FMaterialUpdateContext* InMaterialUpdateContext = nullptr) const; /** Merges flattened material into atlas textures */ void MergeFlattenedMaterials(TArray& InMaterialList, int32 InGutter, FFlattenMaterial& OutMergedMaterial, TArray& OutUVTransforms) const; /** Merges flattened material into binned textures */ void FlattenBinnedMaterials(TArray& InMaterialList, const TArray& InMaterialBoxes, int32 InGutter, bool bCopyOnlyMaskedPixels, FFlattenMaterial& OutMergedMaterial, TArray& OutUVTransforms) const; void CreateMergedMaterial(FMeshMergeDataTracker& InDataTracker, const FMeshMergingSettings& InSettings, const TArray& InStaticMeshComponentsToMerge, TArray& InAdapters, const TArray& InUniqueMaterials, const TMap& InCollapsedMaterialMap, TMultiMap& InOutputMaterialsMap, bool bInMergeAllLODs, bool bInMergeMaterialData, const FVector& InMergedAssetPivot, FFlattenMaterial& OutFlattenMaterial) const; /** Helper function to create the final merged raw meshes */ void CreateMergedRawMeshes(FMeshMergeDataTracker& InDataTracker, const FMeshMergingSettings& InSettings, const TArray& InStaticMeshComponentsToMerge, const TArray& InUniqueMaterials, const TMap& InCollapsedMaterialMap, const TMultiMap& InOutputMaterialsMap, bool bInMergeAllLODs, bool bInMergeMaterialData, const FVector& InMergedAssetPivot, TArray& OutMergedRawMeshes) const; protected: /** Flattens out emissive scale across all flatten material instances */ float FlattenEmissivescale(TArray& InMaterialList) const; /** Populates material options object from legacy material proxy settings */ UMaterialOptions* PopulateMaterialOptions(const FMaterialProxySettings& MaterialSettings) const; /** Populates a single property entry with correct material baking settings */ void PopulatePropertyEntry(const FMaterialProxySettings& MaterialSettings, EMaterialProperty MaterialProperty, struct FPropertyEntry& InOutPropertyEntry) const; /** Copies part (box) from a texture to another texture */ void CopyTextureRect(const FColor* Src, const FIntPoint& SrcSize, FColor* Dst, const FIntPoint& DstSize, const FIntPoint& DstPos, bool bCopyOnlyMaskedPixels = false) const; /** Sets a part (box) on a texture to ColorValue */ void SetTextureRect(const FColor& ColorValue, const FIntPoint& SrcSize, FColor* Dst, const FIntPoint& DstSize, const FIntPoint& DstPos) const; /** Conditionally resizes the source data into OutImage */ FIntPoint ConditionalImageResize(const FIntPoint& SrcSize, const FIntPoint& DesiredSize, TArray& InOutImage, bool bLinearSpace) const; /** Converts bake output structure data to flatten material format */ void ConvertOutputToFlatMaterials(const TArray& BakeOutputs, const TArray& MaterialData, TArray &FlattenedMaterials) const; /** Transfer bake output structure data to flatten material format. * @warning This is a destructive operation for InOutBakeOutputs */ void TransferOutputToFlatMaterials(const TArray& InMaterialData, TArray& InOutBakeOutputs, TArray &OutFlattenedMaterials) const; /** Converts material property enum value to flatten material property */ EFlattenMaterialProperties ToFlattenProperty(EMaterialProperty MaterialProperty) const; private: FProxyGenerationProcessor* Processor; FDelegateHandle ModuleLoadedDelegateHandle; TArray MeshMergeExtensions; };