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 "TextureAlignModePrivatePCH.h"
2014-05-21 10:00:58 -04:00
# include "EditorSupportDelegates.h"
2014-11-12 04:43:54 -05:00
# include "Engine/Polys.h"
2014-03-14 14:13:41 -04:00
IMPLEMENT_MODULE ( FTextureAlignModeModule , TextureAlignMode ) ;
DEFINE_LOG_CATEGORY_STATIC ( LogTextureAlignMode , Log , All ) ;
void FTextureAlignModeModule : : StartupModule ( )
{
2014-06-18 10:16:16 -04:00
FEditorModeRegistry : : Get ( ) . RegisterMode < FEdModeTexture > (
FBuiltinEditorModes : : EM_Texture ,
NSLOCTEXT ( " EditorModes " , " TextureAlignmentMode " , " Texture Alignment " )
) ;
2014-03-14 14:13:41 -04:00
}
void FTextureAlignModeModule : : ShutdownModule ( )
{
2014-06-18 10:16:16 -04:00
FEditorModeRegistry : : Get ( ) . UnregisterMode ( FBuiltinEditorModes : : EM_Texture ) ;
2014-03-14 14:13:41 -04:00
}
/*------------------------------------------------------------------------------
Texture
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
FEdModeTexture : : FEdModeTexture ( )
: ScopedTransaction ( NULL )
, TrackingWorld ( NULL )
{
Tools . Add ( new FModeTool_Texture ( ) ) ;
SetCurrentTool ( MT_Texture ) ;
}
FEdModeTexture : : ~ FEdModeTexture ( )
{
// Ensure no transaction is outstanding.
check ( ! ScopedTransaction ) ;
}
void FEdModeTexture : : Enter ( )
{
FEdMode : : Enter ( ) ;
const bool bGetRawValue = true ;
2014-06-18 10:16:16 -04:00
SaveCoordSystem = GLevelEditorModeTools ( ) . GetCoordSystem ( bGetRawValue ) ;
GLevelEditorModeTools ( ) . SetCoordSystem ( COORD_Local ) ;
2014-03-14 14:13:41 -04:00
}
void FEdModeTexture : : Exit ( )
{
if ( ScopedTransaction ! = NULL )
{
delete ScopedTransaction ;
ScopedTransaction = NULL ;
}
FEdMode : : Exit ( ) ;
2014-06-18 10:16:16 -04:00
GLevelEditorModeTools ( ) . SetCoordSystem ( SaveCoordSystem ) ;
2014-03-14 14:13:41 -04:00
FEditorSupportDelegates : : RedrawAllViewports . Broadcast ( ) ;
}
FVector FEdModeTexture : : GetWidgetLocation ( ) const
{
for ( TSelectedSurfaceIterator < > It ( GetWorld ( ) ) ; It ; + + It )
{
FBspSurf * Surf = * It ;
ABrush * BrushActor = ( ABrush * ) Surf - > Actor ;
if ( BrushActor )
{
FPoly * poly = & BrushActor - > Brush - > Polys - > Element [ Surf - > iBrushPoly ] ;
return BrushActor - > ActorToWorld ( ) . TransformPosition ( poly - > GetMidPoint ( ) ) ;
}
}
return FEdMode : : GetWidgetLocation ( ) ;
}
bool FEdModeTexture : : ShouldDrawWidget ( ) const
{
return true ;
}
bool FEdModeTexture : : GetCustomDrawingCoordinateSystem ( FMatrix & InMatrix , void * InData )
{
// Texture mode is ALWAYS in local space
2014-06-18 10:16:16 -04:00
GLevelEditorModeTools ( ) . SetCoordSystem ( COORD_Local ) ;
2014-03-14 14:13:41 -04:00
FPoly * poly = NULL ;
for ( TSelectedSurfaceIterator < > It ( GetWorld ( ) ) ; It ; + + It )
{
FBspSurf * Surf = * It ;
ABrush * BrushActor = ( ABrush * ) Surf - > Actor ;
if ( BrushActor )
{
poly = & BrushActor - > Brush - > Polys - > Element [ Surf - > iBrushPoly ] ;
break ;
}
}
if ( ! poly )
{
return false ;
}
InMatrix = FMatrix : : Identity ;
InMatrix . SetAxis ( 2 , poly - > Normal ) ;
InMatrix . SetAxis ( 0 , poly - > TextureU ) ;
InMatrix . SetAxis ( 1 , poly - > TextureV ) ;
InMatrix . RemoveScaling ( ) ;
return true ;
}
bool FEdModeTexture : : GetCustomInputCoordinateSystem ( FMatrix & InMatrix , void * InData )
{
return false ;
}
EAxisList : : Type FEdModeTexture : : GetWidgetAxisToDraw ( FWidget : : EWidgetMode InWidgetMode ) const
{
2015-03-31 20:12:31 -04:00
switch ( InWidgetMode ) //-V719
2014-03-14 14:13:41 -04:00
{
case FWidget : : WM_Translate :
case FWidget : : WM_Scale :
return EAxisList : : XY ;
break ;
case FWidget : : WM_Rotate :
return EAxisList : : Z ;
break ;
}
return EAxisList : : XYZ ;
}
2014-06-18 10:16:16 -04:00
bool FEdModeTexture : : StartTracking ( FEditorViewportClient * InViewportClient , FViewport * InViewport )
2014-03-14 14:13:41 -04:00
{
// call base version because it calls the StartModify() virtual method needed to track drag events
bool BaseRtn = FEdMode : : StartTracking ( InViewportClient , InViewport ) ;
// Complete the previous transaction if one exists
if ( ScopedTransaction )
{
EndTracking ( InViewportClient , InViewport ) ;
}
// Start a new transaction
ScopedTransaction = new FScopedTransaction ( NSLOCTEXT ( " UnrealEd " , " TextureManipulation " , " Texture Manipulation " ) ) ;
for ( FConstLevelIterator Iterator = GetWorld ( ) - > GetLevelIterator ( ) ; Iterator ; + + Iterator )
{
UModel * Model = ( * Iterator ) - > Model ;
Model - > ModifySelectedSurfs ( true ) ;
}
return BaseRtn ;
}
2014-06-18 10:16:16 -04:00
bool FEdModeTexture : : EndTracking ( FEditorViewportClient * InViewportClient , FViewport * InViewport )
2014-03-14 14:13:41 -04:00
{
// Clean up the scoped transaction if one is still pending
if ( ScopedTransaction ! = NULL )
{
delete ScopedTransaction ;
ScopedTransaction = NULL ;
}
if ( TrackingWorld )
{
TrackingWorld - > MarkPackageDirty ( ) ;
ULevel : : LevelDirtiedEvent . Broadcast ( ) ;
TrackingWorld = NULL ;
}
// call base version because it calls the EndModify() virtual method needed to track drag events
return FEdMode : : EndTracking ( InViewportClient , InViewport ) ;
}
2014-06-18 10:16:16 -04:00
bool FEdModeTexture : : IsCompatibleWith ( FEditorModeID OtherModeID ) const
{
return OtherModeID = = FBuiltinEditorModes : : EM_Bsp ;
}
2014-03-14 14:13:41 -04:00
/*-----------------------------------------------------------------------------
FModeTool_TextureAlign .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
FModeTool_Texture : : FModeTool_Texture ( )
{
ID = MT_Texture ;
bUseWidget = 1 ;
PreviousInputDrag = FVector : : ZeroVector ;
}
/**
* @ return true if the delta was handled by this editor mode tool .
*/
2014-06-18 10:16:16 -04:00
bool FModeTool_Texture : : InputDelta ( FEditorViewportClient * InViewportClient , FViewport * InViewport , FVector & InDrag , FRotator & InRot , FVector & InScale )
2014-03-14 14:13:41 -04:00
{
if ( InViewportClient - > GetCurrentWidgetAxis ( ) = = EAxisList : : None )
{
return false ;
}
// calculate delta drag for this tick for the call to GEditor->polyTexPan below which is using relative (delta) mode
FVector deltaDrag = InDrag ;
if ( true = = InViewportClient - > IsPerspective ( ) )
{
// perspective viewports pass the absolute drag so subtract the last tick's drag value to get the delta
deltaDrag - = PreviousInputDrag ;
}
PreviousInputDrag = InDrag ;
if ( ! deltaDrag . IsZero ( ) )
{
// Ensure each polygon has a unique base point index.
for ( FConstLevelIterator Iterator = InViewportClient - > GetWorld ( ) - > GetLevelIterator ( ) ; Iterator ; + + Iterator )
{
UModel * Model = ( * Iterator ) - > Model ;
for ( int32 SurfaceIndex = 0 ; SurfaceIndex < Model - > Surfs . Num ( ) ; SurfaceIndex + + )
{
FBspSurf & Surf = Model - > Surfs [ SurfaceIndex ] ;
if ( Surf . PolyFlags & PF_Selected )
{
const FVector Base = Model - > Points [ Surf . pBase ] ;
Surf . pBase = Model - > Points . Add ( Base ) ;
}
}
2014-06-18 10:16:16 -04:00
FMatrix Mat = GLevelEditorModeTools ( ) . GetCustomDrawingCoordinateSystem ( ) ;
2014-03-14 14:13:41 -04:00
FVector UVW = Mat . InverseTransformVector ( deltaDrag ) ; // InverseTransformNormal because Mat is the transform from the surface/widget's coords to world coords
GEditor - > polyTexPan ( Model , UVW . X , UVW . Y , 0 ) ; // 0 is relative mode because UVW is made from deltaDrag - the user input since the last tick
}
}
if ( ! InRot . IsZero ( ) )
{
const FRotationMatrix RotationMatrix ( InRot ) ;
// Ensure each polygon has unique texture vector indices.
for ( TSelectedSurfaceIterator < > It ( InViewportClient - > GetWorld ( ) ) ; It ; + + It )
{
FBspSurf * Surf = * It ;
UModel * Model = It . GetModel ( ) ;
FVector TextureU = Model - > Vectors [ Surf - > vTextureU ] ;
FVector TextureV = Model - > Vectors [ Surf - > vTextureV ] ;
TextureU = RotationMatrix . TransformPosition ( TextureU ) ;
TextureV = RotationMatrix . TransformPosition ( TextureV ) ;
Surf - > vTextureU = Model - > Vectors . Add ( TextureU ) ;
Surf - > vTextureV = Model - > Vectors . Add ( TextureV ) ;
GEditor - > polyUpdateMaster ( Model , It . GetSurfaceIndex ( ) , 1 ) ;
}
}
if ( ! InScale . IsZero ( ) )
{
float ScaleU = InScale . X / GEditor - > GetGridSize ( ) ;
float ScaleV = InScale . Y / GEditor - > GetGridSize ( ) ;
ScaleU = 1.f - ( ScaleU / 100.f ) ;
ScaleV = 1.f - ( ScaleV / 100.f ) ;
// Ensure each polygon has unique texture vector indices.
for ( FConstLevelIterator Iterator = InViewportClient - > GetWorld ( ) - > GetLevelIterator ( ) ; Iterator ; + + Iterator )
{
UModel * Model = ( * Iterator ) - > Model ;
for ( int32 SurfaceIndex = 0 ; SurfaceIndex < Model - > Surfs . Num ( ) ; SurfaceIndex + + )
{
FBspSurf & Surf = Model - > Surfs [ SurfaceIndex ] ;
if ( Surf . PolyFlags & PF_Selected )
{
const FVector TextureU = Model - > Vectors [ Surf . vTextureU ] ;
const FVector TextureV = Model - > Vectors [ Surf . vTextureV ] ;
Surf . vTextureU = Model - > Vectors . Add ( TextureU ) ;
Surf . vTextureV = Model - > Vectors . Add ( TextureV ) ;
}
}
GEditor - > polyTexScale ( Model , ScaleU , 0.f , 0.f , ScaleV , false ) ;
}
}
return true ;
}