Adding AutoLOD tools to the static mesh editor.

Static Mesh Editor changes:
- Share ownership of StaticMeshViewportClient's ModeTools via the EditorModeManager member
- Set up the EditorModeManager's preview scene and selected components when it's copied
- Add a set of FStaticMeshEditorToolbarExtender delegates to the module (similar to FSkeletalMeshEditorToolbarExtender)
- Allow adding an overlay widget to the viewport
- Add a ModeUILayer member to handle mode toolkit hosting

StaticMeshEditorModeling (new module):
- Create a mode and toolkit with AutoLOD and LODManager tools
- Add a button to the StaticMeshEditor's toolbar to toggle UMeshLODPluginEditMode

#rb brooke.hubert semion.piskarev
#jira UETOOL-3663
#preflight 61435ce14778fa00016a0b28
#preflight 614370e8b5a4fa00016459a0

[CL 17541979 by tyson brochu in ue5-main branch]
This commit is contained in:
tyson brochu
2021-09-16 13:56:39 -04:00
parent b3888165b3
commit ba3c5ed88e
18 changed files with 855 additions and 1 deletions
@@ -127,6 +127,9 @@ public:
/** Returns the preview scene being renderd in the viewport */
TSharedRef<FAdvancedPreviewScene> GetPreviewScene() { return PreviewScene.ToSharedRef(); }
TSharedPtr<SOverlay> GetViewportOverlay() { return ViewportOverlay; }
protected:
/** SEditorViewport interface */
virtual TSharedRef<FEditorViewportClient> MakeEditorViewportClient() override;
@@ -52,6 +52,11 @@
#include "EditorViewportTabContent.h"
#include "EditorViewportLayout.h"
#include "Toolkits/AssetEditorToolkitMenuContext.h"
#include "EditorModeManager.h"
#include "StaticMeshEditorModeUILayer.h"
#include "AssetEditorModeManager.h"
#include "Engine/Selection.h"
#define LOCTEXT_NAMESPACE "StaticMeshEditor"
@@ -261,12 +266,27 @@ void FStaticMeshEditor::InitStaticMeshEditor( const EToolkitMode::Type Mode, con
const bool bCreateDefaultToolbar = true;
FAssetEditorToolkit::InitAssetEditor( Mode, InitToolkitHost, StaticMeshEditorAppIdentifier, StandaloneDefaultLayout, bCreateDefaultToolbar, bCreateDefaultStandaloneMenu, ObjectToEdit );
TSharedPtr<class IToolkitHost> PinnedToolkitHost = ToolkitHost.Pin();
check(PinnedToolkitHost.IsValid());
ModeUILayer = MakeShareable(new FStaticMeshEditorModeUILayer(PinnedToolkitHost.Get()));
ExtendMenu();
ExtendToolBar();
RegenerateMenusAndToolbars();
GenerateSecondaryToolbar();
}
void FStaticMeshEditor::PostInitAssetEditor()
{
// (Copied from FUVEditorToolkit::PostInitAssetEditor)
// We need the viewport client to start out focused, or else it won't get ticked until we click inside it.
FStaticMeshEditorViewportClient& ViewportClient = GetStaticMeshViewport()->GetViewportClient();
ViewportClient.ReceivedFocus(ViewportClient.Viewport);
}
void FStaticMeshEditor::GenerateSecondaryToolbar()
{
// Generate the secondary toolbar only if there are registered extensions
@@ -926,6 +946,16 @@ void FStaticMeshEditor::ExtendToolBar()
AddToolbarExtender(ToolbarExtender);
IStaticMeshEditorModule* StaticMeshEditorModule = &FModuleManager::LoadModuleChecked<IStaticMeshEditorModule>("StaticMeshEditor");
TArray<IStaticMeshEditorModule::FStaticMeshEditorToolbarExtender> ToolbarExtenderDelegates = StaticMeshEditorModule->GetAllStaticMeshEditorToolbarExtenders();
for (auto& ToolbarExtenderDelegate : ToolbarExtenderDelegates)
{
if (ToolbarExtenderDelegate.IsBound())
{
AddToolbarExtender(ToolbarExtenderDelegate.Execute(GetToolkitCommands(), SharedThis(this)));
}
}
EditorToolbarExtender = StaticMeshEditorModule->GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects());
AddToolbarExtender(EditorToolbarExtender);
AddSecondaryToolbarExtender(StaticMeshEditorModule->GetSecondaryToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
@@ -2484,6 +2514,67 @@ TStatId FStaticMeshEditor::GetStatId() const
RETURN_QUICK_DECLARE_CYCLE_STAT(FStaticMeshEditor, STATGROUP_TaskGraphTasks);
}
void FStaticMeshEditor::AddViewportOverlayWidget(TSharedRef<SWidget> InOverlaidWidget)
{
TSharedPtr<SStaticMeshEditorViewport> Viewport = GetStaticMeshViewport();
if (Viewport.IsValid() && Viewport->GetViewportOverlay().IsValid())
{
Viewport->GetViewportOverlay()->AddSlot()
[
InOverlaidWidget
];
}
}
void FStaticMeshEditor::RemoveViewportOverlayWidget(TSharedRef<SWidget> InViewportOverlayWidget)
{
TSharedPtr<SStaticMeshEditorViewport> Viewport = GetStaticMeshViewport();
if (Viewport.IsValid() && Viewport->GetViewportOverlay().IsValid())
{
Viewport->GetViewportOverlay()->RemoveSlot(InViewportOverlayWidget);
}
}
void FStaticMeshEditor::CreateEditorModeManager()
{
//
// This function doesn't actually create a new manager -- it assigns StaticMeshEditorViewport->GetViewportClient().GetModeTools()
// to this->EditorModeManager. This is because these two pointers should refer to the same mode manager object, and currently
// the ViewPortClient's ModeTools object is created first.
//
// This function also:
// - sets the manager's PreviewScene to be StaticMeshEditorViewport->GetPreviewScene()
// - adds StaticMeshEditorViewport->GetStaticMeshComponent() to the manager's ComponentSet (i.e. selected mesh components)
//
TSharedPtr<FAssetEditorModeManager> NewManager = MakeShared<FAssetEditorModeManager>();
TSharedPtr<SStaticMeshEditorViewport> StaticMeshEditorViewport = GetStaticMeshViewport();
if (StaticMeshEditorViewport.IsValid())
{
TSharedPtr<FEditorModeTools> SharedModeTools = StaticMeshEditorViewport->GetViewportClient().GetModeTools()->AsShared();
NewManager = StaticCastSharedPtr<FAssetEditorModeManager>(SharedModeTools);
check(NewManager.IsValid());
TSharedRef<FAdvancedPreviewScene> PreviewScene = StaticMeshEditorViewport->GetPreviewScene();
NewManager->SetPreviewScene(&PreviewScene.Get());
UStaticMeshComponent* const Component = StaticMeshEditorViewport->GetStaticMeshComponent();
// Copied from FPersonaEditorModeManager::SetPreviewScene(FPreviewScene * NewPreviewScene)
USelection* ComponentSet = NewManager->GetSelectedComponents();
ComponentSet->BeginBatchSelectOperation();
ComponentSet->DeselectAll();
ComponentSet->Select(Component, true);
ComponentSet->EndBatchSelectOperation();
}
EditorModeManager = NewManager;
}
bool FStaticMeshEditor::CanRemoveUVChannel()
{
// Can remove UV channel if there's one that is currently being selected and displayed,
@@ -2904,4 +2995,15 @@ void FStaticMeshEditor::RemoveCurrentUVChannel()
}
}
void FStaticMeshEditor::OnToolkitHostingStarted(const TSharedRef<IToolkit>& Toolkit)
{
ModeUILayer->OnToolkitHostingStarted(Toolkit);
}
void FStaticMeshEditor::OnToolkitHostingFinished(const TSharedRef<IToolkit>& Toolkit)
{
ModeUILayer->OnToolkitHostingFinished(Toolkit);
}
#undef LOCTEXT_NAMESPACE
@@ -35,6 +35,7 @@ class UStaticMeshSocket;
class FViewportTabContent;
struct FPropertyChangedEvent;
struct FTabSpawnerEntry;
class FStaticMeshEditorModeUILayer;
/**
* StaticMesh Editor class
@@ -69,10 +70,16 @@ private:
/** Initializes the editor to use a static mesh. Should be the first thing called. */
void InitEditorForStaticMesh(UStaticMesh* ObjectToEdit);
virtual void PostInitAssetEditor() override;
public:
virtual void RegisterTabSpawners(const TSharedRef<class FTabManager>& TabManager) override;
virtual void UnregisterTabSpawners(const TSharedRef<class FTabManager>& TabManager) override;
// IToolkitHost Interface
void OnToolkitHostingStarted(const TSharedRef<IToolkit>& Toolkit) override;
void OnToolkitHostingFinished(const TSharedRef<IToolkit>& Toolkit) override;
/**
* Edits the specified static mesh object
*
@@ -217,6 +224,13 @@ public:
/** Returns the stat ID for this tickable class */
virtual TStatId GetStatId() const final;
/** Add a widget to the StaticMeshViewport's ViewportOverlay */
void AddViewportOverlayWidget(TSharedRef<SWidget> InOverlaidWidget) override;
/** Remove a widget from the StaticMeshViewport's ViewportOverlay */
void RemoveViewportOverlayWidget(TSharedRef<SWidget> InViewportOverlayWidget) override;
void CreateEditorModeManager() override;
private:
TSharedRef<SDockTab> SpawnTab_Viewport(const FSpawnTabArgs& Args);
@@ -576,4 +590,6 @@ private:
bool bDrawWireframes;
bool bDrawVertexColors;
bool bDrawAdditionalData;
TSharedPtr<FStaticMeshEditorModeUILayer> ModeUILayer;
};
@@ -0,0 +1,38 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "StaticMeshEditorModeUILayer.h"
#include "WorkspaceMenuStructure.h"
#include "WorkspaceMenuStructureModule.h"
#include "Toolkits/IToolkit.h"
FStaticMeshEditorModeUILayer::FStaticMeshEditorModeUILayer(const IToolkitHost* InToolkitHost) :
FAssetEditorModeUILayer(InToolkitHost)
{}
void FStaticMeshEditorModeUILayer::OnToolkitHostingStarted(const TSharedRef<IToolkit>& Toolkit)
{
if (!Toolkit->IsAssetEditor())
{
FAssetEditorModeUILayer::OnToolkitHostingStarted(Toolkit);
HostedToolkit = Toolkit;
Toolkit->SetModeUILayer(SharedThis(this));
Toolkit->RegisterTabSpawners(ToolkitHost->GetTabManager().ToSharedRef());
RegisterModeTabSpawners();
OnToolkitHostReadyForUI.ExecuteIfBound();
}
}
void FStaticMeshEditorModeUILayer::OnToolkitHostingFinished(const TSharedRef<IToolkit>& Toolkit)
{
if (HostedToolkit.IsValid() && HostedToolkit.Pin() == Toolkit)
{
FAssetEditorModeUILayer::OnToolkitHostingFinished(Toolkit);
}
}
TSharedPtr<FWorkspaceItem> FStaticMeshEditorModeUILayer::GetModeMenuCategory() const
{
const IWorkspaceMenuStructure& MenuStructure = WorkspaceMenu::GetMenuStructure();
return MenuStructure.GetLevelEditorModesCategory();
}
@@ -0,0 +1,18 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Toolkits/AssetEditorModeUILayer.h"
class FStaticMeshEditorModeUILayer : public FAssetEditorModeUILayer
{
public:
FStaticMeshEditorModeUILayer(const IToolkitHost* InToolkitHost);
void OnToolkitHostingStarted(const TSharedRef<IToolkit>& Toolkit) override;
void OnToolkitHostingFinished(const TSharedRef<IToolkit>& Toolkit) override;
TSharedPtr<FWorkspaceItem> GetModeMenuCategory() const override;
};
@@ -56,10 +56,13 @@ public:
virtual TSharedPtr<FExtensibilityManager> GetToolBarExtensibilityManager() override { return ToolBarExtensibilityManager; }
virtual TSharedPtr<FExtensibilityManager> GetSecondaryToolBarExtensibilityManager() override { return SecondaryToolBarExtensibilityManager; }
virtual TArray<FStaticMeshEditorToolbarExtender>& GetAllStaticMeshEditorToolbarExtenders() override { return StaticMeshEditorToolbarExtenders; }
private:
TSharedPtr<FExtensibilityManager> MenuExtensibilityManager;
TSharedPtr<FExtensibilityManager> ToolBarExtensibilityManager;
TSharedPtr<FExtensibilityManager> SecondaryToolBarExtensibilityManager;
TArray<FStaticMeshEditorToolbarExtender> StaticMeshEditorToolbarExtenders;
};
IMPLEMENT_MODULE( FStaticMeshEditorModule, StaticMeshEditor );
@@ -29,6 +29,9 @@ public:
virtual TSharedPtr<FExtensibilityManager> GetSecondaryToolBarExtensibilityManager() = 0;
DECLARE_DELEGATE_RetVal_TwoParams(TSharedRef<FExtender>, FStaticMeshEditorToolbarExtender, const TSharedRef<FUICommandList>, TSharedRef<IStaticMeshEditor>);
virtual TArray<FStaticMeshEditorToolbarExtender>& GetAllStaticMeshEditorToolbarExtenders() = 0;
private:
FStaticMeshEditorOpenedEvent StaticMeshEditorOpenedEvent;
};
@@ -46,6 +46,8 @@ public class StaticMeshEditor : ModuleRules
"StaticMeshDescription",
"ToolMenus",
"DetailCustomizations",
"StatusBar",
"WorkspaceMenuStructure",
"PhysicsUtilities",
}
);
@@ -55,7 +57,6 @@ public class StaticMeshEditor : ModuleRules
"SceneOutliner",
"ClassViewer",
"ContentBrowser",
"WorkspaceMenuStructure",
"MeshReductionInterface",
}
);