void CreateTileSetsFromTextures(TArray<UTexture2D*>& Textures) { const FString DefaultSuffix = TEXT("_TileSet"); FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools"); FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser"); TArray<UObject*> ObjectsToSync; for (auto TextureIt = Textures.CreateConstIterator(); TextureIt; ++TextureIt) { UTexture2D* Texture = *TextureIt; // Create the factory used to generate the tile set UPaperTileSetFactory* TileSetFactory = NewObject<UPaperTileSetFactory>(); TileSetFactory->InitialTexture = Texture; // Get a unique name for the tile set FString Name; FString PackageName; AssetToolsModule.Get().CreateUniqueAssetName(Texture->GetOutermost()->GetName(), DefaultSuffix, /*out*/ PackageName, /*out*/ Name); const FString PackagePath = FPackageName::GetLongPackagePath(PackageName); if (UObject* NewAsset = AssetToolsModule.Get().CreateAsset(Name, PackagePath, UPaperTileSet::StaticClass(), TileSetFactory)) { ObjectsToSync.Add(NewAsset); } } if (ObjectsToSync.Num() > 0) { ContentBrowserModule.Get().SyncBrowserToAssets(ObjectsToSync); } }
void CreateSpritesFromTextures(TArray<UTexture2D*>& Textures) { const FString DefaultSuffix = TEXT("_Sprite"); FAssetToolsModule& AssetToolsModule = FModuleManager::Get().LoadModuleChecked<FAssetToolsModule>("AssetTools"); FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser"); TArray<UObject*> ObjectsToSync; for (auto TextureIt = Textures.CreateConstIterator(); TextureIt; ++TextureIt) { UTexture2D* Texture = *TextureIt; // Create the factory used to generate the sprite UPaperSpriteFactory* SpriteFactory = ConstructObject<UPaperSpriteFactory>(UPaperSpriteFactory::StaticClass()); SpriteFactory->InitialTexture = Texture; // Create the sprite FString Name; FString PackageName; if (!bExtractSprites) { // Get a unique name for the sprite AssetToolsModule.Get().CreateUniqueAssetName(Texture->GetOutermost()->GetName(), DefaultSuffix, /*out*/ PackageName, /*out*/ Name); const FString PackagePath = FPackageName::GetLongPackagePath(PackageName); if (UObject* NewAsset = AssetToolsModule.Get().CreateAsset(Name, PackagePath, UPaperSprite::StaticClass(), SpriteFactory)) { ObjectsToSync.Add(NewAsset); } } else { FScopedSlowTask Feedback(1, NSLOCTEXT("Paper2D", "Paper2D_ExtractSpritesFromTexture", "Extracting Sprites From Texture")); Feedback.MakeDialog(true); // First extract the rects from the texture TArray<FIntRect> ExtractedRects; UPaperSprite::ExtractRectsFromTexture(Texture, /*out*/ ExtractedRects); // Sort the rectangles by approximate row struct FRectangleSortHelper { FRectangleSortHelper(TArray<FIntRect>& InOutSprites) { // Sort by Y, then by X (top left corner), descending order (so we can use it as a stack from the top row down) TArray<FIntRect> SpritesLeft = InOutSprites; SpritesLeft.Sort([](const FIntRect& A, const FIntRect& B) { return (A.Min.Y == B.Min.Y) ? (A.Min.X > B.Min.X) : (A.Min.Y > B.Min.Y); }); InOutSprites.Reset(); // Start pulling sprites out, the first one in each row will dominate remaining ones and cause them to get labeled TArray<FIntRect> DominatedSprites; DominatedSprites.Empty(SpritesLeft.Num()); while (SpritesLeft.Num()) { FIntRect DominatingSprite = SpritesLeft.Pop(); DominatedSprites.Add(DominatingSprite); // Find the sprites that are dominated (intersect the infinite horizontal band described by the dominating sprite) for (int32 Index = 0; Index < SpritesLeft.Num();) { const FIntRect& CurElement = SpritesLeft[Index]; if ((CurElement.Min.Y <= DominatingSprite.Max.Y) && (CurElement.Max.Y >= DominatingSprite.Min.Y)) { DominatedSprites.Add(CurElement); SpritesLeft.RemoveAt(Index, /*Count=*/ 1, /*bAllowShrinking=*/ false); } else { ++Index; } } // Sort the sprites in the band by X and add them to the result DominatedSprites.Sort([](const FIntRect& A, const FIntRect& B) { return (A.Min.X < B.Min.X); }); InOutSprites.Append(DominatedSprites); DominatedSprites.Reset(); } } }; FRectangleSortHelper RectSorter(ExtractedRects); Feedback.TotalAmountOfWork = ExtractedRects.Num(); for (int ExtractedRectIndex = 0; ExtractedRectIndex < ExtractedRects.Num(); ++ExtractedRectIndex) { Feedback.EnterProgressFrame(1, NSLOCTEXT("Paper2D", "Paper2D_ExtractSpritesFromTexture", "Extracting Sprites From Texture")); FIntRect& ExtractedRect = ExtractedRects[ExtractedRectIndex]; SpriteFactory->bUseSourceRegion = true; SpriteFactory->InitialSourceUV = FVector2D(ExtractedRect.Min.X, ExtractedRect.Min.Y); SpriteFactory->InitialSourceDimension = FVector2D(ExtractedRect.Width(), ExtractedRect.Height()); // Get a unique name for the sprite const FString Suffix = FString::Printf(TEXT("%s_%d"), *DefaultSuffix, ExtractedRectIndex); AssetToolsModule.Get().CreateUniqueAssetName(Texture->GetOutermost()->GetName(), Suffix, /*out*/ PackageName, /*out*/ Name); const FString PackagePath = FPackageName::GetLongPackagePath(PackageName); if (UObject* NewAsset = AssetToolsModule.Get().CreateAsset(Name, PackagePath, UPaperSprite::StaticClass(), SpriteFactory)) { ObjectsToSync.Add(NewAsset); } if (GWarn->ReceivedUserCancel()) { break; } } } } if (ObjectsToSync.Num() > 0) { ContentBrowserModule.Get().SyncBrowserToAssets(ObjectsToSync); } }
void FAssetTypeActions_Texture::ExecuteCreateSubUVAnimation(TArray<TWeakObjectPtr<UTexture>> Objects) { const FString DefaultSuffix = TEXT("_SubUV"); if ( Objects.Num() == 1 ) { UTexture2D* Object = Cast<UTexture2D>(Objects[0].Get()); if ( Object ) { // Determine an appropriate name FString Name; FString PackagePath; CreateUniqueAssetName(Object->GetOutermost()->GetName(), DefaultSuffix, PackagePath, Name); // Create the factory used to generate the asset USubUVAnimationFactory* Factory = NewObject<USubUVAnimationFactory>(); Factory->InitialTexture = Object; FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser"); ContentBrowserModule.Get().CreateNewAsset(Name, FPackageName::GetLongPackagePath(PackagePath), USubUVAnimation::StaticClass(), Factory); } } else { TArray<UObject*> ObjectsToSync; for (auto ObjIt = Objects.CreateConstIterator(); ObjIt; ++ObjIt) { UTexture2D* Object = Cast<UTexture2D>((*ObjIt).Get()); if ( Object ) { FString Name; FString PackageName; CreateUniqueAssetName(Object->GetOutermost()->GetName(), DefaultSuffix, PackageName, Name); // Create the factory used to generate the asset USubUVAnimationFactory* Factory = NewObject<USubUVAnimationFactory>(); Factory->InitialTexture = Object; FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools"); UObject* NewAsset = AssetToolsModule.Get().CreateAsset(Name, FPackageName::GetLongPackagePath(PackageName), USubUVAnimation::StaticClass(), Factory); if ( NewAsset ) { ObjectsToSync.Add(NewAsset); } } } if ( ObjectsToSync.Num() > 0 ) { FAssetTools::Get().SyncBrowserToAssets(ObjectsToSync); } } }