2019-12-27 09:26:59 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-10-01 20:41:42 -04:00
# include "TransformMeshesTool.h"
# include "InteractiveToolManager.h"
# include "InteractiveGizmoManager.h"
2021-01-14 19:07:52 -04:00
# include "Mechanics/DragAlignmentMechanic.h"
2019-10-01 20:41:42 -04:00
# include "ToolBuilderUtil.h"
# include "ToolSetupUtil.h"
2021-06-13 00:36:02 -04:00
# include "DynamicMesh/DynamicMesh3.h"
2019-10-01 20:41:42 -04:00
# include "BaseBehaviors/ClickDragBehavior.h"
2020-10-22 19:19:16 -04:00
# include "ToolSceneQueriesUtil.h"
2021-06-15 02:46:37 -04:00
# include "ModelingToolTargetUtil.h"
2019-10-01 20:41:42 -04:00
# include "BaseGizmos/GizmoComponents.h"
2021-05-20 16:39:39 -04:00
# include "BaseGizmos/TransformGizmoUtil.h"
2019-10-01 20:41:42 -04:00
# include "Components/PrimitiveComponent.h"
2021-06-15 02:46:37 -04:00
# include "Components/InstancedStaticMeshComponent.h"
2019-10-01 20:41:42 -04:00
# include "Engine/World.h"
2021-03-11 11:40:03 -04:00
# include "TargetInterfaces/PrimitiveComponentBackedTarget.h"
# include "ToolTargetManager.h"
2021-03-09 19:33:56 -04:00
using namespace UE : : Geometry ;
2019-10-01 20:41:42 -04:00
# define LOCTEXT_NAMESPACE "UTransformMeshesTool"
2021-03-09 19:33:56 -04:00
2019-10-01 20:41:42 -04:00
/*
* ToolBuilder
*/
2021-03-11 11:40:03 -04:00
const FToolTargetTypeRequirements & UTransformMeshesToolBuilder : : GetTargetRequirements ( ) const
{
static FToolTargetTypeRequirements TypeRequirements (
UPrimitiveComponentBackedTarget : : StaticClass ( )
) ;
return TypeRequirements ;
}
2021-11-23 09:42:40 -05:00
UMultiSelectionMeshEditingTool * UTransformMeshesToolBuilder : : CreateNewTool ( const FToolBuilderState & SceneState ) const
2019-10-01 20:41:42 -04:00
{
2021-11-23 09:42:40 -05:00
return NewObject < UTransformMeshesTool > ( SceneState . ToolManager ) ;
2019-10-01 20:41:42 -04:00
}
/*
* Tool
*/
UTransformMeshesTool : : UTransformMeshesTool ( )
{
}
void UTransformMeshesTool : : Setup ( )
{
UInteractiveTool : : Setup ( ) ;
2021-01-14 19:07:52 -04:00
// Must be done before creating gizmos, so that we can bind the mechanic to them.
DragAlignmentMechanic = NewObject < UDragAlignmentMechanic > ( this ) ;
DragAlignmentMechanic - > Setup ( this ) ;
2019-10-01 20:41:42 -04:00
UClickDragInputBehavior * ClickDragBehavior = NewObject < UClickDragInputBehavior > ( this ) ;
ClickDragBehavior - > Initialize ( this ) ;
AddInputBehavior ( ClickDragBehavior ) ;
TransformProps = NewObject < UTransformMeshesToolProperties > ( ) ;
AddToolPropertySource ( TransformProps ) ;
2021-06-15 02:46:37 -04:00
TransformProps - > RestoreProperties ( this ) ;
TransformProps - > WatchProperty ( TransformProps - > TransformMode , [ this ] ( ETransformMeshesTransformMode NewMode ) { UpdateTransformMode ( NewMode ) ; } ) ;
TransformProps - > WatchProperty ( TransformProps - > bApplyToInstances , [ this ] ( bool bNewValue ) { UpdateTransformMode ( TransformProps - > TransformMode ) ; } ) ;
TransformProps - > WatchProperty ( TransformProps - > bSetPivotMode , [ this ] ( bool bNewValue ) { UpdateSetPivotModes ( bNewValue ) ; } ) ;
// determine if we have any ISMCs
TransformProps - > bHaveInstances = false ;
for ( int32 ComponentIdx = 0 ; ComponentIdx < Targets . Num ( ) ; ComponentIdx + + )
{
if ( Cast < UInstancedStaticMeshComponent > ( UE : : ToolTarget : : GetTargetComponent ( Targets [ ComponentIdx ] ) ) ! = nullptr )
{
TransformProps - > bHaveInstances = true ;
}
}
2019-10-01 20:41:42 -04:00
UpdateTransformMode ( TransformProps - > TransformMode ) ;
2021-02-08 17:02:09 -04:00
SetToolDisplayName ( LOCTEXT ( " ToolName " , " Transform " ) ) ;
2019-10-01 20:41:42 -04:00
GetToolManager ( ) - > DisplayMessage (
2021-06-15 02:46:37 -04:00
LOCTEXT ( " OnStartTransformMeshesTool " , " Transform the selected objects. Middle-mouse-drag on gizmo to reposition it. Hold Ctrl while dragging to snap/align. [A] cycles through Transform modes. [S] toggles Set Pivot Mode. [D] Toggles Snap Drag Mode. [W] and [E] cycle through Snap Drag Source and Rotation types. " ) ,
2019-10-01 20:41:42 -04:00
EToolMessageLevel : : UserNotification ) ;
}
2022-01-28 18:40:54 -05:00
void UTransformMeshesTool : : OnShutdown ( EToolShutdownType ShutdownType )
2019-10-01 20:41:42 -04:00
{
2021-06-15 02:46:37 -04:00
TransformProps - > SaveProperties ( this ) ;
2021-02-25 20:04:21 -04:00
DragAlignmentMechanic - > Shutdown ( ) ;
2021-11-23 09:42:40 -05:00
GetToolManager ( ) - > GetPairedGizmoManager ( ) - > DestroyAllGizmosByOwner ( this ) ;
2019-10-01 20:41:42 -04:00
}
void UTransformMeshesTool : : Render ( IToolsContextRenderAPI * RenderAPI )
{
2021-01-14 19:07:52 -04:00
DragAlignmentMechanic - > Render ( RenderAPI ) ;
2019-10-01 20:41:42 -04:00
}
void UTransformMeshesTool : : UpdateSetPivotModes ( bool bEnableSetPivot )
{
for ( FTransformMeshesTarget & Target : ActiveGizmos )
{
Target . TransformProxy - > bSetPivotMode = bEnableSetPivot ;
}
}
void UTransformMeshesTool : : RegisterActions ( FInteractiveToolActionSet & ActionSet )
{
2022-06-15 16:00:47 -04:00
// Note: we should really disallow hotkeys while dragging, but we are discouraged from adding
// members to an object in a hotfix, so we can't add a bCurrentlySnapDragging (and we can't use
// ActiveSnapDragIndex directly because it can be set even without getting capture). For now, we
// just make sure to call CheckAndUpdateWatched() after any property changes to avoid some invalid
// states that can happen between a drag call and the next tick.
2019-10-01 20:41:42 -04:00
ActionSet . RegisterAction ( this , ( int32 ) EStandardToolActions : : BaseClientDefinedActionID + 1 ,
TEXT ( " ToggleSetPivot " ) ,
LOCTEXT ( " TransformToggleSetPivot " , " Toggle Set Pivot " ) ,
LOCTEXT ( " TransformToggleSetPivotTooltip " , " Toggle Set Pivot on and off " ) ,
EModifierKey : : None , EKeys : : S ,
2022-01-14 14:24:37 -05:00
[ this ] ( ) {
TransformProps - > bSetPivotMode = ! TransformProps - > bSetPivotMode ;
2022-06-15 16:00:47 -04:00
TransformProps - > CheckAndUpdateWatched ( ) ;
2022-01-14 14:24:37 -05:00
NotifyOfPropertyChangeByTool ( TransformProps ) ;
} ) ;
2019-10-01 20:41:42 -04:00
ActionSet . RegisterAction ( this , ( int32 ) EStandardToolActions : : BaseClientDefinedActionID + 2 ,
TEXT ( " ToggleSnapDrag " ) ,
LOCTEXT ( " TransformToggleSnapDrag " , " Toggle SnapDrag " ) ,
LOCTEXT ( " TransformToggleSnapDragTooltip " , " Toggle SnapDrag on and off " ) ,
EModifierKey : : None , EKeys : : D ,
2022-01-14 14:24:37 -05:00
[ this ] ( ) {
TransformProps - > bEnableSnapDragging = ! TransformProps - > bEnableSnapDragging ;
2022-06-15 16:00:47 -04:00
TransformProps - > CheckAndUpdateWatched ( ) ;
2022-01-14 14:24:37 -05:00
NotifyOfPropertyChangeByTool ( TransformProps ) ;
} ) ;
2019-10-01 20:41:42 -04:00
ActionSet . RegisterAction ( this , ( int32 ) EStandardToolActions : : BaseClientDefinedActionID + 3 ,
TEXT ( " CycleTransformMode " ) ,
LOCTEXT ( " TransformCycleTransformMode " , " Next Transform Mode " ) ,
LOCTEXT ( " TransformCycleTransformModeTooltip " , " Cycle through available Transform Modes " ) ,
EModifierKey : : None , EKeys : : A ,
2022-01-14 14:24:37 -05:00
[ this ] ( ) {
TransformProps - > TransformMode = ( ETransformMeshesTransformMode ) ( ( ( uint8 ) TransformProps - > TransformMode + 1 ) % ( uint8 ) ETransformMeshesTransformMode : : LastValue ) ;
2022-06-15 16:00:47 -04:00
TransformProps - > CheckAndUpdateWatched ( ) ;
2022-01-14 14:24:37 -05:00
NotifyOfPropertyChangeByTool ( TransformProps ) ;
} ) ;
2019-10-01 20:41:42 -04:00
ActionSet . RegisterAction ( this , ( int32 ) EStandardToolActions : : BaseClientDefinedActionID + 4 ,
TEXT ( " CycleSourceMode " ) ,
LOCTEXT ( " TransformCycleSourceMode " , " Next SnapDrag Source Mode " ) ,
LOCTEXT ( " TransformCycleSourceModeTooltip " , " Cycle through available SnapDrag Source Modes " ) ,
EModifierKey : : None , EKeys : : W ,
2022-01-14 14:24:37 -05:00
[ this ] ( ) {
TransformProps - > SnapDragSource = ( ETransformMeshesSnapDragSource ) ( ( ( uint8 ) TransformProps - > SnapDragSource + 1 ) % ( uint8 ) ETransformMeshesSnapDragSource : : LastValue ) ;
2022-06-15 16:00:47 -04:00
TransformProps - > CheckAndUpdateWatched ( ) ;
2022-01-14 14:24:37 -05:00
NotifyOfPropertyChangeByTool ( TransformProps ) ;
} ) ;
2019-10-01 20:41:42 -04:00
ActionSet . RegisterAction ( this , ( int32 ) EStandardToolActions : : BaseClientDefinedActionID + 5 ,
TEXT ( " CycleRotationMode " ) ,
LOCTEXT ( " TransformCycleRotationMode " , " Next SnapDrag Rotation Mode " ) ,
LOCTEXT ( " TransformCycleRotationModeTooltip " , " Cycle through available SnapDrag Rotation Modes " ) ,
EModifierKey : : None , EKeys : : E ,
2022-01-14 14:24:37 -05:00
[ this ] ( ) {
TransformProps - > RotationMode = ( ETransformMeshesSnapDragRotationMode ) ( ( ( uint8 ) TransformProps - > RotationMode + 1 ) % ( uint8 ) ETransformMeshesSnapDragRotationMode : : LastValue ) ;
2022-06-15 16:00:47 -04:00
TransformProps - > CheckAndUpdateWatched ( ) ;
2022-01-14 14:24:37 -05:00
NotifyOfPropertyChangeByTool ( TransformProps ) ;
} ) ;
2019-10-01 20:41:42 -04:00
}
void UTransformMeshesTool : : UpdateTransformMode ( ETransformMeshesTransformMode NewMode )
{
ResetActiveGizmos ( ) ;
switch ( NewMode )
{
default :
case ETransformMeshesTransformMode : : SharedGizmo :
SetActiveGizmos_Single ( false ) ;
break ;
case ETransformMeshesTransformMode : : SharedGizmoLocal :
SetActiveGizmos_Single ( true ) ;
break ;
case ETransformMeshesTransformMode : : PerObjectGizmo :
SetActiveGizmos_PerObject ( ) ;
break ;
}
CurTransformMode = NewMode ;
}
2021-06-15 02:46:37 -04:00
namespace UE {
namespace Local {
static void AddInstancedComponentInstance ( UInstancedStaticMeshComponent * ISMC , int32 Index , UTransformProxy * TransformProxy , bool bModifyOnTransform )
{
TransformProxy - > AddComponentCustom ( ISMC ,
[ ISMC , Index ] ( ) {
FTransform Tmp ;
ISMC - > GetInstanceTransform ( Index , Tmp , true ) ;
return Tmp ;
} ,
[ ISMC , Index ] ( FTransform NewTransform ) {
ISMC - > UpdateInstanceTransform ( Index , NewTransform , true , true , true ) ;
} ,
Index , bModifyOnTransform
) ;
}
}
}
2019-10-01 20:41:42 -04:00
void UTransformMeshesTool : : SetActiveGizmos_Single ( bool bLocalRotations )
{
check ( ActiveGizmos . Num ( ) = = 0 ) ;
FTransformMeshesTarget Transformable ;
Transformable . TransformProxy = NewObject < UTransformProxy > ( this ) ;
Transformable . TransformProxy - > bRotatePerObject = bLocalRotations ;
2021-01-14 19:07:52 -04:00
TArray < const UPrimitiveComponent * > ComponentsToIgnoreInAlignment ;
2021-03-11 11:40:03 -04:00
for ( int32 ComponentIdx = 0 ; ComponentIdx < Targets . Num ( ) ; ComponentIdx + + )
2019-10-01 20:41:42 -04:00
{
2021-06-15 02:46:37 -04:00
UPrimitiveComponent * Component = UE : : ToolTarget : : GetTargetComponent ( Targets [ ComponentIdx ] ) ;
UInstancedStaticMeshComponent * InstancedComponent = Cast < UInstancedStaticMeshComponent > ( Component ) ;
if ( InstancedComponent ! = nullptr & & TransformProps - > bApplyToInstances )
{
int32 NumInstances = InstancedComponent - > GetInstanceCount ( ) ;
for ( int32 k = 0 ; k < NumInstances ; + + k )
{
if ( InstancedComponent - > IsValidInstance ( k ) = = false ) return ;
UE : : Local : : AddInstancedComponentInstance ( InstancedComponent , k , Transformable . TransformProxy , true ) ;
}
}
else
{
Transformable . TransformProxy - > AddComponent ( Component ) ;
}
ComponentsToIgnoreInAlignment . Add ( Component ) ;
2019-10-01 20:41:42 -04:00
}
2020-01-27 20:11:15 -05:00
// leave out nonuniform scale if we have multiple objects in non-local mode
2021-03-11 11:40:03 -04:00
bool bCanNonUniformScale = Targets . Num ( ) = = 1 | | bLocalRotations ;
2020-01-27 20:11:15 -05:00
ETransformGizmoSubElements GizmoElements = ( bCanNonUniformScale ) ?
ETransformGizmoSubElements : : FullTranslateRotateScale : ETransformGizmoSubElements : : TranslateRotateUniformScale ;
2021-05-20 16:39:39 -04:00
Transformable . TransformGizmo = UE : : TransformGizmoUtil : : CreateCustomRepositionableTransformGizmo ( GetToolManager ( ) , GizmoElements , this ) ;
2019-10-01 20:41:42 -04:00
Transformable . TransformGizmo - > SetActiveTarget ( Transformable . TransformProxy ) ;
2021-01-14 19:07:52 -04:00
DragAlignmentMechanic - > AddToGizmo ( Transformable . TransformGizmo , & ComponentsToIgnoreInAlignment ) ;
2019-10-01 20:41:42 -04:00
ActiveGizmos . Add ( Transformable ) ;
}
void UTransformMeshesTool : : SetActiveGizmos_PerObject ( )
{
check ( ActiveGizmos . Num ( ) = = 0 ) ;
2021-01-14 19:07:52 -04:00
TArray < const UPrimitiveComponent * > ComponentsToIgnoreInAlignment ;
2021-03-11 11:40:03 -04:00
for ( int32 ComponentIdx = 0 ; ComponentIdx < Targets . Num ( ) ; ComponentIdx + + )
2019-10-01 20:41:42 -04:00
{
2021-06-15 02:46:37 -04:00
UPrimitiveComponent * Component = UE : : ToolTarget : : GetTargetComponent ( Targets [ ComponentIdx ] ) ;
UInstancedStaticMeshComponent * InstancedComponent = Cast < UInstancedStaticMeshComponent > ( Component ) ;
if ( InstancedComponent ! = nullptr & & TransformProps - > bApplyToInstances )
{
int32 NumInstances = InstancedComponent - > GetInstanceCount ( ) ;
for ( int32 k = 0 ; k < NumInstances ; + + k )
{
if ( InstancedComponent - > IsValidInstance ( k ) = = false ) return ;
2021-03-11 11:40:03 -04:00
2021-01-14 19:07:52 -04:00
2021-06-15 02:46:37 -04:00
FTransformMeshesTarget Transformable ;
Transformable . TransformProxy = NewObject < UTransformProxy > ( this ) ;
UE : : Local : : AddInstancedComponentInstance ( InstancedComponent , k , Transformable . TransformProxy , true ) ;
2021-01-14 19:07:52 -04:00
2021-06-15 02:46:37 -04:00
ETransformGizmoSubElements GizmoElements = ETransformGizmoSubElements : : FullTranslateRotateScale ;
Transformable . TransformGizmo = UE : : TransformGizmoUtil : : CreateCustomRepositionableTransformGizmo ( GetToolManager ( ) , GizmoElements , this ) ;
Transformable . TransformGizmo - > SetActiveTarget ( Transformable . TransformProxy ) ;
2021-01-14 19:07:52 -04:00
2021-06-15 02:46:37 -04:00
ComponentsToIgnoreInAlignment . Reset ( ) ;
ComponentsToIgnoreInAlignment . Add ( Component ) ;
DragAlignmentMechanic - > AddToGizmo ( Transformable . TransformGizmo , & ComponentsToIgnoreInAlignment ) ;
2021-01-14 19:07:52 -04:00
2021-06-15 02:46:37 -04:00
ActiveGizmos . Add ( Transformable ) ;
}
}
else
{
FTransformMeshesTarget Transformable ;
Transformable . TransformProxy = NewObject < UTransformProxy > ( this ) ;
Transformable . TransformProxy - > AddComponent ( Component ) ;
ETransformGizmoSubElements GizmoElements = ETransformGizmoSubElements : : FullTranslateRotateScale ;
Transformable . TransformGizmo = UE : : TransformGizmoUtil : : CreateCustomRepositionableTransformGizmo ( GetToolManager ( ) , GizmoElements , this ) ;
Transformable . TransformGizmo - > SetActiveTarget ( Transformable . TransformProxy ) ;
ComponentsToIgnoreInAlignment . Reset ( ) ;
ComponentsToIgnoreInAlignment . Add ( Component ) ;
DragAlignmentMechanic - > AddToGizmo ( Transformable . TransformGizmo , & ComponentsToIgnoreInAlignment ) ;
ActiveGizmos . Add ( Transformable ) ;
}
2019-10-01 20:41:42 -04:00
}
}
void UTransformMeshesTool : : ResetActiveGizmos ( )
{
2021-11-23 09:42:40 -05:00
GetToolManager ( ) - > GetPairedGizmoManager ( ) - > DestroyAllGizmosByOwner ( this ) ;
2019-10-01 20:41:42 -04:00
ActiveGizmos . Reset ( ) ;
}
// does not make sense that CanBeginClickDragSequence() returns a RayHit? Needs to be an out-argument...
FInputRayHit UTransformMeshesTool : : CanBeginClickDragSequence ( const FInputDeviceRay & PressPos )
{
if ( TransformProps - > bEnableSnapDragging = = false | | ActiveGizmos . Num ( ) = = 0 )
{
return FInputRayHit ( ) ;
}
ActiveSnapDragIndex = - 1 ;
float MinHitDistance = TNumericLimits < float > : : Max ( ) ;
FVector HitNormal ;
2021-03-11 11:40:03 -04:00
for ( int k = 0 ; k < Targets . Num ( ) ; + + k )
2019-10-01 20:41:42 -04:00
{
2021-11-23 09:42:40 -05:00
const IPrimitiveComponentBackedTarget * Target = Cast < IPrimitiveComponentBackedTarget > ( Targets [ k ] ) ;
2019-10-01 20:41:42 -04:00
FHitResult WorldHit ;
2021-03-11 11:40:03 -04:00
if ( Target - > HitTestComponent ( PressPos . WorldRay , WorldHit ) )
2019-10-01 20:41:42 -04:00
{
MinHitDistance = FMath : : Min ( MinHitDistance , WorldHit . Distance ) ;
HitNormal = WorldHit . Normal ;
ActiveSnapDragIndex = k ;
}
}
return ( MinHitDistance < TNumericLimits < float > : : Max ( ) ) ? FInputRayHit ( MinHitDistance , HitNormal ) : FInputRayHit ( ) ;
}
void UTransformMeshesTool : : OnClickPress ( const FInputDeviceRay & PressPos )
{
FInputRayHit HitPos = CanBeginClickDragSequence ( PressPos ) ;
check ( HitPos . bHit ) ;
GetToolManager ( ) - > BeginUndoTransaction ( LOCTEXT ( " TransformToolTransformTxnName " , " SnapDrag " ) ) ;
FTransformMeshesTarget & ActiveTarget =
( TransformProps - > TransformMode = = ETransformMeshesTransformMode : : PerObjectGizmo ) ?
ActiveGizmos [ ActiveSnapDragIndex ] : ActiveGizmos [ 0 ] ;
USceneComponent * GizmoComponent = ActiveTarget . TransformGizmo - > GetGizmoActor ( ) - > GetRootComponent ( ) ;
StartDragTransform = GizmoComponent - > GetComponentToWorld ( ) ;
if ( TransformProps - > SnapDragSource = = ETransformMeshesSnapDragSource : : ClickPoint )
{
2021-03-30 21:25:22 -04:00
StartDragFrameWorld = FFrame3d ( ( FVector3d ) PressPos . WorldRay . PointAt ( HitPos . HitDepth ) , ( FVector3d ) HitPos . HitNormal ) ;
2019-10-01 20:41:42 -04:00
}
else
{
StartDragFrameWorld = FFrame3d ( StartDragTransform ) ;
}
}
void UTransformMeshesTool : : OnClickDrag ( const FInputDeviceRay & DragPos )
{
2021-06-15 02:46:37 -04:00
bool bApplyToPivot = TransformProps - > bSetPivotMode ;
2019-10-01 20:41:42 -04:00
2021-01-14 19:07:52 -04:00
TArray < const UPrimitiveComponent * > IgnoreComponents ;
2019-10-01 20:41:42 -04:00
if ( bApplyToPivot = = false )
{
int IgnoreIndex = ( TransformProps - > TransformMode = = ETransformMeshesTransformMode : : PerObjectGizmo ) ?
ActiveSnapDragIndex : - 1 ;
2021-03-11 11:40:03 -04:00
for ( int k = 0 ; k < Targets . Num ( ) ; + + k )
2019-10-01 20:41:42 -04:00
{
if ( IgnoreIndex = = - 1 | | k = = IgnoreIndex )
{
2021-06-15 02:46:37 -04:00
IgnoreComponents . Add ( UE : : ToolTarget : : GetTargetComponent ( Targets [ k ] ) ) ;
2019-10-01 20:41:42 -04:00
}
}
}
bool bRotate = ( TransformProps - > RotationMode ! = ETransformMeshesSnapDragRotationMode : : Ignore ) ;
float NormalSign = ( TransformProps - > RotationMode = = ETransformMeshesSnapDragRotationMode : : AlignFlipped ) ? - 1.0f : 1.0f ;
FHitResult Result ;
2021-12-09 14:46:09 -05:00
bool bWorldHit = ToolSceneQueriesUtil : : FindNearestVisibleObjectHit ( this , Result , DragPos . WorldRay , & IgnoreComponents ) ;
2019-10-01 20:41:42 -04:00
if ( bWorldHit = = false )
{
return ;
}
if ( bApplyToPivot )
{
FVector HitPos = Result . ImpactPoint ;
FVector TargetNormal = ( - NormalSign ) * Result . Normal ;
FQuaterniond AlignRotation = ( bRotate ) ?
2021-03-30 21:25:22 -04:00
FQuaterniond ( FVector3d : : UnitZ ( ) , ( FVector3d ) TargetNormal ) : FQuaterniond : : Identity ( ) ;
2019-10-01 20:41:42 -04:00
FTransform NewTransform = StartDragTransform ;
NewTransform . SetRotation ( ( FQuat ) AlignRotation ) ;
NewTransform . SetTranslation ( HitPos ) ;
FTransformMeshesTarget & ActiveTarget =
( TransformProps - > TransformMode = = ETransformMeshesTransformMode : : PerObjectGizmo ) ?
ActiveGizmos [ ActiveSnapDragIndex ] : ActiveGizmos [ 0 ] ;
2021-02-25 20:04:21 -04:00
ActiveTarget . TransformGizmo - > SetNewGizmoTransform ( NewTransform ) ;
2019-10-01 20:41:42 -04:00
}
else
{
FVector HitPos = Result . ImpactPoint ;
FVector TargetNormal = NormalSign * Result . Normal ;
FFrame3d FromFrameWorld = StartDragFrameWorld ;
2021-03-30 21:25:22 -04:00
FFrame3d ToFrameWorld ( ( FVector3d ) HitPos , ( FVector3d ) TargetNormal ) ;
2019-10-01 20:41:42 -04:00
FFrame3d ObjectFrameWorld ( StartDragTransform ) ;
FVector3d CenterShift = FromFrameWorld . Origin - ObjectFrameWorld . Origin ;
FQuaterniond AlignRotation ( FromFrameWorld . Z ( ) , ToFrameWorld . Z ( ) ) ;
if ( bRotate = = false )
{
AlignRotation = FQuaterniond : : Identity ( ) ;
}
FVector3d AlignTranslate = ToFrameWorld . Origin - FromFrameWorld . Origin ;
FTransform NewTransform = StartDragTransform ;
2019-12-19 18:07:47 -05:00
NewTransform . Accumulate ( FTransform ( ( FVector ) CenterShift ) ) ;
NewTransform . Accumulate ( FTransform ( ( FQuat ) AlignRotation ) ) ;
NewTransform . Accumulate ( FTransform ( ( FVector ) AlignTranslate ) ) ;
2019-10-01 20:41:42 -04:00
CenterShift = AlignRotation * CenterShift ;
2019-12-19 18:07:47 -05:00
NewTransform . Accumulate ( FTransform ( ( FVector ) - CenterShift ) ) ;
2019-10-01 20:41:42 -04:00
FTransformMeshesTarget & ActiveTarget =
( TransformProps - > TransformMode = = ETransformMeshesTransformMode : : PerObjectGizmo ) ?
ActiveGizmos [ ActiveSnapDragIndex ] : ActiveGizmos [ 0 ] ;
2021-02-25 20:04:21 -04:00
ActiveTarget . TransformGizmo - > SetNewGizmoTransform ( NewTransform ) ;
2019-10-01 20:41:42 -04:00
}
}
void UTransformMeshesTool : : OnClickRelease ( const FInputDeviceRay & ReleasePos )
{
OnTerminateDragSequence ( ) ;
}
void UTransformMeshesTool : : OnTerminateDragSequence ( )
{
FTransformMeshesTarget & ActiveTarget =
( TransformProps - > TransformMode = = ETransformMeshesTransformMode : : PerObjectGizmo ) ?
ActiveGizmos [ ActiveSnapDragIndex ] : ActiveGizmos [ 0 ] ;
USceneComponent * GizmoComponent = ActiveTarget . TransformGizmo - > GetGizmoActor ( ) - > GetRootComponent ( ) ;
FTransform EndDragtransform = GizmoComponent - > GetComponentToWorld ( ) ;
TUniquePtr < FComponentWorldTransformChange > Change = MakeUnique < FComponentWorldTransformChange > ( StartDragTransform , EndDragtransform ) ;
GetToolManager ( ) - > EmitObjectChange ( GizmoComponent , MoveTemp ( Change ) ,
LOCTEXT ( " TransformToolTransformTxnName " , " SnapDrag " ) ) ;
GetToolManager ( ) - > EndUndoTransaction ( ) ;
ActiveSnapDragIndex = - 1 ;
}
# undef LOCTEXT_NAMESPACE