HAxis sos
This commit is contained in:
54
Plugins/PolishBuildings/Source/PolishBuildings.Build.cs
Normal file
54
Plugins/PolishBuildings/Source/PolishBuildings.Build.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class PolishBuildings : ModuleRules
|
||||
{
|
||||
public PolishBuildings(TargetInfo Target)
|
||||
{
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
"Private",
|
||||
"Private/PolishBuildingsTool",
|
||||
"Private/BuildingsProxyTool"
|
||||
}
|
||||
);
|
||||
|
||||
PrivateIncludePathModuleNames.AddRange(
|
||||
new string[] {
|
||||
"AssetRegistry",
|
||||
"ContentBrowser",
|
||||
"Documentation",
|
||||
"LevelEditor",
|
||||
"MeshUtilities",
|
||||
"PropertyEditor",
|
||||
"RawMesh",
|
||||
"WorkspaceMenuStructure"
|
||||
}
|
||||
);
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[] {
|
||||
"Core",
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"InputCore",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"EditorStyle",
|
||||
"UnrealEd",
|
||||
}
|
||||
);
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[] {
|
||||
"AssetRegistry",
|
||||
"ContentBrowser",
|
||||
"Documentation",
|
||||
"LevelEditor",
|
||||
"MeshUtilities",
|
||||
"PropertyEditor"
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "PolishBuildingsPrivatePCH.h"
|
||||
#include "BuildingsProxyTool.h"
|
||||
#include "SBuildingsProxyDialog.h"
|
||||
#include "MeshUtilities.h"
|
||||
#include "ContentBrowserModule.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "Engine/StaticMeshActor.h"
|
||||
#include "Engine/StaticMesh.h"
|
||||
#include "Engine/Selection.h"
|
||||
|
||||
|
||||
#define LOCTEXT_NAMESPACE "BuildingsProxyTool"
|
||||
|
||||
|
||||
TSharedRef<SWidget> FBuildingsProxyTool::GetWidget()
|
||||
{
|
||||
return SNew(SBuildingsProxyDialog, this);
|
||||
}
|
||||
|
||||
|
||||
FText FBuildingsProxyTool::GetTooltipText() const
|
||||
{
|
||||
return LOCTEXT("BuildingsProxyToolTooltip", "Harvest geometry from selected actors and merge them into single mesh.");
|
||||
}
|
||||
|
||||
|
||||
FString FBuildingsProxyTool::GetDefaultPackageName() const
|
||||
{
|
||||
FString PackageName;
|
||||
|
||||
USelection* SelectedActors = GEditor->GetSelectedActors();
|
||||
|
||||
// Iterate through selected actors and find first static mesh asset
|
||||
// Use this static mesh path as destination package name for a merged mesh
|
||||
for (FSelectionIterator Iter(*SelectedActors); Iter; ++Iter)
|
||||
{
|
||||
AActor* Actor = Cast<AActor>(*Iter);
|
||||
if (Actor)
|
||||
{
|
||||
TInlineComponentArray<UStaticMeshComponent*> SMComponets;
|
||||
Actor->GetComponents<UStaticMeshComponent>(SMComponets);
|
||||
for (UStaticMeshComponent* Component : SMComponets)
|
||||
{
|
||||
if (Component->StaticMesh)
|
||||
{
|
||||
PackageName = FPackageName::GetLongPackagePath(Component->StaticMesh->GetOutermost()->GetName());
|
||||
PackageName += FString(TEXT("/PROXY_")) + Component->StaticMesh->GetName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PackageName.IsEmpty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (PackageName.IsEmpty())
|
||||
{
|
||||
PackageName = FPackageName::FilenameToLongPackageName(FPaths::GameContentDir() + TEXT("PROXY"));
|
||||
PackageName = MakeUniqueObjectName(NULL, UPackage::StaticClass(), *PackageName).ToString();
|
||||
}
|
||||
|
||||
return PackageName;
|
||||
}
|
||||
|
||||
|
||||
bool FBuildingsProxyTool::RunMerge(const FString& PackageName)
|
||||
{
|
||||
TArray<AActor*> Actors;
|
||||
TArray<UObject*> AssetsToSync;
|
||||
|
||||
//Get the module for the proxy mesh utilities
|
||||
IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities");
|
||||
|
||||
USelection* SelectedActors = GEditor->GetSelectedActors();
|
||||
for (FSelectionIterator Iter(*SelectedActors); Iter; ++Iter)
|
||||
{
|
||||
AActor* Actor = Cast<AActor>(*Iter);
|
||||
if (Actor)
|
||||
{
|
||||
Actors.Add(Actor);
|
||||
}
|
||||
}
|
||||
|
||||
if (Actors.Num())
|
||||
{
|
||||
GWarn->BeginSlowTask(LOCTEXT("BuildingsProxy_CreatingProxy", "Creating Mesh Proxy"), true);
|
||||
GEditor->BeginTransaction(LOCTEXT("BuildingsProxy_Create", "Creating Mesh Proxy"));
|
||||
|
||||
FVector ProxyLocation = FVector::ZeroVector;
|
||||
|
||||
FCreateProxyDelegate ProxyDelegate;
|
||||
ProxyDelegate.BindLambda(
|
||||
[]( const FGuid Guid, TArray<UObject*>& InAssetsToSync )
|
||||
{
|
||||
//Update the asset registry that a new static mash and material has been created
|
||||
if ( InAssetsToSync.Num() )
|
||||
{
|
||||
FAssetRegistryModule& AssetRegistry = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>( "AssetRegistry" );
|
||||
int32 AssetCount = InAssetsToSync.Num();
|
||||
for ( int32 AssetIndex = 0; AssetIndex < AssetCount; AssetIndex++ )
|
||||
{
|
||||
AssetRegistry.AssetCreated( InAssetsToSync[AssetIndex] );
|
||||
GEditor->BroadcastObjectReimported( InAssetsToSync[AssetIndex] );
|
||||
}
|
||||
|
||||
//Also notify the content browser that the new assets exists
|
||||
FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>( "ContentBrowser" );
|
||||
ContentBrowserModule.Get().SyncBrowserToAssets( InAssetsToSync, true );
|
||||
}
|
||||
} );
|
||||
|
||||
FGuid JobGuid = FGuid::NewGuid();
|
||||
MeshUtilities.CreateProxyMesh( Actors, ProxySettings, NULL, PackageName, JobGuid, ProxyDelegate );
|
||||
|
||||
GEditor->EndTransaction();
|
||||
GWarn->EndSlowTask();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "IPolishBuildingsTool.h"
|
||||
|
||||
/**
|
||||
* Mesh Proxy Tool
|
||||
*/
|
||||
class FBuildingsProxyTool : public IPolishBuildingsTool
|
||||
{
|
||||
friend class SBuildingsProxyDialog;
|
||||
|
||||
public:
|
||||
|
||||
// IMergeActorsTool interface
|
||||
virtual TSharedRef<SWidget> GetWidget() override;
|
||||
virtual FName GetIconName() const override { return "PolishBuildings.BuildingsProxyTool"; }
|
||||
virtual FText GetTooltipText() const override;
|
||||
virtual FString GetDefaultPackageName() const override;
|
||||
virtual bool RunMerge(const FString& PackageName) override;
|
||||
|
||||
private:
|
||||
|
||||
FMeshProxySettings ProxySettings;
|
||||
};
|
||||
@@ -0,0 +1,614 @@
|
||||
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "PolishBuildingsPrivatePCH.h"
|
||||
#include "SBuildingsProxyDialog.h"
|
||||
#include "Dialogs/DlgPickAssetPath.h"
|
||||
#include "SNumericEntryBox.h"
|
||||
#include "STextComboBox.h"
|
||||
#include "BuildingsProxyTool/BuildingsProxyTool.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "SBuildingsProxyDialog"
|
||||
|
||||
|
||||
void SBuildingsProxyDialog::Construct(const FArguments& InArgs, FBuildingsProxyTool* InTool)
|
||||
{
|
||||
Tool = InTool;
|
||||
check(Tool != nullptr);
|
||||
|
||||
CuttingPlaneOptions.Add(MakeShareable(new FString(TEXT("+X"))));
|
||||
CuttingPlaneOptions.Add(MakeShareable(new FString(TEXT("+Y"))));
|
||||
CuttingPlaneOptions.Add(MakeShareable(new FString(TEXT("+Z"))));
|
||||
CuttingPlaneOptions.Add(MakeShareable(new FString(TEXT("-X"))));
|
||||
CuttingPlaneOptions.Add(MakeShareable(new FString(TEXT("-Y"))));
|
||||
CuttingPlaneOptions.Add(MakeShareable(new FString(TEXT("-Z"))));
|
||||
|
||||
TextureResolutionOptions.Add(MakeShareable(new FString(TEXT("64"))));
|
||||
TextureResolutionOptions.Add(MakeShareable(new FString(TEXT("128"))));
|
||||
TextureResolutionOptions.Add(MakeShareable(new FString(TEXT("256"))));
|
||||
TextureResolutionOptions.Add(MakeShareable(new FString(TEXT("512"))));
|
||||
TextureResolutionOptions.Add(MakeShareable(new FString(TEXT("1024"))));
|
||||
TextureResolutionOptions.Add(MakeShareable(new FString(TEXT("2048"))));
|
||||
|
||||
CreateLayout();
|
||||
}
|
||||
|
||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
void SBuildingsProxyDialog::CreateLayout()
|
||||
{
|
||||
int32 TextureResEntryIndex = FindTextureResolutionEntryIndex( Tool->ProxySettings.MaterialSettings.TextureSize.X );
|
||||
int32 LightMapResEntryIndex = FindTextureResolutionEntryIndex( Tool->ProxySettings.LightMapResolution );
|
||||
TextureResEntryIndex = FMath::Max( TextureResEntryIndex, 0 );
|
||||
LightMapResEntryIndex = FMath::Max( LightMapResEntryIndex, 0 );
|
||||
|
||||
this->ChildSlot
|
||||
[
|
||||
SNew(SVerticalBox)
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.HAlign(HAlign_Center)
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(10)
|
||||
[
|
||||
// Simplygon logo
|
||||
SNew(SImage)
|
||||
.Image(FEditorStyle::GetBrush("BuildingsProxy.SimplygonLogo"))
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
[
|
||||
SNew(SBorder)
|
||||
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
||||
[
|
||||
// Proxy options
|
||||
SNew(SVerticalBox)
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("OnScreenSizeLabel", "On Screen Size (pixels)"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.ToolTipText( GetPropertyToolTipText( GET_MEMBER_NAME_CHECKED( FMeshProxySettings, ScreenSize ) ) )
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.HAlign(HAlign_Left)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.HAlign(HAlign_Fill)
|
||||
.MinDesiredWidth(100.0f)
|
||||
.MaxDesiredWidth(100.0f)
|
||||
[
|
||||
SNew(SNumericEntryBox<int32>)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.MinValue(40)
|
||||
.MaxValue(1200)
|
||||
.MinSliderValue(40)
|
||||
.MaxSliderValue(1200)
|
||||
.AllowSpin(true)
|
||||
.Value(this, &SBuildingsProxyDialog::GetScreenSize)
|
||||
.OnValueChanged(this, &SBuildingsProxyDialog::ScreenSizeChanged)
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("MergeDistanceLabel", "Merge Distance (pixels)"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.ToolTipText( GetPropertyToolTipText( GET_MEMBER_NAME_CHECKED( FMeshProxySettings, MergeDistance ) ) )
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.HAlign(HAlign_Left)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.HAlign(HAlign_Fill)
|
||||
.MinDesiredWidth(100.0f)
|
||||
.MaxDesiredWidth(100.0f)
|
||||
[
|
||||
SNew(SNumericEntryBox<int32>)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.MinValue(0)
|
||||
.MaxValue(300)
|
||||
.MinSliderValue(0)
|
||||
.MaxSliderValue(300)
|
||||
.AllowSpin(true)
|
||||
.Value(this, &SBuildingsProxyDialog::GetMergeDistance)
|
||||
.OnValueChanged(this, &SBuildingsProxyDialog::MergeDistanceChanged)
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("TextureResolutionLabel", "Texture Resolution"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.HAlign(HAlign_Left)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextComboBox)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.OptionsSource(&TextureResolutionOptions)
|
||||
.InitiallySelectedItem( TextureResolutionOptions[TextureResEntryIndex] )
|
||||
.OnSelectionChanged(this, &SBuildingsProxyDialog::SetTextureResolution)
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew( SHorizontalBox )
|
||||
+ SHorizontalBox::Slot()
|
||||
.FillWidth( 0.5f )
|
||||
.VAlign( VAlign_Center )
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text( LOCTEXT( "LightMapResolutionLabel", "LightMap Resolution" ) )
|
||||
.Font( FEditorStyle::GetFontStyle( "StandardDialog.SmallFont" ) )
|
||||
.ToolTipText( GetPropertyToolTipText( GET_MEMBER_NAME_CHECKED( FMeshProxySettings, LightMapResolution ) ) )
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.FillWidth( 0.5f )
|
||||
.HAlign( HAlign_Left )
|
||||
.VAlign( VAlign_Center )
|
||||
[
|
||||
SNew( STextComboBox )
|
||||
.Font( FEditorStyle::GetFontStyle( "StandardDialog.SmallFont" ) )
|
||||
.OptionsSource( &TextureResolutionOptions )
|
||||
.InitiallySelectedItem( TextureResolutionOptions[LightMapResEntryIndex] )
|
||||
.OnSelectionChanged( this, &SBuildingsProxyDialog::SetLightMapResolution )
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(0.0, 0.0, 3.0, 0.0)
|
||||
[
|
||||
SNew( STextBlock )
|
||||
.Text( LOCTEXT( "HardAngleLabel", "Hard Edge Angle" ) )
|
||||
.Font( FEditorStyle::GetFontStyle( "StandardDialog.SmallFont" ) )
|
||||
.ToolTipText( GetPropertyToolTipText( GET_MEMBER_NAME_CHECKED( FMeshProxySettings, HardAngleThreshold ) ) )
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.HAlign(HAlign_Left)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.HAlign(HAlign_Fill)
|
||||
.MinDesiredWidth(100.0f)
|
||||
.MaxDesiredWidth(100.0f)
|
||||
[
|
||||
SNew(SNumericEntryBox<float>)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.MinValue(0.f)
|
||||
.MaxValue(180.f)
|
||||
.MinSliderValue(0.f)
|
||||
.MaxSliderValue(180.f)
|
||||
.AllowSpin(true)
|
||||
.Value(this, &SBuildingsProxyDialog::GetHardAngleThreshold)
|
||||
.OnValueChanged(this, &SBuildingsProxyDialog::HardAngleThresholdChanged)
|
||||
.IsEnabled(this, &SBuildingsProxyDialog::HardAngleThresholdEnabled)
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked( this, &SBuildingsProxyDialog::GetRecalculateNormals )
|
||||
.OnCheckStateChanged( this, &SBuildingsProxyDialog::SetRecalculateNormals )
|
||||
.Content()
|
||||
[
|
||||
SNew( STextBlock )
|
||||
.Text( LOCTEXT( "RecalcNormalsLabel", "Recalculate Normals" ) )
|
||||
.Font( FEditorStyle::GetFontStyle( "StandardDialog.SmallFont" ) )
|
||||
.ToolTipText( GetPropertyToolTipText( GET_MEMBER_NAME_CHECKED( FMeshProxySettings, bRecalculateNormals ) ) )
|
||||
]
|
||||
]
|
||||
|
||||
+ SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding( FEditorStyle::GetMargin( "StandardDialog.ContentPadding" ) )
|
||||
[
|
||||
SNew( SCheckBox )
|
||||
.Type( ESlateCheckBoxType::CheckBox )
|
||||
.IsChecked(this, &SBuildingsProxyDialog::GetUseClippingPlane)
|
||||
.OnCheckStateChanged(this, &SBuildingsProxyDialog::SetUseClippingPlane)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ClippingPlaneLabel", "Use Clipping Plane"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.VAlign(VAlign_Center)
|
||||
.FillWidth(0.5f)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
[
|
||||
SNew(SBox)
|
||||
.MinDesiredWidth(30)
|
||||
[
|
||||
SNullWidget::NullWidget
|
||||
]
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.HAlign(HAlign_Left)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.IsEnabled(this, &SBuildingsProxyDialog::UseClippingPlaneEnabled)
|
||||
.Text(LOCTEXT("ClippingAxisLabel", "Clipping Axis"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.ToolTipText( GetPropertyToolTipText( GET_MEMBER_NAME_CHECKED( FMeshProxySettings, AxisIndex ) ) )
|
||||
]
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.HAlign(HAlign_Left)
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(8.0, 0.0, 8.0, 0.0)
|
||||
[
|
||||
SNew(STextComboBox)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.OptionsSource(&CuttingPlaneOptions)
|
||||
.InitiallySelectedItem(CuttingPlaneOptions[0])
|
||||
.OnSelectionChanged(this, &SBuildingsProxyDialog::SetClippingAxis)
|
||||
.IsEnabled(this, &SBuildingsProxyDialog::UseClippingPlaneEnabled)
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(0.0, 0.0, 3.0, 0.0)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
[
|
||||
SNew(SBox)
|
||||
.MinDesiredWidth(30)
|
||||
[
|
||||
SNullWidget::NullWidget
|
||||
]
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.HAlign(HAlign_Left)
|
||||
.AutoWidth()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("PlaneLevelLabel", "Plane level"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.IsEnabled(this, &SBuildingsProxyDialog::UseClippingPlaneEnabled)
|
||||
.ToolTipText( GetPropertyToolTipText( GET_MEMBER_NAME_CHECKED( FMeshProxySettings, ClippingLevel ) ) )
|
||||
]
|
||||
]
|
||||
+SHorizontalBox::Slot()
|
||||
.FillWidth(0.5f)
|
||||
.HAlign(HAlign_Left)
|
||||
[
|
||||
SNew(SBox)
|
||||
.HAlign(HAlign_Fill)
|
||||
.MinDesiredWidth(100.0f)
|
||||
.MaxDesiredWidth(100.0f)
|
||||
[
|
||||
SNew(SNumericEntryBox<float>)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
.Value(this, &SBuildingsProxyDialog::GetClippingLevel)
|
||||
.OnValueChanged(this, &SBuildingsProxyDialog::ClippingLevelChanged)
|
||||
.IsEnabled(this, &SBuildingsProxyDialog::UseClippingPlaneEnabled)
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SBuildingsProxyDialog::GetExportNormalMap)
|
||||
.OnCheckStateChanged(this, &SBuildingsProxyDialog::SetExportNormalMap)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportNormalMapLabel", "Export Normal Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SBuildingsProxyDialog::GetExportMetallicMap)
|
||||
.OnCheckStateChanged(this, &SBuildingsProxyDialog::SetExportMetallicMap)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportMetallicMapLabel", "Export Metallic Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SBuildingsProxyDialog::GetExportRoughnessMap)
|
||||
.OnCheckStateChanged(this, &SBuildingsProxyDialog::SetExportRoughnessMap)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportRoughnessMapLabel", "Export Roughness Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SBuildingsProxyDialog::GetExportSpecularMap)
|
||||
.OnCheckStateChanged(this, &SBuildingsProxyDialog::SetExportSpecularMap)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportSpecularMapLabel", "Export Specular Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
||||
int32 SBuildingsProxyDialog::FindTextureResolutionEntryIndex( int32 InResolution ) const
|
||||
{
|
||||
FString ResolutionStr = TTypeToString<int32>::ToString( InResolution );
|
||||
|
||||
int32 Result = TextureResolutionOptions.IndexOfByPredicate( [&]( const TSharedPtr<FString>& Entry )
|
||||
{
|
||||
return ( ResolutionStr == *Entry );
|
||||
} );
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
FText SBuildingsProxyDialog::GetPropertyToolTipText( const FName& PropertyName ) const
|
||||
{
|
||||
UProperty* Property = FMeshProxySettings::StaticStruct()->FindPropertyByName( PropertyName );
|
||||
if ( Property )
|
||||
{
|
||||
return Property->GetToolTipText();
|
||||
}
|
||||
|
||||
return FText::GetEmpty();
|
||||
}
|
||||
|
||||
//Screen size
|
||||
TOptional<int32> SBuildingsProxyDialog::GetScreenSize() const
|
||||
{
|
||||
return Tool->ProxySettings.ScreenSize;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::ScreenSizeChanged(int32 NewValue)
|
||||
{
|
||||
Tool->ProxySettings.ScreenSize = NewValue;
|
||||
}
|
||||
|
||||
//Recalculate normals
|
||||
ECheckBoxState SBuildingsProxyDialog::GetRecalculateNormals() const
|
||||
{
|
||||
return Tool->ProxySettings.bRecalculateNormals ? ECheckBoxState::Checked: ECheckBoxState::Unchecked;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetRecalculateNormals(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->ProxySettings.bRecalculateNormals = (NewValue == ECheckBoxState::Checked);
|
||||
}
|
||||
|
||||
//Hard Angle Threshold
|
||||
bool SBuildingsProxyDialog::HardAngleThresholdEnabled() const
|
||||
{
|
||||
if(Tool->ProxySettings.bRecalculateNormals)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
TOptional<float> SBuildingsProxyDialog::GetHardAngleThreshold() const
|
||||
{
|
||||
return Tool->ProxySettings.HardAngleThreshold;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::HardAngleThresholdChanged(float NewValue)
|
||||
{
|
||||
Tool->ProxySettings.HardAngleThreshold = NewValue;
|
||||
}
|
||||
|
||||
//Merge Distance
|
||||
TOptional<int32> SBuildingsProxyDialog::GetMergeDistance() const
|
||||
{
|
||||
return Tool->ProxySettings.MergeDistance;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::MergeDistanceChanged(int32 NewValue)
|
||||
{
|
||||
Tool->ProxySettings.MergeDistance = NewValue;
|
||||
}
|
||||
|
||||
//Clipping Plane
|
||||
ECheckBoxState SBuildingsProxyDialog::GetUseClippingPlane() const
|
||||
{
|
||||
return Tool->ProxySettings.bUseClippingPlane ? ECheckBoxState::Checked: ECheckBoxState::Unchecked;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetUseClippingPlane(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->ProxySettings.bUseClippingPlane = (NewValue == ECheckBoxState::Checked);
|
||||
}
|
||||
|
||||
bool SBuildingsProxyDialog::UseClippingPlaneEnabled() const
|
||||
{
|
||||
if(Tool->ProxySettings.bUseClippingPlane)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetClippingAxis(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo )
|
||||
{
|
||||
//This is a ugly hack, but it solves the problem for now
|
||||
int32 AxisIndex = CuttingPlaneOptions.Find(NewSelection);
|
||||
//FMessageDialog::Debugf(*FString::Printf(TEXT("%d"), AxisIndex ));
|
||||
if(AxisIndex < 3)
|
||||
{
|
||||
Tool->ProxySettings.bPlaneNegativeHalfspace = false;
|
||||
Tool->ProxySettings.AxisIndex = AxisIndex;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Tool->ProxySettings.bPlaneNegativeHalfspace = true;
|
||||
Tool->ProxySettings.AxisIndex = AxisIndex - 3;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
TOptional<float> SBuildingsProxyDialog::GetClippingLevel() const
|
||||
{
|
||||
return Tool->ProxySettings.ClippingLevel;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::ClippingLevelChanged(float NewValue)
|
||||
{
|
||||
Tool->ProxySettings.ClippingLevel = NewValue;
|
||||
}
|
||||
|
||||
//Texture Resolution
|
||||
void SBuildingsProxyDialog::SetTextureResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
|
||||
{
|
||||
int32 Resolution = 512;
|
||||
TTypeFromString<int32>::FromString(Resolution, **NewSelection);
|
||||
FIntPoint TextureSize(Resolution, Resolution);
|
||||
|
||||
Tool->ProxySettings.MaterialSettings.TextureSize = TextureSize;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetLightMapResolution( TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo )
|
||||
{
|
||||
int32 Resolution = 256;
|
||||
TTypeFromString<int32>::FromString( Resolution, **NewSelection );
|
||||
|
||||
Tool->ProxySettings.LightMapResolution = Resolution;
|
||||
}
|
||||
|
||||
ECheckBoxState SBuildingsProxyDialog::GetExportNormalMap() const
|
||||
{
|
||||
return Tool->ProxySettings.MaterialSettings.bNormalMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetExportNormalMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->ProxySettings.MaterialSettings.bNormalMap = ( NewValue == ECheckBoxState::Checked );
|
||||
}
|
||||
|
||||
ECheckBoxState SBuildingsProxyDialog::GetExportMetallicMap() const
|
||||
{
|
||||
return Tool->ProxySettings.MaterialSettings.bMetallicMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetExportMetallicMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->ProxySettings.MaterialSettings.bMetallicMap = ( NewValue == ECheckBoxState::Checked );
|
||||
}
|
||||
|
||||
ECheckBoxState SBuildingsProxyDialog::GetExportRoughnessMap() const
|
||||
{
|
||||
return Tool->ProxySettings.MaterialSettings.bRoughnessMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetExportRoughnessMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->ProxySettings.MaterialSettings.bRoughnessMap = ( NewValue == ECheckBoxState::Checked );
|
||||
}
|
||||
|
||||
ECheckBoxState SBuildingsProxyDialog::GetExportSpecularMap() const
|
||||
{
|
||||
return Tool->ProxySettings.MaterialSettings.bSpecularMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
|
||||
}
|
||||
|
||||
void SBuildingsProxyDialog::SetExportSpecularMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->ProxySettings.MaterialSettings.bSpecularMap = ( NewValue == ECheckBoxState::Checked );
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
class FBuildingsProxyTool;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
SBuildingsProxyDialog
|
||||
-----------------------------------------------------------------------------*/
|
||||
class SBuildingsProxyDialog : public SCompoundWidget
|
||||
{
|
||||
public:
|
||||
SLATE_BEGIN_ARGS(SBuildingsProxyDialog)
|
||||
{
|
||||
}
|
||||
SLATE_END_ARGS()
|
||||
|
||||
public:
|
||||
/** SWidget functions */
|
||||
void Construct(const FArguments& InArgs, FBuildingsProxyTool* InTool);
|
||||
|
||||
protected:
|
||||
/** ScreenSize accessors */
|
||||
TOptional<int32> GetScreenSize() const;
|
||||
void ScreenSizeChanged(int32 NewValue); //used with editable text block (Simplygon)
|
||||
|
||||
/** Recalculate Normals accessors */
|
||||
ECheckBoxState GetRecalculateNormals() const;
|
||||
void SetRecalculateNormals(ECheckBoxState NewValue);
|
||||
|
||||
/** Hard Angle Threshold accessors */
|
||||
TOptional<float> GetHardAngleThreshold() const;
|
||||
bool HardAngleThresholdEnabled() const;
|
||||
void HardAngleThresholdChanged(float NewValue);
|
||||
|
||||
/** Hole filling accessors */
|
||||
TOptional<int32> GetMergeDistance() const;
|
||||
void MergeDistanceChanged(int32 NewValue);
|
||||
|
||||
/** Clipping Plane accessors */
|
||||
ECheckBoxState GetUseClippingPlane() const;
|
||||
void SetUseClippingPlane(ECheckBoxState NewValue);
|
||||
bool UseClippingPlaneEnabled() const;
|
||||
void SetClippingAxis(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo);
|
||||
TOptional<float> GetClippingLevel() const;
|
||||
void ClippingLevelChanged(float NewValue);
|
||||
|
||||
/** TextureResolution accessors */
|
||||
void SetTextureResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo);
|
||||
void SetLightMapResolution( TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo );
|
||||
|
||||
/** Export material properties acessors **/
|
||||
ECheckBoxState GetExportNormalMap() const;
|
||||
void SetExportNormalMap(ECheckBoxState NewValue);
|
||||
ECheckBoxState GetExportMetallicMap() const;
|
||||
void SetExportMetallicMap(ECheckBoxState NewValue);
|
||||
ECheckBoxState GetExportRoughnessMap() const;
|
||||
void SetExportRoughnessMap(ECheckBoxState NewValue);
|
||||
ECheckBoxState GetExportSpecularMap() const;
|
||||
void SetExportSpecularMap(ECheckBoxState NewValue);
|
||||
|
||||
private:
|
||||
/** Creates the geometry mode controls */
|
||||
void CreateLayout();
|
||||
|
||||
int32 FindTextureResolutionEntryIndex( int32 InResolution ) const;
|
||||
FText GetPropertyToolTipText( const FName& PropertyName ) const;
|
||||
|
||||
private:
|
||||
FBuildingsProxyTool* Tool;
|
||||
|
||||
TArray< TSharedPtr<FString> > CuttingPlaneOptions;
|
||||
TArray< TSharedPtr<FString> > TextureResolutionOptions;
|
||||
};
|
||||
|
||||
162
Plugins/PolishBuildings/Source/Private/PolishBuildingsModule.cpp
Normal file
162
Plugins/PolishBuildings/Source/Private/PolishBuildingsModule.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "PolishBuildingsPrivatePCH.h"
|
||||
#include "SPolishBuildingsToolbar.h"
|
||||
#include "ModuleManager.h"
|
||||
#include "WorkspaceMenuStructureModule.h"
|
||||
#include "PolishBuildingsTool.h"
|
||||
#include "BuildingsProxyTool.h"
|
||||
#include "SDockTab.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "PolishBuildingsModule"
|
||||
|
||||
|
||||
static const FName PolishBuildingsTabName = FName("PolishBuildings");
|
||||
|
||||
/**
|
||||
* Merge Actors module
|
||||
*/
|
||||
class FPolishBuildingsModule : public IPolishBuildingsModule
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Called right after the module DLL has been loaded and the module object has been created
|
||||
*/
|
||||
virtual void StartupModule() override;
|
||||
|
||||
/**
|
||||
* Called before the module is unloaded, right before the module object is destroyed.
|
||||
*/
|
||||
virtual void ShutdownModule() override;
|
||||
|
||||
/**
|
||||
* Register an IPolishBuildingsTool with the module, passing ownership to it
|
||||
*/
|
||||
virtual bool RegisterPolishBuildingsTool(TUniquePtr<IPolishBuildingsTool> Tool) override;
|
||||
|
||||
/**
|
||||
* Unregister an IPolishBuildingsTool with the module
|
||||
*/
|
||||
virtual bool UnregisterPolishBuildingsTool(IPolishBuildingsTool* Tool) override;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** Creates the dock tab widget used by the tab manager */
|
||||
TSharedRef<SDockTab> CreatePolishBuildingsTab(const FSpawnTabArgs& Args);
|
||||
|
||||
private:
|
||||
|
||||
/** Pointer to the toolbar widget */
|
||||
TWeakPtr<SPolishBuildingsToolbar> PolishBuildingsToolbarPtr;
|
||||
|
||||
/** List of registered PolishBuildingsTool instances */
|
||||
TArray<TUniquePtr<IPolishBuildingsTool>> PolishBuildingsTools;
|
||||
};
|
||||
|
||||
IMPLEMENT_MODULE(FPolishBuildingsModule, PolishBuildings);
|
||||
|
||||
|
||||
TSharedRef<SDockTab> FPolishBuildingsModule::CreatePolishBuildingsTab(const FSpawnTabArgs& Args)
|
||||
{
|
||||
// Build array of PolishBuildingsTool raw pointers
|
||||
TArray<IPolishBuildingsTool*> ToolsToRegister;
|
||||
for (const auto& MergeActorTool : PolishBuildingsTools)
|
||||
{
|
||||
check(MergeActorTool.Get() != nullptr);
|
||||
ToolsToRegister.Add(MergeActorTool.Get());
|
||||
}
|
||||
|
||||
// Construct toolbar widget
|
||||
TSharedRef<SPolishBuildingsToolbar> PolishBuildingsToolbar =
|
||||
SNew(SPolishBuildingsToolbar)
|
||||
.ToolsToRegister(ToolsToRegister);
|
||||
|
||||
// Construct dock tab
|
||||
TSharedRef<SDockTab> DockTab =
|
||||
SNew(SDockTab)
|
||||
.TabRole(ETabRole::NomadTab)
|
||||
[
|
||||
PolishBuildingsToolbar
|
||||
];
|
||||
|
||||
// Keep weak pointer to toolbar widget
|
||||
PolishBuildingsToolbarPtr = PolishBuildingsToolbar;
|
||||
|
||||
return DockTab;
|
||||
}
|
||||
|
||||
|
||||
void FPolishBuildingsModule::StartupModule()
|
||||
{
|
||||
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(PolishBuildingsTabName, FOnSpawnTab::CreateRaw(this, &FPolishBuildingsModule::CreatePolishBuildingsTab))
|
||||
.SetDisplayName(LOCTEXT("TabTitle", "Polish Buildings"))
|
||||
.SetTooltipText(LOCTEXT("TooltipText", "Open the Polish Buildings tab."))
|
||||
.SetGroup(WorkspaceMenu::GetMenuStructure().GetLevelEditorCategory())
|
||||
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "ClassViewer.TabIcon"));
|
||||
// This is still experimental in the editor, so it's added specifically in FMainMenu for now.
|
||||
// When no longer experimental, remove the below.
|
||||
//.SetAutoGenerateMenuEntry(false);
|
||||
|
||||
// Register built-in merging tools straight away
|
||||
ensure(RegisterPolishBuildingsTool(MakeUnique<FPolishBuildingsTool>()));
|
||||
|
||||
IMeshUtilities* MeshUtilities = FModuleManager::Get().LoadModulePtr<IMeshUtilities>("MeshUtilities");
|
||||
if (MeshUtilities != nullptr && MeshUtilities->GetMeshMergingInterface() != nullptr)
|
||||
{
|
||||
// Only register BuildingsProxyTool if Simplygon is available
|
||||
ensure(RegisterPolishBuildingsTool(MakeUnique<FBuildingsProxyTool>()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FPolishBuildingsModule::ShutdownModule()
|
||||
{
|
||||
if (FSlateApplication::IsInitialized())
|
||||
{
|
||||
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(PolishBuildingsTabName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool FPolishBuildingsModule::RegisterPolishBuildingsTool(TUniquePtr<IPolishBuildingsTool> Tool)
|
||||
{
|
||||
if (Tool.Get() != nullptr && !PolishBuildingsTools.Contains(MoveTemp(Tool)))
|
||||
{
|
||||
PolishBuildingsTools.Add(MoveTemp(Tool));
|
||||
|
||||
// If a tool is added while the toolbar widget is active, update it accordingly
|
||||
TSharedPtr<SPolishBuildingsToolbar> PolishBuildingsToolbar = PolishBuildingsToolbarPtr.Pin();
|
||||
if (PolishBuildingsToolbar.IsValid())
|
||||
{
|
||||
PolishBuildingsToolbar->AddTool(Tool.Get());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool FPolishBuildingsModule::UnregisterPolishBuildingsTool(IPolishBuildingsTool* Tool)
|
||||
{
|
||||
if (Tool != nullptr)
|
||||
{
|
||||
if (PolishBuildingsTools.RemoveAll([=](const TUniquePtr<IPolishBuildingsTool>& Ptr) { return Ptr.Get() == Tool; }) > 0)
|
||||
{
|
||||
TSharedPtr<SPolishBuildingsToolbar> PolishBuildingsToolbar = PolishBuildingsToolbarPtr.Pin();
|
||||
if (PolishBuildingsToolbar.IsValid())
|
||||
{
|
||||
PolishBuildingsToolbar->RemoveTool(Tool);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "UnrealEd.h"
|
||||
#include "IPolishBuildingsModule.h"
|
||||
@@ -0,0 +1,149 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "PolishBuildingsPrivatePCH.h"
|
||||
#include "PolishBuildingsTool.h"
|
||||
#include "SPolishBuildingsDialog.h"
|
||||
#include "PropertyEditorModule.h"
|
||||
#include "Engine/TextureLODSettings.h"
|
||||
#include "RawMesh.h"
|
||||
#include "Engine/StaticMeshActor.h"
|
||||
#include "Engine/StaticMesh.h"
|
||||
#include "Engine/Selection.h"
|
||||
#include "SystemSettings.h"
|
||||
#include "Engine/TextureLODSettings.h"
|
||||
#include "ContentBrowserModule.h"
|
||||
#include "AssetRegistryModule.h"
|
||||
#include "ScopedTransaction.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "PolishBuildingsTool"
|
||||
|
||||
|
||||
FPolishBuildingsTool::FPolishBuildingsTool()
|
||||
: bReplaceSourceActors(false)
|
||||
, bExportSpecificLOD(false)
|
||||
, ExportLODIndex(0)
|
||||
{}
|
||||
|
||||
|
||||
TSharedRef<SWidget> FPolishBuildingsTool::GetWidget()
|
||||
{
|
||||
return SNew(SPolishBuildingsDialog, this);
|
||||
}
|
||||
|
||||
|
||||
FText FPolishBuildingsTool::GetTooltipText() const
|
||||
{
|
||||
return LOCTEXT("PolishBuildingsToolTooltip", "Harvest geometry from selected actors and merge grouping them by materials.");
|
||||
}
|
||||
|
||||
|
||||
FString FPolishBuildingsTool::GetDefaultPackageName() const
|
||||
{
|
||||
FString PackageName = FPackageName::FilenameToLongPackageName(FPaths::GameContentDir() + TEXT("SM_MERGED"));
|
||||
|
||||
USelection* SelectedActors = GEditor->GetSelectedActors();
|
||||
// Iterate through selected actors and find first static mesh asset
|
||||
// Use this static mesh path as destination package name for a merged mesh
|
||||
for (FSelectionIterator Iter(*SelectedActors); Iter; ++Iter)
|
||||
{
|
||||
AActor* Actor = Cast<AActor>(*Iter);
|
||||
if (Actor)
|
||||
{
|
||||
FString ActorName = Actor->GetName();
|
||||
PackageName = FString::Printf(TEXT("%s_%s"), *PackageName, *ActorName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (PackageName.IsEmpty())
|
||||
{
|
||||
PackageName = MakeUniqueObjectName(NULL, UPackage::StaticClass(), *PackageName).ToString();
|
||||
}
|
||||
|
||||
return PackageName;
|
||||
}
|
||||
|
||||
|
||||
bool FPolishBuildingsTool::RunMerge(const FString& PackageName)
|
||||
{
|
||||
IMeshUtilities& MeshUtilities = FModuleManager::Get().LoadModuleChecked<IMeshUtilities>("MeshUtilities");
|
||||
USelection* SelectedActors = GEditor->GetSelectedActors();
|
||||
TArray<AActor*> Actors;
|
||||
TArray<ULevel*> UniqueLevels;
|
||||
for (FSelectionIterator Iter(*SelectedActors); Iter; ++Iter)
|
||||
{
|
||||
AActor* Actor = Cast<AActor>(*Iter);
|
||||
if (Actor)
|
||||
{
|
||||
Actors.Add(Actor);
|
||||
UniqueLevels.AddUnique(Actor->GetLevel());
|
||||
}
|
||||
}
|
||||
|
||||
// This restriction is only for replacement of selected actors with merged mesh actor
|
||||
if (UniqueLevels.Num() > 1 && bReplaceSourceActors)
|
||||
{
|
||||
FText Message = NSLOCTEXT("UnrealEd", "FailedToPolishBuildingsSublevels_Msg", "The selected actors should be in the same level");
|
||||
OpenMsgDlgInt(EAppMsgType::Ok, Message, NSLOCTEXT("UnrealEd", "FailedToPolishBuildings_Title", "Unable to merge actors"));
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 TargetMeshLOD = bExportSpecificLOD ? ExportLODIndex : INDEX_NONE;
|
||||
FVector MergedActorLocation;
|
||||
TArray<UObject*> AssetsToSync;
|
||||
// Merge...
|
||||
{
|
||||
FScopedSlowTask SlowTask(0, LOCTEXT("MergingActorsSlowTask", "Merging actors..."));
|
||||
SlowTask.MakeDialog();
|
||||
|
||||
MeshUtilities.MergeActors(Actors, MergingSettings, NULL, PackageName, TargetMeshLOD, AssetsToSync, MergedActorLocation);
|
||||
}
|
||||
|
||||
if (AssetsToSync.Num())
|
||||
{
|
||||
FAssetRegistryModule& AssetRegistry = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
|
||||
int32 AssetCount = AssetsToSync.Num();
|
||||
for (int32 AssetIndex = 0; AssetIndex < AssetCount; AssetIndex++)
|
||||
{
|
||||
AssetRegistry.AssetCreated(AssetsToSync[AssetIndex]);
|
||||
GEditor->BroadcastObjectReimported(AssetsToSync[AssetIndex]);
|
||||
}
|
||||
|
||||
//Also notify the content browser that the new assets exists
|
||||
FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
|
||||
ContentBrowserModule.Get().SyncBrowserToAssets(AssetsToSync, true);
|
||||
|
||||
// Place new mesh in the world
|
||||
if (bReplaceSourceActors)
|
||||
{
|
||||
UStaticMesh* MergedMesh = nullptr;
|
||||
if (AssetsToSync.FindItemByClass(&MergedMesh))
|
||||
{
|
||||
const FScopedTransaction Transaction(LOCTEXT("PlaceMergedActor", "Place Merged Actor"));
|
||||
UniqueLevels[0]->Modify();
|
||||
|
||||
UWorld* World = UniqueLevels[0]->OwningWorld;
|
||||
FActorSpawnParameters Params;
|
||||
Params.OverrideLevel = UniqueLevels[0];
|
||||
FRotator MergedActorRotation(ForceInit);
|
||||
|
||||
AStaticMeshActor* MergedActor = World->SpawnActor<AStaticMeshActor>(MergedActorLocation, MergedActorRotation, Params);
|
||||
MergedActor->GetStaticMeshComponent()->StaticMesh = MergedMesh;
|
||||
MergedActor->SetActorLabel(AssetsToSync[0]->GetName());
|
||||
|
||||
// Remove source actors
|
||||
/*
|
||||
for (AActor* Actor : Actors)
|
||||
{
|
||||
Actor->Destroy();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "IPolishBuildingsTool.h"
|
||||
#include "MeshUtilities.h"
|
||||
|
||||
/**
|
||||
* Mesh Merging Tool
|
||||
*/
|
||||
class FPolishBuildingsTool : public IPolishBuildingsTool
|
||||
{
|
||||
friend class SPolishBuildingsDialog;
|
||||
|
||||
public:
|
||||
|
||||
FPolishBuildingsTool();
|
||||
|
||||
// IPolishBuildingsTool interface
|
||||
virtual TSharedRef<SWidget> GetWidget() override;
|
||||
virtual FName GetIconName() const override { return "PolishBuildings.PolishBuildingsTool"; }
|
||||
virtual FText GetTooltipText() const override;
|
||||
virtual FString GetDefaultPackageName() const override;
|
||||
virtual bool RunMerge(const FString& PackageName) override;
|
||||
|
||||
private:
|
||||
|
||||
/** Current mesh merging settings */
|
||||
FMeshMergingSettings MergingSettings;
|
||||
|
||||
/** Whether to replace source actors with a merged actor in the world */
|
||||
bool bReplaceSourceActors;
|
||||
|
||||
bool bExportSpecificLOD;
|
||||
int32 ExportLODIndex;
|
||||
};
|
||||
@@ -0,0 +1,520 @@
|
||||
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "PolishBuildingsPrivatePCH.h"
|
||||
#include "SPolishBuildingsDialog.h"
|
||||
#include "Dialogs/DlgPickAssetPath.h"
|
||||
#include "STextComboBox.h"
|
||||
#include "RawMesh.h"
|
||||
#include "PolishBuildingsTool/PolishBuildingsTool.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "SPolishBuildingsDialog"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SPolishBuildingsDialog
|
||||
|
||||
SPolishBuildingsDialog::SPolishBuildingsDialog()
|
||||
{
|
||||
}
|
||||
|
||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
void SPolishBuildingsDialog::Construct(const FArguments& InArgs, FPolishBuildingsTool* InTool)
|
||||
{
|
||||
Tool = InTool;
|
||||
check(Tool != nullptr);
|
||||
|
||||
// Setup available resolutions for lightmap and merged materials
|
||||
const int32 MinTexResolution = 1 << FTextureLODGroup().MinLODMipCount;
|
||||
const int32 MaxTexResolution = 1 << FTextureLODGroup().MaxLODMipCount;
|
||||
for (int32 TexRes = MinTexResolution; TexRes <= MaxTexResolution; TexRes*=2)
|
||||
{
|
||||
LightMapResolutionOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(TexRes))));
|
||||
MergedMaterialResolutionOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(TexRes))));
|
||||
}
|
||||
|
||||
Tool->MergingSettings.TargetLightMapResolution = FMath::Clamp(Tool->MergingSettings.TargetLightMapResolution, MinTexResolution, MaxTexResolution);
|
||||
Tool->MergingSettings.MaterialSettings.TextureSize.X = FMath::Clamp( Tool->MergingSettings.MaterialSettings.TextureSize.X, MinTexResolution, MaxTexResolution );
|
||||
Tool->MergingSettings.MaterialSettings.TextureSize.Y = FMath::Clamp( Tool->MergingSettings.MaterialSettings.TextureSize.Y, MinTexResolution, MaxTexResolution );
|
||||
|
||||
// Setup available UV channels for an atlased lightmap
|
||||
for (int32 Index = 0; Index < MAX_MESH_TEXTURE_COORDS; Index++)
|
||||
{
|
||||
LightMapChannelOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(Index))));
|
||||
}
|
||||
|
||||
for (int32 Index = 0; Index < MAX_STATIC_MESH_LODS; Index++)
|
||||
{
|
||||
ExportLODOptions.Add(MakeShareable(new FString(TTypeToString<int32>::ToString(Index))));
|
||||
}
|
||||
|
||||
// Create widget layout
|
||||
this->ChildSlot
|
||||
[
|
||||
SNew(SVerticalBox)
|
||||
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(0,2,0,0)
|
||||
[
|
||||
// Lightmap settings
|
||||
SNew(SBorder)
|
||||
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
||||
[
|
||||
SNew(SVerticalBox)
|
||||
|
||||
// Enable atlasing
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetGenerateLightmapUV)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetGenerateLightmapUV)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("AtlasLightmapUVLabel", "Generate Lightmap UVs"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
// Target lightmap channel / Max lightmap resolution
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsLightmapChannelEnabled)
|
||||
.Text(LOCTEXT("TargetLightMapChannelLabel", "Target Channel:"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(4,0,4,0)
|
||||
[
|
||||
SNew(STextComboBox)
|
||||
.IsEnabled( this, &SPolishBuildingsDialog::IsLightmapChannelEnabled )
|
||||
.OptionsSource(&LightMapChannelOptions)
|
||||
.InitiallySelectedItem(LightMapChannelOptions[Tool->MergingSettings.TargetLightMapUVChannel])
|
||||
.OnSelectionChanged(this, &SPolishBuildingsDialog::SetTargetLightMapChannel)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsLightmapChannelEnabled)
|
||||
.Text(LOCTEXT("TargetLightMapResolutionLabel", "Target Resolution:"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(4,0,4,0)
|
||||
[
|
||||
SNew(STextComboBox)
|
||||
.IsEnabled( this, &SPolishBuildingsDialog::IsLightmapChannelEnabled )
|
||||
.OptionsSource(&LightMapResolutionOptions)
|
||||
.InitiallySelectedItem(LightMapResolutionOptions[FMath::FloorLog2(Tool->MergingSettings.TargetLightMapResolution)])
|
||||
.OnSelectionChanged(this, &SPolishBuildingsDialog::SetTargetLightMapResolution)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
// Other merging settings
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(0,2,0,0)
|
||||
[
|
||||
SNew(SBorder)
|
||||
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
||||
[
|
||||
SNew(SVerticalBox)
|
||||
|
||||
// LOD to export
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetExportSpecificLODEnabled)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportSpecificLODEnabled)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsExportSpecificLODEnabled)
|
||||
.Text(LOCTEXT("TargetMeshLODIndexLabel", "Export specific LOD:"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(4,0,4,0)
|
||||
[
|
||||
SNew(STextComboBox)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsExportSpecificLODEnabled)
|
||||
.OptionsSource(&ExportLODOptions)
|
||||
.InitiallySelectedItem(ExportLODOptions[Tool->ExportLODIndex])
|
||||
.OnSelectionChanged(this, &SPolishBuildingsDialog::SetExportSpecificLODIndex)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
// Vertex colors
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetImportVertexColors)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetImportVertexColors)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ImportVertexColorsLabel", "Import Vertex Colors"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
// Pivot at zero
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetPivotPointAtZero)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetPivotPointAtZero)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("PivotPointAtZeroLabel", "Pivot Point At (0,0,0)"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
// Replace source actors
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetReplaceSourceActors)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetReplaceSourceActors)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ReplaceSourceActorsLabel", "Replace Source Actors"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
// Merge physics data
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetMergePhyisicData)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetMergePhyisicData)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("MergePhysicsDataLabel", "Merge Physics Data"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
// Merge materials
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetMergeMaterials)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetMergeMaterials)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("MergeMaterialsLabel", "Merge Materials"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
// Export normal map
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetExportNormalMap)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportNormalMap)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportNormalMapLabel", "Export Normal Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
// Export metallic map
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetExportMetallicMap)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportMetallicMap)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportMetallicMapLabel", "Export Metallic Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
// Export roughness map
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetExportRoughnessMap)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportRoughnessMap)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportRoughnessMapLabel", "Export Roughness Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
// Export specular map
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Type(ESlateCheckBoxType::CheckBox)
|
||||
.IsChecked(this, &SPolishBuildingsDialog::GetExportSpecularMap)
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsDialog::SetExportSpecularMap)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
|
||||
.Content()
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(LOCTEXT("ExportSpecularMapLabel", "Export Specular Map"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
|
||||
// Merged texture size
|
||||
+SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.Padding(FEditorStyle::GetMargin("StandardDialog.ContentPadding"))
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
|
||||
.Text(LOCTEXT("MergedMaterialAtlasResolutionLabel", "Merged Material Atlas Resolution:"))
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
|
||||
+SHorizontalBox::Slot()
|
||||
.AutoWidth()
|
||||
.VAlign(VAlign_Center)
|
||||
.Padding(4,0,4,0)
|
||||
[
|
||||
SNew(STextComboBox)
|
||||
.IsEnabled(this, &SPolishBuildingsDialog::IsMaterialMergingEnabled)
|
||||
.OptionsSource(&MergedMaterialResolutionOptions)
|
||||
.InitiallySelectedItem( MergedMaterialResolutionOptions[FMath::FloorLog2( Tool->MergingSettings.MaterialSettings.TextureSize.X )] )
|
||||
.OnSelectionChanged(this, &SPolishBuildingsDialog::SetMergedMaterialAtlasResolution)
|
||||
.Font(FEditorStyle::GetFontStyle("StandardDialog.SmallFont"))
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetGenerateLightmapUV() const
|
||||
{
|
||||
return (Tool->MergingSettings.bGenerateLightMapUV ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetGenerateLightmapUV(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.bGenerateLightMapUV = (ECheckBoxState::Checked == NewValue);
|
||||
}
|
||||
|
||||
bool SPolishBuildingsDialog::IsLightmapChannelEnabled() const
|
||||
{
|
||||
return Tool->MergingSettings.bGenerateLightMapUV;
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetTargetLightMapChannel(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
|
||||
{
|
||||
TTypeFromString<int32>::FromString(Tool->MergingSettings.TargetLightMapUVChannel, **NewSelection);
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetTargetLightMapResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
|
||||
{
|
||||
TTypeFromString<int32>::FromString(Tool->MergingSettings.TargetLightMapResolution, **NewSelection);
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetExportSpecificLODEnabled() const
|
||||
{
|
||||
return (Tool->bExportSpecificLOD ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetExportSpecificLODEnabled(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->bExportSpecificLOD = (NewValue == ECheckBoxState::Checked);
|
||||
}
|
||||
|
||||
bool SPolishBuildingsDialog::IsExportSpecificLODEnabled() const
|
||||
{
|
||||
return Tool->bExportSpecificLOD;
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetExportSpecificLODIndex(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
|
||||
{
|
||||
TTypeFromString<int32>::FromString(Tool->ExportLODIndex, **NewSelection);
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetImportVertexColors() const
|
||||
{
|
||||
return ( Tool->MergingSettings.bBakeVertexData ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetImportVertexColors(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.bBakeVertexData = ( ECheckBoxState::Checked == NewValue );
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetPivotPointAtZero() const
|
||||
{
|
||||
return (Tool->MergingSettings.bPivotPointAtZero ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetPivotPointAtZero(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.bPivotPointAtZero = (ECheckBoxState::Checked == NewValue);
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetReplaceSourceActors() const
|
||||
{
|
||||
return (Tool->bReplaceSourceActors ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetReplaceSourceActors(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->bReplaceSourceActors = (ECheckBoxState::Checked == NewValue);
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetMergePhyisicData() const
|
||||
{
|
||||
return (Tool->MergingSettings.bMergePhysicsData ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetMergePhyisicData(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.bMergePhysicsData = (ECheckBoxState::Checked == NewValue);
|
||||
}
|
||||
|
||||
bool SPolishBuildingsDialog::IsMaterialMergingEnabled() const
|
||||
{
|
||||
return Tool->MergingSettings.bMergeMaterials;
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetMergeMaterials() const
|
||||
{
|
||||
return (Tool->MergingSettings.bMergeMaterials ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetMergeMaterials(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.bMergeMaterials = (ECheckBoxState::Checked == NewValue);
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetExportNormalMap() const
|
||||
{
|
||||
return ( Tool->MergingSettings.MaterialSettings.bNormalMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetExportNormalMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.MaterialSettings.bNormalMap = ( ECheckBoxState::Checked == NewValue );
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetExportMetallicMap() const
|
||||
{
|
||||
return ( Tool->MergingSettings.MaterialSettings.bMetallicMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetExportMetallicMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.MaterialSettings.bMetallicMap = ( ECheckBoxState::Checked == NewValue );
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetExportRoughnessMap() const
|
||||
{
|
||||
return ( Tool->MergingSettings.MaterialSettings.bRoughnessMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetExportRoughnessMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.MaterialSettings.bRoughnessMap = ( ECheckBoxState::Checked == NewValue );
|
||||
}
|
||||
|
||||
ECheckBoxState SPolishBuildingsDialog::GetExportSpecularMap() const
|
||||
{
|
||||
return ( Tool->MergingSettings.MaterialSettings.bSpecularMap ? ECheckBoxState::Checked : ECheckBoxState::Unchecked );
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetExportSpecularMap(ECheckBoxState NewValue)
|
||||
{
|
||||
Tool->MergingSettings.MaterialSettings.bSpecularMap = ( ECheckBoxState::Checked == NewValue );
|
||||
}
|
||||
|
||||
void SPolishBuildingsDialog::SetMergedMaterialAtlasResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
|
||||
{
|
||||
TTypeFromString<int32>::FromString( Tool->MergingSettings.MaterialSettings.TextureSize.X, **NewSelection );
|
||||
TTypeFromString<int32>::FromString( Tool->MergingSettings.MaterialSettings.TextureSize.Y, **NewSelection );
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
class FPolishBuildingsTool;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
SPolishBuildingsDialog
|
||||
-----------------------------------------------------------------------------*/
|
||||
class SPolishBuildingsDialog : public SCompoundWidget
|
||||
{
|
||||
public:
|
||||
SLATE_BEGIN_ARGS(SPolishBuildingsDialog)
|
||||
{
|
||||
}
|
||||
|
||||
SLATE_END_ARGS()
|
||||
|
||||
public:
|
||||
/** **/
|
||||
SPolishBuildingsDialog();
|
||||
|
||||
/** SWidget functions */
|
||||
void Construct(const FArguments& InArgs, FPolishBuildingsTool* InTool);
|
||||
|
||||
private:
|
||||
|
||||
/** Called when the Merge button is clicked */
|
||||
FReply OnMergeClicked();
|
||||
|
||||
/** */
|
||||
ECheckBoxState GetGenerateLightmapUV() const;
|
||||
void SetGenerateLightmapUV(ECheckBoxState NewValue);
|
||||
|
||||
/** Target lightmap channel */
|
||||
bool IsLightmapChannelEnabled() const;
|
||||
void SetTargetLightMapChannel(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo);
|
||||
void SetTargetLightMapResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo);
|
||||
|
||||
/** */
|
||||
ECheckBoxState GetExportSpecificLODEnabled() const;
|
||||
void SetExportSpecificLODEnabled(ECheckBoxState NewValue);
|
||||
bool IsExportSpecificLODEnabled() const;
|
||||
void SetExportSpecificLODIndex(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo);
|
||||
|
||||
/** */
|
||||
ECheckBoxState GetImportVertexColors() const;
|
||||
void SetImportVertexColors(ECheckBoxState NewValue);
|
||||
|
||||
/** */
|
||||
ECheckBoxState GetPivotPointAtZero() const;
|
||||
void SetPivotPointAtZero(ECheckBoxState NewValue);
|
||||
|
||||
ECheckBoxState GetReplaceSourceActors() const;
|
||||
void SetReplaceSourceActors(ECheckBoxState NewValue);
|
||||
|
||||
ECheckBoxState GetMergePhyisicData() const;
|
||||
void SetMergePhyisicData(ECheckBoxState NewValue);
|
||||
|
||||
/** Material merging */
|
||||
bool IsMaterialMergingEnabled() const;
|
||||
ECheckBoxState GetMergeMaterials() const;
|
||||
void SetMergeMaterials(ECheckBoxState NewValue);
|
||||
|
||||
ECheckBoxState GetExportNormalMap() const;
|
||||
void SetExportNormalMap(ECheckBoxState NewValue);
|
||||
|
||||
ECheckBoxState GetExportMetallicMap() const;
|
||||
void SetExportMetallicMap(ECheckBoxState NewValue);
|
||||
|
||||
ECheckBoxState GetExportRoughnessMap() const;
|
||||
void SetExportRoughnessMap(ECheckBoxState NewValue);
|
||||
|
||||
ECheckBoxState GetExportSpecularMap() const;
|
||||
void SetExportSpecularMap(ECheckBoxState NewValue);
|
||||
|
||||
void SetMergedMaterialAtlasResolution(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo);
|
||||
|
||||
private:
|
||||
|
||||
FPolishBuildingsTool* Tool;
|
||||
|
||||
TArray<TSharedPtr<FString>> ExportLODOptions;
|
||||
TArray<TSharedPtr<FString>> LightMapResolutionOptions;
|
||||
TArray<TSharedPtr<FString>> LightMapChannelOptions;
|
||||
TArray<TSharedPtr<FString>> MergedMaterialResolutionOptions;
|
||||
};
|
||||
@@ -0,0 +1,219 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "PolishBuildingsPrivatePCH.h"
|
||||
#include "SPolishBuildingsToolbar.h"
|
||||
#include "LevelEditor.h"
|
||||
#include "IDocumentation.h"
|
||||
#include "ContentBrowserModule.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "SPolishBuildingsToolbar"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void SPolishBuildingsToolbar::Construct(const FArguments& InArgs)
|
||||
{
|
||||
// Important: We use raw bindings here because we are releasing our binding in our destructor (where a weak pointer would be invalid)
|
||||
// It's imperative that our delegate is removed in the destructor for the level editor module to play nicely with reloading.
|
||||
|
||||
FLevelEditorModule& LevelEditor = FModuleManager::GetModuleChecked<FLevelEditorModule>("LevelEditor");
|
||||
LevelEditor.OnActorSelectionChanged().AddRaw(this, &SPolishBuildingsToolbar::OnActorSelectionChanged);
|
||||
|
||||
RegisteredTools = InArgs._ToolsToRegister;
|
||||
|
||||
ChildSlot
|
||||
[
|
||||
SNew(SVerticalBox)
|
||||
|
||||
+ SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.HAlign(HAlign_Left)
|
||||
.Padding(0, 0, 0, 0)
|
||||
[
|
||||
SAssignNew(ToolbarContainer, SBorder)
|
||||
.BorderImage(FEditorStyle::GetBrush("NoBorder"))
|
||||
.Padding(FMargin(4, 0, 0, 0))
|
||||
]
|
||||
|
||||
+ SVerticalBox::Slot()
|
||||
.FillHeight(1.0f)
|
||||
.Padding(2, 0, 0, 0)
|
||||
[
|
||||
SNew(SBorder)
|
||||
.BorderImage(FEditorStyle::GetBrush("ToolPanel.GroupBorder"))
|
||||
.Padding(0.f)
|
||||
.IsEnabled(this, &SPolishBuildingsToolbar::GetContentEnabledState)
|
||||
[
|
||||
SNew(SVerticalBox)
|
||||
|
||||
+ SVerticalBox::Slot()
|
||||
.FillHeight(1.0f)
|
||||
.Padding(4, 4, 4, 4)
|
||||
[
|
||||
SNew(SScrollBox)
|
||||
+SScrollBox::Slot()
|
||||
[
|
||||
SAssignNew(InlineContentHolder, SBox)
|
||||
]
|
||||
]
|
||||
|
||||
+ SVerticalBox::Slot()
|
||||
.AutoHeight()
|
||||
.HAlign(HAlign_Right)
|
||||
.Padding(4, 4, 10, 4)
|
||||
[
|
||||
SNew(SButton)
|
||||
.Text(LOCTEXT("PolishBuildings", "Merge Actors"))
|
||||
.OnClicked(this, &SPolishBuildingsToolbar::OnPolishBuildingsClicked)
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
UpdateToolbar();
|
||||
|
||||
// Update selected actor state for the first time
|
||||
GUnrealEd->UpdateFloatingPropertyWindows();
|
||||
}
|
||||
|
||||
|
||||
SPolishBuildingsToolbar::~SPolishBuildingsToolbar()
|
||||
{
|
||||
FLevelEditorModule& LevelEditor = FModuleManager::GetModuleChecked<FLevelEditorModule>("LevelEditor");
|
||||
LevelEditor.OnActorSelectionChanged().RemoveAll(this);
|
||||
}
|
||||
|
||||
|
||||
void SPolishBuildingsToolbar::OnActorSelectionChanged(const TArray<UObject*>& NewSelection, bool bForceRefresh)
|
||||
{
|
||||
SelectedObjects = NewSelection;
|
||||
bIsContentEnabled = (NewSelection.Num() > 0);
|
||||
}
|
||||
|
||||
|
||||
void SPolishBuildingsToolbar::OnToolSelectionChanged(const ECheckBoxState NewCheckedState, int32 ToolIndex)
|
||||
{
|
||||
if (NewCheckedState == ECheckBoxState::Checked)
|
||||
{
|
||||
CurrentlySelectedTool = ToolIndex;
|
||||
UpdateInlineContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ECheckBoxState SPolishBuildingsToolbar::OnIsToolSelected(int32 ToolIndex) const
|
||||
{
|
||||
return (CurrentlySelectedTool == ToolIndex) ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
|
||||
}
|
||||
|
||||
|
||||
FReply SPolishBuildingsToolbar::OnPolishBuildingsClicked()
|
||||
{
|
||||
if (CurrentlySelectedTool >= 0 && CurrentlySelectedTool < RegisteredTools.Num())
|
||||
{
|
||||
const FString DefaultPackageName = RegisteredTools[CurrentlySelectedTool]->GetDefaultPackageName();
|
||||
const FString DefaultPath = FPackageName::GetLongPackagePath(DefaultPackageName);
|
||||
const FString DefaultName = FPackageName::GetShortName(DefaultPackageName);
|
||||
|
||||
// Initialize SaveAssetDialog config
|
||||
FSaveAssetDialogConfig SaveAssetDialogConfig;
|
||||
SaveAssetDialogConfig.DialogTitleOverride = LOCTEXT("CreateMergedActorTitle", "Create Merged Actor");
|
||||
SaveAssetDialogConfig.DefaultPath = DefaultPath;
|
||||
SaveAssetDialogConfig.DefaultAssetName = DefaultName;
|
||||
SaveAssetDialogConfig.ExistingAssetPolicy = ESaveAssetDialogExistingAssetPolicy::AllowButWarn;
|
||||
|
||||
FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
|
||||
FString SaveObjectPath = ContentBrowserModule.Get().CreateModalSaveAssetDialog(SaveAssetDialogConfig);
|
||||
if (!SaveObjectPath.IsEmpty())
|
||||
{
|
||||
const FString PackageName = FPackageName::ObjectPathToPackageName(SaveObjectPath);
|
||||
|
||||
RegisteredTools[CurrentlySelectedTool]->RunMerge(PackageName);
|
||||
}
|
||||
}
|
||||
|
||||
return FReply::Handled();
|
||||
}
|
||||
|
||||
|
||||
bool SPolishBuildingsToolbar::GetContentEnabledState() const
|
||||
{
|
||||
return bIsContentEnabled;
|
||||
}
|
||||
|
||||
|
||||
void SPolishBuildingsToolbar::AddTool(IPolishBuildingsTool* Tool)
|
||||
{
|
||||
check(!RegisteredTools.Contains(Tool));
|
||||
RegisteredTools.Add(Tool);
|
||||
UpdateToolbar();
|
||||
}
|
||||
|
||||
|
||||
void SPolishBuildingsToolbar::RemoveTool(IPolishBuildingsTool* Tool)
|
||||
{
|
||||
int32 IndexToRemove = RegisteredTools.Find(Tool);
|
||||
if (IndexToRemove != INDEX_NONE)
|
||||
{
|
||||
RegisteredTools.RemoveAt(IndexToRemove);
|
||||
|
||||
if (CurrentlySelectedTool > IndexToRemove)
|
||||
{
|
||||
CurrentlySelectedTool--;
|
||||
}
|
||||
UpdateToolbar();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SPolishBuildingsToolbar::UpdateToolbar()
|
||||
{
|
||||
const ISlateStyle& StyleSet = FEditorStyle::Get();
|
||||
|
||||
TSharedRef<SHorizontalBox> HorizontalBox =
|
||||
SNew(SHorizontalBox);
|
||||
|
||||
for (int32 ToolIndex = 0; ToolIndex < RegisteredTools.Num(); ToolIndex++)
|
||||
{
|
||||
const IPolishBuildingsTool* Tool = RegisteredTools[ToolIndex];
|
||||
|
||||
HorizontalBox->AddSlot()
|
||||
.Padding(StyleSet.GetMargin("EditorModesToolbar.SToolBarButtonBlock.Padding"))
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.Style(&StyleSet, "EditorModesToolbar.ToggleButton")
|
||||
.OnCheckStateChanged(this, &SPolishBuildingsToolbar::OnToolSelectionChanged, ToolIndex)
|
||||
.IsChecked(this, &SPolishBuildingsToolbar::OnIsToolSelected, ToolIndex)
|
||||
.Padding(StyleSet.GetMargin("EditorModesToolbar.SToolBarButtonBlock.CheckBox.Padding"))
|
||||
.ToolTip(IDocumentation::Get()->CreateToolTip(Tool->GetTooltipText(), nullptr, FString(), FString()))
|
||||
[
|
||||
SNew(SImage)
|
||||
.Image(StyleSet.GetBrush(Tool->GetIconName()))
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
TSharedRef<SBorder> ToolbarContent =
|
||||
SNew(SBorder)
|
||||
.Padding(0)
|
||||
.BorderImage(StyleSet.GetBrush("NoBorder"))
|
||||
[
|
||||
HorizontalBox
|
||||
];
|
||||
|
||||
ToolbarContainer->SetContent(ToolbarContent);
|
||||
|
||||
UpdateInlineContent();
|
||||
}
|
||||
|
||||
|
||||
void SPolishBuildingsToolbar::UpdateInlineContent()
|
||||
{
|
||||
if (CurrentlySelectedTool >= 0 && CurrentlySelectedTool < RegisteredTools.Num())
|
||||
{
|
||||
InlineContentHolder->SetContent(RegisteredTools[CurrentlySelectedTool]->GetWidget());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,83 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
class IPolishBuildingsTool;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// SPolishBuildingsToolbar
|
||||
|
||||
class SPolishBuildingsToolbar : public SCompoundWidget
|
||||
{
|
||||
public:
|
||||
|
||||
SLATE_BEGIN_ARGS(SPolishBuildingsToolbar) {}
|
||||
SLATE_ARGUMENT(TArray<IPolishBuildingsTool*>, ToolsToRegister)
|
||||
SLATE_END_ARGS()
|
||||
|
||||
/**
|
||||
* Construct the widget
|
||||
*
|
||||
* @param InArgs A declaration from which to construct the widget
|
||||
*/
|
||||
void Construct(const FArguments& InArgs);
|
||||
|
||||
/** Constructor */
|
||||
SPolishBuildingsToolbar()
|
||||
: CurrentlySelectedTool(0)
|
||||
{}
|
||||
|
||||
/** Destructor */
|
||||
virtual ~SPolishBuildingsToolbar();
|
||||
|
||||
/** Add a new tool to the toolbar */
|
||||
void AddTool(IPolishBuildingsTool* Tool);
|
||||
|
||||
/** Remove an existing tool from the toolbar */
|
||||
void RemoveTool(IPolishBuildingsTool* Tool);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** Called when the level actor selection changes */
|
||||
void OnActorSelectionChanged(const TArray<UObject*>& NewSelection, bool bForceRefresh);
|
||||
|
||||
/** Called when the currently selected tool changes */
|
||||
void OnToolSelectionChanged(const ECheckBoxState NewCheckedState, int32 ToolIndex);
|
||||
|
||||
/** Called to determine whether a toolbox widget is selected or not */
|
||||
ECheckBoxState OnIsToolSelected(int32 ToolIndex) const;
|
||||
|
||||
/** Called when the Merge Actors button is clicked */
|
||||
FReply OnPolishBuildingsClicked();
|
||||
|
||||
/** Determine whether the widget content is enabled or not */
|
||||
bool GetContentEnabledState() const;
|
||||
|
||||
/** Update the toolbar container based on the currently registered tools */
|
||||
void UpdateToolbar();
|
||||
|
||||
/** Updates the inline content widget for the current tool */
|
||||
void UpdateInlineContent();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** List of registered tool instances */
|
||||
TArray<IPolishBuildingsTool*> RegisteredTools;
|
||||
|
||||
/** Index of currently selected tool */
|
||||
int32 CurrentlySelectedTool;
|
||||
|
||||
/** List of currently selected objects */
|
||||
TArray<UObject*> SelectedObjects;
|
||||
|
||||
/** Whether the merge actors tool panel is enabled or not */
|
||||
bool bIsContentEnabled;
|
||||
|
||||
/** The container holding the toolbar */
|
||||
TSharedPtr<SBorder> ToolbarContainer;
|
||||
|
||||
/** Inline content area for different tool modes */
|
||||
TSharedPtr<SBox> InlineContentHolder;
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "ModuleManager.h"
|
||||
#include "IPolishBuildingsTool.h"
|
||||
|
||||
|
||||
/**
|
||||
* Merge Actors module interface
|
||||
*/
|
||||
class IPolishBuildingsModule : public IModuleInterface
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Get reference to the Merge Actors module instance
|
||||
*/
|
||||
static inline IPolishBuildingsModule& Get()
|
||||
{
|
||||
return FModuleManager::LoadModuleChecked<IPolishBuildingsModule>("PolishBuildings");
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an IPolishBuildingsTool with the module, passing ownership to it
|
||||
*/
|
||||
virtual bool RegisterPolishBuildingsTool(TUniquePtr<IPolishBuildingsTool> Tool) = 0;
|
||||
|
||||
/**
|
||||
* Unregister an IPolishBuildingsTool with the module
|
||||
*/
|
||||
virtual bool UnregisterPolishBuildingsTool(IPolishBuildingsTool* Tool) = 0;
|
||||
};
|
||||
43
Plugins/PolishBuildings/Source/Public/IPolishBuildingsTool.h
Normal file
43
Plugins/PolishBuildings/Source/Public/IPolishBuildingsTool.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Merge Actors tool interface
|
||||
*/
|
||||
class IPolishBuildingsTool
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/** Virtual destructor */
|
||||
virtual ~IPolishBuildingsTool() {}
|
||||
|
||||
/**
|
||||
* Gets the widget instance associated with this tool
|
||||
*/
|
||||
virtual TSharedRef<SWidget> GetWidget() = 0;
|
||||
|
||||
/**
|
||||
* Get the name of the icon displayed in the Merge Actors toolbar
|
||||
*/
|
||||
virtual FName GetIconName() const = 0;
|
||||
|
||||
/**
|
||||
* Get Tooltip text displayed in the Merge Actors toolbar
|
||||
*/
|
||||
virtual FText GetTooltipText() const = 0;
|
||||
|
||||
/**
|
||||
* Get default name for the merged asset package
|
||||
*/
|
||||
virtual FString GetDefaultPackageName() const = 0;
|
||||
|
||||
/**
|
||||
* Perform merge operation
|
||||
*
|
||||
* @param PackageName Long package name of the asset to create
|
||||
* @return true if the merge succeeded
|
||||
*/
|
||||
virtual bool RunMerge(const FString& PackageName) = 0;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user