├── .gitignore ├── LICENSE ├── README.md ├── Resources ├── ButtonIcon_40x.png └── icon128.png ├── Source └── ThumbnailCreator │ ├── Private │ ├── Client │ │ └── ThumbnailViewportClient.cpp │ ├── Objects │ │ └── ThumbnailOptions.cpp │ ├── Slate │ │ └── SThumbnailViewport.cpp │ ├── ThumbnailCreator.cpp │ ├── ThumbnailCreatorCommands.cpp │ └── ThumbnailCreatorStyle.cpp │ ├── Public │ ├── Client │ │ └── ThumbnailViewportClient.h │ ├── Objects │ │ └── ThumbnailOptions.h │ ├── Slate │ │ └── SThumbnailViewport.h │ ├── ThumbnailCreator.h │ ├── ThumbnailCreatorCommands.h │ └── ThumbnailCreatorStyle.h │ └── ThumbnailCreator.Build.cs └── ThumbnailCreator.uplugin /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2015 user specific files 2 | .vs/ 3 | 4 | # Visual Studio 2015 database file 5 | *.VC.db 6 | 7 | # Compiled Object files 8 | *.slo 9 | *.lo 10 | *.o 11 | *.obj 12 | 13 | # Precompiled Headers 14 | *.gch 15 | *.pch 16 | 17 | # Compiled Dynamic libraries 18 | *.so 19 | *.dylib 20 | *.dll 21 | 22 | # Fortran module files 23 | *.mod 24 | 25 | # Compiled Static libraries 26 | *.lai 27 | *.la 28 | *.a 29 | *.lib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.ipa 36 | 37 | # These project files can be generated by the engine 38 | *.xcodeproj 39 | *.xcworkspace 40 | *.sln 41 | *.suo 42 | *.opensdf 43 | *.sdf 44 | *.VC.db 45 | *.VC.opendb 46 | 47 | # Precompiled Assets 48 | SourceArt/**/*.png 49 | SourceArt/**/*.tga 50 | 51 | # Binary Files 52 | Binaries/* 53 | 54 | # Builds 55 | Build/* 56 | 57 | # Whitelist PakBlacklist-.txt files 58 | !Build/*/ 59 | Build/*/** 60 | !Build/*/PakBlacklist*.txt 61 | 62 | # Don't ignore icon files in Build 63 | !Build/**/*.ico 64 | 65 | # Built data for maps 66 | *_BuiltData.uasset 67 | 68 | # Configuration files generated by the Editor 69 | Saved/* 70 | 71 | # Compiled source files for the engine to use 72 | Intermediate/* 73 | 74 | # Cache files for the editor to use 75 | DerivedDataCache/* 76 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Copyright (c) 2018 PANDA STUDIOS COMM. V. 3 | 4 | You can use and alter this plugin for creating thumbnails for your Unreal Engine Projects. 5 | You are however not allowed to redistribute the source code or binaries of the compiled source code regardless if the code has been altered or not, commercially or non-commercially. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 13 | SOFTWARE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnrealThumbnailGenerator 2 | 3 | I created this tool because our team needed it to quickly make some thumbnails semi-automatic, instead of posing camera, taking a picture, cropping, re-importing and adjusting settings for every item in our games. I don't intend to give support on this asset if something breaks in a future version other than that if I would personally need the update for our projects. I will however check out community pull requests in case someone wants to PR the fixes or updates. 4 | 5 | The tool is primarily designed for our needs but should fit people's need in general. I've added Static Mesh, Skeletal Mesh, animations and materials. 6 | 7 | **IMPORTANT - Read before use** 8 | If you install this plugin into your project, make sure you go to project settings and put the setting "Custom Depth-Stencil Pass" to "Enabled With Stencil". If you don't like this option, you can turn it off when you are not using the creator. However, for the transparency to work, that has to be enabled for the duration of the usage. 9 | 10 | **How it works:** 11 | You open the thumbnail generator and are started out with a scene and options panel on the left, on the options panel you can click buttons and also setup settings for the scene and screenshots. 12 | Once you click on create screenshot it'll create a screenshot every 0.03s, once that all is done it'll go over all created screenshots and reimport them as UTexture2D into the engine and saved into the content browser. 13 | For animations - Assign the skeletal mesh before assigning the animation. 14 | 15 | **Binaries Downloads - for those who don't want to compile it themselves** 16 | 4.18 -> https://drive.google.com/open?id=1D2wWOf1OO7Z1HgDnPVrSc83vH8oVQSGP 17 | 4.19 -> https://drive.google.com/open?id=1zL1vahdDB-3GRyvB-WXrekFm8METUqJl 18 | 19 | **How to install** 20 | Locate the .uproject file of your project. Once in that folder create a new folder and call it "Plugins", then create a new folder called "UnrealThumbnailCreator" inside that folder. Then go into that folder and drop the contens of the zip file into it. Then just launch the project. It's possible you need to enable the plugin inside the Plugins window of the editor. Don't forget to turn on the "Enabled with Stencil" as described above. 21 | 22 | **Tips** 23 | Don't use the generator for objects that are relatively differently sized, it will use the same view rotation and view location for every shot taken, so you can bulk this with items of relatively the same size. (Chairs, Tables, Swords, bows, staffs, handguns, etc.) 24 | 25 | **Exported** 26 | Images are exported as Texture2D's into the content browser under ThumbnailExports and are prefixed with Thumb_ 27 | 28 | ![](https://i.imgur.com/q82lJjJ.png) 29 | 30 | **Some special thanks to eXifreXi for giving input throughout the development** 31 | 32 | **Example of the UI** 33 | ![](https://i.imgur.com/zraPCAR.png) 34 | ![](https://i.imgur.com/NCVYqtw.png) 35 | -------------------------------------------------------------------------------- /Resources/ButtonIcon_40x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CelPlays/UnrealThumbnailGenerator/7808673fec8dbe1809ce5ee0acaa66940c7123a5/Resources/ButtonIcon_40x.png -------------------------------------------------------------------------------- /Resources/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CelPlays/UnrealThumbnailGenerator/7808673fec8dbe1809ce5ee0acaa66940c7123a5/Resources/icon128.png -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Private/Client/ThumbnailViewportClient.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Panda Studios Comm. V. - All Rights Reserves. Under no circumstance should this could be distributed, used, copied or be published without written approved of Panda Studios Comm. V. 2 | #include "ThumbnailViewportClient.h" 3 | 4 | //Thumbnail Core 5 | #include "ThumbnailOptions.h" 6 | #include "ThumbnailCreator.h" 7 | 8 | //Image 9 | #include "Runtime/Engine/Public/HighResScreenshot.h" 10 | #include "Editor/LevelEditor/Private/HighresScreenshotUI.h" 11 | 12 | //Engine 13 | #include "AssetEditorModeManager.h" 14 | #include "Runtime/CoreUObject/Public/UObject/ConstructorHelpers.h" 15 | #include "LevelEditor.h" 16 | #include "Utils.h" 17 | #include "EngineGlobals.h" 18 | 19 | //Slate 20 | #include "SViewport.h" 21 | #include "SThumbnailViewport.h" 22 | #include "Editor/UnrealEd/Public/UnrealWidget.h" 23 | 24 | //Components 25 | #include "Components/SkeletalMeshComponent.h" 26 | #include "Runtime/Engine/Classes/Engine/StaticMeshActor.h" 27 | #include "Runtime/Engine/Classes/Components/PostProcessComponent.h" 28 | #include "Runtime/Engine/Classes/Materials/MaterialInterface.h" 29 | 30 | //Scene 31 | #include "Runtime/Engine/Public/SceneView.h" 32 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewScene.h" 33 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewScene.h" 34 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewSceneModule.h" 35 | #include "Runtime/Engine/Classes/Engine/PostProcessVolume.h" 36 | #include "Runtime/Engine/Public/SceneManagement.h" 37 | #include "Runtime/Engine/Public/CanvasTypes.h" 38 | #include "Runtime/Engine/Classes/Materials/Material.h" 39 | #include "Runtime/Engine/Public/PreviewScene.h" 40 | 41 | 42 | FThumbnailViewportClient::FThumbnailViewportClient(const TSharedRef& InThumbnailViewport, const TSharedRef& InPreviewScene) 43 | : FEditorViewportClient(nullptr, &InPreviewScene.Get(), StaticCastSharedRef(InThumbnailViewport)) 44 | , ViewportPtr(InThumbnailViewport) 45 | { 46 | 47 | AdvancedPreviewScene = static_cast(PreviewScene); 48 | 49 | // Enable RealTime 50 | SetRealtime(true); 51 | 52 | // Hide grid, we don't need this. 53 | DrawHelper.bDrawGrid = false; 54 | DrawHelper.bDrawPivot = false; 55 | DrawHelper.AxesLineThickness = 5; 56 | DrawHelper.PivotSize = 5; 57 | 58 | //Initiate view 59 | SetViewLocation(FVector(75, 75, 75)); 60 | SetViewRotation(FVector(-75, -75, -75).Rotation()); 61 | 62 | EngineShowFlags.SetScreenPercentage(true); 63 | 64 | // Set the Default type to Ortho and the XZ Plane 65 | ELevelViewportType NewViewportType = LVT_Perspective; 66 | SetViewportType(NewViewportType); 67 | 68 | // View Modes in Persp and Ortho 69 | SetViewModes(VMI_Lit, VMI_Lit); 70 | 71 | //Create the static mesh component 72 | MeshComp = ViewportPtr.Pin()->MeshComp; 73 | MeshComp->bRenderCustomDepth = true; 74 | 75 | MaterialComp = ViewportPtr.Pin()->MaterialComp; 76 | MaterialComp->bRenderCustomDepth = true; 77 | MaterialComp->SetVisibility(false); 78 | 79 | //Create skeletal mesh component 80 | SkelMeshComp = ViewportPtr.Pin()->SkelMeshComp; 81 | SkelMeshComp->bRenderCustomDepth = true; 82 | SkelMeshComp->SetVisibility(false); 83 | 84 | //Add our own post process on the world 85 | UPostProcessComponent* PostComp = ViewportPtr.Pin()->PostComp; 86 | 87 | //Add both components to the scene 88 | PreviewScene->AddComponent(MeshComp, FTransform(), false); 89 | PreviewScene->AddComponent(SkelMeshComp, FTransform(), false); 90 | PreviewScene->AddComponent(PostComp, FTransform(), false); 91 | PreviewScene->AddComponent(MaterialComp, FTransform(), false); 92 | 93 | //Create a new defaults cube 94 | UStaticMesh* NewMesh = Cast(StaticLoadObject(UStaticMesh::StaticClass(), NULL, *(FString("StaticMesh'/Engine/VREditor/BasicMeshes/SM_Pyramid_01.SM_Pyramid_01'")))); 95 | UStaticMesh* MaterialMesh = Cast(StaticLoadObject(UStaticMesh::StaticClass(), NULL, *(FString("StaticMesh'/Engine/EngineMeshes/MaterialSphere.MaterialSphere'")))); 96 | 97 | //If mesh is valid... set the mesh and render custom depth 98 | if (NewMesh) 99 | { 100 | MeshComp->SetStaticMesh(NewMesh); 101 | } 102 | 103 | if (MaterialMesh) 104 | { 105 | MaterialComp->SetStaticMesh(MaterialMesh); 106 | } 107 | 108 | //Allow post process materials... 109 | EngineShowFlags.SetPostProcessMaterial(true); 110 | EngineShowFlags.SetPostProcessing(true); 111 | 112 | //Force screen percentage higher 113 | PostComp->Settings.ScreenPercentage = 200; 114 | 115 | //Unbound 116 | PostComp->bUnbound = true; 117 | 118 | //Set that the mask is enabled for screenshots so it records transparency in the output 119 | GetHighResScreenshotConfig().bMaskEnabled = true; 120 | 121 | //Register components inside the array 122 | ActorComponents.Add(MeshComp); 123 | ActorComponents.Add(SkelMeshComp); 124 | ActorComponents.Add(MaterialComp); 125 | 126 | } 127 | 128 | void FThumbnailViewportClient::Tick(float DeltaSeconds) 129 | { 130 | FEditorViewportClient::Tick(DeltaSeconds); 131 | 132 | // Tick the preview scene world. 133 | if (!GIntraFrameDebuggingGameThread) 134 | { 135 | if(AdvancedPreviewScene) 136 | AdvancedPreviewScene->GetWorld()->Tick(LEVELTICK_All, DeltaSeconds); 137 | } 138 | } 139 | 140 | void FThumbnailViewportClient::TakeSingleShot() 141 | { 142 | //Enable green mask 143 | EngineShowFlags.SetHighResScreenshotMask(true); 144 | 145 | //set the size of the screenshot 146 | GScreenshotResolutionX = ThumbnailOptions->ScreenshotXSize; 147 | GScreenshotResolutionY = ThumbnailOptions->ScreenshotYSize; 148 | 149 | //Set the name of the screenshot 150 | FString UseName = GetAssetName(); 151 | 152 | GetHighResScreenshotConfig().FilenameOverride = "Thumb_" + UseName; 153 | 154 | //Take the shots 155 | TakeHighResScreenShot(); 156 | 157 | //Turn off green mask 158 | EngineShowFlags.SetHighResScreenshotMask(false); 159 | 160 | 161 | //Remove this image from known images so we can process it again 162 | auto ModulePtr = FModuleManager::LoadModulePtr(FName("ThumbnailCreator")); 163 | if (ModulePtr) 164 | { 165 | ModulePtr->RemoveFromPreKnown(UseName); 166 | } 167 | } 168 | 169 | void FThumbnailViewportClient::ResetScene() 170 | { 171 | //PreviewScene = NULL; 172 | } 173 | 174 | void FThumbnailViewportClient::SetMesh(class UStaticMesh* inMesh, bool bTakeShot) 175 | { 176 | //Update static mesh to new one 177 | MeshComp->SetStaticMesh(inMesh); 178 | MeshComp->SetRenderCustomDepth(true); 179 | MeshComp->MarkRenderStateDirty(); 180 | 181 | SetComponentVisibility(MeshComp, EScreenshotType::Mesh); 182 | 183 | //If we need to take a shot, take one 184 | if (bTakeShot) 185 | { 186 | TakeSingleShot(); 187 | } 188 | 189 | 190 | } 191 | 192 | void FThumbnailViewportClient::SetSkelMesh(class USkeletalMesh* inMesh, class UAnimationAsset* AnimAsset /*= NULL*/, bool bTakeShot /*= false*/) 193 | { 194 | if (inMesh || AnimAsset) 195 | { 196 | //Only update mesh if we have one 197 | if(inMesh) 198 | SkelMeshComp->SetSkeletalMesh(inMesh); 199 | 200 | //If our anim asset is valid and we have a skeletal mesh then play it 201 | if (AnimAsset && SkelMeshComp->SkeletalMesh) 202 | { 203 | SkelMeshComp->PlayAnimation(AnimAsset, true); 204 | } 205 | 206 | //Flip visibility 207 | MeshComp->SetVisibility(false); 208 | SkelMeshComp->SetVisibility(true); 209 | } 210 | 211 | SetComponentVisibility(SkelMeshComp, EScreenshotType::Skeletal); 212 | 213 | //If we need to take a shot, take one 214 | if (bTakeShot) 215 | { 216 | TakeSingleShot(); 217 | } 218 | } 219 | 220 | void FThumbnailViewportClient::SetMaterial(UMaterialInterface* inMaterial, bool bTakeShot /*= false*/) 221 | { 222 | if (MaterialComp && inMaterial) 223 | { 224 | MaterialComp->SetMaterial(0, inMaterial); 225 | } 226 | 227 | SetComponentVisibility(MaterialComp, EScreenshotType::Material); 228 | 229 | if (bTakeShot) 230 | { 231 | TakeSingleShot(); 232 | } 233 | } 234 | 235 | void FThumbnailViewportClient::SetComponentVisibility(UActorComponent* ComponentToActivate, EScreenshotType Type) 236 | { 237 | //go over all components and only show the one we want to activate 238 | for (UPrimitiveComponent* Comp : ActorComponents) 239 | { 240 | Comp->SetVisibility(ComponentToActivate == Comp); 241 | } 242 | 243 | //Set the active type afterwards 244 | ActiveType = Type; 245 | } 246 | 247 | 248 | FString FThumbnailViewportClient::GetAssetName() 249 | { 250 | if (ActiveType == EScreenshotType::Mesh) 251 | { 252 | FString Name; 253 | MeshComp->GetStaticMesh()->GetName(Name); 254 | return Name; 255 | } 256 | else if (ActiveType == EScreenshotType::Skeletal) 257 | { 258 | FString Name; 259 | SkelMeshComp->SkeletalMesh->GetName(Name); 260 | return Name; 261 | } 262 | else 263 | { 264 | FString Name; 265 | MaterialComp->GetMaterial(0)->GetName(Name); 266 | return Name; 267 | } 268 | } 269 | 270 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Private/Objects/ThumbnailOptions.cpp: -------------------------------------------------------------------------------- 1 | 2 | // Copyright (c) Panda Studios Comm. V. - All Rights Reserves. Under no circumstance should this could be distributed, used, copied or be published without written approved of Panda Studios Comm. V. 3 | 4 | #include "ThumbnailOptions.h" 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Private/Slate/SThumbnailViewport.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) Panda Studios Comm. V. - All Rights Reserves. Under no circumstance should this could be distributed, used, copied or be published without written approved of Panda Studios Comm. V. 2 | 3 | #include "SThumbnailViewport.h" 4 | #include "SViewport.h" 5 | #include "Editor/LevelEditor/Private/SLevelViewportToolBar.h" 6 | #include "AssetEditorModeManager.h" 7 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewScene.h" 8 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewSceneModule.h" 9 | #include "Components/SkeletalMeshComponent.h" 10 | #include "Engine/SkeletalMesh.h" 11 | #include "Components/StaticMeshComponent.h" 12 | #include "Components/PostProcessComponent.h" 13 | #include "ThumbnailViewportClient.h" 14 | 15 | 16 | void SThumbnailViewport::AddReferencedObjects(FReferenceCollector& Collector) 17 | { 18 | Collector.AddReferencedObject(MeshComp); 19 | Collector.AddReferencedObject(MaterialComp); 20 | Collector.AddReferencedObject(SkelMeshComp); 21 | Collector.AddReferencedObject(PostComp); 22 | } 23 | 24 | TSharedRef SThumbnailViewport::GetViewportWidget() 25 | { 26 | return SharedThis(this); 27 | } 28 | 29 | TSharedPtr SThumbnailViewport::GetExtenders() const 30 | { 31 | TSharedPtr Result(MakeShareable(new FExtender)); 32 | return Result; 33 | } 34 | 35 | void SThumbnailViewport::OnFloatingButtonClicked() 36 | { 37 | // Nothing 38 | } 39 | 40 | //Just create the advnaced preview scene and initiate components 41 | SThumbnailViewport::SThumbnailViewport() : PreviewScene(MakeShareable(new FAdvancedPreviewScene(FPreviewScene::ConstructionValues()))) 42 | { 43 | 44 | MeshComp = NewObject(); 45 | 46 | MaterialComp = NewObject(); 47 | 48 | SkelMeshComp = NewObject(); 49 | 50 | PostComp = NewObject (); 51 | } 52 | 53 | SThumbnailViewport::~SThumbnailViewport() 54 | { 55 | if (TypedViewportClient.IsValid()) 56 | { 57 | TypedViewportClient->Viewport = NULL; 58 | } 59 | } 60 | 61 | void SThumbnailViewport::Construct(const FArguments& InArgs) 62 | { 63 | SEditorViewport::Construct(SEditorViewport::FArguments()); 64 | } 65 | 66 | 67 | TSharedRef SThumbnailViewport::MakeEditorViewportClient() 68 | { 69 | TypedViewportClient = MakeShareable(new FThumbnailViewportClient(SharedThis(this), PreviewScene.ToSharedRef())); 70 | return TypedViewportClient.ToSharedRef(); 71 | } 72 | 73 | void SThumbnailViewport::BindCommands() 74 | { 75 | SEditorViewport::BindCommands(); 76 | } 77 | 78 | EVisibility SThumbnailViewport::GetTransformToolbarVisibility() const 79 | { 80 | return EVisibility::Visible; 81 | } 82 | 83 | void SThumbnailViewport::OnFocusViewportToSelection() 84 | { 85 | 86 | } 87 | 88 | 89 | void SThumbnailViewport::SetMesh(class UStaticMesh* inMesh, bool bTakeShot) 90 | { 91 | //Set the mesh inside the client's meshcomp 92 | TypedViewportClient->SetMesh(inMesh, bTakeShot); 93 | } 94 | 95 | FText SThumbnailViewport::GetTitleText() const 96 | { 97 | //return the title text of the viewport 98 | return FText::FromString("Thumbnail Generator"); 99 | } 100 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Private/ThumbnailCreator.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "ThumbnailCreator.h" 4 | 5 | //Engine 6 | #include "LevelEditor.h" 7 | #include "PreviewScene.h" 8 | #include "Editor.h" 9 | #include "Runtime/Engine/Classes/Engine/Selection.h" 10 | #include "Engine/SkeletalMesh.h" 11 | #include "Runtime/Core/Public/Containers/Ticker.h" 12 | #include "Editor/UnrealEd/Public/ObjectTools.h" 13 | 14 | //Thumbnail Core 15 | #include "ThumbnailViewportClient.h" 16 | #include "ThumbnailOptions.h" 17 | #include "Runtime/Engine/Classes/Animation/AnimationAsset.h" 18 | #include "ThumbnailCreatorCommands.h" 19 | #include "ThumbnailCreatorStyle.h" 20 | #include "Components/SkeletalMeshComponent.h" 21 | #include "Engine/SkeletalMesh.h" 22 | 23 | //Image 24 | #include "Runtime/Engine/Public/ImageUtils.h" 25 | #include "Runtime/Core/Public/Misc/FileHelper.h" 26 | #include "Runtime/Engine/Classes/EditorFramework/AssetImportData.h" 27 | #include "Editor/UnrealEd/Classes/Factories/TextureFactory.h" 28 | #include "Engine/Texture2D.h" 29 | #include "Runtime/Core/Public/HAL/FileManager.h" 30 | #include "Runtime/ImageWrapper/Public/IImageWrapper.h" 31 | #include "Runtime/ImageWrapper/Public/IImageWrapperModule.h" 32 | #include "Runtime/AssetRegistry/Public/AssetRegistryModule.h" 33 | #include "Runtime/Core/Public/Misc/Paths.h" 34 | #include "Runtime/Core/Public/HAL/FileManagerGeneric.h" 35 | 36 | //Slate 37 | #include "Runtime/Engine/Public/Slate/SlateTextures.h" 38 | #include "Widgets/Docking/SDockTab.h" 39 | #include "Widgets/Layout/SBox.h" 40 | #include "SButton.h" 41 | #include "Widgets/Text/STextBlock.h" 42 | #include "SSplitter.h" 43 | #include "SThumbnailViewport.h" 44 | #include "SEditorViewport.h" 45 | #include "PropertyEditorModule.h" 46 | #include "Editor/AdvancedPreviewScene/Public/SAdvancedPreviewDetailsTab.h" 47 | #include "SImage.h" 48 | #include "Editor/PropertyEditor/Public/IDetailsView.h" 49 | 50 | static const FName ThumbnailCreatorTabName("ThumbnailCreator"); 51 | 52 | #define LOCTEXT_NAMESPACE "FThumbnailCreatorModule" 53 | 54 | void FThumbnailCreatorModule::StartupModule() 55 | { 56 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 57 | 58 | FThumbnailCreatorStyle::Initialize(); 59 | FThumbnailCreatorStyle::ReloadTextures(); 60 | 61 | FThumbnailCreatorCommands::Register(); 62 | 63 | PluginCommands = MakeShareable(new FUICommandList); 64 | 65 | PluginCommands->MapAction( 66 | FThumbnailCreatorCommands::Get().OpenPluginWindow, 67 | FExecuteAction::CreateRaw(this, &FThumbnailCreatorModule::PluginButtonClicked), 68 | FCanExecuteAction()); 69 | 70 | FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked("LevelEditor"); 71 | 72 | { 73 | TSharedPtr MenuExtender = MakeShareable(new FExtender()); 74 | MenuExtender->AddMenuExtension("WindowLayout", EExtensionHook::After, PluginCommands, FMenuExtensionDelegate::CreateRaw(this, &FThumbnailCreatorModule::AddMenuExtension)); 75 | 76 | LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender); 77 | } 78 | 79 | { 80 | TSharedPtr ToolbarExtender = MakeShareable(new FExtender); 81 | ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FThumbnailCreatorModule::AddToolbarExtension)); 82 | 83 | LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender); 84 | } 85 | 86 | FGlobalTabmanager::Get()->RegisterNomadTabSpawner(ThumbnailCreatorTabName, FOnSpawnTab::CreateRaw(this, &FThumbnailCreatorModule::OnSpawnPluginTab)) 87 | .SetDisplayName(LOCTEXT("FThumbnailCreatorTabTitle", "ThumbnailCreator")) 88 | .SetMenuType(ETabSpawnerMenuType::Hidden); 89 | 90 | 91 | //Setup a timer every 0.03 seconds to crete a new image or process taken image 92 | ImageTickDelegate = FTickerDelegate::CreateRaw(this, &FThumbnailCreatorModule::NextInQueue); 93 | FTicker::GetCoreTicker().AddTicker(ImageTickDelegate, 0.03f); 94 | 95 | 96 | //Get all startup images to exclude from processing 97 | IFileManager& FileManager = IFileManager::Get(); 98 | 99 | 100 | 101 | TArray StartUpShort; 102 | FileManager.FindFiles(StartUpShort, *FPaths::ScreenShotDir()); 103 | for (FString Short : StartUpShort) 104 | { 105 | //Add path because Short is just the name, we still need to add the path to the string 106 | StartupImages.Add(FPaths::ScreenShotDir() + Short); 107 | } 108 | 109 | //THIS IS NEEDED, if you don't do this you will crash the engine upon shutdown 110 | FCoreDelegates::OnPreExit.AddLambda([this]() 111 | { 112 | if (!ViewportPtr.IsValid()) 113 | return; 114 | 115 | ViewportPtr->PreviewScene.Reset(); 116 | ViewportPtr->TypedViewportClient.Reset(); 117 | ViewportPtr.Reset(); 118 | }); 119 | 120 | } 121 | 122 | void FThumbnailCreatorModule::ShutdownModule() 123 | { 124 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 125 | // we call this function before unloading the module. 126 | 127 | 128 | FThumbnailCreatorStyle::Shutdown(); 129 | 130 | FThumbnailCreatorCommands::Unregister(); 131 | 132 | FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(ThumbnailCreatorTabName); 133 | } 134 | 135 | void FThumbnailCreatorModule::PreUnloadCallback() 136 | { 137 | 138 | IModuleInterface::PreUnloadCallback(); 139 | } 140 | 141 | TSharedRef FThumbnailCreatorModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs) 142 | { 143 | 144 | //Create the new SThumbnailViewport for this tab 145 | ViewportPtr = SNew(SThumbnailViewport); 146 | 147 | //Setup thumbnail options property details view settings 148 | FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked("PropertyEditor"); 149 | FDetailsViewArgs Args; 150 | Args.bAllowSearch = false; 151 | Args.bCustomNameAreaLocation = true; 152 | Args.bShowActorLabel = false; 153 | Args.bHideSelectionTip = false; 154 | Args.bShowScrollBar = false; 155 | 156 | DetailsView = PropertyModule.CreateDetailView(Args); 157 | 158 | //Create advanced scene preview 159 | FAdvancedPreviewSceneModule& AdvancedPreviewSceneModule = FModuleManager::LoadModuleChecked("AdvancedPreviewScene"); 160 | TSharedRef PreviewDetails = AdvancedPreviewSceneModule.CreateAdvancedPreviewSceneSettingsWidget(ViewportPtr->PreviewScene.ToSharedRef()); 161 | 162 | //Create thumbnmail options object 163 | if (!ThumbnailOptions) 164 | { 165 | ThumbnailOptions = NewObject(GetTransientPackage(), UThumbnailOptions::StaticClass()); 166 | ThumbnailOptions->AddToRoot(); 167 | } 168 | 169 | auto var = SNew(SDockTab) 170 | .TabRole(ETabRole::NomadTab) 171 | [ 172 | // Put your tab content here! 173 | 174 | SNew(SSplitter) 175 | .Orientation(Orient_Horizontal) 176 | +SSplitter::Slot().Value(0.25f) 177 | [ 178 | SNew(SVerticalBox) 179 | + SVerticalBox::Slot() 180 | .Padding(5, 0, 5, 10) 181 | .HAlign(HAlign_Fill).VAlign(VAlign_Top).AutoHeight() 182 | [ 183 | SNew(SButton) 184 | .OnClicked_Raw(this, &FThumbnailCreatorModule::GenerateFromSelection) 185 | [ 186 | SNew(STextBlock).Text(FText::FromString("Generate Content Selection")) 187 | ] 188 | ] 189 | + SVerticalBox::Slot() 190 | .Padding(5, 0, 5, 10) 191 | .HAlign(HAlign_Fill).VAlign(VAlign_Top).AutoHeight() 192 | [ 193 | SNew(SButton) 194 | .OnClicked_Raw(this, &FThumbnailCreatorModule::GenerateView) 195 | [ 196 | SNew(STextBlock).Text(FText::FromString("Generate Current View")) 197 | ] 198 | ] 199 | + SVerticalBox::Slot() 200 | .Padding(5, 0, 5, 10) 201 | .HAlign(HAlign_Fill).VAlign(VAlign_Top).AutoHeight() 202 | [ 203 | SNew(SButton) 204 | .OnClicked_Raw(this, &FThumbnailCreatorModule::PreviewSelected) 205 | [ 206 | SNew(STextBlock).Text(FText::FromString("Preview Content Selected Mesh")) 207 | ] 208 | ] 209 | + SVerticalBox::Slot() 210 | .Padding(5, 0, 5, 10) 211 | .HAlign(HAlign_Fill).VAlign(VAlign_Fill).AutoHeight() 212 | [ 213 | DetailsView->AsShared() 214 | ] 215 | + SVerticalBox::Slot() 216 | .Padding(5, 0, 5, 10) 217 | .HAlign(HAlign_Fill).VAlign(VAlign_Fill).FillHeight(1) 218 | [ 219 | SNew(SBox) 220 | .WidthOverride(250.f) 221 | [ 222 | PreviewDetails->AsShared() 223 | ] 224 | ] 225 | ] 226 | + SSplitter::Slot() 227 | [ 228 | SNew(SBox) 229 | .HAlign(HAlign_Fill) 230 | .VAlign(VAlign_Fill) 231 | [ 232 | SNew(SHorizontalBox) 233 | + SHorizontalBox::Slot() 234 | .HAlign(HAlign_Fill) 235 | .VAlign(VAlign_Fill) 236 | .FillWidth(1) 237 | .Padding(5, 10, 5, 0) 238 | [ 239 | SNew(SBox) 240 | [ 241 | ViewportPtr.ToSharedRef() 242 | ] 243 | ] 244 | ] 245 | ] 246 | ]; 247 | 248 | //Set th objects for the details view 249 | DetailsView->SetObject(ThumbnailOptions, true); 250 | 251 | //Set the thumbnail options object in the viewport client 252 | ViewportPtr.Get()->GetViewportClient()->ThumbnailOptions = ThumbnailOptions; 253 | 254 | return var; 255 | } 256 | 257 | void FThumbnailCreatorModule::PluginButtonClicked() 258 | { 259 | FGlobalTabmanager::Get()->InvokeTab(ThumbnailCreatorTabName); 260 | } 261 | 262 | void FThumbnailCreatorModule::AddMenuExtension(FMenuBuilder& Builder) 263 | { 264 | Builder.AddMenuEntry(FThumbnailCreatorCommands::Get().OpenPluginWindow); 265 | } 266 | 267 | FReply FThumbnailCreatorModule::GenerateFromSelection() 268 | { 269 | //Get content selection 270 | TArray Selection; 271 | GEditor->GetContentBrowserSelections(Selection); 272 | 273 | //Set selection as queue 274 | Queue = Selection; 275 | 276 | return FReply::Handled(); 277 | } 278 | 279 | FReply FThumbnailCreatorModule::PreviewSelected() 280 | { 281 | //Get content selection 282 | TArray Selection; 283 | GEditor->GetContentBrowserSelections(Selection); 284 | 285 | //For all selected set the mesh in the viewport.. generally only the latest in selection will be viewed if you select more than one 286 | for (FAssetData _Data : Selection) 287 | { 288 | AssignAsset(_Data, false); 289 | } 290 | return FReply::Handled(); 291 | 292 | } 293 | 294 | FReply FThumbnailCreatorModule::GenerateView() 295 | { 296 | //Take a screnshot of the current view 297 | ViewportPtr->GetViewportClient()->TakeSingleShot(); 298 | return FReply::Handled(); 299 | } 300 | 301 | bool FThumbnailCreatorModule::NextInQueue(float Delta) 302 | { 303 | //If we have a queue(FAssetData) 304 | if (Queue.Num() > 0) 305 | { 306 | //Take the firs tin queue 307 | FAssetData _Data = Queue[0]; 308 | //Delete from queue 309 | Queue.RemoveAt(0); 310 | AssignAsset(_Data, true); 311 | 312 | } 313 | //If we have created images... 314 | else if(CreatedImages.Num() > 0) 315 | { 316 | TArray RawImage; 317 | 318 | //get first created image and remove from queu 319 | FString pngfile = CreatedImages[0]; 320 | CreatedImages.RemoveAt(0); 321 | 322 | IImageWrapperModule& ImageWrapperModule = FModuleManager::LoadModuleChecked(FName("ImageWrapper")); 323 | // Note: PNG format. Other formats are supported 324 | TSharedPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper(EImageFormat::PNG); 325 | 326 | if (FFileHelper::LoadFileToArray(RawImage, *pngfile)) 327 | { 328 | if (ImageWrapper.IsValid() && ImageWrapper->SetCompressed(RawImage.GetData(), RawImage.Num())) 329 | { 330 | const TArray* UncompressedBGRA = NULL; 331 | if (ImageWrapper->GetRaw(ERGBFormat::BGRA, 8, UncompressedBGRA)) 332 | { 333 | // Setup packagename 334 | FString AssetName = pngfile.RightChop(pngfile.Find("/", ESearchCase::IgnoreCase, ESearchDir::FromEnd) + 1); 335 | FString USeAssetName = AssetName.LeftChop(AssetName.Len() - AssetName.Find( ".png", ESearchCase::IgnoreCase, ESearchDir::FromEnd)); 336 | 337 | FString PackageName = TEXT("/Game/ThumbnailExports/" + USeAssetName); 338 | // Create new UPackage from PackageName 339 | UPackage* Package = CreatePackage(NULL, *PackageName); 340 | //Try to get the old package if this image already exists 341 | UPackage* OldPackage = LoadPackage(NULL, *PackageName,0); 342 | 343 | // Create Texture2D Factory 344 | auto TextureFact = NewObject(); 345 | TextureFact->AddToRoot(); 346 | TextureFact->SuppressImportOverwriteDialog(); 347 | 348 | // Get a pointer to the raw image data 349 | const uint8* PtrTexture = RawImage.GetData(); 350 | 351 | // Stupidly use the damn factory 352 | UTexture2D* Texture = (UTexture2D*)TextureFact->FactoryCreateBinary(UTexture2D::StaticClass(), OldPackage? OldPackage : Package, *USeAssetName, RF_Standalone | RF_Public, NULL, TEXT("png"), PtrTexture, PtrTexture + RawImage.Num(), GWarn); 353 | 354 | if (Texture) 355 | { 356 | Texture->AssetImportData->Update(IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*USeAssetName)); 357 | 358 | Package->SetDirtyFlag(true); 359 | TextureFact->RemoveFromRoot(); 360 | 361 | //If we already have an old package we don't want to overwrite settings to defaults 362 | if (!OldPackage) 363 | { 364 | //Set settings to fit with UI 365 | Texture->Filter = TextureFilter::TF_Trilinear; 366 | //2D pixels for UI gives clearest results 367 | Texture->LODGroup = TextureGroup::TEXTUREGROUP_Pixels2D; 368 | } 369 | //Notify new asset created or store in the old package 370 | if (OldPackage) 371 | { 372 | OldPackage->SetDirtyFlag(true); 373 | } 374 | else 375 | { 376 | FAssetRegistryModule::AssetCreated(Texture); 377 | } 378 | } 379 | } 380 | } 381 | } 382 | } 383 | //If none of the above 384 | else 385 | { 386 | TArray AllImages; 387 | 388 | //Get all images in teh screenshot folter 389 | IFileManager& FileManager = IFileManager::Get(); 390 | FileManager.FindFiles(AllImages, *FPaths::ScreenShotDir()); 391 | for (FString Image : AllImages) 392 | { 393 | //Format full string 394 | FString Full = FPaths::ScreenShotDir() + Image; 395 | //If this image isn't in the startup(so wasn't known about before) we know it's new and we should process 396 | if (!StartupImages.Contains(Full)) 397 | { 398 | 399 | //Add to startup images to prevent processing again 400 | StartupImages.Add(Full); 401 | CreatedImages.Add(Full); 402 | } 403 | } 404 | } 405 | 406 | return true; 407 | } 408 | 409 | //remove from startup images so we can process the image again 410 | void FThumbnailCreatorModule::RemoveFromPreKnown(const FString ToRemove) 411 | { 412 | FString ToUseString = FPaths::ScreenShotDir() + "Thumb_" + ToRemove + ".png"; 413 | StartupImages.Remove(ToUseString); 414 | } 415 | 416 | void FThumbnailCreatorModule::AddToolbarExtension(FToolBarBuilder& Builder) 417 | { 418 | Builder.AddToolBarButton(FThumbnailCreatorCommands::Get().OpenPluginWindow); 419 | } 420 | 421 | 422 | void FThumbnailCreatorModule::AssignAsset(FAssetData _Data, bool bTakeShot) 423 | { 424 | //Cast to static mesh 425 | UStaticMesh* Mesh = Cast(_Data.GetAsset()); 426 | if (Mesh) 427 | { 428 | //If static mesh, set the static mesh and take a screenshot 429 | ViewportPtr->SetMesh(Mesh, bTakeShot); 430 | 431 | return; 432 | } 433 | 434 | //If not a mesh... try a skeletal mesh 435 | USkeletalMesh* SkelMesh = Cast(_Data.GetAsset()); 436 | if (SkelMesh) 437 | { 438 | ViewportPtr->GetViewportClient()->SetSkelMesh(SkelMesh, nullptr, bTakeShot); 439 | 440 | return; 441 | } 442 | 443 | //If also not a skeletal mesh... try an animation 444 | UAnimationAsset* AnimationAsset = Cast(_Data.GetAsset()); 445 | if (AnimationAsset) 446 | { 447 | ViewportPtr->GetViewportClient()->SetSkelMesh(AnimationAsset->GetSkeleton()->GetPreviewMesh(), AnimationAsset, bTakeShot); 448 | return; 449 | } 450 | 451 | //If also not a skeletal mesh... try an animation 452 | UMaterialInterface* MaterialAsset = Cast(_Data.GetAsset()); 453 | if (MaterialAsset) 454 | { 455 | ViewportPtr->GetViewportClient()->SetMaterial(MaterialAsset, bTakeShot); 456 | return; 457 | } 458 | } 459 | 460 | 461 | #undef LOCTEXT_NAMESPACE 462 | 463 | IMPLEMENT_MODULE(FThumbnailCreatorModule, ThumbnailCreator) -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Private/ThumbnailCreatorCommands.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "ThumbnailCreatorCommands.h" 4 | 5 | #define LOCTEXT_NAMESPACE "FThumbnailCreatorModule" 6 | 7 | void FThumbnailCreatorCommands::RegisterCommands() 8 | { 9 | UI_COMMAND(OpenPluginWindow, "ThumbnailCreator", "Bring up ThumbnailCreator window", EUserInterfaceActionType::Button, FInputGesture()); 10 | } 11 | 12 | #undef LOCTEXT_NAMESPACE 13 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Private/ThumbnailCreatorStyle.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "ThumbnailCreatorStyle.h" 4 | #include "Styling/SlateStyleRegistry.h" 5 | #include "Framework/Application/SlateApplication.h" 6 | #include "SlateGameResources.h" 7 | #include "IPluginManager.h" 8 | 9 | TSharedPtr< FSlateStyleSet > FThumbnailCreatorStyle::StyleInstance = NULL; 10 | 11 | void FThumbnailCreatorStyle::Initialize() 12 | { 13 | if (!StyleInstance.IsValid()) 14 | { 15 | StyleInstance = Create(); 16 | FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); 17 | } 18 | } 19 | 20 | void FThumbnailCreatorStyle::Shutdown() 21 | { 22 | FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); 23 | ensure(StyleInstance.IsUnique()); 24 | StyleInstance.Reset(); 25 | } 26 | 27 | FName FThumbnailCreatorStyle::GetStyleSetName() 28 | { 29 | static FName StyleSetName(TEXT("ThumbnailCreatorStyle")); 30 | return StyleSetName; 31 | } 32 | 33 | #define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 34 | #define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 35 | #define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 36 | #define TTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) 37 | #define OTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) 38 | 39 | const FVector2D Icon16x16(16.0f, 16.0f); 40 | const FVector2D Icon20x20(20.0f, 20.0f); 41 | const FVector2D Icon40x40(40.0f, 40.0f); 42 | 43 | TSharedRef< FSlateStyleSet > FThumbnailCreatorStyle::Create() 44 | { 45 | TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("ThumbnailCreatorStyle")); 46 | Style->SetContentRoot(IPluginManager::Get().FindPlugin("ThumbnailCreator")->GetBaseDir() / TEXT("Resources")); 47 | 48 | Style->Set("ThumbnailCreator.OpenPluginWindow", new IMAGE_BRUSH(TEXT("ButtonIcon_40x"), Icon40x40)); 49 | 50 | return Style; 51 | } 52 | 53 | #undef IMAGE_BRUSH 54 | #undef BOX_BRUSH 55 | #undef BORDER_BRUSH 56 | #undef TTF_FONT 57 | #undef OTF_FONT 58 | 59 | void FThumbnailCreatorStyle::ReloadTextures() 60 | { 61 | if (FSlateApplication::IsInitialized()) 62 | { 63 | FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); 64 | } 65 | } 66 | 67 | const ISlateStyle& FThumbnailCreatorStyle::Get() 68 | { 69 | return *StyleInstance; 70 | } 71 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Public/Client/ThumbnailViewportClient.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Panda Studios Comm. V. - All Rights Reserves. Under no circumstance should this could be distributed, used, copied or be published without written approved of Panda Studios Comm. V. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "UObject/NoExportTypes.h" 7 | #include "HighResScreenshot.h" 8 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewScene.h" 9 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewSceneModule.h" 10 | #include "Editor/AdvancedPreviewScene/Public/SAdvancedPreviewDetailsTab.h" 11 | #include "Editor/UnrealEd/Public/LevelEditorViewport.h" 12 | #include "Editor/UnrealEd/Public/EditorViewportClient.h" 13 | 14 | enum class EScreenshotType : uint8 15 | { 16 | Mesh, 17 | Skeletal, 18 | Material 19 | }; 20 | 21 | 22 | class THUMBNAILCREATOR_API FThumbnailViewportClient : public FEditorViewportClient 23 | { 24 | 25 | public: 26 | 27 | /** The preview scene we use instead of the real gameplay scene */ 28 | 29 | /** Pointer back to the Editor Viewport */ 30 | TWeakPtr ViewportPtr; 31 | 32 | //Constructor and destructor 33 | FThumbnailViewportClient(const TSharedRef& InThumbnailViewport, const TSharedRef& InPreviewScene); 34 | 35 | //Components in the scne 36 | UPROPERTY() 37 | UStaticMeshComponent* MeshComp; 38 | UPROPERTY() 39 | USkeletalMeshComponent* SkelMeshComp; 40 | UPROPERTY() 41 | UStaticMeshComponent* MaterialComp; 42 | 43 | /** Stored pointer to the preview scene in which the static mesh is shown */ 44 | FAdvancedPreviewScene* AdvancedPreviewScene; 45 | 46 | //All registerd actor components 47 | UPROPERTY() 48 | TArray ActorComponents; 49 | 50 | //Active type of the screenshot 51 | EScreenshotType ActiveType; 52 | 53 | //Options file 54 | class UThumbnailOptions* ThumbnailOptions; 55 | 56 | virtual void Tick(float DeltaSeconds) override; 57 | 58 | //Take one single shot 59 | void TakeSingleShot(); 60 | 61 | void ResetScene(); 62 | /* 63 | * Set the static mesh 64 | * @param inMesh Mesh to use 65 | * @param bTakeShot Should we take a shot with this change? 66 | */ 67 | void SetMesh(class UStaticMesh* inMesh, bool bTakeShot = false); 68 | /* 69 | * Set the Skeletal mesh 70 | * @param inMesh Mesh to use 71 | * @param AnimAsset Animation asset to set it with 72 | * @param bTakeShot Should we take a shot with this change? 73 | */ 74 | void SetSkelMesh(class USkeletalMesh* inMesh, class UAnimationAsset* AnimAsset = NULL, bool bTakeShot = false); 75 | /* 76 | * Set the material preview 77 | * @param inMaterial Material to use 78 | * @param bTakeShot Should we take a shot with this change? 79 | */ 80 | void SetMaterial(class UMaterialInterface* inMaterial, bool bTakeShot = false); 81 | /* 82 | * Update visibilty of the proper mesh 83 | * @param ComponentToActivate Component to activate 84 | * @param Type Type of the screenshot to activate 85 | */ 86 | void SetComponentVisibility(UActorComponent* ComponentToActivate, EScreenshotType Type); 87 | 88 | /* 89 | * Get the name of the active asset 90 | */ 91 | FString GetAssetName(); 92 | }; 93 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Public/Objects/ThumbnailOptions.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Panda Studios Comm. V. - All Rights Reserves. Under no circumstance should this could be distributed, used, copied or be published without written approved of Panda Studios Comm. V. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "UObject/NoExportTypes.h" 7 | #include "ThumbnailOptions.generated.h" 8 | 9 | 10 | UCLASS(Transient) 11 | class THUMBNAILCREATOR_API UThumbnailOptions : public UObject 12 | { 13 | GENERATED_BODY() 14 | 15 | 16 | public: 17 | //Screenshot X Size 18 | UPROPERTY(EditAnywhere, Category = "Setup") 19 | int32 ScreenshotXSize = 512; 20 | //Screenshot Y Size 21 | UPROPERTY(EditAnywhere, Category = "Setup") 22 | int32 ScreenshotYSize = 512; 23 | }; 24 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Public/Slate/SThumbnailViewport.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) Panda Studios Comm. V. - All Rights Reserves. Under no circumstance should this could be distributed, used, copied or be published without written approved of Panda Studios Comm. V. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Components/Viewport.h" 7 | #include "SViewport.h" 8 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewScene.h" 9 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewSceneModule.h" 10 | #include "SLevelViewport.h" 11 | #include "SEditorViewport.h" 12 | #include "Editor/UnrealEd/Public/SCommonEditorViewportToolbarBase.h" 13 | #include "SlateFwd.h" 14 | #include "UObject/GCObject.h" 15 | 16 | 17 | class SThumbnailViewport : public SEditorViewport, public FGCObject, public ICommonEditorViewportToolbarInfoProvider 18 | { 19 | public: 20 | 21 | //Constructor and destructor 22 | //SThumbnailViewport(); 23 | 24 | SLATE_BEGIN_ARGS(SThumbnailViewport) {} 25 | SLATE_END_ARGS() 26 | 27 | /** The scene for this viewport. */ 28 | TSharedPtr PreviewScene; 29 | 30 | 31 | //FGCObject 32 | void AddReferencedObjects(FReferenceCollector& Collector) override; 33 | //Toolbar interface 34 | virtual TSharedRef GetViewportWidget() override; 35 | virtual TSharedPtr GetExtenders() const override; 36 | virtual void OnFloatingButtonClicked() override; 37 | 38 | //All components to use in the client 39 | UStaticMeshComponent* MeshComp; 40 | UStaticMeshComponent* MaterialComp; 41 | USkeletalMeshComponent* SkelMeshComp; 42 | UPostProcessComponent* PostComp; 43 | 44 | SThumbnailViewport(); 45 | ~SThumbnailViewport(); 46 | /* 47 | * Construct this viewport widget 48 | * 49 | * @param inArgs Arguments 50 | */ 51 | void Construct(const FArguments& InArgs); 52 | 53 | /* 54 | * Construct this viewport widget 55 | * 56 | * @return the created EditorViewportClient 57 | */ 58 | virtual TSharedRef MakeEditorViewportClient() override; 59 | 60 | void BindCommands() override; 61 | EVisibility GetTransformToolbarVisibility() const; 62 | void OnFocusViewportToSelection() override; 63 | /* 64 | * Get the viewport client 65 | * 66 | * @return the viewport client 67 | */ 68 | TSharedPtr GetViewportClient() { return TypedViewportClient; }; 69 | 70 | 71 | /* 72 | * Set mesh of the mesh component 73 | * 74 | * @param inMesh Mesh to change it with 75 | * @param bTakeShot Take a shot in this change? 76 | */ 77 | void SetMesh(class UStaticMesh* inMesh, bool bTakeShot = false); 78 | 79 | //Shared ptr to the client 80 | TSharedPtr TypedViewportClient; 81 | 82 | protected: 83 | FText GetTitleText() const; 84 | 85 | private: 86 | 87 | 88 | }; 89 | -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Public/ThumbnailCreator.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Runtime/Core/Public/Containers/Ticker.h" 7 | #include "SImage.h" 8 | #include "SEditorViewport.h" 9 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewScene.h" 10 | #include "Editor/AdvancedPreviewScene/Public/AdvancedPreviewSceneModule.h" 11 | #include "ModuleManager.h" 12 | 13 | class FToolBarBuilder; 14 | class FMenuBuilder; 15 | 16 | class FThumbnailCreatorModule : public IModuleInterface 17 | { 18 | public: 19 | 20 | /** IModuleInterface implementation */ 21 | virtual void StartupModule() override; 22 | virtual void ShutdownModule() override; 23 | void PreUnloadCallback() override; 24 | 25 | /** This function will be bound to Command (by default it will bring up plugin window) */ 26 | void PluginButtonClicked(); 27 | 28 | /* 29 | * Assign asset to the viewport client scene 30 | * 31 | * @param _Dats FAssetData of the asset to use 32 | * @param bTakeShot Should we take a shot with this change? 33 | */ 34 | void AssignAsset(FAssetData _Data, bool bTakeShot); 35 | 36 | //Generate all screenshots from selection of the conten browser 37 | FReply GenerateFromSelection(); 38 | //Set preview mesh to the one selected in the content browser 39 | FReply PreviewSelected(); 40 | //generate image without changing any mesh with the current view 41 | FReply GenerateView(); 42 | 43 | //Next in queue for the image tick 44 | bool NextInQueue(float Delta); 45 | 46 | //Remove from StartupImages 47 | void RemoveFromPreKnown(const FString ToRemove); 48 | 49 | /** Pointer to the Viewport */ 50 | TSharedPtr ViewportPtr; 51 | //Details view of the screenshot settings 52 | TSharedPtr DetailsView; 53 | 54 | //Queue of active to take screenshots 55 | TArray Queue; 56 | //All created images still to process 57 | TArray CreatedImages; 58 | //Images to ignore for process 59 | TArray StartupImages; 60 | 61 | //Tick delegate for the 0.03s image tick 62 | FTickerDelegate ImageTickDelegate; 63 | 64 | //Thumbnail options for the screenshots 65 | class UThumbnailOptions* ThumbnailOptions; 66 | 67 | private: 68 | 69 | void AddToolbarExtension(FToolBarBuilder& Builder); 70 | void AddMenuExtension(FMenuBuilder& Builder); 71 | 72 | TSharedRef OnSpawnPluginTab(const class FSpawnTabArgs& SpawnTabArgs); 73 | 74 | private: 75 | TSharedPtr PluginCommands; 76 | }; -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Public/ThumbnailCreatorCommands.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Framework/Commands/Commands.h" 7 | #include "ThumbnailCreatorStyle.h" 8 | 9 | class FThumbnailCreatorCommands : public TCommands 10 | { 11 | public: 12 | 13 | FThumbnailCreatorCommands() 14 | : TCommands(TEXT("ThumbnailCreator"), NSLOCTEXT("Contexts", "ThumbnailCreator", "ThumbnailCreator Plugin"), NAME_None, FThumbnailCreatorStyle::GetStyleSetName()) 15 | { 16 | } 17 | 18 | // TCommands<> interface 19 | virtual void RegisterCommands() override; 20 | 21 | public: 22 | TSharedPtr< FUICommandInfo > OpenPluginWindow; 23 | }; -------------------------------------------------------------------------------- /Source/ThumbnailCreator/Public/ThumbnailCreatorStyle.h: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Styling/SlateStyle.h" 7 | 8 | /** */ 9 | class FThumbnailCreatorStyle 10 | { 11 | public: 12 | 13 | static void Initialize(); 14 | 15 | static void Shutdown(); 16 | 17 | /** reloads textures used by slate renderer */ 18 | static void ReloadTextures(); 19 | 20 | /** @return The Slate style set for the Shooter game */ 21 | static const ISlateStyle& Get(); 22 | 23 | static FName GetStyleSetName(); 24 | 25 | private: 26 | 27 | static TSharedRef< class FSlateStyleSet > Create(); 28 | 29 | private: 30 | 31 | static TSharedPtr< class FSlateStyleSet > StyleInstance; 32 | }; -------------------------------------------------------------------------------- /Source/ThumbnailCreator/ThumbnailCreator.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class ThumbnailCreator : ModuleRules 6 | { 7 | public ThumbnailCreator(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicIncludePaths.AddRange( 12 | new string[] { 13 | "ThumbnailCreator/Public" 14 | // ... add public include paths required here ... 15 | } 16 | ); 17 | 18 | 19 | PrivateIncludePaths.AddRange( 20 | new string[] { 21 | "ThumbnailCreator/Private", 22 | // ... add other private include paths required here ... 23 | } 24 | ); 25 | 26 | 27 | PublicDependencyModuleNames.AddRange( 28 | new string[] 29 | { 30 | "Core", 31 | "UnrealEd", 32 | "ImageWrapper", 33 | "AssetRegistry", 34 | "PropertyEditor", 35 | "AdvancedPreviewScene" 36 | // ... add other public dependencies that you statically link with here ... 37 | } 38 | ); 39 | 40 | 41 | PrivateDependencyModuleNames.AddRange( 42 | new string[] 43 | { 44 | "Projects", 45 | "InputCore", 46 | "UnrealEd", 47 | "LevelEditor", 48 | "CoreUObject", 49 | "Engine", 50 | "Slate", 51 | "SlateCore", 52 | "ImageWrapper", 53 | "AssetRegistry", 54 | "PropertyEditor", 55 | "AdvancedPreviewScene", 56 | "Paper2D" 57 | 58 | 59 | // ... add private dependencies that you statically link with here ... 60 | } 61 | ); 62 | 63 | 64 | DynamicallyLoadedModuleNames.AddRange( 65 | new string[] 66 | { 67 | // ... add any modules that your module loads dynamically here ... 68 | } 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ThumbnailCreator.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "ThumbnailCreator", 6 | "Description": "", 7 | "Category": "Other", 8 | "CreatedBy": "", 9 | "CreatedByURL": "", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": true, 14 | "IsBetaVersion": false, 15 | "Installed": false, 16 | "Modules": [ 17 | { 18 | "Name": "ThumbnailCreator", 19 | "Type": "Editor", 20 | "LoadingPhase": "PostEngineInit" 21 | } 22 | ] 23 | } --------------------------------------------------------------------------------