2019-12-26 15:33:43 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-06-11 18:27:07 -04:00
# include "RuntimeVirtualTextureDetailsCustomization.h"
2020-08-11 01:36:57 -04:00
# include "AssetToolsModule.h"
2019-06-11 18:27:07 -04:00
# include "Components/RuntimeVirtualTextureComponent.h"
# include "DetailCategoryBuilder.h"
# include "DetailLayoutBuilder.h"
# include "DetailWidgetRow.h"
2020-09-24 00:43:27 -04:00
# include "Editor.h"
2020-08-11 01:36:57 -04:00
# include "Engine/Texture2D.h"
# include "Factories/Texture2dFactoryNew.h"
# include "RuntimeVirtualTextureBuildStreamingMips.h"
# include "RuntimeVirtualTextureSetBounds.h"
2019-08-21 09:07:42 -04:00
# include "ScopedTransaction.h"
2019-06-11 18:27:07 -04:00
# include "SResetToDefaultMenu.h"
2020-08-11 01:36:57 -04:00
# include "VirtualTextureBuilderFactory.h"
2019-06-11 18:27:07 -04:00
# include "VT/RuntimeVirtualTexture.h"
2020-08-11 01:36:57 -04:00
# include "VT/VirtualTextureBuilder.h"
2019-06-11 18:27:07 -04:00
# include "Widgets/Input/SButton.h"
# include "Widgets/Layout/SBox.h"
2020-09-24 00:43:27 -04:00
# include "Widgets/Images/SImage.h"
2019-06-11 18:27:07 -04:00
# include "Widgets/Layout/SWrapBox.h"
2022-10-26 12:57:32 -04:00
# include "Widgets/Text/STextBlock.h"
2019-06-11 18:27:07 -04:00
# define LOCTEXT_NAMESPACE "VirtualTexturingEditorModule"
FRuntimeVirtualTextureDetailsCustomization : : FRuntimeVirtualTextureDetailsCustomization ( )
: VirtualTexture ( nullptr )
{
}
TSharedRef < IDetailCustomization > FRuntimeVirtualTextureDetailsCustomization : : MakeInstance ( )
{
return MakeShareable ( new FRuntimeVirtualTextureDetailsCustomization ) ;
}
namespace
{
// Helper for adding text containing real values to the properties that are edited as power (or multiple) of 2
void AddTextToProperty ( IDetailLayoutBuilder & DetailBuilder , IDetailCategoryBuilder & CategoryBuilder , FName const & PropertyName , TSharedPtr < STextBlock > & TextBlock )
{
TSharedPtr < IPropertyHandle > PropertyHandle = DetailBuilder . GetProperty ( PropertyName ) ;
DetailBuilder . HideProperty ( PropertyHandle ) ;
TSharedPtr < SResetToDefaultMenu > ResetToDefaultMenu ;
CategoryBuilder . AddCustomRow ( PropertyHandle - > GetPropertyDisplayName ( ) )
. NameContent ( )
[
PropertyHandle - > CreatePropertyNameWidget ( )
]
. ValueContent ( )
. MinDesiredWidth ( 200.f )
[
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. Padding ( 4.0f )
[
SNew ( SWrapBox )
2020-04-16 17:02:30 -04:00
. UseAllottedSize ( true )
2019-06-11 18:27:07 -04:00
+ SWrapBox : : Slot ( )
. Padding ( FMargin ( 0.0f , 2.0f , 2.0f , 0.0f ) )
[
SAssignNew ( TextBlock , STextBlock )
]
]
+ SHorizontalBox : : Slot ( )
[
PropertyHandle - > CreatePropertyValueWidget ( )
]
+ SHorizontalBox : : Slot ( )
. AutoWidth ( )
. Padding ( 4.0f )
[
// Would be better to use SResetToDefaultPropertyEditor here but that is private in the PropertyEditor lib
SAssignNew ( ResetToDefaultMenu , SResetToDefaultMenu )
]
] ;
ResetToDefaultMenu - > AddProperty ( PropertyHandle . ToSharedRef ( ) ) ;
}
}
void FRuntimeVirtualTextureDetailsCustomization : : CustomizeDetails ( IDetailLayoutBuilder & DetailBuilder )
{
// Get and store the linked URuntimeVirtualTexture
TArray < TWeakObjectPtr < UObject > > ObjectsBeingCustomized ;
DetailBuilder . GetObjectsBeingCustomized ( ObjectsBeingCustomized ) ;
if ( ObjectsBeingCustomized . Num ( ) > 1 )
{
return ;
}
VirtualTexture = Cast < URuntimeVirtualTexture > ( ObjectsBeingCustomized [ 0 ] . Get ( ) ) ;
if ( VirtualTexture = = nullptr )
{
return ;
}
2020-10-22 19:19:16 -04:00
// Set UIMax dependent on adaptive page table setting
FString MaxTileCountString = FString : : Printf ( TEXT ( " %d " ) , URuntimeVirtualTexture : : GetMaxTileCountLog2 ( VirtualTexture - > GetAdaptivePageTable ( ) ) ) ;
DetailBuilder . GetProperty ( FName ( TEXT ( " TileCount " ) ) ) - > SetInstanceMetaData ( " UIMax " , MaxTileCountString ) ;
2019-06-11 18:27:07 -04:00
// Add size helpers
IDetailCategoryBuilder & SizeCategory = DetailBuilder . EditCategory ( " Size " , FText : : GetEmpty ( ) ) ;
2019-09-17 20:34:11 -04:00
AddTextToProperty ( DetailBuilder , SizeCategory , " TileCount " , TileCountText ) ;
2019-06-11 18:27:07 -04:00
AddTextToProperty ( DetailBuilder , SizeCategory , " TileSize " , TileSizeText ) ;
AddTextToProperty ( DetailBuilder , SizeCategory , " TileBorderSize " , TileBorderSizeText ) ;
// Add details block
IDetailCategoryBuilder & DetailsCategory = DetailBuilder . EditCategory ( " Details " , FText : : GetEmpty ( ) , ECategoryPriority : : Important ) ;
2020-10-22 19:19:16 -04:00
static const FText CustomRowSizeText = LOCTEXT ( " Details_RowFilter_Size " , " Virtual Size " ) ;
DetailsCategory . AddCustomRow ( CustomRowSizeText )
2020-09-24 00:43:27 -04:00
. NameContent ( )
2019-06-11 18:27:07 -04:00
[
2020-09-24 00:43:27 -04:00
SNew ( STextBlock )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
. Text ( LOCTEXT ( " Details_Size " , " Virtual Texture Size " ) )
. ToolTipText ( LOCTEXT ( " Details_Size_Tooltip " , " Virtual resolution derived from Size properties. " ) )
]
. ValueContent ( )
[
SAssignNew ( SizeText , STextBlock )
2019-06-11 18:27:07 -04:00
] ;
2020-10-22 19:19:16 -04:00
static const FText CustomRowPageTableSizeText = LOCTEXT ( " Details_RowFilter_PageTableSize " , " Page Table Size " ) ;
DetailsCategory . AddCustomRow ( CustomRowPageTableSizeText )
. NameContent ( )
[
SNew ( STextBlock )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
. Text ( LOCTEXT ( " Details_PageTableSize " , " Page Table Size " ) )
. ToolTipText ( LOCTEXT ( " Details_PageTableSize_Tooltip " , " Final page table size. This can vary according to the adaptive page table setting. " ) )
]
. ValueContent ( )
[
SAssignNew ( PageTableSizeText , STextBlock )
] ;
// Cache detail builder to refresh view updates
CachedDetailBuilder = & DetailBuilder ;
2019-06-11 18:27:07 -04:00
// Add refresh callback for all properties
2020-10-22 19:19:16 -04:00
DetailBuilder . GetProperty ( FName ( TEXT ( " TileCount " ) ) ) - > SetOnPropertyValueChanged ( FSimpleDelegate : : CreateSP ( this , & FRuntimeVirtualTextureDetailsCustomization : : RefreshTextDetails ) ) ;
DetailBuilder . GetProperty ( FName ( TEXT ( " TileSize " ) ) ) - > SetOnPropertyValueChanged ( FSimpleDelegate : : CreateSP ( this , & FRuntimeVirtualTextureDetailsCustomization : : RefreshTextDetails ) ) ;
DetailBuilder . GetProperty ( FName ( TEXT ( " TileBorderSize " ) ) ) - > SetOnPropertyValueChanged ( FSimpleDelegate : : CreateSP ( this , & FRuntimeVirtualTextureDetailsCustomization : : RefreshTextDetails ) ) ;
DetailBuilder . GetProperty ( FName ( TEXT ( " bAdaptive " ) ) ) - > SetOnPropertyValueChanged ( FSimpleDelegate : : CreateSP ( this , & FRuntimeVirtualTextureDetailsCustomization : : RefreshDetailsView ) ) ;
2019-06-11 18:27:07 -04:00
// Initialize text blocks
2020-10-22 19:19:16 -04:00
RefreshTextDetails ( ) ;
2019-06-11 18:27:07 -04:00
}
2020-10-22 19:19:16 -04:00
void FRuntimeVirtualTextureDetailsCustomization : : RefreshTextDetails ( )
2019-06-11 18:27:07 -04:00
{
FNumberFormattingOptions SizeOptions ;
SizeOptions . UseGrouping = false ;
SizeOptions . MaximumFractionalDigits = 0 ;
2019-09-17 20:34:11 -04:00
TileCountText - > SetText ( FText : : Format ( LOCTEXT ( " Details_Number " , " {0} " ) , FText : : AsNumber ( VirtualTexture - > GetTileCount ( ) , & SizeOptions ) ) ) ;
2020-10-22 19:19:16 -04:00
TileSizeText - > SetText ( FText : : Format ( LOCTEXT ( " Details_Number " , " {0} " ) , FText : : AsNumber ( VirtualTexture - > GetTileSize ( ) , & SizeOptions ) ) ) ;
2019-06-11 18:27:07 -04:00
TileBorderSizeText - > SetText ( FText : : Format ( LOCTEXT ( " Details_Number " , " {0} " ) , FText : : AsNumber ( VirtualTexture - > GetTileBorderSize ( ) , & SizeOptions ) ) ) ;
2020-10-22 19:19:16 -04:00
FString SizeUnits = TEXT ( " Texels " ) ;
int32 Size = VirtualTexture - > GetSize ( ) ;
int32 SizeLog2 = FMath : : CeilLogTwo ( Size ) ;
if ( SizeLog2 > = 30 )
{
Size = Size > > 30 ;
SizeUnits = TEXT ( " GiTexels " ) ;
}
else if ( SizeLog2 > = 20 )
{
Size = Size > > 20 ;
SizeUnits = TEXT ( " MiTexels " ) ;
}
else if ( SizeLog2 > = 10 )
{
Size = Size > > 10 ;
SizeUnits = TEXT ( " KiTexels " ) ;
}
SizeText - > SetText ( FText : : Format ( LOCTEXT ( " Details_Number_Units " , " {0} {1} " ) , FText : : AsNumber ( Size , & SizeOptions ) , FText : : FromString ( SizeUnits ) ) ) ;
PageTableSizeText - > SetText ( FText : : Format ( LOCTEXT ( " Details_Number " , " {0} " ) , FText : : AsNumber ( VirtualTexture - > GetPageTableSize ( ) , & SizeOptions ) ) ) ;
}
void FRuntimeVirtualTextureDetailsCustomization : : RefreshDetailsView ( )
{
if ( CachedDetailBuilder ! = nullptr )
{
CachedDetailBuilder - > ForceRefreshDetails ( ) ;
}
2019-06-11 18:27:07 -04:00
}
FRuntimeVirtualTextureComponentDetailsCustomization : : FRuntimeVirtualTextureComponentDetailsCustomization ( )
{
}
TSharedRef < IDetailCustomization > FRuntimeVirtualTextureComponentDetailsCustomization : : MakeInstance ( )
{
return MakeShareable ( new FRuntimeVirtualTextureComponentDetailsCustomization ) ;
}
void FRuntimeVirtualTextureComponentDetailsCustomization : : CustomizeDetails ( IDetailLayoutBuilder & DetailBuilder )
{
2020-08-11 01:36:57 -04:00
// Get and store the linked URuntimeVirtualTextureComponent.
2019-06-11 18:27:07 -04:00
TArray < TWeakObjectPtr < UObject > > ObjectsBeingCustomized ;
DetailBuilder . GetObjectsBeingCustomized ( ObjectsBeingCustomized ) ;
if ( ObjectsBeingCustomized . Num ( ) > 1 )
{
return ;
}
RuntimeVirtualTextureComponent = Cast < URuntimeVirtualTextureComponent > ( ObjectsBeingCustomized [ 0 ] . Get ( ) ) ;
if ( RuntimeVirtualTextureComponent = = nullptr )
{
return ;
}
2020-09-24 00:43:27 -04:00
// Apply custom widget for SetBounds.
TSharedRef < IPropertyHandle > SetBoundsPropertyHandle = DetailBuilder . GetProperty ( TEXT ( " bSetBoundsButton " ) ) ;
DetailBuilder . EditDefaultProperty ( SetBoundsPropertyHandle ) - > CustomWidget ( )
2020-08-11 01:36:57 -04:00
. NameContent ( )
[
SNew ( STextBlock )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
. Text ( LOCTEXT ( " Button_SetBounds " , " Set Bounds " ) )
. ToolTipText ( LOCTEXT ( " Button_SetBounds_Tooltip " , " Set the rotation to match the Bounds Align Actor and expand bounds to include all primitives that write to this virtual texture. " ) )
]
. ValueContent ( )
. MinDesiredWidth ( 125.f )
[
SNew ( SButton )
. VAlign ( VAlign_Center )
. HAlign ( HAlign_Center )
. ContentPadding ( 2 )
. Text ( LOCTEXT ( " Button_SetBounds " , " Set Bounds " ) )
. OnClicked ( this , & FRuntimeVirtualTextureComponentDetailsCustomization : : SetBounds )
2020-09-01 14:07:48 -04:00
. IsEnabled ( this , & FRuntimeVirtualTextureComponentDetailsCustomization : : IsSetBoundsEnabled )
2020-08-11 01:36:57 -04:00
] ;
2020-09-24 00:43:27 -04:00
// Apply custom widget for BuildStreamingMips.
TSharedRef < IPropertyHandle > BuildStreamingMipsPropertyHandle = DetailBuilder . GetProperty ( TEXT ( " bBuildStreamingMipsButton " ) ) ;
DetailBuilder . EditDefaultProperty ( BuildStreamingMipsPropertyHandle ) - > CustomWidget ( )
2019-08-21 08:57:14 -04:00
. NameContent ( )
[
2020-04-19 15:49:19 -04:00
SNew ( STextBlock )
. Font ( IDetailLayoutBuilder : : GetDetailFont ( ) )
2020-09-24 00:43:27 -04:00
. Text ( LOCTEXT ( " Button_BuildStreamingTexture " , " Build Streaming Texture " ) )
2020-08-11 01:36:57 -04:00
. ToolTipText ( LOCTEXT ( " Button_Build_Tooltip " , " Build the low mips as streaming virtual texture data " ) )
2019-08-21 08:57:14 -04:00
]
. ValueContent ( )
[
2020-09-24 00:43:27 -04:00
SNew ( SHorizontalBox )
+ SHorizontalBox : : Slot ( )
. FillWidth ( 4.0f )
[
SNew ( SButton )
. HAlign ( HAlign_Center )
. VAlign ( VAlign_Center )
. ContentPadding ( 2 )
. Text ( LOCTEXT ( " Button_Build " , " Build " ) )
. OnClicked ( this , & FRuntimeVirtualTextureComponentDetailsCustomization : : BuildStreamedMips )
2021-01-21 16:22:06 -04:00
. IsEnabled ( this , & FRuntimeVirtualTextureComponentDetailsCustomization : : IsBuildStreamedMipsEnabled )
2020-09-24 00:43:27 -04:00
]
+ SHorizontalBox : : Slot ( )
2020-04-19 15:49:19 -04:00
. HAlign ( HAlign_Center )
. VAlign ( VAlign_Center )
2020-09-24 00:43:27 -04:00
[
SNew ( SImage )
2022-05-09 13:12:28 -04:00
. Image ( FAppStyle : : GetBrush ( " Icons.Warning " ) )
2020-09-24 00:43:27 -04:00
. Visibility ( this , & FRuntimeVirtualTextureComponentDetailsCustomization : : IsBuildWarningIconVisible )
. ToolTipText ( LOCTEXT ( " Warning_Build_Tooltip " , " The settings have changed since the Streaming Texture was last rebuilt. Streaming mips are disabled. " ) )
]
2020-08-11 01:36:57 -04:00
] ;
}
2020-09-01 14:07:48 -04:00
bool FRuntimeVirtualTextureComponentDetailsCustomization : : IsSetBoundsEnabled ( ) const
{
return RuntimeVirtualTextureComponent - > GetVirtualTexture ( ) ! = nullptr ;
}
2020-08-11 01:36:57 -04:00
FReply FRuntimeVirtualTextureComponentDetailsCustomization : : SetBounds ( )
{
2020-09-01 14:07:48 -04:00
if ( RuntimeVirtualTextureComponent - > GetVirtualTexture ( ) ! = nullptr )
{
const FScopedTransaction Transaction ( LOCTEXT ( " Transaction_SetBounds " , " Set RuntimeVirtualTextureComponent Bounds " ) ) ;
RuntimeVirtualTexture : : SetBounds ( RuntimeVirtualTextureComponent ) ;
2020-09-24 00:43:27 -04:00
// Force update of editor view widget.
GEditor - > NoteSelectionChange ( false ) ;
2020-09-01 14:07:48 -04:00
return FReply : : Handled ( ) ;
}
return FReply : : Unhandled ( ) ;
2019-06-11 18:27:07 -04:00
}
2021-01-21 16:22:06 -04:00
bool FRuntimeVirtualTextureComponentDetailsCustomization : : IsBuildStreamedMipsEnabled ( ) const
{
return RuntimeVirtualTextureComponent - > GetVirtualTexture ( ) ! = nullptr ;
}
2020-09-24 00:43:27 -04:00
EVisibility FRuntimeVirtualTextureComponentDetailsCustomization : : IsBuildWarningIconVisible ( ) const
{
2021-11-18 14:37:34 -05:00
const bool bVisible = RuntimeVirtualTextureComponent - > IsStreamingTextureInvalid ( ) ;
2021-01-08 19:56:07 -04:00
return bVisible ? EVisibility : : Visible : EVisibility : : Hidden ;
2020-09-24 00:43:27 -04:00
}
2019-08-21 08:57:14 -04:00
FReply FRuntimeVirtualTextureComponentDetailsCustomization : : BuildStreamedMips ( )
2020-08-11 01:36:57 -04:00
{
// Create a new asset if none is already bound
UVirtualTextureBuilder * CreatedTexture = nullptr ;
2021-01-08 19:56:07 -04:00
if ( RuntimeVirtualTextureComponent - > GetVirtualTexture ( ) ! = nullptr & & RuntimeVirtualTextureComponent - > GetStreamingTexture ( ) = = nullptr )
2020-08-11 01:36:57 -04:00
{
FAssetToolsModule & AssetToolsModule = FModuleManager : : GetModuleChecked < FAssetToolsModule > ( " AssetTools " ) ;
const FString DefaultPath = FPackageName : : GetLongPackagePath ( RuntimeVirtualTextureComponent - > GetVirtualTexture ( ) - > GetPathName ( ) ) ;
const FString DefaultName = FPackageName : : GetShortName ( RuntimeVirtualTextureComponent - > GetVirtualTexture ( ) - > GetName ( ) + TEXT ( " _SVT " ) ) ;
UFactory * Factory = NewObject < UVirtualTextureBuilderFactory > ( ) ;
UObject * Object = AssetToolsModule . Get ( ) . CreateAssetWithDialog ( DefaultName , DefaultPath , UVirtualTextureBuilder : : StaticClass ( ) , Factory ) ;
CreatedTexture = Cast < UVirtualTextureBuilder > ( Object ) ;
}
// Build the texture contents
bool bOK = false ;
if ( RuntimeVirtualTextureComponent - > GetStreamingTexture ( ) ! = nullptr | | CreatedTexture ! = nullptr )
{
2020-09-24 00:43:27 -04:00
const FScopedTransaction Transaction ( LOCTEXT ( " Transaction_BuildDebugStreamingTexture " , " Build Streaming Texture " ) ) ;
2020-08-11 01:36:57 -04:00
if ( CreatedTexture ! = nullptr )
{
RuntimeVirtualTextureComponent - > Modify ( ) ;
RuntimeVirtualTextureComponent - > SetStreamingTexture ( CreatedTexture ) ;
}
RuntimeVirtualTextureComponent - > GetStreamingTexture ( ) - > Modify ( ) ;
2020-09-24 00:43:27 -04:00
const bool bDebug = RuntimeVirtualTextureComponent - > IsBuildDebugStreamingMips ( ) ;
2020-08-11 01:36:57 -04:00
const ERuntimeVirtualTextureDebugType DebugType = bDebug ? ERuntimeVirtualTextureDebugType : : Debug : ERuntimeVirtualTextureDebugType : : None ;
if ( RuntimeVirtualTexture : : BuildStreamedMips ( RuntimeVirtualTextureComponent , DebugType ) )
{
bOK = true ;
}
}
return bOK ? FReply : : Handled ( ) : FReply : : Unhandled ( ) ;
}
2019-06-11 18:27:07 -04:00
# undef LOCTEXT_NAMESPACE