HAxis sos

This commit is contained in:
guus
2018-08-11 16:46:35 +02:00
commit 510654f8a1
480 changed files with 54126 additions and 0 deletions

View 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"
}
);
}
}

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;
};

View 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

View File

@@ -0,0 +1,6 @@
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "UnrealEd.h"
#include "IPolishBuildingsModule.h"

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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;
};

View 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;
};