Files
UnrealEngine/Engine/Source/Editor/UnrealEd/Private/MouseDeltaTracker.cpp
2025-05-18 13:04:45 +08:00

724 lines
22 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "MouseDeltaTracker.h"
#include "EngineDefines.h"
#include "SceneView.h"
#include "EditorViewportClient.h"
#include "Settings/LevelEditorViewportSettings.h"
#include "Editor.h"
#include "EditorDragTools.h"
#include "SnappingUtils.h"
#include "UnrealWidget.h"
#include "EditorDragTools/EditorDragToolBehaviorTarget.h"
#include "Misc/AxisDisplayInfo.h"
#define LOCTEXT_NAMESPACE "MouseDeltaTracker"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// FMouseDeltaTracker
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FMouseDeltaTracker::FMouseDeltaTracker()
: Start( FVector::ZeroVector )
, StartSnapped( FVector::ZeroVector )
, StartScreen( FVector::ZeroVector )
, End( FVector::ZeroVector )
, EndSnapped( FVector::ZeroVector )
, EndScreen( FVector::ZeroVector )
, RawDelta( FVector::ZeroVector )
, ReductionAmount( FVector::ZeroVector )
, DragTool( NULL )
, bHasAttemptedDragTool(false)
, bUsedDragModifier(false)
, bIsDeletingDragTool(false)
{
}
FMouseDeltaTracker::~FMouseDeltaTracker()
{
}
/**
* Sets the current axis of the widget for the specified viewport.
*
* @param InViewportClient The viewport whose widget axis is to be set.
*/
void FMouseDeltaTracker::DetermineCurrentAxis(FEditorViewportClient* InViewportClient)
{
const bool AltDown = InViewportClient->IsAltPressed();
const bool ShiftDown = InViewportClient->IsShiftPressed();
const bool ControlDown = InViewportClient->IsCtrlPressed();
const bool LeftMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::LeftMouseButton);
const bool RightMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::RightMouseButton);
const bool MiddleMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::MiddleMouseButton);
const bool bIsRotateObjectMode = InViewportClient->IsOrtho() && ControlDown && RightMouseButtonDown;
// Ctrl + LEFT/RIGHT mouse button acts the same as dragging the most appropriate widget handle.
if( (!InViewportClient->ShouldOrbitCamera() && bIsRotateObjectMode ) || ((!bIsRotateObjectMode && ControlDown && !AltDown ) &&
(LeftMouseButtonDown || RightMouseButtonDown)) )
{
// Only try to pick an axis if we're not dragging by widget handle.
if ( InViewportClient->GetCurrentWidgetAxis() == EAxisList::None )
{
switch( InViewportClient->GetWidgetMode() )
{
case UE::Widget::WM_Scale:
// Non-uniform scale when shift is down, uniform when it is up
if (ShiftDown)
{
switch( InViewportClient->ViewportType )
{
case LVT_Perspective:
if( LeftMouseButtonDown && !RightMouseButtonDown )
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::X );
}
else if( !LeftMouseButtonDown && RightMouseButtonDown )
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::Y );
}
else if( LeftMouseButtonDown && RightMouseButtonDown )
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::Z );
}
break;
case LVT_OrthoXY:
case LVT_OrthoNegativeXY:
InViewportClient->SetCurrentWidgetAxis( EAxisList::XY );
break;
case LVT_OrthoXZ:
case LVT_OrthoNegativeXZ:
InViewportClient->SetCurrentWidgetAxis( EAxisList::XZ );
break;
case LVT_OrthoYZ:
case LVT_OrthoNegativeYZ:
InViewportClient->SetCurrentWidgetAxis( EAxisList::YZ );
break;
default:
break;
}
}
else
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::XYZ );
}
break;
case UE::Widget::WM_Translate:
case UE::Widget::WM_TranslateRotateZ:
case UE::Widget::WM_2D:
switch( InViewportClient->ViewportType )
{
case LVT_Perspective:
if( LeftMouseButtonDown && !RightMouseButtonDown )
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::X );
}
else if( !LeftMouseButtonDown && RightMouseButtonDown )
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::Y );
}
else if( LeftMouseButtonDown && RightMouseButtonDown )
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::Z );
}
break;
case LVT_OrthoXY:
case LVT_OrthoNegativeXY:
InViewportClient->SetCurrentWidgetAxis(EAxisList::XY);
break;
case LVT_OrthoXZ:
case LVT_OrthoNegativeXZ:
InViewportClient->SetCurrentWidgetAxis(EAxisList::XZ);
break;
case LVT_OrthoYZ:
case LVT_OrthoNegativeYZ:
InViewportClient->SetCurrentWidgetAxis(EAxisList::YZ);
break;
default:
break;
}
break;
case UE::Widget::WM_Rotate:
switch( InViewportClient->ViewportType )
{
case LVT_Perspective:
if (LeftMouseButtonDown && !RightMouseButtonDown)
{
InViewportClient->SetCurrentWidgetAxis(EAxisList::X);
}
else if (!LeftMouseButtonDown && RightMouseButtonDown)
{
InViewportClient->SetCurrentWidgetAxis(EAxisList::Y);
}
else if (LeftMouseButtonDown && RightMouseButtonDown)
{
InViewportClient->SetCurrentWidgetAxis(EAxisList::Z);
}
break;
case LVT_OrthoXY:
case LVT_OrthoNegativeXY:
InViewportClient->SetCurrentWidgetAxis(EAxisList::Z);
break;
case LVT_OrthoXZ:
case LVT_OrthoNegativeXZ:
InViewportClient->SetCurrentWidgetAxis(EAxisList::Y);
break;
case LVT_OrthoYZ:
case LVT_OrthoNegativeYZ:
InViewportClient->SetCurrentWidgetAxis(EAxisList::X);
break;
default:
break;
}
break;
default:
break;
}
//if we now have a widget axis we must have used a modifier to get it
if( InViewportClient->GetCurrentWidgetAxis() != EAxisList::None )
{
bUsedDragModifier = true;
}
}
}
}
/**
* Begin tracking at the specified location for the specified viewport.
*/
void FMouseDeltaTracker::StartTracking(FEditorViewportClient* InViewportClient, const int32 InX, const int32 InY, const FInputEventState& InInputState, bool bNudge, bool bResetDragToolState)
{
DetermineCurrentAxis(InViewportClient);
// Initialize widget axis (in case it hasn't been set by the hovered hit proxy)
if (InViewportClient->Widget && InViewportClient->GetCurrentWidgetAxis() == EAxisList::None)
{
check(InViewportClient->Viewport);
HHitProxy* HitProxy = InViewportClient->Viewport->GetHitProxy(InX, InY);
if (HitProxy && HitProxy->IsA(HWidgetAxis::StaticGetType()))
{
EAxisList::Type ProxyAxis = ((HWidgetAxis*)HitProxy)->Axis;
InViewportClient->SetCurrentWidgetAxis(ProxyAxis);
}
}
const bool AltDown = InViewportClient->IsAltPressed();
const bool ShiftDown = InViewportClient->IsShiftPressed();
const bool ControlDown = InViewportClient->IsCtrlPressed();
const bool LeftMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::LeftMouseButton);
const bool RightMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::RightMouseButton);
const bool MiddleMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::MiddleMouseButton);
bool bIsDragging = ((ControlDown || ShiftDown) && (LeftMouseButtonDown || RightMouseButtonDown || MiddleMouseButtonDown)) ||
(InViewportClient->GetCurrentWidgetAxis() != EAxisList::None) || bNudge;
// Update bWidgetAxisControlledByDrag since we now know that we have begun dragging an object with the mouse.
if ( bIsDragging )
{
InViewportClient->bWidgetAxisControlledByDrag = true;
}
InViewportClient->TrackingStarted( InInputState, bIsDragging, bNudge );
if (InViewportClient->Widget)
{
InViewportClient->Widget->SetDragStartPosition(FVector2D(InX, InY));
InViewportClient->Widget->SetDragging(bIsDragging);
if (InViewportClient->GetWidgetMode() == UE::Widget::WM_Rotate)
{
InViewportClient->Invalidate();
}
}
// Clear bool that tracks whether AddDelta has been called
bHasReceivedAddDelta = false;
if( bResetDragToolState )
{
bHasAttemptedDragTool = false;
}
ensure( !DragTool.IsValid() );
StartSnapped = Start = StartScreen = FVector( InX, InY, 0 );
RawDelta = FVector::ZeroVector;
TrackingWidgetMode = InViewportClient->GetWidgetMode();
// No drag tool is active, so handle snapping.
switch( TrackingWidgetMode )
{
case UE::Widget::WM_Translate:
FSnappingUtils::SnapPointToGrid( StartSnapped, FVector(GEditor->GetGridSize(),GEditor->GetGridSize(),GEditor->GetGridSize()) );
break;
case UE::Widget::WM_Scale:
FSnappingUtils::SnapScale( StartSnapped, FVector(GEditor->GetGridSize(),GEditor->GetGridSize(),GEditor->GetGridSize()) );
break;
case UE::Widget::WM_Rotate:
{
FRotator Rotation( StartSnapped.X, StartSnapped.Y, StartSnapped.Z );
FSnappingUtils::SnapRotatorToGrid( Rotation );
StartSnapped = FVector( Rotation.Pitch, Rotation.Yaw, Rotation.Roll );
}
break;
case UE::Widget::WM_TranslateRotateZ:
case UE::Widget::WM_2D:
FSnappingUtils::SnapPointToGrid( StartSnapped, FVector(GEditor->GetGridSize(),GEditor->GetGridSize(),GEditor->GetGridSize()) );
break;
default:
break;
}
// Clear any snapping helpers on new movement
const bool bClearImmediatley = true;
FSnappingUtils::ClearSnappingHelpers( bClearImmediatley );
End = EndScreen = Start;
EndSnapped = StartSnapped;
bExternalMovement = false; //no external movement has occurred yet.
InViewportClient->Widget->ResetDeltaRotation();
}
/**
* Called when a mouse button has been released. If there are no other
* mouse buttons being held down, the internal information is reset.
*/
bool FMouseDeltaTracker::EndTracking(FEditorViewportClient* InViewportClient)
{
DetermineCurrentAxis( InViewportClient );
if (InViewportClient->Widget)
{
InViewportClient->Widget->SetDragging(false);
}
InViewportClient->TrackingStopped();
InViewportClient->Widget->ResetDeltaRotation();
Start = StartSnapped = StartScreen = End = EndSnapped = EndScreen = RawDelta = ReductionAmount = FVector::ZeroVector;
if (!bIsDeletingDragTool)
{
// Ending the drag tool may pop up a modal dialog which can cause unwanted reentrancy - protect against this.
TGuardValue<bool> RecursionGuard(bIsDeletingDragTool, true);
// Delete the drag tool if one exists.
if (DragTool.IsValid())
{
if (DragTool->IsDragging())
{
DragTool->EndDrag();
}
DragTool.Reset();
return false;
}
}
// Do not fade snapping indicators over time if this viewport is not real time
bool bClearImmediately = !InViewportClient->IsRealtime();
FSnappingUtils::ClearSnappingHelpers( bClearImmediately );
return true;
}
void FMouseDeltaTracker::ConditionalBeginUsingDragTool( FEditorViewportClient* InViewportClient )
{
if (UE::Editor::DragTools::UseEditorDragTools())
{
return;
}
const bool LeftMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::LeftMouseButton);
const bool RightMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::RightMouseButton);
const bool MiddleMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::MiddleMouseButton);
const bool bAltDown = InViewportClient->IsAltPressed();
const bool bShiftDown = InViewportClient->IsShiftPressed();
const bool bControlDown = InViewportClient->IsCtrlPressed();
// Has there been enough mouse movement to begin using a drag tool. We don't want to start using a tool for clicks(could have very small mouse movements)
bool bEnoughMouseMovement = GetRawDelta().SizeSquared() > MOUSE_CLICK_DRAG_DELTA;
if( bEnoughMouseMovement )
{
const bool bCanDrag = !DragTool.IsValid() && !RightMouseButtonDown && InViewportClient->CanUseDragTool();
if (bCanDrag && !bHasAttemptedDragTool)
{
// Create a drag tool.
if (!(bAltDown + bShiftDown) && bControlDown && MiddleMouseButtonDown && !LeftMouseButtonDown && !RightMouseButtonDown)
{
DragTool = InViewportClient->MakeDragTool(EDragTool::ViewportChange);
}
else
{
if (InViewportClient->IsOrtho())
{
if (LeftMouseButtonDown)
{
DragTool = InViewportClient->MakeDragTool(EDragTool::BoxSelect);
}
else if (!(bControlDown + bAltDown + bShiftDown) && MiddleMouseButtonDown)
{
DragTool = InViewportClient->MakeDragTool(EDragTool::Measure);
}
}
else
{
if (LeftMouseButtonDown && bControlDown && bAltDown)
{
DragTool = InViewportClient->MakeDragTool(EDragTool::FrustumSelect);
}
}
}
if (DragTool.IsValid())
{
DragTool->StartDrag(InViewportClient, GEditor->ClickLocation, FVector2D(StartScreen));
}
}
// Can not attempt to use a drag tool the rest of this tracking session
bHasAttemptedDragTool = true;
}
}
/**
* Adds delta movement into the tracker.
*/
void FMouseDeltaTracker::AddDelta(FEditorViewportClient* InViewportClient, FKey InKey, const int32 InDelta, bool InNudge)
{
const bool LeftMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::LeftMouseButton);
const bool RightMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::RightMouseButton);
const bool MiddleMouseButtonDown = InViewportClient->Viewport->KeyState(EKeys::MiddleMouseButton);
const bool bAltDown = InViewportClient->IsAltPressed();
const bool bShiftDown = InViewportClient->IsShiftPressed();
const bool bControlDown = InViewportClient->IsCtrlPressed();
if( !LeftMouseButtonDown && !MiddleMouseButtonDown && !RightMouseButtonDown && !InNudge )
{
return;
}
// Accumulate raw delta
RawDelta += FVector(InKey == EKeys::MouseX ? InDelta : 0,
InKey == EKeys::MouseY ? InDelta : 0,
0);
// Note that AddDelta has been called since StartTracking
bHasReceivedAddDelta = true;
// If we are using a drag tool, the widget isn't involved so set it to having no active axis. This
// means we will get unmodified mouse movement returned to us by other functions.
const EAxisList::Type SaveAxis = InViewportClient->GetCurrentWidgetAxis();
// If the user isn't dragging with the left mouse button, clear out the axis
// as the widget only responds to the left mouse button.
//
// We allow an exception for dragging with the left and/or right mouse button while holding control
// as that simulates moving objects with the gizmo
//
// We also allow the exception of the middle mouse button when Alt is pressed, or when the current axis is the pivot centre, as it
// allows movement of only the pivot
const bool bIsOrthoObjectRotation = bControlDown && InViewportClient->IsOrtho();
const bool bUsingDragTool = UsingDragTool();
const bool bUsingAxis = !bUsingDragTool && (LeftMouseButtonDown || (bAltDown && MiddleMouseButtonDown) || (SaveAxis == EAxisList::Screen && MiddleMouseButtonDown) || ((bIsOrthoObjectRotation || bControlDown) && RightMouseButtonDown));
ConditionalBeginUsingDragTool( InViewportClient );
if( bUsingDragTool || !InViewportClient->IsTracking() || !bUsingAxis )
{
InViewportClient->SetCurrentWidgetAxis( EAxisList::None );
}
FVector Wk = InViewportClient->TranslateDelta( InKey, static_cast<float>(InDelta), InNudge );
EndScreen += Wk;
if( InViewportClient->GetCurrentWidgetAxis() != EAxisList::None )
{
// Affect input delta by the camera speed
UE::Widget::EWidgetMode WidgetMode = InViewportClient->GetWidgetMode();
bool bIsRotation = (WidgetMode == UE::Widget::WM_Rotate)
|| ( ( WidgetMode == UE::Widget::WM_TranslateRotateZ ) && ( InViewportClient->GetCurrentWidgetAxis() == EAxisList::ZRotation ) )
|| ( ( WidgetMode == UE::Widget::WM_2D) && (InViewportClient->GetCurrentWidgetAxis() == EAxisList::Rotate2D ) );
if (bIsRotation)
{
Wk *= GetDefault<ULevelEditorViewportSettings>()->MouseSensitivty;
}
else if( WidgetMode == UE::Widget::WM_Scale && !GEditor->UsePercentageBasedScaling() )
{
const float ScaleSpeedMultipler = 0.01f;
Wk *= ScaleSpeedMultipler;
}
// Make rotations occur at the same speed, regardless of ortho zoom
if( InViewportClient->IsOrtho() )
{
if (bIsRotation)
{
double Scale = 1.0;
if( InViewportClient->IsOrtho() )
{
Scale = DEFAULT_ORTHOZOOM / InViewportClient->GetOrthoZoom();
}
Wk *= Scale;
}
}
//if Absolute Translation, and not just moving the camera around
else if (InViewportClient->IsUsingAbsoluteTranslation(false))
{
// Compute a view.
FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
InViewportClient->Viewport,
InViewportClient->GetScene(),
InViewportClient->EngineShowFlags )
.SetRealtimeUpdate( InViewportClient->IsRealtime() ));
FSceneView* View = InViewportClient->CalcSceneView( &ViewFamily );
//calculate mouse position
check(InViewportClient->Viewport);
FVector2D MousePosition(InViewportClient->Viewport->GetMouseX(), InViewportClient->Viewport->GetMouseY());
FVector WidgetPosition = InViewportClient->GetWidgetLocation();
FRotator TempRot;
FVector TempScale;
InViewportClient->Widget->AbsoluteTranslationConvertMouseMovementToAxisMovement(View, InViewportClient, WidgetPosition, MousePosition, Wk, TempRot, TempScale );
}
}
End += Wk;
EndSnapped = End;
if( UsingDragTool() )
{
FVector Drag = Wk;
if( DragTool->bConvertDelta )
{
FRotator Rot;
InViewportClient->ConvertMovementToDragRot( Wk, Drag, Rot );
}
if ( InViewportClient->IsPerspective() )
{
DragTool->AddDelta(Wk);
}
else
{
DragTool->AddDelta( Drag );
}
InViewportClient->SetCurrentWidgetAxis( SaveAxis );
}
else
{
switch( InViewportClient->GetWidgetMode() )
{
case UE::Widget::WM_Translate:
FSnappingUtils::SnapPointToGrid( EndSnapped, FVector(GEditor->GetGridSize(),GEditor->GetGridSize(),GEditor->GetGridSize()) );
break;
case UE::Widget::WM_Scale:
FSnappingUtils::SnapScale( EndSnapped, FVector(GEditor->GetGridSize(),GEditor->GetGridSize(),GEditor->GetGridSize()) );
break;
case UE::Widget::WM_Rotate:
{
FRotator Rotation( EndSnapped.X, EndSnapped.Y, EndSnapped.Z );
FSnappingUtils::SnapRotatorToGrid( Rotation );
EndSnapped = FVector( Rotation.Pitch, Rotation.Yaw, Rotation.Roll );
}
break;
case UE::Widget::WM_TranslateRotateZ:
case UE::Widget::WM_2D:
{
if (InViewportClient->GetCurrentWidgetAxis() == EAxisList::Rotate2D)
{
FRotator Rotation( EndSnapped.X, EndSnapped.Y, EndSnapped.Z );
FSnappingUtils::SnapRotatorToGrid( Rotation );
EndSnapped = FVector( Rotation.Pitch, Rotation.Yaw, Rotation.Roll );
}
else
{
//translation (either xy plane or z)
FSnappingUtils::SnapPointToGrid( EndSnapped, FVector(GEditor->GetGridSize(),GEditor->GetGridSize(),GEditor->GetGridSize()) );
}
}
default:
break;
}
}
}
/**
* Returns the raw mouse delta, in pixels.
*/
const FVector FMouseDeltaTracker::GetRawDelta() const
{
return RawDelta;
}
/**
* Returns the current delta.
*/
const FVector FMouseDeltaTracker::GetDelta() const
{
const FVector Delta( End - Start );
return Delta;
}
/**
* Returns the current snapped delta.
*/
const FVector FMouseDeltaTracker::GetDeltaSnapped() const
{
const FVector SnappedDelta( EndSnapped - StartSnapped );
return SnappedDelta;
}
/**
* Returns the absolute delta since dragging started.
*/
const FVector FMouseDeltaTracker::GetAbsoluteDelta() const
{
const FVector Delta( End - Start + ReductionAmount );
return Delta;
}
/**
* Returns the absolute snapped delta since dragging started.
*/
const FVector FMouseDeltaTracker::GetAbsoluteDeltaSnapped() const
{
const FVector SnappedDelta( EndSnapped - StartSnapped + ReductionAmount );
return SnappedDelta;
}
/**
* Returns the screen space delta since dragging started.
*/
const FVector FMouseDeltaTracker::GetScreenDelta() const
{
const FVector Delta( EndScreen - StartScreen );
return Delta;
}
/**
* Converts the delta movement to drag/rotation/scale based on the viewport type or widget axis
*/
void FMouseDeltaTracker::ConvertMovementDeltaToDragRot(FSceneView* InView, FEditorViewportClient* InViewportClient, FVector& InOutDragDelta, FVector& OutDrag, FRotator& OutRotation, FVector& OutScale) const
{
OutDrag = FVector::ZeroVector;
OutRotation = FRotator::ZeroRotator;
OutScale = FVector::ZeroVector;
if( InViewportClient->GetCurrentWidgetAxis() != EAxisList::None )
{
InViewportClient->Widget->ConvertMouseMovementToAxisMovement( InView, InViewportClient, bUsedDragModifier, InOutDragDelta, OutDrag, OutRotation, OutScale );
if (AxisDisplayInfo::GetAxisDisplayCoordinateSystem() == EAxisList::LeftUpForward)
{
OutDrag.Y = -OutDrag.Y;
}
}
else
{
InViewportClient->ConvertMovementToDragRot( InOutDragDelta, OutDrag, OutRotation );
}
}
/**
* Absolute Translation conversion from mouse position on the screen to widget axis movement/rotation.
*/
void FMouseDeltaTracker::AbsoluteTranslationConvertMouseToDragRot(FSceneView* InView, FEditorViewportClient* InViewportClient,FVector& OutDrag, FRotator& OutRotation, FVector& OutScale ) const
{
OutDrag = FVector::ZeroVector;
OutRotation = FRotator::ZeroRotator;
OutScale = FVector::ZeroVector;
check ( InViewportClient->GetCurrentWidgetAxis() != EAxisList::None );
//calculate mouse position
check(InViewportClient->Viewport);
FVector2D MousePosition(InViewportClient->Viewport->GetMouseX(), InViewportClient->Viewport->GetMouseY());
InViewportClient->Widget->AbsoluteTranslationConvertMouseMovementToAxisMovement(InView, InViewportClient, InViewportClient->GetWidgetLocation(), MousePosition, OutDrag, OutRotation, OutScale );
}
/**
* Subtracts the specified value from End and EndSnapped.
*/
void FMouseDeltaTracker::ReduceBy(const FVector& In)
{
End -= In;
EndSnapped -= In;
ReductionAmount += In;
}
/**
* @return true if a drag tool is being used by the tracker, false otherwise.
*/
bool FMouseDeltaTracker::UsingDragTool() const
{
return DragTool.IsValid() && DragTool->IsDragging() ;
}
/**
* Renders the drag tool. Does nothing if no drag tool exists.
*/
void FMouseDeltaTracker::Render3DDragTool(const FSceneView* View,FPrimitiveDrawInterface* PDI)
{
if ( DragTool.IsValid() )
{
DragTool->Render3D( View, PDI );
}
}
/**
* Renders the drag tool. Does nothing if no drag tool exists.
*/
void FMouseDeltaTracker::RenderDragTool(const FSceneView* View,FCanvas* Canvas)
{
if ( DragTool.IsValid() )
{
DragTool->Render( View, Canvas );
}
}
const FVector FMouseDeltaTracker::GetDragStartPos() const
{
return Start;
}
const bool FMouseDeltaTracker::GetUsedDragModifier() const
{
return bUsedDragModifier;
}
void FMouseDeltaTracker::ResetUsedDragModifier()
{
bUsedDragModifier = false;
}
#undef LOCTEXT_NAMESPACE