2014-03-14 14:13:41 -04:00
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
# include "LandscapeEditorPrivatePCH.h"
# include "ObjectTools.h"
# include "LandscapeEdMode.h"
# include "ScopedTransaction.h"
# include "Landscape/LandscapeEdit.h"
# include "Landscape/LandscapeRender.h"
# include "Landscape/LandscapeDataAccess.h"
# include "Landscape/LandscapeSplineProxies.h"
# include "LandscapeEditorModule.h"
# include "Editor/PropertyEditor/Public/PropertyEditorModule.h"
# include "LandscapeEdModeTools.h"
# include "Components/SplineMeshComponent.h"
# include "LandscapeSplineImportExport.h"
2014-05-22 07:52:43 -04:00
# include "Landscape/LandscapeSplinesComponent.h"
# include "Landscape/LandscapeSplineControlPoint.h"
# include "Landscape/LandscapeSplineSegment.h"
# include "Landscape/ControlPointMeshComponent.h"
2014-03-14 14:13:41 -04:00
# define LOCTEXT_NAMESPACE "Landscape"
//
// FLandscapeToolSplines
//
class FLandscapeToolSplines : public FLandscapeTool , public FEditorUndoClient
{
public :
2014-07-17 12:20:34 -04:00
FLandscapeToolSplines ( FEdModeLandscape * InEdMode )
2014-03-14 14:13:41 -04:00
: EdMode ( InEdMode )
, LandscapeInfo ( NULL )
, SelectedSplineControlPoints ( )
, SelectedSplineSegments ( )
, DraggingTangent_Segment ( NULL )
, DraggingTangent_End ( false )
, bMovingControlPoint ( false )
, bAutoRotateOnJoin ( true )
, bAutoChangeConnectionsOnMove ( true )
, bDeleteLooseEnds ( false )
, bCopyMeshToNewControlPoint ( false )
{
// Register to update when an undo/redo operation has been called to update our list of actors
GEditor - > RegisterForUndo ( this ) ;
}
~ FLandscapeToolSplines ( )
{
// GEditor is invalid at shutdown as the object system is unloaded before the landscape module.
2014-07-17 12:20:34 -04:00
if ( UObjectInitialized ( ) )
2014-03-14 14:13:41 -04:00
{
// Remove undo delegate
GEditor - > UnregisterForUndo ( this ) ;
}
}
2014-06-13 06:14:46 -04:00
virtual const TCHAR * GetToolName ( ) override { return TEXT ( " Splines " ) ; }
virtual FText GetDisplayName ( ) override { return NSLOCTEXT ( " UnrealEd " , " LandscapeMode_Splines " , " Splines " ) ; } ;
2014-03-14 14:13:41 -04:00
2014-06-13 06:14:46 -04:00
virtual void SetEditRenderType ( ) override { GLandscapeEditRenderMode = ELandscapeEditRenderMode : : None | ( GLandscapeEditRenderMode & ELandscapeEditRenderMode : : BitMaskForMask ) ; }
virtual bool SupportsMask ( ) override { return false ; }
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
void CreateSplineComponent ( ALandscapeProxy * Landscape , FVector Scale3D )
2014-03-14 14:13:41 -04:00
{
Landscape - > SplineComponent = ConstructObject < ULandscapeSplinesComponent > ( ULandscapeSplinesComponent : : StaticClass ( ) , Landscape , NAME_None , RF_Transactional ) ;
2014-04-28 02:52:54 -04:00
Landscape - > SplineComponent - > RelativeScale3D = Scale3D ;
2014-03-14 14:13:41 -04:00
Landscape - > SplineComponent - > AttachTo ( Landscape - > GetRootComponent ( ) ) ;
Landscape - > SplineComponent - > ShowSplineEditorMesh ( true ) ;
}
void UpdatePropertiesWindows ( )
{
2014-07-17 12:20:34 -04:00
if ( GLevelEditorModeTools ( ) . IsModeActive ( EdMode - > GetID ( ) ) )
2014-03-14 14:13:41 -04:00
{
TArray < UObject * > Objects ;
Objects . Reset ( SelectedSplineControlPoints . Num ( ) + SelectedSplineSegments . Num ( ) ) ;
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
Objects . Add ( ControlPoint ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
Objects . Add ( Segment ) ;
2014-03-14 14:13:41 -04:00
}
2014-07-17 12:20:34 -04:00
FPropertyEditorModule & PropertyModule = FModuleManager : : Get ( ) . LoadModuleChecked < FPropertyEditorModule > ( TEXT ( " PropertyEditor " ) ) ;
2014-03-14 14:13:41 -04:00
PropertyModule . UpdatePropertyViews ( Objects ) ;
}
}
void ClearSelectedControlPoints ( )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
checkSlow ( ControlPoint - > IsSplineSelected ( ) ) ;
ControlPoint - > Modify ( ) ;
ControlPoint - > SetSplineSelected ( false ) ;
2014-03-14 14:13:41 -04:00
}
SelectedSplineControlPoints . Empty ( ) ;
}
void ClearSelectedSegments ( )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
checkSlow ( Segment - > IsSplineSelected ( ) ) ;
Segment - > Modify ( ) ;
Segment - > SetSplineSelected ( false ) ;
2014-03-14 14:13:41 -04:00
}
SelectedSplineSegments . Empty ( ) ;
}
void ClearSelection ( )
{
ClearSelectedControlPoints ( ) ;
ClearSelectedSegments ( ) ;
}
void DeselectControlPoint ( ULandscapeSplineControlPoint * ControlPoint )
{
checkSlow ( ControlPoint - > IsSplineSelected ( ) ) ;
SelectedSplineControlPoints . Remove ( ControlPoint ) ;
ControlPoint - > Modify ( ) ;
ControlPoint - > SetSplineSelected ( false ) ;
}
void DeSelectSegment ( ULandscapeSplineSegment * Segment )
{
checkSlow ( Segment - > IsSplineSelected ( ) ) ;
SelectedSplineSegments . Remove ( Segment ) ;
Segment - > Modify ( ) ;
Segment - > SetSplineSelected ( false ) ;
}
void SelectControlPoint ( ULandscapeSplineControlPoint * ControlPoint )
{
checkSlow ( ! ControlPoint - > IsSplineSelected ( ) ) ;
SelectedSplineControlPoints . Add ( ControlPoint ) ;
ControlPoint - > Modify ( ) ;
ControlPoint - > SetSplineSelected ( true ) ;
}
void SelectSegment ( ULandscapeSplineSegment * Segment )
{
checkSlow ( ! Segment - > IsSplineSelected ( ) ) ;
SelectedSplineSegments . Add ( Segment ) ;
Segment - > Modify ( ) ;
Segment - > SetSplineSelected ( true ) ;
2014-06-18 10:16:16 -04:00
GLevelEditorModeTools ( ) . SetWidgetMode ( FWidget : : WM_Scale ) ;
2014-03-14 14:13:41 -04:00
}
void SelectConnected ( )
{
TArray < ULandscapeSplineControlPoint * > ControlPointsToProcess = SelectedSplineControlPoints . Array ( ) ;
while ( ControlPointsToProcess . Num ( ) > 0 )
{
const ULandscapeSplineControlPoint * ControlPoint = ControlPointsToProcess . Pop ( ) ;
2014-05-29 16:46:26 -04:00
for ( const FLandscapeSplineConnection & Connection : ControlPoint - > ConnectedSegments )
2014-03-14 14:13:41 -04:00
{
ULandscapeSplineControlPoint * OtherEnd = Connection . GetFarConnection ( ) . ControlPoint ;
if ( ! OtherEnd - > IsSplineSelected ( ) )
{
SelectControlPoint ( OtherEnd ) ;
ControlPointsToProcess . Add ( OtherEnd ) ;
}
}
}
TArray < ULandscapeSplineSegment * > SegmentsToProcess = SelectedSplineSegments . Array ( ) ;
while ( SegmentsToProcess . Num ( ) > 0 )
{
const ULandscapeSplineSegment * Segment = SegmentsToProcess . Pop ( ) ;
2014-05-29 16:46:26 -04:00
for ( const FLandscapeSplineSegmentConnection & SegmentConnection : Segment - > Connections )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( const FLandscapeSplineConnection & Connection : SegmentConnection . ControlPoint - > ConnectedSegments )
2014-03-14 14:13:41 -04:00
{
if ( Connection . Segment ! = Segment & & ! Connection . Segment - > IsSplineSelected ( ) )
{
SelectSegment ( Connection . Segment ) ;
SegmentsToProcess . Add ( Connection . Segment ) ;
}
}
}
}
}
void SelectAdjacentControlPoints ( )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
if ( ! Segment - > Connections [ 0 ] . ControlPoint - > IsSplineSelected ( ) )
{
SelectControlPoint ( Segment - > Connections [ 0 ] . ControlPoint ) ;
}
if ( ! Segment - > Connections [ 1 ] . ControlPoint - > IsSplineSelected ( ) )
{
SelectControlPoint ( Segment - > Connections [ 1 ] . ControlPoint ) ;
}
}
}
void SelectAdjacentSegments ( )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( const FLandscapeSplineConnection & Connection : ControlPoint - > ConnectedSegments )
2014-03-14 14:13:41 -04:00
{
if ( ! Connection . Segment - > IsSplineSelected ( ) )
{
SelectSegment ( Connection . Segment ) ;
}
}
}
}
void AddSegment ( ULandscapeSplineControlPoint * Start , ULandscapeSplineControlPoint * End , bool bAutoRotateStart , bool bAutoRotateEnd )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_AddSegment " , " Add Landscape Spline Segment " ) ) ;
2014-03-14 14:13:41 -04:00
if ( Start = = End )
{
//UE_LOG( TEXT("Can't join spline control point to itself.") );
return ;
}
if ( Start - > GetOuterULandscapeSplinesComponent ( ) ! = End - > GetOuterULandscapeSplinesComponent ( ) )
{
//UE_LOG( TEXT("Can't join spline control points across different terrains.") );
return ;
}
2014-05-29 16:46:26 -04:00
for ( const FLandscapeSplineConnection & Connection : Start - > ConnectedSegments )
2014-03-14 14:13:41 -04:00
{
// if the *other* end on the connected segment connects to the "end" control point...
if ( Connection . GetFarConnection ( ) . ControlPoint = = End )
{
//UE_LOG( TEXT("Spline control points already joined connected!") );
return ;
}
}
ULandscapeSplinesComponent * SplinesComponent = Start - > GetOuterULandscapeSplinesComponent ( ) ;
SplinesComponent - > Modify ( ) ;
Start - > Modify ( ) ;
End - > Modify ( ) ;
ULandscapeSplineSegment * NewSegment = ConstructObject < ULandscapeSplineSegment > ( ULandscapeSplineSegment : : StaticClass ( ) , SplinesComponent , NAME_None , RF_Transactional ) ;
SplinesComponent - > Segments . Add ( NewSegment ) ;
NewSegment - > Connections [ 0 ] . ControlPoint = Start ;
NewSegment - > Connections [ 1 ] . ControlPoint = End ;
NewSegment - > Connections [ 0 ] . SocketName = Start - > GetBestConnectionTo ( End - > Location ) ;
NewSegment - > Connections [ 1 ] . SocketName = End - > GetBestConnectionTo ( Start - > Location ) ;
FVector StartLocation ; FRotator StartRotation ;
Start - > GetConnectionLocationAndRotation ( NewSegment - > Connections [ 0 ] . SocketName , StartLocation , StartRotation ) ;
FVector EndLocation ; FRotator EndRotation ;
End - > GetConnectionLocationAndRotation ( NewSegment - > Connections [ 1 ] . SocketName , EndLocation , EndRotation ) ;
// Set up tangent lengths
NewSegment - > Connections [ 0 ] . TangentLen = ( EndLocation - StartLocation ) . Size ( ) ;
NewSegment - > Connections [ 1 ] . TangentLen = NewSegment - > Connections [ 0 ] . TangentLen ;
NewSegment - > AutoFlipTangents ( ) ;
// set up other segment options
if ( Start - > ConnectedSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
NewSegment - > LayerName = Start - > ConnectedSegments [ 0 ] . Segment - > LayerName ;
NewSegment - > SplineMeshes = Start - > ConnectedSegments [ 0 ] . Segment - > SplineMeshes ;
2014-03-14 14:13:41 -04:00
NewSegment - > LDMaxDrawDistance = Start - > ConnectedSegments [ 0 ] . Segment - > LDMaxDrawDistance ;
2014-07-17 12:20:34 -04:00
NewSegment - > bRaiseTerrain = Start - > ConnectedSegments [ 0 ] . Segment - > bRaiseTerrain ;
NewSegment - > bLowerTerrain = Start - > ConnectedSegments [ 0 ] . Segment - > bLowerTerrain ;
NewSegment - > bEnableCollision = Start - > ConnectedSegments [ 0 ] . Segment - > bEnableCollision ;
NewSegment - > bCastShadow = Start - > ConnectedSegments [ 0 ] . Segment - > bCastShadow ;
2014-03-14 14:13:41 -04:00
}
else if ( End - > ConnectedSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
NewSegment - > LayerName = End - > ConnectedSegments [ 0 ] . Segment - > LayerName ;
NewSegment - > SplineMeshes = End - > ConnectedSegments [ 0 ] . Segment - > SplineMeshes ;
2014-03-14 14:13:41 -04:00
NewSegment - > LDMaxDrawDistance = End - > ConnectedSegments [ 0 ] . Segment - > LDMaxDrawDistance ;
2014-07-17 12:20:34 -04:00
NewSegment - > bRaiseTerrain = End - > ConnectedSegments [ 0 ] . Segment - > bRaiseTerrain ;
NewSegment - > bLowerTerrain = End - > ConnectedSegments [ 0 ] . Segment - > bLowerTerrain ;
NewSegment - > bEnableCollision = End - > ConnectedSegments [ 0 ] . Segment - > bEnableCollision ;
NewSegment - > bCastShadow = End - > ConnectedSegments [ 0 ] . Segment - > bCastShadow ;
2014-03-14 14:13:41 -04:00
}
else
{
// Use defaults
}
Start - > ConnectedSegments . Add ( FLandscapeSplineConnection ( NewSegment , 0 ) ) ;
End - > ConnectedSegments . Add ( FLandscapeSplineConnection ( NewSegment , 1 ) ) ;
if ( bAutoRotateStart )
{
Start - > AutoCalcRotation ( ) ;
Start - > UpdateSplinePoints ( ) ;
}
if ( bAutoRotateEnd )
{
End - > AutoCalcRotation ( ) ;
End - > UpdateSplinePoints ( ) ;
}
// Control points' points are currently based on connected segments, so need to be updated.
if ( Start - > Mesh ! = NULL )
{
Start - > UpdateSplinePoints ( ) ;
}
if ( End - > Mesh ! = NULL )
{
Start - > UpdateSplinePoints ( ) ;
}
NewSegment - > UpdateSplinePoints ( ) ;
}
2014-04-23 20:12:41 -04:00
void AddControlPoint ( ALandscapeProxy * Landscape , const FVector & LocalLocation )
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_AddControlPoint " , " Add Landscape Spline Control Point " ) ) ;
2014-03-14 14:13:41 -04:00
Landscape - > SplineComponent - > Modify ( ) ;
ULandscapeSplineControlPoint * NewControlPoint = ConstructObject < ULandscapeSplineControlPoint > ( ULandscapeSplineControlPoint : : StaticClass ( ) , Landscape - > SplineComponent , NAME_None , RF_Transactional ) ;
Landscape - > SplineComponent - > ControlPoints . Add ( NewControlPoint ) ;
NewControlPoint - > Location = LocalLocation ;
if ( SelectedSplineControlPoints . Num ( ) > 0 )
{
ULandscapeSplineControlPoint * FirstPoint = * SelectedSplineControlPoints . CreateConstIterator ( ) ;
NewControlPoint - > Rotation = ( NewControlPoint - > Location - FirstPoint - > Location ) . Rotation ( ) ;
NewControlPoint - > Width = FirstPoint - > Width ;
NewControlPoint - > SideFalloff = FirstPoint - > SideFalloff ;
NewControlPoint - > EndFalloff = FirstPoint - > EndFalloff ;
if ( bCopyMeshToNewControlPoint )
{
NewControlPoint - > Mesh = FirstPoint - > Mesh ;
NewControlPoint - > MeshScale = FirstPoint - > MeshScale ;
NewControlPoint - > bEnableCollision = FirstPoint - > bEnableCollision ;
NewControlPoint - > bCastShadow = FirstPoint - > bCastShadow ;
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
AddSegment ( ControlPoint , NewControlPoint , bAutoRotateOnJoin , true ) ;
2014-03-14 14:13:41 -04:00
}
}
ClearSelection ( ) ;
SelectControlPoint ( NewControlPoint ) ;
UpdatePropertiesWindows ( ) ;
if ( ! Landscape - > SplineComponent - > IsRegistered ( ) )
{
Landscape - > SplineComponent - > RegisterComponent ( ) ;
}
else
{
Landscape - > SplineComponent - > MarkRenderStateDirty ( ) ;
}
}
2014-03-15 01:14:25 -04:00
void DeleteSegment ( ULandscapeSplineSegment * ToDelete , bool bInDeleteLooseEnds )
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_DeleteSegment " , " Delete Landscape Spline Segment " ) ) ;
2014-03-14 14:13:41 -04:00
ULandscapeSplinesComponent * SplinesComponent = ToDelete - > GetOuterULandscapeSplinesComponent ( ) ;
SplinesComponent - > Modify ( ) ;
ToDelete - > Modify ( ) ;
ToDelete - > DeleteSplinePoints ( ) ;
ToDelete - > Connections [ 0 ] . ControlPoint - > Modify ( ) ;
ToDelete - > Connections [ 1 ] . ControlPoint - > Modify ( ) ;
ToDelete - > Connections [ 0 ] . ControlPoint - > ConnectedSegments . Remove ( FLandscapeSplineConnection ( ToDelete , 0 ) ) ;
ToDelete - > Connections [ 1 ] . ControlPoint - > ConnectedSegments . Remove ( FLandscapeSplineConnection ( ToDelete , 1 ) ) ;
2014-03-15 01:14:25 -04:00
if ( bInDeleteLooseEnds )
2014-03-14 14:13:41 -04:00
{
if ( ToDelete - > Connections [ 0 ] . ControlPoint - > ConnectedSegments . Num ( ) = = 0 )
{
SplinesComponent - > ControlPoints . Remove ( ToDelete - > Connections [ 0 ] . ControlPoint ) ;
}
if ( ToDelete - > Connections [ 1 ] . ControlPoint ! = ToDelete - > Connections [ 0 ] . ControlPoint
& & ToDelete - > Connections [ 1 ] . ControlPoint - > ConnectedSegments . Num ( ) = = 0 )
{
SplinesComponent - > ControlPoints . Remove ( ToDelete - > Connections [ 1 ] . ControlPoint ) ;
}
}
SplinesComponent - > Segments . Remove ( ToDelete ) ;
// Control points' points are currently based on connected segments, so need to be updated.
if ( ToDelete - > Connections [ 0 ] . ControlPoint - > Mesh ! = NULL )
{
ToDelete - > Connections [ 0 ] . ControlPoint - > UpdateSplinePoints ( ) ;
}
if ( ToDelete - > Connections [ 1 ] . ControlPoint - > Mesh ! = NULL )
{
ToDelete - > Connections [ 1 ] . ControlPoint - > UpdateSplinePoints ( ) ;
}
SplinesComponent - > MarkRenderStateDirty ( ) ;
}
2014-03-15 01:14:25 -04:00
void DeleteControlPoint ( ULandscapeSplineControlPoint * ToDelete , bool bInDeleteLooseEnds )
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_DeleteControlPoint " , " Delete Landscape Spline Control Point " ) ) ;
2014-03-14 14:13:41 -04:00
ULandscapeSplinesComponent * SplinesComponent = ToDelete - > GetOuterULandscapeSplinesComponent ( ) ;
SplinesComponent - > Modify ( ) ;
ToDelete - > Modify ( ) ;
ToDelete - > DeleteSplinePoints ( ) ;
if ( ToDelete - > ConnectedSegments . Num ( ) = = 2
& & ToDelete - > ConnectedSegments [ 0 ] . Segment ! = ToDelete - > ConnectedSegments [ 1 ] . Segment )
{
2014-07-17 12:20:34 -04:00
int32 Result = FMessageDialog : : Open ( EAppMsgType : : YesNoCancel , LOCTEXT ( " WantToJoinControlPoint " , " Control point has two segments attached, do you want to join them? " ) ) ;
2014-03-14 14:13:41 -04:00
switch ( Result )
{
case EAppReturnType : : Yes :
2014-07-17 12:20:34 -04:00
{
// Copy the other end of connection 1 into the near end of connection 0, then delete connection 1
TArray < FLandscapeSplineConnection > & Connections = ToDelete - > ConnectedSegments ;
Connections [ 0 ] . Segment - > Modify ( ) ;
Connections [ 1 ] . Segment - > Modify ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
Connections [ 0 ] . GetNearConnection ( ) = Connections [ 1 ] . GetFarConnection ( ) ;
Connections [ 0 ] . Segment - > UpdateSplinePoints ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
Connections [ 1 ] . Segment - > DeleteSplinePoints ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
// Get the control point at the *other* end of the segment and remove it from it
ULandscapeSplineControlPoint * OtherEnd = Connections [ 1 ] . GetFarConnection ( ) . ControlPoint ;
OtherEnd - > Modify ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
FLandscapeSplineConnection * OtherConnection = OtherEnd - > ConnectedSegments . FindByKey ( FLandscapeSplineConnection ( Connections [ 1 ] . Segment , 1 - Connections [ 1 ] . End ) ) ;
* OtherConnection = FLandscapeSplineConnection ( Connections [ 0 ] . Segment , Connections [ 0 ] . End ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
SplinesComponent - > Segments . Remove ( Connections [ 1 ] . Segment ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
ToDelete - > ConnectedSegments . Empty ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
SplinesComponent - > ControlPoints . Remove ( ToDelete ) ;
SplinesComponent - > MarkRenderStateDirty ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
return ;
}
2014-03-14 14:13:41 -04:00
break ;
case EAppReturnType : : No :
// Use the "delete all segments" code below
break ;
case EAppReturnType : : Cancel :
// Do nothing
return ;
}
}
2014-05-29 16:46:26 -04:00
for ( FLandscapeSplineConnection & Connection : ToDelete - > ConnectedSegments )
2014-03-14 14:13:41 -04:00
{
Connection . Segment - > Modify ( ) ;
Connection . Segment - > DeleteSplinePoints ( ) ;
// Get the control point at the *other* end of the segment and remove it from it
ULandscapeSplineControlPoint * OtherEnd = Connection . GetFarConnection ( ) . ControlPoint ;
OtherEnd - > Modify ( ) ;
OtherEnd - > ConnectedSegments . Remove ( FLandscapeSplineConnection ( Connection . Segment , 1 - Connection . End ) ) ;
SplinesComponent - > Segments . Remove ( Connection . Segment ) ;
2014-03-15 01:14:25 -04:00
if ( bInDeleteLooseEnds )
2014-03-14 14:13:41 -04:00
{
if ( OtherEnd ! = ToDelete
& & OtherEnd - > ConnectedSegments . Num ( ) = = 0 )
{
SplinesComponent - > ControlPoints . Remove ( OtherEnd ) ;
}
}
}
ToDelete - > ConnectedSegments . Empty ( ) ;
SplinesComponent - > ControlPoints . Remove ( ToDelete ) ;
SplinesComponent - > MarkRenderStateDirty ( ) ;
}
void SplitSegment ( ULandscapeSplineSegment * Segment , const FVector & LocalLocation )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_SplitSegment " , " Split Landscape Spline Segment " ) ) ;
2014-03-14 14:13:41 -04:00
ULandscapeSplinesComponent * SplinesComponent = Segment - > GetOuterULandscapeSplinesComponent ( ) ;
SplinesComponent - > Modify ( ) ;
Segment - > Modify ( ) ;
Segment - > Connections [ 1 ] . ControlPoint - > Modify ( ) ;
float t ;
FVector Location ;
FVector Tangent ;
Segment - > FindNearest ( LocalLocation , t , Location , Tangent ) ;
ULandscapeSplineControlPoint * NewControlPoint = ConstructObject < ULandscapeSplineControlPoint > ( ULandscapeSplineControlPoint : : StaticClass ( ) , SplinesComponent , NAME_None , RF_Transactional ) ;
SplinesComponent - > ControlPoints . Add ( NewControlPoint ) ;
NewControlPoint - > Location = Location ;
NewControlPoint - > Rotation = Tangent . Rotation ( ) ;
NewControlPoint - > Rotation . Roll = FMath : : Lerp ( Segment - > Connections [ 0 ] . ControlPoint - > Rotation . Roll , Segment - > Connections [ 1 ] . ControlPoint - > Rotation . Roll , t ) ;
NewControlPoint - > Width = FMath : : Lerp ( Segment - > Connections [ 0 ] . ControlPoint - > Width , Segment - > Connections [ 1 ] . ControlPoint - > Width , t ) ;
NewControlPoint - > SideFalloff = FMath : : Lerp ( Segment - > Connections [ 0 ] . ControlPoint - > SideFalloff , Segment - > Connections [ 1 ] . ControlPoint - > SideFalloff , t ) ;
NewControlPoint - > EndFalloff = FMath : : Lerp ( Segment - > Connections [ 0 ] . ControlPoint - > EndFalloff , Segment - > Connections [ 1 ] . ControlPoint - > EndFalloff , t ) ;
ULandscapeSplineSegment * NewSegment = ConstructObject < ULandscapeSplineSegment > ( ULandscapeSplineSegment : : StaticClass ( ) , SplinesComponent , NAME_None , RF_Transactional ) ;
SplinesComponent - > Segments . Add ( NewSegment ) ;
NewSegment - > Connections [ 0 ] . ControlPoint = NewControlPoint ;
NewSegment - > Connections [ 0 ] . TangentLen = Tangent . Size ( ) * ( 1 - t ) ;
NewSegment - > Connections [ 0 ] . ControlPoint - > ConnectedSegments . Add ( FLandscapeSplineConnection ( NewSegment , 0 ) ) ;
NewSegment - > Connections [ 1 ] . ControlPoint = Segment - > Connections [ 1 ] . ControlPoint ;
NewSegment - > Connections [ 1 ] . TangentLen = Segment - > Connections [ 1 ] . TangentLen * ( 1 - t ) ;
NewSegment - > Connections [ 1 ] . ControlPoint - > ConnectedSegments . Add ( FLandscapeSplineConnection ( NewSegment , 1 ) ) ;
2014-07-17 12:20:34 -04:00
NewSegment - > LayerName = Segment - > LayerName ;
NewSegment - > SplineMeshes = Segment - > SplineMeshes ;
2014-03-14 14:13:41 -04:00
NewSegment - > LDMaxDrawDistance = Segment - > LDMaxDrawDistance ;
2014-07-17 12:20:34 -04:00
NewSegment - > bRaiseTerrain = Segment - > bRaiseTerrain ;
NewSegment - > bLowerTerrain = Segment - > bLowerTerrain ;
NewSegment - > bEnableCollision = Segment - > bEnableCollision ;
NewSegment - > bCastShadow = Segment - > bCastShadow ;
2014-03-14 14:13:41 -04:00
Segment - > Connections [ 0 ] . TangentLen * = t ;
Segment - > Connections [ 1 ] . ControlPoint - > ConnectedSegments . Remove ( FLandscapeSplineConnection ( Segment , 1 ) ) ;
Segment - > Connections [ 1 ] . ControlPoint = NewControlPoint ;
Segment - > Connections [ 1 ] . TangentLen = - Tangent . Size ( ) * t ;
Segment - > Connections [ 1 ] . ControlPoint - > ConnectedSegments . Add ( FLandscapeSplineConnection ( Segment , 1 ) ) ;
Segment - > UpdateSplinePoints ( ) ;
NewSegment - > UpdateSplinePoints ( ) ;
ClearSelection ( ) ;
UpdatePropertiesWindows ( ) ;
SplinesComponent - > MarkRenderStateDirty ( ) ;
}
void FlipSegment ( ULandscapeSplineSegment * Segment )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_FlipSegment " , " Flip Landscape Spline Segment " ) ) ;
2014-03-14 14:13:41 -04:00
ULandscapeSplinesComponent * SplinesComponent = Segment - > GetOuterULandscapeSplinesComponent ( ) ;
SplinesComponent - > Modify ( ) ;
Segment - > Modify ( ) ;
Segment - > Connections [ 0 ] . ControlPoint - > Modify ( ) ;
Segment - > Connections [ 1 ] . ControlPoint - > Modify ( ) ;
Segment - > Connections [ 0 ] . ControlPoint - > ConnectedSegments . FindByKey ( FLandscapeSplineConnection ( Segment , 0 ) ) - > End = 1 ;
Segment - > Connections [ 1 ] . ControlPoint - > ConnectedSegments . FindByKey ( FLandscapeSplineConnection ( Segment , 1 ) ) - > End = 0 ;
Swap ( Segment - > Connections [ 0 ] , Segment - > Connections [ 1 ] ) ;
Segment - > UpdateSplinePoints ( ) ;
}
void SnapControlPointToGround ( ULandscapeSplineControlPoint * ControlPoint )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_SnapToGround " , " Snap Landscape Spline to Ground " ) ) ;
2014-03-14 14:13:41 -04:00
ULandscapeSplinesComponent * SplinesComponent = ControlPoint - > GetOuterULandscapeSplinesComponent ( ) ;
SplinesComponent - > Modify ( ) ;
ControlPoint - > Modify ( ) ;
2014-04-23 18:24:07 -04:00
const FTransform LocalToWorld = SplinesComponent - > GetComponentToWorld ( ) ;
2014-03-14 14:13:41 -04:00
const FVector Start = LocalToWorld . TransformPosition ( ControlPoint - > Location ) ;
const FVector End = Start + FVector ( 0 , 0 , - HALF_WORLD_MAX ) ;
static FName TraceTag = FName ( TEXT ( " SnapLandscapeSplineControlPointToGround " ) ) ;
FHitResult Hit ;
UWorld * World = SplinesComponent - > GetWorld ( ) ;
check ( World ) ;
if ( World - > LineTraceSingle ( Hit , Start , End , FCollisionQueryParams ( true ) , FCollisionObjectQueryParams ( ECC_WorldStatic ) ) )
{
ControlPoint - > Location = LocalToWorld . InverseTransformPosition ( Hit . Location ) ;
ControlPoint - > UpdateSplinePoints ( ) ;
SplinesComponent - > MarkRenderStateDirty ( ) ;
}
}
2014-07-17 12:20:34 -04:00
void ShowSplineProperties ( )
2014-03-14 14:13:41 -04:00
{
TArray < UObject * > Objects ;
Objects . Reset ( SelectedSplineControlPoints . Num ( ) + SelectedSplineSegments . Num ( ) ) ;
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
Objects . Add ( ControlPoint ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
Objects . Add ( Segment ) ;
2014-03-14 14:13:41 -04:00
}
2014-07-17 12:20:34 -04:00
FPropertyEditorModule & PropertyModule = FModuleManager : : Get ( ) . LoadModuleChecked < FPropertyEditorModule > ( TEXT ( " PropertyEditor " ) ) ;
if ( ! PropertyModule . HasUnlockedDetailViews ( ) )
2014-03-14 14:13:41 -04:00
{
PropertyModule . CreateFloatingDetailsView ( Objects , true ) ;
}
else
{
PropertyModule . UpdatePropertyViews ( Objects ) ;
}
}
2014-07-17 12:20:34 -04:00
virtual bool BeginTool ( FEditorViewportClient * ViewportClient , const FLandscapeToolTarget & InTarget , const FVector & InHitLocation ) override
2014-03-14 14:13:41 -04:00
{
2014-09-08 10:45:50 -04:00
if ( ViewportClient - > IsCtrlPressed ( ) )
2014-03-14 14:13:41 -04:00
{
2014-09-08 10:45:50 -04:00
LandscapeInfo = InTarget . LandscapeInfo . Get ( ) ;
ALandscapeProxy * Landscape = LandscapeInfo - > GetCurrentLevelLandscapeProxy ( true ) ;
if ( ! Landscape )
{
return false ;
}
if ( ! Landscape - > SplineComponent )
{
CreateSplineComponent ( Landscape , FVector ( 1.f ) / Landscape - > GetRootComponent ( ) - > RelativeScale3D ) ;
}
const FTransform LandscapeToSpline = Landscape - > LandscapeActorToWorld ( ) . GetRelativeTransform ( Landscape - > SplineComponent - > ComponentToWorld ) ;
AddControlPoint ( Landscape , LandscapeToSpline . TransformPosition ( InHitLocation ) ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
return true ;
2014-03-14 14:13:41 -04:00
}
2014-09-08 10:45:50 -04:00
return false ;
2014-03-14 14:13:41 -04:00
}
2014-06-18 10:16:16 -04:00
virtual void EndTool ( FEditorViewportClient * ViewportClient ) override
2014-03-14 14:13:41 -04:00
{
LandscapeInfo = NULL ;
}
2014-07-17 12:20:34 -04:00
virtual bool MouseMove ( FEditorViewportClient * ViewportClient , FViewport * Viewport , int32 x , int32 y ) override
2014-03-14 14:13:41 -04:00
{
FVector HitLocation ;
2014-05-29 16:46:26 -04:00
if ( EdMode - > LandscapeMouseTrace ( ViewportClient , x , y , HitLocation ) )
2014-03-14 14:13:41 -04:00
{
//if( bToolActive )
//{
// // Apply tool
// ApplyTool(ViewportClient);
//}
}
return true ;
2014-05-29 16:46:26 -04:00
}
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
virtual void ApplyTool ( FEditorViewportClient * ViewportClient )
2014-03-14 14:13:41 -04:00
{
}
2014-07-17 12:20:34 -04:00
virtual bool HandleClick ( HHitProxy * HitProxy , const FViewportClick & Click ) override
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
if ( ( ! HitProxy | | ! HitProxy - > IsA ( HWidgetAxis : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
& & ! Click . IsShiftDown ( ) )
{
ClearSelection ( ) ;
UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
}
if ( HitProxy )
{
ULandscapeSplineControlPoint * ClickedControlPoint = NULL ;
ULandscapeSplineSegment * ClickedSplineSegment = NULL ;
2014-07-17 12:20:34 -04:00
if ( HitProxy - > IsA ( HLandscapeSplineProxy_ControlPoint : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HLandscapeSplineProxy_ControlPoint * SplineProxy = ( HLandscapeSplineProxy_ControlPoint * ) HitProxy ;
ClickedControlPoint = SplineProxy - > ControlPoint ;
}
2014-07-17 12:20:34 -04:00
else if ( HitProxy - > IsA ( HLandscapeSplineProxy_Segment : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HLandscapeSplineProxy_Segment * SplineProxy = ( HLandscapeSplineProxy_Segment * ) HitProxy ;
ClickedSplineSegment = SplineProxy - > SplineSegment ;
}
2014-07-17 12:20:34 -04:00
else if ( HitProxy - > IsA ( HActor : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HActor * ActorProxy = ( HActor * ) HitProxy ;
2014-05-29 16:46:26 -04:00
AActor * Actor = ActorProxy - > Actor ;
ULandscapeSplinesComponent * SplineComponent = Actor - > FindComponentByClass < ULandscapeSplinesComponent > ( ) ;
2014-03-14 14:13:41 -04:00
if ( SplineComponent ! = NULL )
{
2014-05-29 16:46:26 -04:00
if ( const UControlPointMeshComponent * ControlPointMeshComponent = Cast < const UControlPointMeshComponent > ( ActorProxy - > PrimComponent ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SplineComponent - > ControlPoints )
2014-03-14 14:13:41 -04:00
{
if ( ControlPoint - > OwnsComponent ( ControlPointMeshComponent ) )
{
ClickedControlPoint = ControlPoint ;
break ;
}
}
}
2014-05-29 16:46:26 -04:00
else if ( const USplineMeshComponent * SplineMeshComponent = Cast < const USplineMeshComponent > ( ActorProxy - > PrimComponent ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * SplineSegment : SplineComponent - > Segments )
2014-03-14 14:13:41 -04:00
{
if ( SplineSegment - > OwnsComponent ( SplineMeshComponent ) )
{
ClickedSplineSegment = SplineSegment ;
break ;
}
}
}
}
}
if ( ClickedControlPoint ! = NULL )
{
if ( Click . IsShiftDown ( ) & & ClickedControlPoint - > IsSplineSelected ( ) )
{
DeselectControlPoint ( ClickedControlPoint ) ;
}
else
{
SelectControlPoint ( ClickedControlPoint ) ;
}
GEditor - > SelectNone ( true , true ) ;
UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
return true ;
}
else if ( ClickedSplineSegment ! = NULL )
{
// save info about what we grabbed
if ( Click . IsShiftDown ( ) & & ClickedSplineSegment - > IsSplineSelected ( ) )
{
DeSelectSegment ( ClickedSplineSegment ) ;
}
else
{
SelectSegment ( ClickedSplineSegment ) ;
}
GEditor - > SelectNone ( true , true ) ;
UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
return true ;
}
}
return false ;
}
2014-07-17 12:20:34 -04:00
virtual bool InputKey ( FEditorViewportClient * InViewportClient , FViewport * InViewport , FKey InKey , EInputEvent InEvent ) override
2014-03-14 14:13:41 -04:00
{
if ( InKey = = EKeys : : F4 & & InEvent = = IE_Pressed )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
ShowSplineProperties ( ) ;
return true ;
}
}
if ( InKey = = EKeys : : R & & InEvent = = IE_Pressed )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_AutoRotate " , " Auto-rotate Landscape Spline Control Points " ) ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ControlPoint - > AutoCalcRotation ( ) ;
ControlPoint - > UpdateSplinePoints ( ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
Segment - > Connections [ 0 ] . ControlPoint - > AutoCalcRotation ( ) ;
Segment - > Connections [ 0 ] . ControlPoint - > UpdateSplinePoints ( ) ;
Segment - > Connections [ 1 ] . ControlPoint - > AutoCalcRotation ( ) ;
Segment - > Connections [ 1 ] . ControlPoint - > UpdateSplinePoints ( ) ;
2014-03-14 14:13:41 -04:00
}
return true ;
}
}
if ( InKey = = EKeys : : F & & InEvent = = IE_Pressed )
{
if ( SelectedSplineSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_FlipSegments " , " Flip Landscape Spline Segments " ) ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
FlipSegment ( Segment ) ;
2014-03-14 14:13:41 -04:00
}
return true ;
}
}
if ( InKey = = EKeys : : T & & InEvent = = IE_Pressed )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_AutoFlipTangents " , " Auto-flip Landscape Spline Tangents " ) ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ControlPoint - > AutoFlipTangents ( ) ;
ControlPoint - > UpdateSplinePoints ( ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
Segment - > Connections [ 0 ] . ControlPoint - > AutoFlipTangents ( ) ;
Segment - > Connections [ 0 ] . ControlPoint - > UpdateSplinePoints ( ) ;
Segment - > Connections [ 1 ] . ControlPoint - > AutoFlipTangents ( ) ;
Segment - > Connections [ 1 ] . ControlPoint - > UpdateSplinePoints ( ) ;
2014-03-14 14:13:41 -04:00
}
return true ;
}
}
if ( InKey = = EKeys : : End & & InEvent = = IE_Pressed )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_SnapToGround " , " Snap Landscape Spline to Ground " ) ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
SnapControlPointToGround ( ControlPoint ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
SnapControlPointToGround ( Segment - > Connections [ 0 ] . ControlPoint ) ;
SnapControlPointToGround ( Segment - > Connections [ 1 ] . ControlPoint ) ;
2014-03-14 14:13:41 -04:00
}
UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
return true ;
}
}
if ( InKey = = EKeys : : A & & InEvent = = IE_Pressed
& & IsCtrlDown ( InViewport ) )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
SelectConnected ( ) ;
UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
return true ;
}
}
if ( SelectedSplineControlPoints . Num ( ) > 0 )
{
if ( InKey = = EKeys : : LeftMouseButton & & InEvent = = IE_Pressed
& & IsCtrlDown ( InViewport ) )
{
int32 HitX = InViewport - > GetMouseX ( ) ;
int32 HitY = InViewport - > GetMouseY ( ) ;
2014-05-29 16:46:26 -04:00
HHitProxy * HitProxy = InViewport - > GetHitProxy ( HitX , HitY ) ;
2014-03-14 14:13:41 -04:00
if ( HitProxy ! = NULL )
{
ULandscapeSplineControlPoint * ClickedControlPoint = NULL ;
2014-07-17 12:20:34 -04:00
if ( HitProxy - > IsA ( HLandscapeSplineProxy_ControlPoint : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HLandscapeSplineProxy_ControlPoint * SplineProxy = ( HLandscapeSplineProxy_ControlPoint * ) HitProxy ;
ClickedControlPoint = SplineProxy - > ControlPoint ;
}
2014-07-17 12:20:34 -04:00
else if ( HitProxy - > IsA ( HActor : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HActor * ActorProxy = ( HActor * ) HitProxy ;
ULandscapeSplinesComponent * SplineComponent = ActorProxy - > Actor - > FindComponentByClass < ULandscapeSplinesComponent > ( ) ;
if ( SplineComponent ! = NULL )
{
const UControlPointMeshComponent * ControlPointMeshComponent = Cast < const UControlPointMeshComponent > ( ActorProxy - > PrimComponent ) ;
if ( ControlPointMeshComponent ! = NULL )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SplineComponent - > ControlPoints )
2014-03-14 14:13:41 -04:00
{
if ( ControlPoint - > OwnsComponent ( ControlPointMeshComponent ) )
{
ClickedControlPoint = ControlPoint ;
break ;
}
}
}
}
}
if ( ClickedControlPoint ! = NULL )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_AddSegment " , " Add Landscape Spline Segment " ) ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
AddSegment ( ControlPoint , ClickedControlPoint , bAutoRotateOnJoin , bAutoRotateOnJoin ) ;
2014-03-14 14:13:41 -04:00
}
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
return true ;
}
}
}
}
if ( SelectedSplineControlPoints . Num ( ) = = 0 )
{
if ( InKey = = EKeys : : LeftMouseButton & & InEvent = = IE_Pressed
& & IsCtrlDown ( InViewport ) )
{
int32 HitX = InViewport - > GetMouseX ( ) ;
int32 HitY = InViewport - > GetMouseY ( ) ;
HHitProxy * HitProxy = InViewport - > GetHitProxy ( HitX , HitY ) ;
if ( HitProxy )
{
ULandscapeSplineSegment * ClickedSplineSegment = NULL ;
FTransform LandscapeToSpline ;
2014-07-17 12:20:34 -04:00
if ( HitProxy - > IsA ( HLandscapeSplineProxy_Segment : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HLandscapeSplineProxy_Segment * SplineProxy = ( HLandscapeSplineProxy_Segment * ) HitProxy ;
ClickedSplineSegment = SplineProxy - > SplineSegment ;
LandscapeToSpline = ClickedSplineSegment - > GetTypedOuter < AActor > ( ) - > ActorToWorld ( ) . GetRelativeTransform ( ClickedSplineSegment - > GetTypedOuter < ULandscapeSplinesComponent > ( ) - > ComponentToWorld ) ;
}
2014-07-17 12:20:34 -04:00
else if ( HitProxy - > IsA ( HActor : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HActor * ActorProxy = ( HActor * ) HitProxy ;
const USplineMeshComponent * SplineMeshComponent = Cast < const USplineMeshComponent > ( ActorProxy - > PrimComponent ) ;
if ( SplineMeshComponent ! = NULL )
{
ULandscapeSplinesComponent * SplineComponent = ActorProxy - > Actor - > FindComponentByClass < ULandscapeSplinesComponent > ( ) ;
if ( SplineComponent ! = NULL )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * SplineSegment : SplineComponent - > Segments )
2014-03-14 14:13:41 -04:00
{
if ( SplineSegment - > OwnsComponent ( SplineMeshComponent ) )
{
ClickedSplineSegment = SplineSegment ;
LandscapeToSpline = ActorProxy - > Actor - > ActorToWorld ( ) . GetRelativeTransform ( SplineComponent - > ComponentToWorld ) ;
break ;
}
}
}
}
}
if ( ClickedSplineSegment ! = NULL )
{
FVector HitLocation ;
2014-05-29 16:46:26 -04:00
if ( EdMode - > LandscapeMouseTrace ( InViewportClient , HitLocation ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_SplitSegment " , " Split Landscape Spline Segment " ) ) ;
2014-03-14 14:13:41 -04:00
SplitSegment ( ClickedSplineSegment , LandscapeToSpline . TransformPosition ( HitLocation ) ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
}
return true ;
}
}
}
}
if ( InKey = = EKeys : : LeftMouseButton )
{
// Press mouse button
if ( InEvent = = IE_Pressed )
{
// See if we clicked on a spline handle..
int32 HitX = InViewport - > GetMouseX ( ) ;
int32 HitY = InViewport - > GetMouseY ( ) ;
HHitProxy * HitProxy = InViewport - > GetHitProxy ( HitX , HitY ) ;
if ( HitProxy )
{
2014-07-17 12:20:34 -04:00
if ( HitProxy - > IsA ( HWidgetAxis : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
checkSlow ( SelectedSplineControlPoints . Num ( ) > 0 ) ;
bMovingControlPoint = true ;
2014-07-17 12:20:34 -04:00
GEditor - > BeginTransaction ( LOCTEXT ( " LandscapeSpline_ModifyControlPoint " , " Modify Landscape Spline Control Point " ) ) ;
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ControlPoint - > Modify ( ) ;
ControlPoint - > GetOuterULandscapeSplinesComponent ( ) - > Modify ( ) ;
2014-03-14 14:13:41 -04:00
}
return false ; // We're not actually handling this case ourselves, just wrapping it in a transaction
}
2014-07-17 12:20:34 -04:00
else if ( HitProxy - > IsA ( HLandscapeSplineProxy_Tangent : : StaticGetType ( ) ) )
2014-03-14 14:13:41 -04:00
{
HLandscapeSplineProxy_Tangent * SplineProxy = ( HLandscapeSplineProxy_Tangent * ) HitProxy ;
DraggingTangent_Segment = SplineProxy - > SplineSegment ;
DraggingTangent_End = SplineProxy - > End ;
2014-07-17 12:20:34 -04:00
GEditor - > BeginTransaction ( LOCTEXT ( " LandscapeSpline_ModifyTangent " , " Modify Landscape Spline Tangent " ) ) ;
2014-03-14 14:13:41 -04:00
ULandscapeSplinesComponent * SplinesComponent = DraggingTangent_Segment - > GetOuterULandscapeSplinesComponent ( ) ;
SplinesComponent - > Modify ( ) ;
DraggingTangent_Segment - > Modify ( ) ;
2014-06-18 10:16:16 -04:00
return false ; // false to let FEditorViewportClient.InputKey start mouse tracking and enable InputDelta() so we can use it
2014-03-14 14:13:41 -04:00
}
}
}
else if ( InEvent = = IE_Released )
{
if ( bMovingControlPoint )
{
bMovingControlPoint = false ;
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ControlPoint - > UpdateSplinePoints ( true ) ;
2014-03-14 14:13:41 -04:00
}
GEditor - > EndTransaction ( ) ;
return false ; // We're not actually handling this case ourselves, just wrapping it in a transaction
}
else if ( DraggingTangent_Segment )
{
DraggingTangent_Segment - > UpdateSplinePoints ( true ) ;
DraggingTangent_Segment = NULL ;
GEditor - > EndTransaction ( ) ;
2014-06-18 10:16:16 -04:00
return false ; // false to let FEditorViewportClient.InputKey end mouse tracking
2014-03-14 14:13:41 -04:00
}
}
}
return false ;
}
2014-07-17 12:20:34 -04:00
virtual bool InputDelta ( FEditorViewportClient * InViewportClient , FViewport * InViewport , FVector & InDrag , FRotator & InRot , FVector & InScale ) override
2014-03-14 14:13:41 -04:00
{
FVector Drag = InDrag ;
if ( DraggingTangent_Segment )
{
const ULandscapeSplinesComponent * SplinesComponent = DraggingTangent_Segment - > GetOuterULandscapeSplinesComponent ( ) ;
FLandscapeSplineSegmentConnection & Connection = DraggingTangent_Segment - > Connections [ DraggingTangent_End ] ;
FVector StartLocation ; FRotator StartRotation ;
Connection . ControlPoint - > GetConnectionLocationAndRotation ( Connection . SocketName , StartLocation , StartRotation ) ;
float OldTangentLen = Connection . TangentLen ;
Connection . TangentLen + = SplinesComponent - > ComponentToWorld . InverseTransformVector ( - Drag ) | StartRotation . Vector ( ) ;
// Disallow a tangent of exactly 0
if ( Connection . TangentLen = = 0 )
{
if ( OldTangentLen > 0 )
{
Connection . TangentLen = SMALL_NUMBER ;
}
else
{
Connection . TangentLen = - SMALL_NUMBER ;
}
}
// Flipping the tangent is only allowed if not using a socket
if ( Connection . SocketName ! = NAME_None )
{
Connection . TangentLen = FMath : : Max ( SMALL_NUMBER , Connection . TangentLen ) ;
}
DraggingTangent_Segment - > UpdateSplinePoints ( false ) ;
return true ;
}
if ( SelectedSplineControlPoints . Num ( ) > 0 & & InViewportClient - > GetCurrentWidgetAxis ( ) ! = EAxisList : : None )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
const ULandscapeSplinesComponent * SplinesComponent = ControlPoint - > GetOuterULandscapeSplinesComponent ( ) ;
ControlPoint - > Location + = SplinesComponent - > ComponentToWorld . InverseTransformVector ( Drag ) ;
FVector RotAxis ; float RotAngle ;
InRot . Quaternion ( ) . ToAxisAndAngle ( RotAxis , RotAngle ) ;
RotAxis = ( SplinesComponent - > ComponentToWorld . GetRotation ( ) . Inverse ( ) * ControlPoint - > Rotation . Quaternion ( ) . Inverse ( ) ) . RotateVector ( RotAxis ) ;
// Hack: for some reason FQuat.Rotator() Clamps to 0-360 range, so use .GetNormalized() to recover the original negative rotation.
ControlPoint - > Rotation + = FQuat ( RotAxis , RotAngle ) . Rotator ( ) . GetNormalized ( ) ;
ControlPoint - > Rotation . Yaw = FRotator : : NormalizeAxis ( ControlPoint - > Rotation . Yaw ) ;
ControlPoint - > Rotation . Pitch = FMath : : Clamp ( ControlPoint - > Rotation . Pitch , - 85.0f , 85.0f ) ;
ControlPoint - > Rotation . Roll = FMath : : Clamp ( ControlPoint - > Rotation . Roll , - 85.0f , 85.0f ) ;
if ( bAutoChangeConnectionsOnMove )
{
ControlPoint - > AutoSetConnections ( true ) ;
}
ControlPoint - > UpdateSplinePoints ( false ) ;
}
return true ;
}
return false ;
}
void FixSelection ( )
{
SelectedSplineControlPoints . Empty ( ) ;
SelectedSplineSegments . Empty ( ) ;
2014-07-17 12:20:34 -04:00
if ( EdMode - > CurrentTool ! = NULL & & EdMode - > CurrentTool = = this )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( const FLandscapeListInfo & Info : EdMode - > GetLandscapeList ( ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ALandscape * Landscape = Info . Info - > LandscapeActor . Get ( ) ;
2014-03-14 14:13:41 -04:00
if ( Landscape ! = NULL & & Landscape - > SplineComponent ! = NULL )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : Landscape - > SplineComponent - > ControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
if ( ControlPoint - > IsSplineSelected ( ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
SelectedSplineControlPoints . Add ( ControlPoint ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : Landscape - > SplineComponent - > Segments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
if ( Segment - > IsSplineSelected ( ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
SelectedSplineSegments . Add ( Segment ) ;
}
}
}
for ( ALandscapeProxy * LandscapeProxy : Info . Info - > Proxies )
{
if ( LandscapeProxy ! = NULL & & LandscapeProxy - > SplineComponent ! = NULL )
{
for ( ULandscapeSplineControlPoint * ControlPoint : LandscapeProxy - > SplineComponent - > ControlPoints )
{
if ( ControlPoint - > IsSplineSelected ( ) )
{
SelectedSplineControlPoints . Add ( ControlPoint ) ;
}
}
for ( ULandscapeSplineSegment * Segment : LandscapeProxy - > SplineComponent - > Segments )
{
if ( Segment - > IsSplineSelected ( ) )
{
SelectedSplineSegments . Add ( Segment ) ;
}
2014-03-14 14:13:41 -04:00
}
}
}
}
}
else
{
2014-05-29 16:46:26 -04:00
for ( const FLandscapeListInfo & Info : EdMode - > GetLandscapeList ( ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ALandscape * Landscape = Info . Info - > LandscapeActor . Get ( ) ;
2014-03-14 14:13:41 -04:00
if ( Landscape ! = NULL & & Landscape - > SplineComponent ! = NULL )
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : Landscape - > SplineComponent - > ControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ControlPoint - > SetSplineSelected ( false ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : Landscape - > SplineComponent - > Segments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
Segment - > SetSplineSelected ( false ) ;
}
}
for ( ALandscapeProxy * LandscapeProxy : Info . Info - > Proxies )
{
if ( LandscapeProxy ! = NULL & & LandscapeProxy - > SplineComponent ! = NULL )
{
for ( ULandscapeSplineControlPoint * ControlPoint : LandscapeProxy - > SplineComponent - > ControlPoints )
{
ControlPoint - > SetSplineSelected ( false ) ;
}
for ( ULandscapeSplineSegment * Segment : LandscapeProxy - > SplineComponent - > Segments )
{
Segment - > SetSplineSelected ( false ) ;
}
2014-03-14 14:13:41 -04:00
}
}
}
}
}
void OnUndo ( )
{
FixSelection ( ) ;
UpdatePropertiesWindows ( ) ;
}
2014-06-13 06:14:46 -04:00
virtual void EnterTool ( ) override
2014-03-14 14:13:41 -04:00
{
GEditor - > SelectNone ( true , true , false ) ;
2014-05-29 16:46:26 -04:00
for ( const FLandscapeListInfo & Info : EdMode - > GetLandscapeList ( ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ALandscapeProxy * Landscape = Info . Info - > GetCurrentLevelLandscapeProxy ( true ) ;
2014-03-14 14:13:41 -04:00
if ( Landscape ! = NULL & & Landscape - > SplineComponent ! = NULL )
{
Landscape - > SplineComponent - > ShowSplineEditorMesh ( true ) ;
}
}
}
2014-06-13 06:14:46 -04:00
virtual void ExitTool ( ) override
2014-03-14 14:13:41 -04:00
{
ClearSelection ( ) ;
UpdatePropertiesWindows ( ) ;
2014-05-29 16:46:26 -04:00
for ( const FLandscapeListInfo & Info : EdMode - > GetLandscapeList ( ) )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ALandscapeProxy * Landscape = Info . Info - > GetCurrentLevelLandscapeProxy ( true ) ;
2014-03-14 14:13:41 -04:00
if ( Landscape ! = NULL & & Landscape - > SplineComponent ! = NULL )
{
Landscape - > SplineComponent - > ShowSplineEditorMesh ( false ) ;
}
}
}
2014-06-13 06:14:46 -04:00
virtual void Render ( const FSceneView * View , FViewport * Viewport , FPrimitiveDrawInterface * PDI ) override
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
const ULandscapeSplinesComponent * SplinesComponent = ControlPoint - > GetOuterULandscapeSplinesComponent ( ) ;
FVector HandlePos0 = SplinesComponent - > ComponentToWorld . TransformPosition ( ControlPoint - > Location + ControlPoint - > Rotation . Vector ( ) * - 20 ) ;
FVector HandlePos1 = SplinesComponent - > ComponentToWorld . TransformPosition ( ControlPoint - > Location + ControlPoint - > Rotation . Vector ( ) * 20 ) ;
DrawDashedLine ( PDI , HandlePos0 , HandlePos1 , FColor : : White , 20 , SDPG_Foreground ) ;
2014-06-18 10:16:16 -04:00
if ( GLevelEditorModeTools ( ) . GetWidgetMode ( ) = = FWidget : : WM_Scale )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( const FLandscapeSplineConnection & Connection : ControlPoint - > ConnectedSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
FVector StartLocation ; FRotator StartRotation ;
Connection . GetNearConnection ( ) . ControlPoint - > GetConnectionLocationAndRotation ( Connection . GetNearConnection ( ) . SocketName , StartLocation , StartRotation ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
FVector StartPos = SplinesComponent - > ComponentToWorld . TransformPosition ( StartLocation ) ;
FVector HandlePos = SplinesComponent - > ComponentToWorld . TransformPosition ( StartLocation + StartRotation . Vector ( ) * Connection . GetNearConnection ( ) . TangentLen / 2 ) ;
PDI - > DrawLine ( StartPos , HandlePos , FColor : : White , SDPG_Foreground ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
if ( PDI - > IsHitTesting ( ) ) PDI - > SetHitProxy ( new HLandscapeSplineProxy_Tangent ( Connection . Segment , Connection . End ) ) ;
PDI - > DrawPoint ( HandlePos , FColor ( 255 , 255 , 255 ) , 10.f , SDPG_Foreground ) ;
if ( PDI - > IsHitTesting ( ) ) PDI - > SetHitProxy ( NULL ) ;
2014-03-14 14:13:41 -04:00
}
}
}
2014-06-18 10:16:16 -04:00
if ( GLevelEditorModeTools ( ) . GetWidgetMode ( ) = = FWidget : : WM_Scale )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
const ULandscapeSplinesComponent * SplinesComponent = Segment - > GetOuterULandscapeSplinesComponent ( ) ;
for ( int32 End = 0 ; End < = 1 ; End + + )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
const FLandscapeSplineSegmentConnection & Connection = Segment - > Connections [ End ] ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
FVector StartLocation ; FRotator StartRotation ;
Connection . ControlPoint - > GetConnectionLocationAndRotation ( Connection . SocketName , StartLocation , StartRotation ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
FVector EndPos = SplinesComponent - > ComponentToWorld . TransformPosition ( StartLocation ) ;
FVector EndHandlePos = SplinesComponent - > ComponentToWorld . TransformPosition ( StartLocation + StartRotation . Vector ( ) * Connection . TangentLen / 2 ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
PDI - > DrawLine ( EndPos , EndHandlePos , FColor : : White , SDPG_Foreground ) ;
2014-07-17 12:20:34 -04:00
if ( PDI - > IsHitTesting ( ) ) PDI - > SetHitProxy ( new HLandscapeSplineProxy_Tangent ( Segment , ! ! End ) ) ;
PDI - > DrawPoint ( EndHandlePos , FColor ( 255 , 255 , 255 ) , 10.f , SDPG_Foreground ) ;
if ( PDI - > IsHitTesting ( ) ) PDI - > SetHitProxy ( NULL ) ;
2014-03-14 14:13:41 -04:00
}
}
}
}
2014-06-13 06:14:46 -04:00
virtual bool OverrideSelection ( ) const override
2014-03-14 14:13:41 -04:00
{
return true ;
}
2014-07-17 12:20:34 -04:00
virtual bool IsSelectionAllowed ( AActor * InActor , bool bInSelection ) const override
2014-03-14 14:13:41 -04:00
{
// Only filter selection not deselection
if ( bInSelection )
{
return false ;
}
return true ;
}
2014-06-13 06:14:46 -04:00
virtual bool UsesTransformWidget ( ) const override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 )
{
return true ;
}
return false ;
}
2014-06-13 06:14:46 -04:00
virtual EAxisList : : Type GetWidgetAxisToDraw ( FWidget : : EWidgetMode CheckMode ) const override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 )
{
//if (CheckMode == FWidget::WM_Rotate
// && SelectedSplineControlPoints.Num() >= 2)
//{
// return AXIS_X;
//}
//else
if ( CheckMode ! = FWidget : : WM_Scale )
{
return EAxisList : : XYZ ;
}
else
{
return EAxisList : : None ;
}
}
return EAxisList : : None ;
}
2014-06-13 06:14:46 -04:00
virtual FVector GetWidgetLocation ( ) const override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 )
{
ULandscapeSplineControlPoint * FirstPoint = * SelectedSplineControlPoints . CreateConstIterator ( ) ;
ULandscapeSplinesComponent * SplinesComponent = FirstPoint - > GetOuterULandscapeSplinesComponent ( ) ;
return SplinesComponent - > ComponentToWorld . TransformPosition ( FirstPoint - > Location ) ;
}
return FVector : : ZeroVector ;
}
2014-06-13 06:14:46 -04:00
virtual FMatrix GetWidgetRotation ( ) const override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 )
{
ULandscapeSplineControlPoint * FirstPoint = * SelectedSplineControlPoints . CreateConstIterator ( ) ;
ULandscapeSplinesComponent * SplinesComponent = FirstPoint - > GetOuterULandscapeSplinesComponent ( ) ;
return FQuatRotationTranslationMatrix ( FirstPoint - > Rotation . Quaternion ( ) * SplinesComponent - > ComponentToWorld . GetRotation ( ) , FVector : : ZeroVector ) ;
}
return FMatrix : : Identity ;
}
2014-06-13 06:14:46 -04:00
virtual EEditAction : : Type GetActionEditDuplicate ( ) override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
return EEditAction : : Process ;
}
return EEditAction : : Skip ;
}
2014-06-13 06:14:46 -04:00
virtual EEditAction : : Type GetActionEditDelete ( ) override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
return EEditAction : : Process ;
}
return EEditAction : : Skip ;
}
2014-06-13 06:14:46 -04:00
virtual EEditAction : : Type GetActionEditCut ( ) override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
return EEditAction : : Process ;
}
return EEditAction : : Skip ;
}
2014-06-13 06:14:46 -04:00
virtual EEditAction : : Type GetActionEditCopy ( ) override
2014-03-14 14:13:41 -04:00
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
return EEditAction : : Process ;
}
return EEditAction : : Skip ;
}
2014-06-13 06:14:46 -04:00
virtual EEditAction : : Type GetActionEditPaste ( ) override
2014-03-14 14:13:41 -04:00
{
FString PasteString ;
FPlatformMisc : : ClipboardPaste ( PasteString ) ;
if ( PasteString . StartsWith ( " BEGIN SPLINES " ) )
{
return EEditAction : : Process ;
}
return EEditAction : : Skip ;
}
2014-06-13 06:14:46 -04:00
virtual bool ProcessEditDuplicate ( ) override
2014-03-14 14:13:41 -04:00
{
InternalProcessEditDuplicate ( ) ;
return true ;
}
2014-06-13 06:14:46 -04:00
virtual bool ProcessEditDelete ( ) override
2014-03-14 14:13:41 -04:00
{
InternalProcessEditDelete ( ) ;
return true ;
}
2014-06-13 06:14:46 -04:00
virtual bool ProcessEditCut ( ) override
2014-03-14 14:13:41 -04:00
{
InternalProcessEditCut ( ) ;
return true ;
}
2014-06-13 06:14:46 -04:00
virtual bool ProcessEditCopy ( ) override
2014-03-14 14:13:41 -04:00
{
InternalProcessEditCopy ( ) ;
return true ;
}
2014-06-13 06:14:46 -04:00
virtual bool ProcessEditPaste ( ) override
2014-03-14 14:13:41 -04:00
{
InternalProcessEditPaste ( ) ;
return true ;
}
void InternalProcessEditDuplicate ( )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_Duplicate " , " Duplicate Landscape Splines " ) ) ;
2014-03-14 14:13:41 -04:00
FString Data ;
InternalProcessEditCopy ( & Data ) ;
InternalProcessEditPaste ( & Data , true ) ;
}
}
void InternalProcessEditDelete ( )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_Delete " , " Delete Landscape Splines " ) ) ;
2014-03-14 14:13:41 -04:00
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
DeleteControlPoint ( ControlPoint , bDeleteLooseEnds ) ;
2014-03-14 14:13:41 -04:00
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
DeleteSegment ( Segment , bDeleteLooseEnds ) ;
2014-03-14 14:13:41 -04:00
}
ClearSelection ( ) ;
UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
}
}
void InternalProcessEditCut ( )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_Cut " , " Cut Landscape Splines " ) ) ;
2014-03-14 14:13:41 -04:00
InternalProcessEditCopy ( ) ;
InternalProcessEditDelete ( ) ;
}
}
void InternalProcessEditCopy ( FString * OutData = NULL )
{
if ( SelectedSplineControlPoints . Num ( ) > 0 | | SelectedSplineSegments . Num ( ) > 0 )
{
TArray < UObject * > Objects ;
Objects . Reserve ( SelectedSplineControlPoints . Num ( ) + SelectedSplineSegments . Num ( ) * 3 ) ; // worst case
// Control Points then segments
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineControlPoint * ControlPoint : SelectedSplineControlPoints )
2014-03-14 14:13:41 -04:00
{
Objects . Add ( ControlPoint ) ;
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
Objects . AddUnique ( Segment - > Connections [ 0 ] . ControlPoint ) ;
Objects . AddUnique ( Segment - > Connections [ 1 ] . ControlPoint ) ;
}
2014-05-29 16:46:26 -04:00
for ( ULandscapeSplineSegment * Segment : SelectedSplineSegments )
2014-03-14 14:13:41 -04:00
{
Objects . Add ( Segment ) ;
}
// Perform export to text format
FStringOutputDevice Ar ;
Ar . Logf ( TEXT ( " Begin Splines \r \n " ) ) ;
2014-05-29 16:46:26 -04:00
for ( UObject * Object : Objects )
2014-03-14 14:13:41 -04:00
{
UExporter : : ExportToOutputDevice ( NULL , Object , NULL , Ar , TEXT ( " copy " ) , 3 , PPF_None , false ) ;
}
Ar . Logf ( TEXT ( " End Splines \r \n " ) ) ;
if ( OutData ! = NULL )
{
* OutData = MoveTemp ( Ar ) ;
}
else
{
FPlatformMisc : : ClipboardCopy ( * Ar ) ;
}
}
}
void InternalProcessEditPaste ( FString * InData = NULL , bool bOffset = false )
{
2014-07-17 12:20:34 -04:00
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_Paste " , " Paste Landscape Splines " ) ) ;
2014-03-14 14:13:41 -04:00
2014-04-23 20:12:41 -04:00
ALandscapeProxy * Landscape = EdMode - > CurrentToolTarget . LandscapeInfo - > GetCurrentLevelLandscapeProxy ( true ) ;
2014-03-14 14:13:41 -04:00
if ( ! Landscape )
{
return ;
}
if ( ! Landscape - > SplineComponent )
{
2014-04-28 02:52:54 -04:00
CreateSplineComponent ( Landscape , FVector ( 1.f ) / Landscape - > GetRootComponent ( ) - > RelativeScale3D ) ;
2014-03-14 14:13:41 -04:00
}
const TCHAR * Data = NULL ;
FString PasteString ;
if ( InData ! = NULL )
{
Data = * * InData ;
}
else
{
FPlatformMisc : : ClipboardPaste ( PasteString ) ;
Data = * PasteString ;
}
FLandscapeSplineTextObjectFactory Factory ;
TArray < UObject * > OutObjects = Factory . ImportSplines ( Landscape - > SplineComponent , Data ) ;
if ( bOffset )
{
2014-05-29 16:46:26 -04:00
for ( UObject * Object : OutObjects )
2014-03-14 14:13:41 -04:00
{
2014-05-29 16:46:26 -04:00
ULandscapeSplineControlPoint * ControlPoint = Cast < ULandscapeSplineControlPoint > ( Object ) ;
2014-03-14 14:13:41 -04:00
if ( ControlPoint ! = NULL )
{
Landscape - > SplineComponent - > ControlPoints . Add ( ControlPoint ) ;
ControlPoint - > Location + = FVector ( 500 , 500 , 0 ) ;
ControlPoint - > UpdateSplinePoints ( ) ;
}
}
}
}
protected :
// Begin FEditorUndoClient
2014-06-13 06:14:46 -04:00
virtual void PostUndo ( bool bSuccess ) override { OnUndo ( ) ; }
virtual void PostRedo ( bool bSuccess ) override { PostUndo ( bSuccess ) ; }
2014-03-14 14:13:41 -04:00
// End of FEditorUndoClient
protected :
2014-07-17 12:20:34 -04:00
FEdModeLandscape * EdMode ;
ULandscapeInfo * LandscapeInfo ;
2014-03-14 14:13:41 -04:00
TSet < ULandscapeSplineControlPoint * > SelectedSplineControlPoints ;
TSet < ULandscapeSplineSegment * > SelectedSplineSegments ;
ULandscapeSplineSegment * DraggingTangent_Segment ;
2014-07-17 12:20:34 -04:00
uint32 DraggingTangent_End : 1 ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
uint32 bMovingControlPoint : 1 ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
uint32 bAutoRotateOnJoin : 1 ;
uint32 bAutoChangeConnectionsOnMove : 1 ;
uint32 bDeleteLooseEnds : 1 ;
uint32 bCopyMeshToNewControlPoint : 1 ;
2014-04-23 19:54:50 -04:00
2014-07-17 12:20:34 -04:00
friend FEdModeLandscape ;
2014-03-14 14:13:41 -04:00
} ;
void FEdModeLandscape : : ShowSplineProperties ( )
{
2014-07-17 12:20:34 -04:00
if ( SplinesTool /*&& SplinesTool == CurrentTool*/ )
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
SplinesTool - > ShowSplineProperties ( ) ;
2014-03-14 14:13:41 -04:00
}
}
void FEdModeLandscape : : SelectAllConnectedSplineControlPoints ( )
{
2014-07-17 12:20:34 -04:00
if ( SplinesTool /*&& SplinesTool == CurrentTool*/ )
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
SplinesTool - > SelectAdjacentControlPoints ( ) ;
SplinesTool - > ClearSelectedSegments ( ) ;
SplinesTool - > SelectConnected ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
SplinesTool - > UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
2014-03-14 14:13:41 -04:00
}
}
void FEdModeLandscape : : SelectAllConnectedSplineSegments ( )
{
2014-07-17 12:20:34 -04:00
if ( SplinesTool /*&& SplinesTool == CurrentTool*/ )
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
SplinesTool - > SelectAdjacentSegments ( ) ;
SplinesTool - > ClearSelectedControlPoints ( ) ;
SplinesTool - > SelectConnected ( ) ;
2014-03-14 14:13:41 -04:00
2014-07-17 12:20:34 -04:00
SplinesTool - > UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
2014-03-14 14:13:41 -04:00
}
}
2014-04-23 20:12:41 -04:00
void FEdModeLandscape : : SplineMoveToCurrentLevel ( )
{
FScopedTransaction Transaction ( LOCTEXT ( " LandscapeSpline_AddControlPoint " , " Add Landscape Spline Control Point " ) ) ;
2014-07-17 12:20:34 -04:00
if ( SplinesTool /*&& SplinesTool == CurrentTool*/ )
2014-04-23 20:12:41 -04:00
{
2014-07-17 12:20:34 -04:00
// Select all connected control points
SplinesTool - > SelectAdjacentSegments ( ) ;
SplinesTool - > SelectAdjacentControlPoints ( ) ;
SplinesTool - > SelectConnected ( ) ;
TSet < ALandscapeProxy * > FromProxies ;
ALandscapeProxy * Landscape = NULL ;
for ( ULandscapeSplineControlPoint * ControlPoint : SplinesTool - > SelectedSplineControlPoints )
2014-04-23 20:12:41 -04:00
{
2014-07-17 12:20:34 -04:00
ULandscapeSplinesComponent * LandscapeSplinesComp = ControlPoint - > GetOuterULandscapeSplinesComponent ( ) ;
ALandscapeProxy * FromProxy = LandscapeSplinesComp ? Cast < ALandscapeProxy > ( LandscapeSplinesComp - > GetOuter ( ) ) : NULL ;
if ( FromProxy )
2014-04-23 20:12:41 -04:00
{
2014-07-17 12:20:34 -04:00
if ( ! Landscape )
2014-04-23 20:12:41 -04:00
{
2014-07-17 12:20:34 -04:00
ULandscapeInfo * LandscapeInfo = FromProxy - > GetLandscapeInfo ( false ) ;
check ( LandscapeInfo ) ;
Landscape = LandscapeInfo - > GetCurrentLevelLandscapeProxy ( true ) ;
2014-04-23 20:12:41 -04:00
if ( ! Landscape )
{
2014-07-17 12:20:34 -04:00
// No Landscape Proxy, don't support for creating only for Spline now
return ;
2014-04-23 20:12:41 -04:00
}
2014-07-17 12:20:34 -04:00
}
2014-04-23 20:12:41 -04:00
2014-07-17 12:20:34 -04:00
if ( Landscape ! = FromProxy )
{
Landscape - > Modify ( ) ;
if ( Landscape - > SplineComponent = = NULL )
2014-04-23 20:12:41 -04:00
{
2014-07-17 12:20:34 -04:00
SplinesTool - > CreateSplineComponent ( Landscape , FromProxy - > SplineComponent - > RelativeScale3D ) ;
2014-04-23 20:12:41 -04:00
}
2014-07-17 12:20:34 -04:00
const FTransform OldToNewTransform =
Landscape - > SplineComponent - > ComponentToWorld . GetRelativeTransform ( FromProxy - > SplineComponent - > ComponentToWorld ) ;
Landscape - > SplineComponent - > Modify ( ) ;
if ( FromProxies . Find ( FromProxy ) = = NULL )
{
FromProxies . Add ( FromProxy ) ;
FromProxy - > Modify ( ) ;
FromProxy - > SplineComponent - > Modify ( ) ;
FromProxy - > SplineComponent - > MarkRenderStateDirty ( ) ;
}
// Add/Remove Control Point/Segment/MeshComponents
FromProxy - > SplineComponent - > ControlPoints . Remove ( ControlPoint ) ;
ControlPoint - > Rename ( NULL , Landscape - > SplineComponent ) ;
Landscape - > SplineComponent - > ControlPoints . Add ( ControlPoint ) ;
ControlPoint - > Location = OldToNewTransform . TransformPosition ( ControlPoint - > Location ) ;
if ( ControlPoint - > MeshComponent )
{
UControlPointMeshComponent * ControlPointMeshComp = ControlPoint - > MeshComponent ;
ControlPointMeshComp - > Modify ( ) ;
ControlPointMeshComp - > UnregisterComponent ( ) ;
ControlPointMeshComp - > DetachFromParent ( true ) ;
ControlPointMeshComp - > InvalidateLightingCache ( ) ;
ControlPointMeshComp - > Rename ( NULL , Landscape ) ;
ControlPointMeshComp - > AttachTo ( Landscape - > SplineComponent , NAME_None , EAttachLocation : : KeepWorldPosition ) ;
}
ControlPoint - > UpdateSplinePoints ( true , false ) ;
2014-04-23 20:12:41 -04:00
}
}
}
2014-07-17 12:20:34 -04:00
for ( ULandscapeSplineSegment * Segment : SplinesTool - > SelectedSplineSegments )
{
ULandscapeSplinesComponent * LandscapeSplinesComp = Segment - > GetOuterULandscapeSplinesComponent ( ) ;
ALandscapeProxy * FromProxy = LandscapeSplinesComp ? Cast < ALandscapeProxy > ( LandscapeSplinesComp - > GetOuter ( ) ) : NULL ;
if ( FromProxy )
{
if ( ! Landscape )
{
ULandscapeInfo * LandscapeInfo = FromProxy - > GetLandscapeInfo ( false ) ;
check ( LandscapeInfo ) ;
Landscape = LandscapeInfo - > GetCurrentLevelLandscapeProxy ( true ) ;
if ( ! Landscape )
{
// No Landscape Proxy, don't support for creating only for Spline now
return ;
}
}
if ( Landscape ! = FromProxy )
{
Landscape - > Modify ( ) ;
if ( Landscape - > SplineComponent = = NULL )
{
SplinesTool - > CreateSplineComponent ( Landscape , FromProxy - > SplineComponent - > RelativeScale3D ) ;
}
Landscape - > SplineComponent - > Modify ( ) ;
if ( FromProxies . Find ( FromProxy ) = = NULL )
{
FromProxies . Add ( FromProxy ) ;
FromProxy - > Modify ( ) ;
FromProxy - > SplineComponent - > Modify ( ) ;
FromProxy - > SplineComponent - > MarkRenderStateDirty ( ) ;
}
// Add/Remove Control Point/Segment/MeshComponents
FromProxy - > SplineComponent - > Segments . Remove ( Segment ) ;
Segment - > Rename ( NULL , Landscape - > SplineComponent ) ;
Landscape - > SplineComponent - > Segments . Add ( Segment ) ;
for ( USplineMeshComponent * SplineMeshComp : Segment - > MeshComponents )
{
SplineMeshComp - > Modify ( ) ;
SplineMeshComp - > UnregisterComponent ( ) ;
SplineMeshComp - > DetachFromParent ( true ) ;
SplineMeshComp - > InvalidateLightingCache ( ) ;
SplineMeshComp - > Rename ( NULL , Landscape ) ;
SplineMeshComp - > AttachTo ( Landscape - > SplineComponent , NAME_None , EAttachLocation : : KeepWorldPosition ) ;
}
Segment - > UpdateSplinePoints ( ) ;
}
}
}
if ( Landscape & & Landscape - > SplineComponent )
{
if ( ! Landscape - > SplineComponent - > IsRegistered ( ) )
{
Landscape - > SplineComponent - > RegisterComponent ( ) ;
}
else
{
Landscape - > SplineComponent - > MarkRenderStateDirty ( ) ;
}
}
SplinesTool - > ClearSelection ( ) ;
SplinesTool - > UpdatePropertiesWindows ( ) ;
GUnrealEd - > RedrawLevelEditingViewports ( ) ;
2014-04-23 20:12:41 -04:00
}
}
2014-04-23 19:54:50 -04:00
void FEdModeLandscape : : SetbUseAutoRotateOnJoin ( bool InbAutoRotateOnJoin )
{
2014-07-17 12:20:34 -04:00
if ( SplinesTool /*&& SplinesTool == CurrentTool*/ )
2014-04-23 19:54:50 -04:00
{
2014-07-17 12:20:34 -04:00
SplinesTool - > bAutoRotateOnJoin = InbAutoRotateOnJoin ;
2014-04-23 19:54:50 -04:00
}
}
bool FEdModeLandscape : : GetbUseAutoRotateOnJoin ( )
{
2014-07-17 12:20:34 -04:00
if ( SplinesTool /*&& SplinesTool == CurrentTool*/ )
2014-04-23 19:54:50 -04:00
{
2014-07-17 12:20:34 -04:00
return SplinesTool - > bAutoRotateOnJoin ;
2014-04-23 19:54:50 -04:00
}
return true ; // default value
}
2014-07-17 12:20:34 -04:00
void FEdModeLandscape : : InitializeTool_Splines ( )
2014-03-14 14:13:41 -04:00
{
2014-07-17 12:20:34 -04:00
auto Tool_Splines = MakeUnique < FLandscapeToolSplines > ( this ) ;
Tool_Splines - > ValidBrushes . Add ( " BrushSet_Splines " ) ;
SplinesTool = Tool_Splines . Get ( ) ;
LandscapeTools . Add ( MoveTemp ( Tool_Splines ) ) ;
2014-03-14 14:13:41 -04:00
}
# undef LOCTEXT_NAMESPACE