2014-12-07 19:09:38 -05:00
|
|
|
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
#include "MaterialEditorModule.h"
|
2014-05-22 11:33:54 -04:00
|
|
|
|
|
|
|
|
#include "Materials/MaterialExpressionTextureBase.h"
|
|
|
|
|
#include "Materials/MaterialExpressionTextureSampleParameter.h"
|
|
|
|
|
|
2014-03-14 14:13:41 -04:00
|
|
|
#include "MaterialInstanceEditor.h"
|
|
|
|
|
#include "MaterialEditor.h"
|
|
|
|
|
#include "MaterialEditorActions.h"
|
|
|
|
|
#include "MaterialEditorUtilities.h"
|
|
|
|
|
|
|
|
|
|
#include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/IDetailsView.h"
|
|
|
|
|
#include "Editor/PropertyEditor/Public/PropertyHandle.h"
|
|
|
|
|
#include "MaterialEditorInstanceDetailCustomization.h"
|
|
|
|
|
|
|
|
|
|
#include "Editor/WorkspaceMenuStructure/Public/WorkspaceMenuStructureModule.h"
|
|
|
|
|
#include "EditorViewportCommands.h"
|
2014-10-14 22:50:06 -04:00
|
|
|
#include "SDockTab.h"
|
2014-11-12 04:43:54 -05:00
|
|
|
#include "Materials/MaterialInstanceConstant.h"
|
|
|
|
|
#include "CanvasTypes.h"
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
#define LOCTEXT_NAMESPACE "MaterialInstanceEditor"
|
|
|
|
|
|
|
|
|
|
DEFINE_LOG_CATEGORY_STATIC(LogMaterialInstanceEditor, Log, All);
|
|
|
|
|
|
|
|
|
|
const FName FMaterialInstanceEditor::PreviewTabId( TEXT( "MaterialInstanceEditor_Preview" ) );
|
|
|
|
|
const FName FMaterialInstanceEditor::PropertiesTabId( TEXT( "MaterialInstanceEditor_MaterialProperties" ) );
|
|
|
|
|
const FName FMaterialInstanceEditor::ParentsTabId( TEXT( "MaterialInstanceEditor_MaterialParents" ) );
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// SMaterialTreeWidgetItem
|
|
|
|
|
class SMaterialTreeWidgetItem : public SMultiColumnTableRow< TWeakObjectPtr<UMaterialInterface> >
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
SLATE_BEGIN_ARGS(SMaterialTreeWidgetItem)
|
2014-07-31 15:43:08 -04:00
|
|
|
: _ParentIndex( -1 )
|
|
|
|
|
, _WidgetInfoToVisualize()
|
2014-03-14 14:13:41 -04:00
|
|
|
{}
|
|
|
|
|
SLATE_ARGUMENT( int32, ParentIndex )
|
|
|
|
|
SLATE_ARGUMENT( TWeakObjectPtr<UMaterialInterface>, WidgetInfoToVisualize )
|
|
|
|
|
SLATE_END_ARGS()
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Construct child widgets that comprise this widget.
|
|
|
|
|
*
|
|
|
|
|
* @param InArgs Declaration from which to construct this widget
|
|
|
|
|
*/
|
|
|
|
|
void Construct( const FArguments& InArgs, const TSharedRef<STableViewBase>& InOwnerTableView )
|
|
|
|
|
{
|
|
|
|
|
this->WidgetInfo = InArgs._WidgetInfoToVisualize;
|
|
|
|
|
this->ParentIndex = InArgs._ParentIndex;
|
|
|
|
|
|
|
|
|
|
SMultiColumnTableRow< TWeakObjectPtr<UMaterialInterface> >::Construct( FSuperRowType::FArguments(), InOwnerTableView );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** @return Widget based on the column name */
|
2014-06-13 06:14:46 -04:00
|
|
|
virtual TSharedRef<SWidget> GenerateWidgetForColumn( const FName& ColumnName ) override
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
|
|
|
|
FText Entry;
|
|
|
|
|
FSlateFontInfo FontInfo = FSlateFontInfo( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 9 );
|
|
|
|
|
if ( ColumnName == "Parent" )
|
|
|
|
|
{
|
|
|
|
|
if ( ParentIndex == 0 )
|
|
|
|
|
{
|
|
|
|
|
Entry = NSLOCTEXT("UnrealEd", "Material", "Material");
|
|
|
|
|
}
|
|
|
|
|
else if ( ParentIndex != -1 )
|
|
|
|
|
{
|
|
|
|
|
FFormatNamedArguments Args;
|
|
|
|
|
Args.Add( TEXT("Index"), ParentIndex );
|
|
|
|
|
Entry = FText::Format( FText::FromString("Parent {Index}"), Args );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Entry = NSLOCTEXT("UnrealEd", "Current", "Current");
|
|
|
|
|
FontInfo = FSlateFontInfo( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 9 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Entry = FText::FromString( WidgetInfo.Get()->GetName() );
|
|
|
|
|
if ( ParentIndex == -1 )
|
|
|
|
|
{
|
|
|
|
|
FontInfo = FSlateFontInfo( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Bold.ttf"), 9 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
SNew(SHorizontalBox)
|
|
|
|
|
+SHorizontalBox::Slot()
|
|
|
|
|
.AutoWidth()
|
|
|
|
|
.Padding(2)
|
|
|
|
|
[
|
|
|
|
|
SNew( STextBlock )
|
|
|
|
|
.Text( Entry )
|
|
|
|
|
.Font( FontInfo )
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
/** The info about the widget that we are visualizing */
|
|
|
|
|
TAttribute< TWeakObjectPtr<UMaterialInterface> > WidgetInfo;
|
|
|
|
|
|
|
|
|
|
/** The index this material has in our parents array */
|
|
|
|
|
int32 ParentIndex;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::RegisterTabSpawners(const TSharedRef<class FTabManager>& TabManager)
|
|
|
|
|
{
|
2014-10-23 15:11:28 -04:00
|
|
|
WorkspaceMenuCategory = TabManager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_MaterialInstanceEditor", "Material Instance Editor"));
|
2014-10-09 12:34:55 -04:00
|
|
|
auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-10-09 12:34:55 -04:00
|
|
|
FAssetEditorToolkit::RegisterTabSpawners(TabManager);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-10-09 12:34:55 -04:00
|
|
|
TabManager->RegisterTabSpawner( PreviewTabId, FOnSpawnTab::CreateSP( this, &FMaterialInstanceEditor::SpawnTab_Preview ) )
|
|
|
|
|
.SetDisplayName( LOCTEXT( "ViewportTab", "Viewport" ) )
|
|
|
|
|
.SetGroup( WorkspaceMenuCategoryRef )
|
|
|
|
|
.SetIcon( FSlateIcon( FEditorStyle::GetStyleSetName(), "LevelEditor.Tabs.Viewports" ) );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-10-09 12:34:55 -04:00
|
|
|
TabManager->RegisterTabSpawner( PropertiesTabId, FOnSpawnTab::CreateSP( this, &FMaterialInstanceEditor::SpawnTab_Properties ) )
|
|
|
|
|
.SetDisplayName( LOCTEXT( "PropertiesTab", "Details" ) )
|
|
|
|
|
.SetGroup( WorkspaceMenuCategoryRef )
|
|
|
|
|
.SetIcon( FSlateIcon( FEditorStyle::GetStyleSetName(), "LevelEditor.Tabs.Details" ) );
|
2014-03-14 14:13:41 -04:00
|
|
|
|
2014-10-09 12:34:55 -04:00
|
|
|
TabManager->RegisterTabSpawner( ParentsTabId, FOnSpawnTab::CreateSP(this, &FMaterialInstanceEditor::SpawnTab_Parents) )
|
2014-03-14 14:13:41 -04:00
|
|
|
.SetDisplayName( LOCTEXT("ParentsTab", "Parents") )
|
2014-10-09 12:34:55 -04:00
|
|
|
.SetGroup( WorkspaceMenuCategoryRef )
|
|
|
|
|
.SetIcon( FSlateIcon( FEditorStyle::GetStyleSetName(), "Kismet.Tabs.Palette" ) );
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::UnregisterTabSpawners(const TSharedRef<class FTabManager>& TabManager)
|
|
|
|
|
{
|
|
|
|
|
FAssetEditorToolkit::UnregisterTabSpawners(TabManager);
|
|
|
|
|
|
|
|
|
|
TabManager->UnregisterTabSpawner( PreviewTabId );
|
|
|
|
|
TabManager->UnregisterTabSpawner( PropertiesTabId );
|
|
|
|
|
TabManager->UnregisterTabSpawner( ParentsTabId );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// FMaterialInstanceEditor
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::InitMaterialInstanceEditor( const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, UObject* ObjectToEdit )
|
|
|
|
|
{
|
|
|
|
|
GEditor->RegisterForUndo( this );
|
|
|
|
|
|
|
|
|
|
check( ObjectToEdit );
|
|
|
|
|
UMaterialInstanceConstant* InstanceConstant = Cast<UMaterialInstanceConstant>(ObjectToEdit);
|
|
|
|
|
|
|
|
|
|
bShowAllMaterialParameters = false;
|
|
|
|
|
bShowMobileStats = false;
|
|
|
|
|
|
|
|
|
|
// Construct a temp holder for our instance parameters.
|
2015-02-03 05:40:57 -05:00
|
|
|
MaterialEditorInstance = NewObject<UMaterialEditorInstanceConstant>(GetTransientPackage(), NAME_None, RF_Transactional);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
bool bTempUseOldStyleMICEditorGroups = true;
|
|
|
|
|
GConfig->GetBool(TEXT("/Script/UnrealEd.EditorEngine"), TEXT("UseOldStyleMICEditorGroups"), bTempUseOldStyleMICEditorGroups, GEngineIni);
|
|
|
|
|
MaterialEditorInstance->bUseOldStyleMICEditorGroups = bTempUseOldStyleMICEditorGroups;
|
|
|
|
|
MaterialEditorInstance->SetSourceInstance(InstanceConstant);
|
|
|
|
|
|
|
|
|
|
// Register our commands. This will only register them if not previously registered
|
|
|
|
|
FMaterialEditorCommands::Register();
|
|
|
|
|
|
|
|
|
|
CreateInternalWidgets();
|
|
|
|
|
|
|
|
|
|
BindCommands();
|
|
|
|
|
|
|
|
|
|
TSharedRef<FTabManager::FLayout> StandaloneDefaultLayout = FTabManager::NewLayout( "Standalone_MaterialInstanceEditor_Layout_v2" )
|
|
|
|
|
->AddArea
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewPrimaryArea() ->SetOrientation( Orient_Vertical )
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack() ->SetSizeCoefficient( 0.1f ) ->SetHideTabWell( true )
|
|
|
|
|
->AddTab( GetToolbarTabId(), ETabState::OpenedTab )
|
|
|
|
|
)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewSplitter() ->SetOrientation(Orient_Horizontal) ->SetSizeCoefficient(0.9f)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewSplitter() ->SetOrientation(Orient_Vertical) ->SetSizeCoefficient(0.27f)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack() ->SetSizeCoefficient(0.6f)
|
|
|
|
|
->AddTab( PropertiesTabId, ETabState::OpenedTab )
|
|
|
|
|
)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack() ->SetSizeCoefficient(0.4f)
|
|
|
|
|
->AddTab( ParentsTabId, ETabState::OpenedTab )
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
->Split
|
|
|
|
|
(
|
|
|
|
|
FTabManager::NewStack() ->SetSizeCoefficient(0.73f) ->SetHideTabWell( true )
|
|
|
|
|
->AddTab( PreviewTabId, ETabState::OpenedTab )
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const bool bCreateDefaultStandaloneMenu = true;
|
|
|
|
|
const bool bCreateDefaultToolbar = true;
|
|
|
|
|
FAssetEditorToolkit::InitAssetEditor( Mode, InitToolkitHost, MaterialInstanceEditorAppIdentifier, StandaloneDefaultLayout, bCreateDefaultStandaloneMenu, bCreateDefaultToolbar, ObjectToEdit );
|
|
|
|
|
|
|
|
|
|
IMaterialEditorModule* MaterialEditorModule = &FModuleManager::LoadModuleChecked<IMaterialEditorModule>( "MaterialEditor" );
|
|
|
|
|
AddMenuExtender(MaterialEditorModule->GetMenuExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
|
|
|
|
|
|
|
|
|
|
ExtendToolbar();
|
|
|
|
|
RegenerateMenusAndToolbars();
|
|
|
|
|
|
|
|
|
|
// @todo toolkit world centric editing
|
|
|
|
|
/*if( IsWorldCentricAssetEditor() )
|
|
|
|
|
{
|
|
|
|
|
SpawnToolkitTab(GetToolbarTabId(), FString(), EToolkitTabSpot::ToolBar);
|
|
|
|
|
SpawnToolkitTab(PreviewTabId, FString(), EToolkitTabSpot::Viewport);
|
|
|
|
|
SpawnToolkitTab(PropertiesTabId, FString(), EToolkitTabSpot::Details);
|
|
|
|
|
SpawnToolkitTab(ParentsTabId, FString(), EToolkitTabSpot::Details);
|
|
|
|
|
}*/
|
|
|
|
|
|
|
|
|
|
// Load editor settings.
|
|
|
|
|
LoadSettings();
|
|
|
|
|
|
|
|
|
|
// Set the preview mesh for the material. This call must occur after the toolbar is initialized.
|
|
|
|
|
USceneThumbnailInfoWithPrimitive* ThumbnailInfoWithPrim = Cast<USceneThumbnailInfoWithPrimitive>(InstanceConstant->ThumbnailInfo);
|
|
|
|
|
if ( ThumbnailInfoWithPrim )
|
|
|
|
|
{
|
|
|
|
|
InstanceConstant->PreviewMesh = ThumbnailInfoWithPrim->PreviewMesh;
|
|
|
|
|
}
|
2015-02-19 00:33:19 -05:00
|
|
|
SetPreviewAssetByName(*InstanceConstant->PreviewMesh.ToString());
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FMaterialInstanceEditor::~FMaterialInstanceEditor()
|
|
|
|
|
{
|
|
|
|
|
GEditor->UnregisterForUndo( this );
|
|
|
|
|
|
|
|
|
|
MaterialEditorInstance = NULL;
|
|
|
|
|
ParentList.Empty();
|
|
|
|
|
|
|
|
|
|
SaveSettings();
|
|
|
|
|
|
|
|
|
|
MaterialInstanceDetails.Reset();
|
|
|
|
|
MaterialInstanceParentsList.Reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::AddReferencedObjects(FReferenceCollector& Collector)
|
|
|
|
|
{
|
|
|
|
|
// Serialize our custom object instance
|
|
|
|
|
Collector.AddReferencedObject(MaterialEditorInstance);
|
|
|
|
|
|
|
|
|
|
// Serialize all parent material instances that are stored in the list.
|
|
|
|
|
for (int32 Index = 0; Index < ParentList.Num(); Index++)
|
|
|
|
|
{
|
|
|
|
|
UMaterialInterface* Parent = ParentList[Index].Get();
|
|
|
|
|
Collector.AddReferencedObject(Parent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::BindCommands()
|
|
|
|
|
{
|
|
|
|
|
const FMaterialEditorCommands& Commands = FMaterialEditorCommands::Get();
|
|
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction(
|
|
|
|
|
Commands.ShowAllMaterialParameters,
|
|
|
|
|
FExecuteAction::CreateSP( this, &FMaterialInstanceEditor::ToggleShowAllMaterialParameters ),
|
|
|
|
|
FCanExecuteAction(),
|
|
|
|
|
FIsActionChecked::CreateSP( this, &FMaterialInstanceEditor::IsShowAllMaterialParametersChecked ) );
|
|
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction(
|
|
|
|
|
FEditorViewportCommands::Get().ToggleRealTime,
|
2015-03-09 10:00:46 -04:00
|
|
|
FExecuteAction::CreateSP( PreviewVC.ToSharedRef(), &SMaterialEditorViewport::OnToggleRealtime ),
|
2014-03-14 14:13:41 -04:00
|
|
|
FCanExecuteAction(),
|
|
|
|
|
FIsActionChecked::CreateSP( PreviewVC.ToSharedRef(), &SMaterialEditorViewport::IsRealtime ) );
|
|
|
|
|
|
|
|
|
|
ToolkitCommands->MapAction(
|
|
|
|
|
Commands.ToggleMobileStats,
|
|
|
|
|
FExecuteAction::CreateSP( this, &FMaterialInstanceEditor::ToggleMobileStats ),
|
|
|
|
|
FCanExecuteAction(),
|
|
|
|
|
FIsActionChecked::CreateSP( this, &FMaterialInstanceEditor::IsToggleMobileStatsChecked ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::ToggleShowAllMaterialParameters()
|
|
|
|
|
{
|
|
|
|
|
bShowAllMaterialParameters = !bShowAllMaterialParameters;
|
|
|
|
|
UpdatePropertyWindow();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FMaterialInstanceEditor::IsShowAllMaterialParametersChecked() const
|
|
|
|
|
{
|
|
|
|
|
return bShowAllMaterialParameters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::ToggleMobileStats()
|
|
|
|
|
{
|
|
|
|
|
bShowMobileStats = !bShowMobileStats;
|
|
|
|
|
UMaterialInstanceConstant* MIC = Cast<UMaterialInstanceConstant>(GetMaterialInterface());
|
|
|
|
|
if (bShowMobileStats && MIC)
|
|
|
|
|
{
|
|
|
|
|
UMaterial* BaseMaterial = MIC->GetBaseMaterial();
|
|
|
|
|
if (BaseMaterial)
|
|
|
|
|
{
|
|
|
|
|
FMaterialUpdateContext UpdateContext;
|
|
|
|
|
UpdateContext.AddMaterial(BaseMaterial);
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
MIC->SetFeatureLevelToCompile(ERHIFeatureLevel::ES2,bShowMobileStats);
|
|
|
|
|
if (MIC->bHasStaticPermutationResource)
|
|
|
|
|
{
|
|
|
|
|
MIC->ForceRecompileForRendering();
|
|
|
|
|
}
|
|
|
|
|
MIC = Cast<UMaterialInstanceConstant>(MIC->Parent);
|
|
|
|
|
} while (MIC);
|
|
|
|
|
BaseMaterial->SetFeatureLevelToCompile(ERHIFeatureLevel::ES2,bShowMobileStats);
|
|
|
|
|
BaseMaterial->ForceRecompileForRendering();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
PreviewVC->RefreshViewport();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool FMaterialInstanceEditor::IsToggleMobileStatsChecked() const
|
|
|
|
|
{
|
|
|
|
|
return bShowMobileStats;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::OnOpenMaterial()
|
|
|
|
|
{
|
|
|
|
|
OpenSelectedParentEditor( GetSelectedParent() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::OnShowInContentBrowser()
|
|
|
|
|
{
|
|
|
|
|
SyncSelectedParentToGB();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::OnInheritanceListDoubleClick( TWeakObjectPtr<UMaterialInterface> InMaterialInterface )
|
|
|
|
|
{
|
|
|
|
|
OpenSelectedParentEditor( InMaterialInterface.Get() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedPtr<SWidget> FMaterialInstanceEditor::OnInheritanceListRightClick()
|
|
|
|
|
{
|
|
|
|
|
UMaterialInterface* SelectedMaterialInterface = GetSelectedParent();
|
|
|
|
|
|
|
|
|
|
// Get all menu extenders for this context menu from the material editor module
|
|
|
|
|
IMaterialEditorModule& MaterialEditor = FModuleManager::GetModuleChecked<IMaterialEditorModule>( TEXT("MaterialEditor") );
|
|
|
|
|
TArray<IMaterialEditorModule::FMaterialMenuExtender_MaterialInterface> MenuExtenderDelegates = MaterialEditor.GetAllMaterialDragDropContextMenuExtenders();
|
|
|
|
|
|
|
|
|
|
TArray<TSharedPtr<FExtender>> Extenders;
|
|
|
|
|
for (int32 i = 0; i < MenuExtenderDelegates.Num(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (MenuExtenderDelegates[i].IsBound())
|
|
|
|
|
{
|
|
|
|
|
Extenders.Add(MenuExtenderDelegates[i].Execute(SelectedMaterialInterface));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
TSharedPtr<FExtender> MenuExtender = FExtender::Combine(Extenders);
|
|
|
|
|
|
|
|
|
|
const bool bCloseAfterSelection = true;
|
|
|
|
|
FMenuBuilder MenuBuilder( bCloseAfterSelection, NULL, MenuExtender );
|
|
|
|
|
|
|
|
|
|
MenuBuilder.BeginSection("MaterialInstanceOptions", LOCTEXT("ParentOptions", "Options") );
|
|
|
|
|
{
|
|
|
|
|
// If this material isn't the currently open one, present the user an option to open it
|
|
|
|
|
if(MaterialEditorInstance->SourceInstance!=SelectedMaterialInterface)
|
|
|
|
|
{
|
|
|
|
|
check(SelectedMaterialInterface != NULL )
|
|
|
|
|
FText Label;
|
|
|
|
|
|
|
|
|
|
if(SelectedMaterialInterface->IsA(UMaterial::StaticClass()))
|
|
|
|
|
{
|
|
|
|
|
Label = NSLOCTEXT("UnrealEd", "MaterialEditor", "Material Editor");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Label = NSLOCTEXT("UnrealEd", "MaterialInstanceEditor", "Material Instance Editor");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MenuBuilder.AddMenuEntry(
|
|
|
|
|
Label,
|
|
|
|
|
LOCTEXT("OpenMaterialTooltilp", "Opens the selected material for editing"),
|
|
|
|
|
FSlateIcon(),
|
|
|
|
|
FUIAction(
|
|
|
|
|
FExecuteAction::CreateSP( this, &FMaterialInstanceEditor::OnOpenMaterial ),
|
|
|
|
|
FCanExecuteAction()
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MenuBuilder.AddMenuEntry(
|
|
|
|
|
LOCTEXT("ShowInCB", "Find in Content Browser..."),
|
|
|
|
|
LOCTEXT("ShowInCBTooltilp", "Finds the selected material in the Content Browser"),
|
|
|
|
|
FSlateIcon(),
|
|
|
|
|
FUIAction(
|
|
|
|
|
FExecuteAction::CreateSP( this, &FMaterialInstanceEditor::OnShowInContentBrowser ),
|
|
|
|
|
FCanExecuteAction()
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
MenuBuilder.EndSection();
|
|
|
|
|
|
|
|
|
|
return MenuBuilder.MakeWidget();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedRef<ITableRow> FMaterialInstanceEditor::OnInheritanceListGenerateRow( TWeakObjectPtr<UMaterialInterface> InMaterialInterface, const TSharedRef<STableViewBase>& OwnerTable )
|
|
|
|
|
{
|
|
|
|
|
// Find the right index to attribute to the material in the widget
|
|
|
|
|
int32 TempIndex, Index = -1;
|
|
|
|
|
if ( ParentList.Find( InMaterialInterface, TempIndex ) )
|
|
|
|
|
{
|
|
|
|
|
if ( TempIndex == 0 )
|
|
|
|
|
{
|
|
|
|
|
Index = 0;
|
|
|
|
|
}
|
|
|
|
|
else if ( TempIndex < ParentList.Num() - 1 )
|
|
|
|
|
{
|
|
|
|
|
Index = ParentList.Num() - 1 - TempIndex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
SNew(SMaterialTreeWidgetItem, OwnerTable)
|
|
|
|
|
.WidgetInfoToVisualize(InMaterialInterface)
|
|
|
|
|
.ParentIndex( Index );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UMaterialInterface* FMaterialInstanceEditor::GetSelectedParent() const
|
|
|
|
|
{
|
|
|
|
|
TArray< TWeakObjectPtr<UMaterialInterface> > SelectedItems = MaterialInstanceParentsList->GetSelectedItems();
|
|
|
|
|
UMaterialInterface* SelectedMaterialInterface = NULL;
|
|
|
|
|
if( SelectedItems.Num() > 0 )
|
|
|
|
|
{
|
|
|
|
|
check( SelectedItems.Last().IsValid() );
|
|
|
|
|
SelectedMaterialInterface = SelectedItems.Last().Get();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SelectedMaterialInterface = MaterialEditorInstance->SourceInstance;
|
|
|
|
|
}
|
|
|
|
|
return SelectedMaterialInterface;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::CreateInternalWidgets()
|
|
|
|
|
{
|
|
|
|
|
PreviewVC = SNew(SMaterialEditorViewport)
|
|
|
|
|
.MaterialEditor(SharedThis(this));
|
|
|
|
|
|
|
|
|
|
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>( "PropertyEditor" );
|
2015-01-26 17:14:50 -05:00
|
|
|
const FDetailsViewArgs DetailsViewArgs( false, false, true, FDetailsViewArgs::HideNameArea, true, this );
|
2014-03-14 14:13:41 -04:00
|
|
|
MaterialInstanceDetails = PropertyEditorModule.CreateDetailView( DetailsViewArgs );
|
|
|
|
|
FOnGetDetailCustomizationInstance LayoutMICDetails = FOnGetDetailCustomizationInstance::CreateStatic(
|
|
|
|
|
&FMaterialInstanceParameterDetails::MakeInstance, MaterialEditorInstance, FGetShowHiddenParameters::CreateSP(this, &FMaterialInstanceEditor::GetShowHiddenParameters) );
|
|
|
|
|
MaterialInstanceDetails->RegisterInstancedCustomPropertyLayout( UMaterialEditorInstanceConstant::StaticClass(), LayoutMICDetails );
|
|
|
|
|
|
|
|
|
|
MaterialInstanceParentsList = SNew(SListView<TWeakObjectPtr<UMaterialInterface>>)
|
|
|
|
|
.SelectionMode(ESelectionMode::Single)
|
|
|
|
|
.ListItemsSource( &ParentList )
|
|
|
|
|
.OnGenerateRow( this, &FMaterialInstanceEditor::OnInheritanceListGenerateRow )
|
|
|
|
|
.OnContextMenuOpening(this, &FMaterialInstanceEditor::OnInheritanceListRightClick)
|
|
|
|
|
.OnMouseButtonDoubleClick(this, &FMaterialInstanceEditor::OnInheritanceListDoubleClick)
|
|
|
|
|
.HeaderRow
|
|
|
|
|
(
|
|
|
|
|
SNew(SHeaderRow)
|
|
|
|
|
+SHeaderRow::Column(FName(TEXT("Parent")))
|
|
|
|
|
.DefaultLabel(NSLOCTEXT("MaterialInstanceEditor", "Parent", "Parent"))
|
|
|
|
|
+SHeaderRow::Column(FName(TEXT("Name")))
|
|
|
|
|
.DefaultLabel(NSLOCTEXT("MaterialInstanceEditor", "Name", "Name"))
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::ExtendToolbar()
|
|
|
|
|
{
|
|
|
|
|
struct Local
|
|
|
|
|
{
|
|
|
|
|
static void FillToolbar(FToolBarBuilder& ToolbarBuilder)
|
|
|
|
|
{
|
|
|
|
|
ToolbarBuilder.BeginSection("Command");
|
|
|
|
|
{
|
|
|
|
|
ToolbarBuilder.AddToolBarButton(FMaterialEditorCommands::Get().ShowAllMaterialParameters);
|
|
|
|
|
// TODO: support in material instance editor.
|
|
|
|
|
ToolbarBuilder.AddToolBarButton(FMaterialEditorCommands::Get().ToggleMobileStats);
|
|
|
|
|
}
|
|
|
|
|
ToolbarBuilder.EndSection();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
|
|
|
|
|
|
|
|
|
|
ToolbarExtender->AddToolBarExtension(
|
|
|
|
|
"Asset",
|
|
|
|
|
EExtensionHook::After,
|
|
|
|
|
GetToolkitCommands(),
|
|
|
|
|
FToolBarExtensionDelegate::CreateStatic( &Local::FillToolbar )
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
AddToolbarExtender(ToolbarExtender);
|
|
|
|
|
|
|
|
|
|
IMaterialEditorModule* MaterialEditorModule = &FModuleManager::LoadModuleChecked<IMaterialEditorModule>( "MaterialEditor" );
|
|
|
|
|
AddToolbarExtender(MaterialEditorModule->GetToolBarExtensibilityManager()->GetAllExtenders(GetToolkitCommands(), GetEditingObjects()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> FMaterialInstanceEditor::SpawnTab_Preview( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == PreviewTabId );
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> SpawnedTab = SNew(SDockTab)
|
|
|
|
|
.Label(LOCTEXT("ViewportTabTitle", "Viewport"))
|
|
|
|
|
[
|
|
|
|
|
PreviewVC.ToSharedRef()
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
PreviewVC->OnAddedToTab( SpawnedTab );
|
|
|
|
|
|
|
|
|
|
AddToSpawnedToolPanels( Args.GetTabId().TabType, SpawnedTab );
|
|
|
|
|
return SpawnedTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> FMaterialInstanceEditor::SpawnTab_Properties( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == PropertiesTabId );
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> SpawnedTab = SNew(SDockTab)
|
|
|
|
|
.Icon( FEditorStyle::GetBrush("MaterialInstanceEditor.Tabs.Properties") )
|
|
|
|
|
.Label(LOCTEXT("MaterialPropertiesTitle", "Details"))
|
|
|
|
|
[
|
|
|
|
|
SNew(SBorder)
|
|
|
|
|
.Padding(4)
|
|
|
|
|
[
|
|
|
|
|
MaterialInstanceDetails.ToSharedRef()
|
|
|
|
|
]
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
UpdatePropertyWindow();
|
|
|
|
|
|
|
|
|
|
AddToSpawnedToolPanels( Args.GetTabId().TabType, SpawnedTab );
|
|
|
|
|
return SpawnedTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> FMaterialInstanceEditor::SpawnTab_Parents( const FSpawnTabArgs& Args )
|
|
|
|
|
{
|
|
|
|
|
check( Args.GetTabId().TabType == ParentsTabId );
|
|
|
|
|
|
|
|
|
|
TSharedRef<SDockTab> SpawnedTab = SNew(SDockTab)
|
|
|
|
|
.Icon( FEditorStyle::GetBrush("MaterialInstanceEditor.Tabs.Parents") )
|
|
|
|
|
.Label( LOCTEXT("MaterialParentsTitle", "Instance Parents") )
|
|
|
|
|
[
|
|
|
|
|
MaterialInstanceParentsList.ToSharedRef()
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
RebuildInheritanceList();
|
|
|
|
|
|
|
|
|
|
AddToSpawnedToolPanels( Args.GetTabId().TabType, SpawnedTab );
|
|
|
|
|
return SpawnedTab;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::AddToSpawnedToolPanels( const FName& TabIdentifier, const TSharedRef<SDockTab>& SpawnedTab )
|
|
|
|
|
{
|
|
|
|
|
TWeakPtr<SDockTab>* TabSpot = SpawnedToolPanels.Find(TabIdentifier);
|
|
|
|
|
if (!TabSpot)
|
|
|
|
|
{
|
|
|
|
|
SpawnedToolPanels.Add(TabIdentifier, SpawnedTab);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
check(!TabSpot->IsValid());
|
|
|
|
|
*TabSpot = SpawnedTab;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FName FMaterialInstanceEditor::GetToolkitFName() const
|
|
|
|
|
{
|
|
|
|
|
return FName("MaterialInstanceEditor");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FText FMaterialInstanceEditor::GetBaseToolkitName() const
|
|
|
|
|
{
|
|
|
|
|
return LOCTEXT("AppLabel", "Material Instance Editor");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FString FMaterialInstanceEditor::GetWorldCentricTabPrefix() const
|
|
|
|
|
{
|
|
|
|
|
return LOCTEXT("WorldCentricTabPrefix", "Material Instance ").ToString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLinearColor FMaterialInstanceEditor::GetWorldCentricTabColorScale() const
|
|
|
|
|
{
|
|
|
|
|
return FLinearColor( 0.3f, 0.2f, 0.5f, 0.5f );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UMaterialInterface* FMaterialInstanceEditor::GetMaterialInterface() const
|
|
|
|
|
{
|
|
|
|
|
return MaterialEditorInstance->SourceInstance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::NotifyPreChange(UProperty* PropertyThatChanged)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::NotifyPostChange( const FPropertyChangedEvent& PropertyChangedEvent, UProperty* PropertyThatChanged)
|
|
|
|
|
{
|
|
|
|
|
// Update the preview window when the user changes a property.
|
|
|
|
|
PreviewVC->RefreshViewport();
|
|
|
|
|
|
|
|
|
|
// If they changed the parent, regenerate the parent list.
|
|
|
|
|
if(PropertyThatChanged->GetName()==TEXT("Parent"))
|
|
|
|
|
{
|
|
|
|
|
bool bSetEmptyParent = false;
|
|
|
|
|
|
|
|
|
|
// Check to make sure they didnt set the parent to themselves.
|
|
|
|
|
if(MaterialEditorInstance->Parent==MaterialEditorInstance->SourceInstance)
|
|
|
|
|
{
|
|
|
|
|
bSetEmptyParent = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bSetEmptyParent)
|
|
|
|
|
{
|
|
|
|
|
MaterialEditorInstance->Parent = NULL;
|
|
|
|
|
|
|
|
|
|
if(MaterialEditorInstance->SourceInstance)
|
|
|
|
|
{
|
|
|
|
|
MaterialEditorInstance->SourceInstance->SetParentEditorOnly(NULL);
|
|
|
|
|
MaterialEditorInstance->SourceInstance->PostEditChange();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RebuildInheritanceList();
|
|
|
|
|
|
|
|
|
|
UpdatePropertyWindow();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//rebuild the property window to account for the possibility that the item changed was
|
|
|
|
|
//a static switch
|
|
|
|
|
|
2014-10-01 14:45:23 -04:00
|
|
|
UObject* PropertyClass = PropertyThatChanged->GetOuter();
|
2014-03-14 14:13:41 -04:00
|
|
|
if(PropertyClass && PropertyClass->GetName() == TEXT("DEditorStaticSwitchParameterValue") && MaterialEditorInstance->Parent && MaterialEditorInstance->SourceInstance )
|
|
|
|
|
{
|
|
|
|
|
TArray<FGuid> PreviousExpressions(MaterialEditorInstance->VisibleExpressions);
|
|
|
|
|
MaterialEditorInstance->VisibleExpressions.Empty();
|
|
|
|
|
FMaterialEditorUtilities::GetVisibleMaterialParameters(MaterialEditorInstance->Parent->GetMaterial(), MaterialEditorInstance->SourceInstance, MaterialEditorInstance->VisibleExpressions);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::RebuildInheritanceList()
|
|
|
|
|
{
|
|
|
|
|
MaterialInstanceParentsList->ClearSelection();
|
|
|
|
|
ParentList.Empty();
|
|
|
|
|
|
|
|
|
|
// Travel up the parent chain for this material instance until we reach the root material.
|
|
|
|
|
UMaterialInstance* InstanceConstant = MaterialEditorInstance->SourceInstance;
|
|
|
|
|
|
|
|
|
|
if(InstanceConstant)
|
|
|
|
|
{
|
|
|
|
|
ParentList.Add(InstanceConstant);
|
|
|
|
|
|
|
|
|
|
// Add all parents
|
|
|
|
|
UMaterialInterface* Parent = InstanceConstant->Parent;
|
|
|
|
|
while(Parent && Parent != InstanceConstant)
|
|
|
|
|
{
|
|
|
|
|
ParentList.Insert(Parent,0);
|
|
|
|
|
|
|
|
|
|
// If the parent is a material then break.
|
|
|
|
|
InstanceConstant = Cast<UMaterialInstance>(Parent);
|
|
|
|
|
|
|
|
|
|
if(InstanceConstant)
|
|
|
|
|
{
|
|
|
|
|
Parent = InstanceConstant->Parent;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// MaterialInstanceParentsList->SetSelection( MaterialEditorInstance->SourceInstance );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaterialInstanceParentsList->RequestListRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::RebuildMaterialInstanceEditor()
|
|
|
|
|
{
|
|
|
|
|
if( MaterialEditorInstance )
|
|
|
|
|
{
|
|
|
|
|
MaterialEditorInstance->RegenerateArrays();
|
|
|
|
|
RebuildInheritanceList(); // Required b/c recompiled parent materials result in invalid weak object pointers
|
|
|
|
|
UpdatePropertyWindow();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::DrawMessages( FViewport* Viewport, FCanvas* Canvas )
|
|
|
|
|
{
|
|
|
|
|
Canvas->PushAbsoluteTransform(FMatrix::Identity);
|
|
|
|
|
if ( MaterialEditorInstance->Parent && MaterialEditorInstance->SourceInstance )
|
|
|
|
|
{
|
2014-10-01 09:08:51 -04:00
|
|
|
const FMaterialResource* MaterialResource = MaterialEditorInstance->SourceInstance->GetMaterialResource(GMaxRHIFeatureLevel);
|
2014-03-14 14:13:41 -04:00
|
|
|
UMaterial* BaseMaterial = MaterialEditorInstance->SourceInstance->GetMaterial();
|
|
|
|
|
int32 DrawPositionY = 5;
|
|
|
|
|
if ( BaseMaterial && MaterialResource )
|
|
|
|
|
{
|
|
|
|
|
FMaterialEditor::DrawMaterialInfoStrings( Canvas, BaseMaterial, MaterialResource, MaterialResource->GetCompileErrors(), DrawPositionY, true );
|
|
|
|
|
}
|
|
|
|
|
if (bShowMobileStats)
|
|
|
|
|
{
|
|
|
|
|
const FMaterialResource* MaterialResourceES2 = MaterialEditorInstance->SourceInstance->GetMaterialResource(ERHIFeatureLevel::ES2);
|
|
|
|
|
if ( BaseMaterial && MaterialResourceES2 )
|
|
|
|
|
{
|
|
|
|
|
FMaterialEditor::DrawMaterialInfoStrings( Canvas, BaseMaterial, MaterialResourceES2, MaterialResourceES2->GetCompileErrors(), DrawPositionY, true );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
DrawSamplerWarningStrings( Canvas, DrawPositionY );
|
|
|
|
|
}
|
|
|
|
|
Canvas->PopTransform();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Draws sampler/texture mismatch warning strings.
|
|
|
|
|
* @param Canvas - The canvas on which to draw.
|
|
|
|
|
* @param DrawPositionY - The Y position at which to draw. Upon return contains the Y value following the last line of text drawn.
|
|
|
|
|
*/
|
|
|
|
|
void FMaterialInstanceEditor::DrawSamplerWarningStrings(FCanvas* Canvas, int32& DrawPositionY)
|
|
|
|
|
{
|
|
|
|
|
if ( MaterialEditorInstance->SourceInstance )
|
|
|
|
|
{
|
|
|
|
|
UMaterial* BaseMaterial = MaterialEditorInstance->SourceInstance->GetMaterial();
|
|
|
|
|
if ( BaseMaterial )
|
|
|
|
|
{
|
|
|
|
|
UFont* FontToUse = GEngine->GetTinyFont();
|
|
|
|
|
const int32 SpacingBetweenLines = 13;
|
2015-01-20 09:33:54 -05:00
|
|
|
UEnum* SamplerTypeEnum = FindObject<UEnum>( NULL, TEXT("/Script/Engine.EMaterialSamplerType") );
|
2014-03-14 14:13:41 -04:00
|
|
|
check( SamplerTypeEnum );
|
|
|
|
|
|
|
|
|
|
const int32 GroupCount = MaterialEditorInstance->ParameterGroups.Num();
|
|
|
|
|
for ( int32 GroupIndex = 0; GroupIndex < GroupCount; ++GroupIndex )
|
|
|
|
|
{
|
|
|
|
|
const FEditorParameterGroup& Group = MaterialEditorInstance->ParameterGroups[ GroupIndex ];
|
|
|
|
|
const int32 ParameterCount = Group.Parameters.Num();
|
|
|
|
|
for ( int32 ParameterIndex = 0; ParameterIndex < ParameterCount; ++ParameterIndex )
|
|
|
|
|
{
|
|
|
|
|
UDEditorTextureParameterValue* TextureParameterValue = Cast<UDEditorTextureParameterValue>( Group.Parameters[ ParameterIndex ] );
|
|
|
|
|
if ( TextureParameterValue && TextureParameterValue->ExpressionId.IsValid() )
|
|
|
|
|
{
|
|
|
|
|
UTexture* Texture = NULL;
|
|
|
|
|
MaterialEditorInstance->SourceInstance->GetTextureParameterValue( TextureParameterValue->ParameterName, Texture );
|
|
|
|
|
if ( Texture )
|
|
|
|
|
{
|
|
|
|
|
EMaterialSamplerType SamplerType = UMaterialExpressionTextureBase::GetSamplerTypeForTexture( Texture );
|
|
|
|
|
UMaterialExpressionTextureSampleParameter* Expression = BaseMaterial->FindExpressionByGUID<UMaterialExpressionTextureSampleParameter>( TextureParameterValue->ExpressionId );
|
|
|
|
|
|
|
|
|
|
// We want a crash report if that happens
|
|
|
|
|
ensure(Expression);
|
|
|
|
|
|
|
|
|
|
if ( Expression && Expression->SamplerType != SamplerType )
|
|
|
|
|
{
|
|
|
|
|
FString SamplerTypeDisplayName;
|
|
|
|
|
if ( SamplerTypeEnum->HasMetaData( TEXT("DisplayName"), Expression->SamplerType ) )
|
|
|
|
|
{
|
|
|
|
|
SamplerTypeDisplayName = SamplerTypeEnum->GetMetaData( TEXT("DisplayName"), Expression->SamplerType );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SamplerTypeDisplayName = SamplerTypeEnum->GetEnumName( Expression->SamplerType );
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-02 18:09:23 -04:00
|
|
|
Canvas->DrawShadowedString(
|
2014-03-14 14:13:41 -04:00
|
|
|
5,
|
|
|
|
|
DrawPositionY,
|
|
|
|
|
*FString::Printf( TEXT("Warning: %s samples %s as %s."),
|
|
|
|
|
*TextureParameterValue->ParameterName.ToString(),
|
|
|
|
|
*Texture->GetPathName(),
|
|
|
|
|
*SamplerTypeDisplayName ),
|
|
|
|
|
FontToUse,
|
|
|
|
|
FLinearColor(1,1,0) );
|
|
|
|
|
DrawPositionY += SpacingBetweenLines;
|
|
|
|
|
}
|
|
|
|
|
if( Expression && ((Expression->SamplerType == (EMaterialSamplerType)TC_Normalmap || Expression->SamplerType == (EMaterialSamplerType)TC_Masks) && Texture->SRGB))
|
|
|
|
|
{
|
|
|
|
|
FString SamplerTypeDisplayName;
|
|
|
|
|
if ( SamplerTypeEnum->HasMetaData( TEXT("DisplayName"), Expression->SamplerType ) )
|
|
|
|
|
{
|
|
|
|
|
SamplerTypeDisplayName = SamplerTypeEnum->GetMetaData( TEXT("DisplayName"), Expression->SamplerType );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SamplerTypeDisplayName = SamplerTypeEnum->GetEnumName( Expression->SamplerType );
|
|
|
|
|
}
|
|
|
|
|
|
2014-04-02 18:09:23 -04:00
|
|
|
Canvas->DrawShadowedString(
|
2014-03-14 14:13:41 -04:00
|
|
|
5,
|
|
|
|
|
DrawPositionY,
|
|
|
|
|
*FString::Printf( TEXT("Warning: %s samples texture as '%s'. SRGB should be disabled for '%s'."),
|
|
|
|
|
*TextureParameterValue->ParameterName.ToString(),
|
|
|
|
|
*SamplerTypeDisplayName,
|
|
|
|
|
*Texture->GetPathName()),
|
|
|
|
|
FontToUse,
|
|
|
|
|
FLinearColor(1,1,0) );
|
|
|
|
|
DrawPositionY += SpacingBetweenLines;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 00:33:19 -05:00
|
|
|
bool FMaterialInstanceEditor::SetPreviewAsset(UObject* InAsset)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
|
|
|
|
if (PreviewVC.IsValid())
|
|
|
|
|
{
|
2015-02-19 00:33:19 -05:00
|
|
|
return PreviewVC->SetPreviewAsset(InAsset);
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 00:33:19 -05:00
|
|
|
bool FMaterialInstanceEditor::SetPreviewAssetByName(const TCHAR* InAssetName)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
|
|
|
|
if (PreviewVC.IsValid())
|
|
|
|
|
{
|
2015-02-19 00:33:19 -05:00
|
|
|
return PreviewVC->SetPreviewAssetByName(InAssetName);
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::SetPreviewMaterial(UMaterialInterface* InMaterialInterface)
|
|
|
|
|
{
|
|
|
|
|
if (PreviewVC.IsValid())
|
|
|
|
|
{
|
|
|
|
|
PreviewVC->SetPreviewMaterial(InMaterialInterface);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::GetShowHiddenParameters(bool& bShowHiddenParameters)
|
|
|
|
|
{
|
|
|
|
|
bShowHiddenParameters = bShowAllMaterialParameters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::SaveSettings()
|
|
|
|
|
{
|
|
|
|
|
// Save the preview scene
|
|
|
|
|
if(PreviewVC.IsValid())
|
|
|
|
|
{
|
|
|
|
|
PreviewVC->PreviewScene.SaveSettings(TEXT("MaterialInstanceEditor"));
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-20 10:12:55 -04:00
|
|
|
GConfig->SetBool(TEXT("MaterialInstanceEditor"), TEXT("bShowGrid"), PreviewVC->IsTogglePreviewGridChecked(), GEditorPerProjectIni);
|
|
|
|
|
GConfig->SetBool(TEXT("MaterialInstanceEditor"), TEXT("bDrawGrid"), PreviewVC->IsRealtime(), GEditorPerProjectIni);
|
|
|
|
|
GConfig->SetInt(TEXT("MaterialInstanceEditor"), TEXT("PrimType"), PreviewVC->PreviewPrimType, GEditorPerProjectIni);
|
|
|
|
|
GConfig->SetBool(TEXT("MaterialInstanceEditor"), TEXT("bWantsMobileStats"), IsToggleMobileStatsChecked(), GEditorPerProjectIni);
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::LoadSettings()
|
|
|
|
|
{
|
|
|
|
|
bool bRealtime=false;
|
|
|
|
|
bool bShowGrid=false;
|
|
|
|
|
int32 PrimType=static_cast<EThumbnailPrimType>( TPT_Sphere );
|
|
|
|
|
bool bWantsMobileStats=false;
|
2015-04-20 10:12:55 -04:00
|
|
|
GConfig->GetBool(TEXT("MaterialInstanceEditor"), TEXT("bShowGrid"), bShowGrid, GEditorPerProjectIni);
|
|
|
|
|
GConfig->GetBool(TEXT("MaterialInstanceEditor"), TEXT("bDrawGrid"), bRealtime, GEditorPerProjectIni);
|
|
|
|
|
GConfig->GetInt(TEXT("MaterialInstanceEditor"), TEXT("PrimType"), PrimType, GEditorPerProjectIni);
|
|
|
|
|
GConfig->GetBool(TEXT("MaterialInstanceEditor"), TEXT("bWantsMobileStats"), bWantsMobileStats, GEditorPerProjectIni);
|
2014-03-14 14:13:41 -04:00
|
|
|
|
|
|
|
|
if (bWantsMobileStats)
|
|
|
|
|
{
|
|
|
|
|
ToggleMobileStats();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(PreviewVC.IsValid())
|
|
|
|
|
{
|
|
|
|
|
if ( bShowGrid )
|
|
|
|
|
{
|
|
|
|
|
PreviewVC->TogglePreviewGrid();
|
|
|
|
|
}
|
|
|
|
|
if ( bRealtime )
|
|
|
|
|
{
|
2015-03-09 10:00:46 -04:00
|
|
|
PreviewVC->OnToggleRealtime();
|
2014-03-14 14:13:41 -04:00
|
|
|
}
|
|
|
|
|
PreviewVC->OnSetPreviewPrimitive( static_cast<EThumbnailPrimType>(PrimType) );
|
|
|
|
|
|
|
|
|
|
// Load the preview scene
|
|
|
|
|
PreviewVC->PreviewScene.LoadSettings(TEXT("MaterialInstanceEditor"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::SyncSelectedParentToGB()
|
|
|
|
|
{
|
|
|
|
|
TArray< UObject* > SelectedObjects;
|
|
|
|
|
SelectedObjects.Add( GetSelectedParent() );
|
|
|
|
|
GEditor->SyncBrowserToObjects(SelectedObjects);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::OpenSelectedParentEditor(UMaterialInterface* InMaterialInterface)
|
|
|
|
|
{
|
|
|
|
|
ensure(InMaterialInterface);
|
|
|
|
|
|
|
|
|
|
// See if its a material or material instance constant. Don't do anything if the user chose the current material instance.
|
|
|
|
|
if(InMaterialInterface && MaterialEditorInstance->SourceInstance!=InMaterialInterface)
|
|
|
|
|
{
|
|
|
|
|
if(InMaterialInterface->IsA(UMaterial::StaticClass()))
|
|
|
|
|
{
|
|
|
|
|
// Show material editor
|
|
|
|
|
UMaterial* Material = Cast<UMaterial>(InMaterialInterface);
|
|
|
|
|
FAssetEditorManager::Get().OpenEditorForAsset(Material);
|
|
|
|
|
}
|
|
|
|
|
else if(InMaterialInterface->IsA(UMaterialInstance::StaticClass()))
|
|
|
|
|
{
|
|
|
|
|
// Show material instance editor
|
|
|
|
|
UMaterialInstance* MaterialInstance = Cast<UMaterialInstance>(InMaterialInterface);
|
|
|
|
|
FAssetEditorManager::Get().OpenEditorForAsset(MaterialInstance);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::UpdatePropertyWindow()
|
|
|
|
|
{
|
|
|
|
|
TArray<UObject*> SelectedObjects;
|
|
|
|
|
SelectedObjects.Add( MaterialEditorInstance );
|
|
|
|
|
MaterialInstanceDetails->SetObjects( SelectedObjects, true );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UObject* FMaterialInstanceEditor::GetSyncObject()
|
|
|
|
|
{
|
|
|
|
|
if (MaterialEditorInstance)
|
|
|
|
|
{
|
|
|
|
|
return MaterialEditorInstance->SourceInstance;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 00:33:19 -05:00
|
|
|
bool FMaterialInstanceEditor::ApproveSetPreviewAsset(UObject* InAsset)
|
2014-03-14 14:13:41 -04:00
|
|
|
{
|
|
|
|
|
// Default impl is to always accept.
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::Refresh()
|
|
|
|
|
{
|
|
|
|
|
int32 TempIndex;
|
|
|
|
|
const bool bParentChanged = !ParentList.Find( MaterialEditorInstance->Parent, TempIndex );
|
|
|
|
|
|
|
|
|
|
PreviewVC->RefreshViewport();
|
|
|
|
|
|
|
|
|
|
if( bParentChanged )
|
|
|
|
|
{
|
|
|
|
|
RebuildInheritanceList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdatePropertyWindow();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::PostUndo( bool bSuccess )
|
|
|
|
|
{
|
2014-04-02 18:09:23 -04:00
|
|
|
MaterialEditorInstance->CopyToSourceInstance();
|
2014-03-14 14:13:41 -04:00
|
|
|
Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void FMaterialInstanceEditor::PostRedo( bool bSuccess )
|
|
|
|
|
{
|
2014-04-02 18:09:23 -04:00
|
|
|
MaterialEditorInstance->CopyToSourceInstance();
|
2014-03-14 14:13:41 -04:00
|
|
|
Refresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef LOCTEXT_NAMESPACE
|