// Copyright Epic Games, Inc. All Rights Reserved. #include "AssetDefinition_Texture.h" #include "ContentBrowserMenuContexts.h" #include "Engine/Texture2D.h" #include "Misc/PackageName.h" #include "Styling/AppStyle.h" #include "Materials/Material.h" #include "Materials/MaterialInstance.h" #include "Factories/MaterialFactoryNew.h" #include "Interfaces/ITextureEditorModule.h" #include "IContentBrowserSingleton.h" #include "ContentBrowserModule.h" #include "Factories/SubUVAnimationFactory.h" #include "Particles/SubUVAnimation.h" #include "AssetRegistry/AssetRegistryModule.h" #include "ToolMenus.h" #include "Misc/FeedbackContext.h" #include "IAssetTools.h" #include "VirtualTexturingEditorModule.h" #include "Algo/AnyOf.h" #include "AssetRegistry/AssetRegistryHelpers.h" #define LOCTEXT_NAMESPACE "UAssetDefinition_Texture" EAssetCommandResult UAssetDefinition_Texture::OpenAssets(const FAssetOpenArgs& OpenArgs) const { for (UTexture* Texture : OpenArgs.LoadObjects()) { ITextureEditorModule* TextureEditorModule = &FModuleManager::LoadModuleChecked("TextureEditor"); TextureEditorModule->CreateTextureEditor(OpenArgs.GetToolkitMode(), OpenArgs.ToolkitHost, Texture); } return EAssetCommandResult::Handled; } // Menu Extensions //-------------------------------------------------------------------- namespace MenuExtension_Texture { void ExecuteCreateMaterial(const FToolMenuContext& InContext) { const UContentBrowserAssetContextMenuContext* CBContext = UContentBrowserAssetContextMenuContext::FindContextWithAssets(InContext); const FString DefaultSuffix = TEXT("_Mat"); if ( const FAssetData* TextureAsset = CBContext->GetSingleSelectedAssetOfType(UTexture::StaticClass()) ) { if (UTexture* Texture = CastChecked(TextureAsset->GetAsset())) { // Determine an appropriate name FString Name; FString PackagePath; IAssetTools::Get().CreateUniqueAssetName(Texture->GetOutermost()->GetName(), DefaultSuffix, PackagePath, Name); // Create the factory used to generate the asset UMaterialFactoryNew* Factory = NewObject(); Factory->InitialTexture = Texture; FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); ContentBrowserModule.Get().CreateNewAsset(Name, FPackageName::GetLongPackagePath(PackagePath), UMaterial::StaticClass(), Factory); } } else { TArray ObjectsToSync; for (UTexture* Texture : CBContext->LoadSelectedObjects()) { FString Name; FString PackageName; IAssetTools::Get().CreateUniqueAssetName(Texture->GetOutermost()->GetName(), DefaultSuffix, PackageName, Name); // Create the factory used to generate the asset UMaterialFactoryNew* Factory = NewObject(); Factory->InitialTexture = Texture; UObject* NewAsset = IAssetTools::Get().CreateAsset(Name, FPackageName::GetLongPackagePath(PackageName), UMaterial::StaticClass(), Factory); if ( NewAsset ) { ObjectsToSync.Add(NewAsset); } } if ( ObjectsToSync.Num() > 0 ) { IAssetTools::Get().SyncBrowserToAssets(ObjectsToSync); } } } static void ExecuteConvertToVirtualTexture(const FToolMenuContext& InContext) { if (const UContentBrowserAssetContextMenuContext* CBContext = UContentBrowserAssetContextMenuContext::FindContextWithAssets(InContext)) { IVirtualTexturingEditorModule* Module = FModuleManager::Get().GetModulePtr("VirtualTexturingEditor"); Module->ConvertVirtualTexturesWithDialog(CBContext->LoadSelectedObjects(), false); } } static void ExecuteConvertToRegularTexture(const FToolMenuContext& InContext) { if (const UContentBrowserAssetContextMenuContext* CBContext = UContentBrowserAssetContextMenuContext::FindContextWithAssets(InContext)) { IVirtualTexturingEditorModule* Module = FModuleManager::Get().GetModulePtr("VirtualTexturingEditor"); Module->ConvertVirtualTexturesWithDialog(CBContext->LoadSelectedObjects(), true); } } static void ExecuteCreateSubUVAnimation(TArray> Objects) { const FString DefaultSuffix = TEXT("_SubUV"); if ( Objects.Num() == 1 ) { UTexture2D* Object = Cast(Objects[0].Get()); if ( Object ) { // Determine an appropriate name FString Name; FString PackagePath; IAssetTools::Get().CreateUniqueAssetName(Object->GetOutermost()->GetName(), DefaultSuffix, PackagePath, Name); // Create the factory used to generate the asset USubUVAnimationFactory* Factory = NewObject(); Factory->InitialTexture = Object; FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); ContentBrowserModule.Get().CreateNewAsset(Name, FPackageName::GetLongPackagePath(PackagePath), USubUVAnimation::StaticClass(), Factory); } } else { TArray ObjectsToSync; for (auto ObjIt = Objects.CreateConstIterator(); ObjIt; ++ObjIt) { UTexture2D* Object = Cast((*ObjIt).Get()); if ( Object ) { FString Name; FString PackageName; IAssetTools::Get().CreateUniqueAssetName(Object->GetOutermost()->GetName(), DefaultSuffix, PackageName, Name); // Create the factory used to generate the asset USubUVAnimationFactory* Factory = NewObject(); Factory->InitialTexture = Object; UObject* NewAsset = IAssetTools::Get().CreateAsset(Name, FPackageName::GetLongPackagePath(PackageName), USubUVAnimation::StaticClass(), Factory); if ( NewAsset ) { ObjectsToSync.Add(NewAsset); } } } if ( ObjectsToSync.Num() > 0 ) { IAssetTools::Get().SyncBrowserToAssets(ObjectsToSync); } } } static void ExecuteFindMaterials(const FToolMenuContext& InContext) { if (const UContentBrowserAssetContextMenuContext* CBContext = UContentBrowserAssetContextMenuContext::FindContextWithAssets(InContext)) { TArray MaterialsUsingTexture; // This finds "Material like" objects. It's called material in the UI string but this generally // seems more useful if ( const FAssetData* TextureAsset = CBContext->GetSingleSelectedAssetOfType(UTexture::StaticClass()) ) { UAssetRegistryHelpers::FindReferencersOfAssetOfClass(TextureAsset->PackageName, { UMaterialInterface::StaticClass(), UMaterialFunction::StaticClass() }, MaterialsUsingTexture); } if (MaterialsUsingTexture.Num() > 0) { IAssetTools::Get().SyncBrowserToAssets(MaterialsUsingTexture); } } } static FDelayedAutoRegisterHelper DelayedAutoRegister(EDelayedRegisterRunPhase::EndOfEngineInit, []{ UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateLambda([]() { FToolMenuOwnerScoped OwnerScoped(UE_MODULE_NAME); UToolMenu* Menu = UE::ContentBrowser::ExtendToolMenu_AssetContextMenu(UTexture::StaticClass()); FToolMenuSection& Section = Menu->FindOrAddSection("GetAssetActions"); Section.AddDynamicEntry("GetAssetActions_UTexture", FNewToolMenuSectionDelegate::CreateLambda([](FToolMenuSection& InSection) { if (const UContentBrowserAssetContextMenuContext* Context = UContentBrowserAssetContextMenuContext::FindContextWithAssets(InSection)) { { const TAttribute Label = LOCTEXT("Texture_CreateMaterial", "Create Material"); const TAttribute ToolTip = LOCTEXT("Texture_CreateMaterialTooltip", "Creates a new material using this texture."); const FSlateIcon Icon = FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Material"); const FToolMenuExecuteAction UIAction = FToolMenuExecuteAction::CreateStatic(&ExecuteCreateMaterial); InSection.AddMenuEntry("Texture_CreateMaterial", Label, ToolTip, Icon, UIAction); } const bool bHasVirtualTextures = Algo::AnyOf(Context->SelectedAssets, [](const FAssetData& AssetData){ bool VirtualTextured = false; AssetData.GetTagValue("VirtualTextureStreaming", VirtualTextured); return VirtualTextured; }); if (bHasVirtualTextures) { const TAttribute Label = LOCTEXT("Texture_ConvertToRegular", "Convert to Regular Texture"); const TAttribute ToolTip = LOCTEXT("Texture_ConvertToRegularTooltip", "Converts this texture to a regular 2D texture if it is a virtual texture."); const FSlateIcon Icon = FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Texture2D"); const FToolMenuExecuteAction UIAction = FToolMenuExecuteAction::CreateStatic(&ExecuteConvertToRegularTexture); InSection.AddMenuEntry("Texture_ConvertToVT", Label, ToolTip, Icon, UIAction); } if (!bHasVirtualTextures) { const TAttribute Label = LOCTEXT("Texture_ConvertToVT", "Convert to Virtual Texture"); const TAttribute ToolTip = LOCTEXT("Texture_ConvertToVTTooltip", "Converts this texture to a virtual texture if it fits the size limit imposed in the texture importer settings."); const FSlateIcon Icon = FSlateIcon(FAppStyle::GetAppStyleSetName(), "ClassIcon.Texture2D"); const FToolMenuExecuteAction UIAction = FToolMenuExecuteAction::CreateStatic(&ExecuteConvertToVirtualTexture); InSection.AddMenuEntry("Texture_ConvertToVT", Label, ToolTip, Icon, UIAction); } if ( Context->SelectedAssets.Num() == 1 ) { const TAttribute Label = LOCTEXT("Texture_FindMaterials", "Find Materials Using This"); const TAttribute ToolTip = LOCTEXT("Texture_FindMaterialsTooltip", "Finds all materials that use this material in the content browser."); const FSlateIcon Icon = FSlateIcon(FAppStyle::GetAppStyleSetName(), "Icons.Find"); const FToolMenuExecuteAction UIAction = FToolMenuExecuteAction::CreateStatic(&ExecuteFindMaterials); InSection.AddMenuEntry("Texture_FindMaterials", Label, ToolTip, Icon, UIAction); } } })); })); }); } #undef LOCTEXT_NAMESPACE