2019-12-27 09:26:59 -05:00
// Copyright Epic Games, Inc. All Rights Reserved.
2019-10-01 20:41:42 -04:00
# include "PolygonOnMeshTool.h"
# include "InteractiveToolManager.h"
# include "ToolBuilderUtil.h"
# include "ToolSetupUtil.h"
2021-06-13 00:36:02 -04:00
# include "DynamicMesh/DynamicMesh3.h"
2020-01-27 20:11:15 -05:00
# include "ToolSceneQueriesUtil.h"
# include "BaseBehaviors/SingleClickBehavior.h"
# include "BaseBehaviors/MouseHoverBehavior.h"
# include "ToolDataVisualizer.h"
# include "Util/ColorConstants.h"
2020-04-21 14:41:25 -04:00
# include "Drawing/LineSetComponent.h"
2019-10-01 20:41:42 -04:00
# include "MeshDescriptionToDynamicMesh.h"
# include "DynamicMeshToMeshDescription.h"
2021-03-24 11:11:02 -04:00
# include "TargetInterfaces/MaterialProvider.h"
# include "TargetInterfaces/PrimitiveComponentBackedTarget.h"
2021-12-06 12:42:19 -05:00
# include "ModelingToolTargetUtil.h"
2021-03-24 11:11:02 -04:00
2021-03-09 19:33:56 -04:00
using namespace UE : : Geometry ;
2019-10-01 20:41:42 -04:00
# define LOCTEXT_NAMESPACE "UPolygonOnMeshTool"
/*
* ToolBuilder
*/
2021-03-24 11:11:02 -04:00
USingleSelectionMeshEditingTool * UPolygonOnMeshToolBuilder : : CreateNewTool ( const FToolBuilderState & SceneState ) const
2019-10-01 20:41:42 -04:00
{
2021-03-24 11:11:02 -04:00
return NewObject < UPolygonOnMeshTool > ( SceneState . ToolManager ) ;
2019-10-01 20:41:42 -04:00
}
/*
* Tool
*/
2020-01-27 20:11:15 -05:00
void UPolygonOnMeshToolActionPropertySet : : PostAction ( EPolygonOnMeshToolActions Action )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
if ( ParentTool . IsValid ( ) )
{
ParentTool - > RequestAction ( Action ) ;
}
2019-10-01 20:41:42 -04:00
}
2020-01-27 20:11:15 -05:00
2019-10-01 20:41:42 -04:00
UPolygonOnMeshTool : : UPolygonOnMeshTool ( )
{
2021-02-08 17:02:09 -04:00
SetToolDisplayName ( LOCTEXT ( " PolygonOnMeshToolName " , " PolyCut " ) ) ;
2019-10-01 20:41:42 -04:00
}
void UPolygonOnMeshTool : : SetWorld ( UWorld * World )
{
this - > TargetWorld = World ;
}
void UPolygonOnMeshTool : : Setup ( )
{
UInteractiveTool : : Setup ( ) ;
2020-01-27 20:11:15 -05:00
// register click and hover behaviors
USingleClickInputBehavior * ClickBehavior = NewObject < USingleClickInputBehavior > ( this ) ;
ClickBehavior - > Initialize ( this ) ;
AddInputBehavior ( ClickBehavior ) ;
UMouseHoverBehavior * HoverBehavior = NewObject < UMouseHoverBehavior > ( this ) ;
HoverBehavior - > Initialize ( this ) ;
AddInputBehavior ( HoverBehavior ) ;
2021-03-24 11:11:02 -04:00
IPrimitiveComponentBackedTarget * TargetComponent = Cast < IPrimitiveComponentBackedTarget > ( Target ) ;
2022-02-24 15:01:41 -05:00
WorldTransform = ( FTransform3d ) TargetComponent - > GetWorldTransform ( ) ;
2020-01-27 20:11:15 -05:00
2019-10-01 20:41:42 -04:00
// hide input StaticMeshComponent
2021-03-24 11:11:02 -04:00
TargetComponent - > SetOwnerVisibility ( false ) ;
2019-10-01 20:41:42 -04:00
2020-01-27 20:11:15 -05:00
BasicProperties = NewObject < UPolygonOnMeshToolProperties > ( this ) ;
2021-07-20 14:26:03 -04:00
BasicProperties - > RestoreProperties ( this ) ;
2019-10-01 20:41:42 -04:00
AddToolPropertySource ( BasicProperties ) ;
2020-01-27 20:11:15 -05:00
ActionProperties = NewObject < UPolygonOnMeshToolActionPropertySet > ( this ) ;
ActionProperties - > Initialize ( this ) ;
AddToolPropertySource ( ActionProperties ) ;
2019-10-01 20:41:42 -04:00
// initialize the PreviewMesh+BackgroundCompute object
2020-04-21 14:41:25 -04:00
SetupPreview ( ) ;
DrawnLineSet = NewObject < ULineSetComponent > ( Preview - > PreviewMesh - > GetRootComponent ( ) ) ;
DrawnLineSet - > SetupAttachment ( Preview - > PreviewMesh - > GetRootComponent ( ) ) ;
DrawnLineSet - > SetLineMaterial ( ToolSetupUtil : : GetDefaultLineComponentMaterial ( GetToolManager ( ) ) ) ;
DrawnLineSet - > RegisterComponent ( ) ;
Preview - > OnOpCompleted . AddLambda (
[ this ] ( const FDynamicMeshOperator * Op )
{
const FEmbedPolygonsOp * PolygonsOp = ( const FEmbedPolygonsOp * ) ( Op ) ;
2020-12-07 15:18:20 -04:00
EdgesOnFailure = PolygonsOp - > EdgesOnFailure ;
2020-04-21 14:41:25 -04:00
EmbeddedEdges = PolygonsOp - > EmbeddedEdges ;
2020-12-07 15:18:20 -04:00
bOperationSucceeded = PolygonsOp - > bOperationSucceeded ;
2020-04-21 14:41:25 -04:00
}
) ;
Preview - > OnMeshUpdated . AddLambda (
2021-02-05 16:33:02 -04:00
[ this ] ( const UMeshOpPreviewWithBackgroundCompute * UpdatedPreview )
2020-04-21 14:41:25 -04:00
{
GetToolManager ( ) - > PostInvalidation ( ) ;
UpdateVisualization ( ) ;
2021-02-05 16:33:02 -04:00
UpdateAcceptWarnings ( UpdatedPreview - > HaveEmptyResult ( ) ? EAcceptWarning : : EmptyForbidden : EAcceptWarning : : NoWarning ) ;
2020-04-21 14:41:25 -04:00
}
) ;
2019-10-01 20:41:42 -04:00
2020-01-27 20:11:15 -05:00
DrawPlaneWorld = FFrame3d ( WorldTransform . GetTranslation ( ) ) ;
2019-10-01 20:41:42 -04:00
2020-01-27 20:11:15 -05:00
PlaneMechanic = NewObject < UConstructionPlaneMechanic > ( this ) ;
PlaneMechanic - > Setup ( this ) ;
PlaneMechanic - > Initialize ( TargetWorld , DrawPlaneWorld ) ;
//PlaneMechanic->UpdateClickPriority(ClickBehavior->GetPriority().MakeHigher());
PlaneMechanic - > OnPlaneChanged . AddLambda ( [ this ] ( ) {
DrawPlaneWorld = PlaneMechanic - > Plane ;
UpdateDrawPlane ( ) ;
} ) ;
2021-03-24 11:11:02 -04:00
PlaneMechanic - > SetPlaneCtrlClickBehaviorTarget - > InvisibleComponentsToHitTest . Add ( TargetComponent - > GetOwnerComponent ( ) ) ;
2019-10-01 20:41:42 -04:00
// Convert input mesh description to dynamic mesh
2021-02-17 11:50:23 -04:00
OriginalDynamicMesh = MakeShared < FDynamicMesh3 , ESPMode : : ThreadSafe > ( ) ;
2019-10-01 20:41:42 -04:00
FMeshDescriptionToDynamicMesh Converter ;
2021-12-06 12:42:19 -05:00
Converter . Convert ( UE : : ToolTarget : : GetMeshDescription ( Target ) , * OriginalDynamicMesh ) ;
2019-10-01 20:41:42 -04:00
// TODO: consider adding an AABB tree construction here? tradeoff vs doing a raycast against full every time a param change happens ...
2020-01-27 20:11:15 -05:00
LastDrawnPolygon = FPolygon2d ( ) ;
UpdatePolygonType ( ) ;
UpdateDrawPlane ( ) ;
2020-09-24 00:43:27 -04:00
GetToolManager ( ) - > DisplayMessage (
2020-10-22 19:19:16 -04:00
LOCTEXT ( " PolygonOnMeshToolDescription " , " Cut the Mesh with a swept Polygon, creating a Hole or new Polygroup. Use the Draw Polygon button to draw a custom polygon on the work plane. Ctrl-click to reposition the work plane. " ) ,
2020-09-24 00:43:27 -04:00
EToolMessageLevel : : UserNotification ) ;
2020-01-27 20:11:15 -05:00
}
2020-04-21 14:41:25 -04:00
void UPolygonOnMeshTool : : UpdateVisualization ( )
{
FColor PartialPathEdgeColor ( 240 , 15 , 15 ) ;
2020-12-07 15:18:20 -04:00
float PartialPathEdgeThickness = 2.0f ;
float PartialPathEdgeDepthBias = 3.0f ;
FColor EmbedEdgeColor ( 100 , 240 , 100 ) ;
float EmbedEdgeThickness = 1.0f ;
float EmbedEdgeDepthBias = 1.0f ;
2020-04-21 14:41:25 -04:00
const FDynamicMesh3 * TargetMesh = Preview - > PreviewMesh - > GetPreviewDynamicMesh ( ) ;
FVector3d A , B ;
DrawnLineSet - > Clear ( ) ;
2020-12-07 15:18:20 -04:00
for ( int EID : EmbeddedEdges )
2020-04-21 14:41:25 -04:00
{
2020-12-07 15:18:20 -04:00
TargetMesh - > GetEdgeV ( EID , A , B ) ;
DrawnLineSet - > AddLine ( ( FVector ) A , ( FVector ) B , EmbedEdgeColor , EmbedEdgeThickness , EmbedEdgeDepthBias ) ;
}
if ( ! bOperationSucceeded )
{
for ( int EID : EdgesOnFailure )
2020-04-21 14:41:25 -04:00
{
TargetMesh - > GetEdgeV ( EID , A , B ) ;
DrawnLineSet - > AddLine ( ( FVector ) A , ( FVector ) B , PartialPathEdgeColor , PartialPathEdgeThickness , PartialPathEdgeDepthBias ) ;
}
}
}
2020-01-27 20:11:15 -05:00
void UPolygonOnMeshTool : : UpdatePolygonType ( )
{
if ( BasicProperties - > Shape = = EPolygonType : : Circle )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
ActivePolygon = FPolygon2d : : MakeCircle ( BasicProperties - > Width * 0.5 , BasicProperties - > Subdivisions ) ;
2019-10-01 20:41:42 -04:00
}
2020-01-27 20:11:15 -05:00
else if ( BasicProperties - > Shape = = EPolygonType : : Square )
{
ActivePolygon = FPolygon2d : : MakeRectangle ( FVector2d : : Zero ( ) , BasicProperties - > Width , BasicProperties - > Width ) ;
}
else if ( BasicProperties - > Shape = = EPolygonType : : Rectangle )
{
ActivePolygon = FPolygon2d : : MakeRectangle ( FVector2d : : Zero ( ) , BasicProperties - > Width , BasicProperties - > Height ) ;
}
else if ( BasicProperties - > Shape = = EPolygonType : : RoundRect )
{
double Corner = BasicProperties - > CornerRatio * FMath : : Min ( BasicProperties - > Width , BasicProperties - > Height ) * 0.49 ;
ActivePolygon = FPolygon2d : : MakeRoundedRectangle ( FVector2d : : Zero ( ) , BasicProperties - > Width , BasicProperties - > Height , Corner , BasicProperties - > Subdivisions ) ;
}
else if ( BasicProperties - > Shape = = EPolygonType : : Custom )
{
if ( LastDrawnPolygon . VertexCount ( ) = = 0 )
{
GetToolManager ( ) - > DisplayMessage ( LOCTEXT ( " PolygonOnMeshDrawMessage " , " Click the Draw Polygon button to draw a custom polygon " ) , EToolMessageLevel : : UserWarning ) ;
ActivePolygon = FPolygon2d : : MakeCircle ( BasicProperties - > Width * 0.5 , BasicProperties - > Subdivisions ) ;
}
else
{
ActivePolygon = LastDrawnPolygon ;
}
}
}
void UPolygonOnMeshTool : : UpdateDrawPlane ( )
{
Preview - > InvalidateResult ( ) ;
2019-10-01 20:41:42 -04:00
}
2020-04-21 14:41:25 -04:00
void UPolygonOnMeshTool : : SetupPreview ( )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
Preview = NewObject < UMeshOpPreviewWithBackgroundCompute > ( this ) ;
Preview - > Setup ( this - > TargetWorld , this ) ;
2021-10-07 22:25:54 -04:00
ToolSetupUtil : : ApplyRenderingConfigurationToPreview ( Preview - > PreviewMesh , nullptr ) ;
2021-06-11 22:42:32 -04:00
Preview - > PreviewMesh - > SetTangentsMode ( EDynamicMeshComponentTangentsMode : : AutoCalculated ) ;
2019-12-19 18:07:47 -05:00
2020-01-27 20:11:15 -05:00
FComponentMaterialSet MaterialSet ;
2021-03-24 11:11:02 -04:00
Cast < IMaterialProvider > ( Target ) - > GetMaterialSet ( MaterialSet ) ;
2020-01-27 20:11:15 -05:00
Preview - > ConfigureMaterials ( MaterialSet . Materials ,
ToolSetupUtil : : GetDefaultWorkingMaterial ( GetToolManager ( ) )
) ;
2019-12-19 18:07:47 -05:00
2020-01-27 20:11:15 -05:00
Preview - > SetVisibility ( true ) ;
2019-10-01 20:41:42 -04:00
}
2022-01-28 18:40:54 -05:00
void UPolygonOnMeshTool : : OnShutdown ( EToolShutdownType ShutdownType )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
PlaneMechanic - > Shutdown ( ) ;
if ( DrawPolygonMechanic ! = nullptr )
{
DrawPolygonMechanic - > Shutdown ( ) ;
}
2021-07-20 14:26:03 -04:00
BasicProperties - > SaveProperties ( this ) ;
2020-01-27 20:11:15 -05:00
2019-10-01 20:41:42 -04:00
// Restore (unhide) the source meshes
2021-03-24 11:11:02 -04:00
Cast < IPrimitiveComponentBackedTarget > ( Target ) - > SetOwnerVisibility ( true ) ;
2019-10-01 20:41:42 -04:00
2019-10-02 12:05:44 -04:00
TArray < FDynamicMeshOpResult > Results ;
2020-01-27 20:11:15 -05:00
Results . Emplace ( Preview - > Shutdown ( ) ) ;
2019-10-01 20:41:42 -04:00
if ( ShutdownType = = EToolShutdownType : : Accept )
{
GenerateAsset ( Results ) ;
}
}
2020-01-27 20:11:15 -05:00
TUniquePtr < FDynamicMeshOperator > UPolygonOnMeshTool : : MakeNewOperator ( )
2019-10-01 20:41:42 -04:00
{
2019-10-04 14:13:21 -04:00
TUniquePtr < FEmbedPolygonsOp > EmbedOp = MakeUnique < FEmbedPolygonsOp > ( ) ;
2020-01-27 20:11:15 -05:00
EmbedOp - > bDiscardAttributes = false ;
EmbedOp - > Operation = BasicProperties - > Operation ;
2020-12-07 15:18:20 -04:00
EmbedOp - > bCutWithBoolean = BasicProperties - > bCutWithBoolean ;
2021-08-04 14:10:34 -04:00
bool bOpLeavesOpenBoundaries =
BasicProperties - > Operation = = EEmbeddedPolygonOpMethod : : TrimInside | |
BasicProperties - > Operation = = EEmbeddedPolygonOpMethod : : TrimOutside ;
EmbedOp - > bAttemptFixHolesOnBoolean = ! bOpLeavesOpenBoundaries & & BasicProperties - > bTryToFixCracks ;
2019-10-01 20:41:42 -04:00
2022-05-11 10:50:28 -04:00
// Match the world plane in the local space
FVector3d LocalOrigin = WorldTransform . InverseTransformPosition ( DrawPlaneWorld . Origin ) ;
FVector3d TempLocalX = WorldTransform . InverseTransformVector ( DrawPlaneWorld . GetAxis ( 0 ) ) ;
FVector3d TempLocalY = WorldTransform . InverseTransformVector ( DrawPlaneWorld . GetAxis ( 1 ) ) ;
FVector3d LocalZ = TempLocalX . Cross ( TempLocalY ) ;
FFrame3d LocalFrame ( LocalOrigin , LocalZ ) ;
2020-01-27 20:11:15 -05:00
EmbedOp - > PolygonFrame = LocalFrame ;
2020-02-14 17:47:49 -05:00
2022-05-11 10:50:28 -04:00
// Transform the active polygon by the polygon scale put it on the local space's frame
2020-02-14 17:47:49 -05:00
EmbedOp - > EmbedPolygon = ActivePolygon ;
2022-05-11 10:50:28 -04:00
const TArray < FVector2d > & Vertices = EmbedOp - > EmbedPolygon . GetVertices ( ) ;
for ( int32 Idx = 0 ; Idx < EmbedOp - > EmbedPolygon . VertexCount ( ) ; + + Idx )
{
FVector2d World2d = Vertices [ Idx ] * BasicProperties - > PolygonScale ;
FVector2d LocalPos = LocalFrame . ToPlaneUV ( WorldTransform . InverseTransformPosition ( DrawPlaneWorld . FromPlaneUV ( World2d ) ) ) ;
EmbedOp - > EmbedPolygon . Set ( Idx , LocalPos ) ;
}
2020-02-14 17:47:49 -05:00
// TODO: scale any extrude by ToLocal.TransformVector(LocalFrame.Z()).Length() ??
// EmbedOp->ExtrudeDistance = Tool->BasicProperties->ExtrudeDistance;
2020-01-27 20:11:15 -05:00
EmbedOp - > OriginalMesh = OriginalDynamicMesh ;
EmbedOp - > SetResultTransform ( WorldTransform ) ;
2019-10-01 20:41:42 -04:00
return EmbedOp ;
}
2020-01-27 20:11:15 -05:00
2019-10-01 20:41:42 -04:00
void UPolygonOnMeshTool : : Render ( IToolsContextRenderAPI * RenderAPI )
{
2020-01-27 20:11:15 -05:00
PlaneMechanic - > Render ( RenderAPI ) ;
if ( DrawPolygonMechanic ! = nullptr )
{
DrawPolygonMechanic - > Render ( RenderAPI ) ;
}
else
{
FToolDataVisualizer Visualizer ;
Visualizer . BeginFrame ( RenderAPI ) ;
double Scale = BasicProperties - > PolygonScale ;
const TArray < FVector2d > & Vertices = ActivePolygon . GetVertices ( ) ;
int32 NumVertices = Vertices . Num ( ) ;
FVector3d PrevPosition = DrawPlaneWorld . FromPlaneUV ( Scale * Vertices [ 0 ] ) ;
for ( int32 k = 1 ; k < = NumVertices ; + + k )
{
FVector3d NextPosition = DrawPlaneWorld . FromPlaneUV ( Scale * Vertices [ k % NumVertices ] ) ;
Visualizer . DrawLine ( PrevPosition , NextPosition , LinearColors : : VideoRed3f ( ) , 3.0f , false ) ;
PrevPosition = NextPosition ;
}
}
2019-10-01 20:41:42 -04:00
}
2020-04-18 18:42:59 -04:00
void UPolygonOnMeshTool : : OnTick ( float DeltaTime )
2019-10-01 20:41:42 -04:00
{
2020-09-24 00:43:27 -04:00
GetToolManager ( ) - > GetContextQueriesAPI ( ) - > GetCurrentViewState ( this - > CameraState ) ;
2020-01-27 20:11:15 -05:00
PlaneMechanic - > Tick ( DeltaTime ) ;
Preview - > Tick ( DeltaTime ) ;
if ( PendingAction ! = EPolygonOnMeshToolActions : : NoAction )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
if ( PendingAction = = EPolygonOnMeshToolActions : : DrawPolygon )
{
BeginDrawPolygon ( ) ;
}
PendingAction = EPolygonOnMeshToolActions : : NoAction ;
2019-10-01 20:41:42 -04:00
}
}
2020-01-07 15:54:23 -05:00
void UPolygonOnMeshTool : : OnPropertyModified ( UObject * PropertySet , FProperty * Property )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
UpdatePolygonType ( ) ;
Preview - > InvalidateResult ( ) ;
2019-10-01 20:41:42 -04:00
}
2020-01-27 20:11:15 -05:00
void UPolygonOnMeshTool : : RequestAction ( EPolygonOnMeshToolActions ActionType )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
if ( PendingAction ! = EPolygonOnMeshToolActions : : NoAction | | DrawPolygonMechanic ! = nullptr )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
return ;
2019-10-01 20:41:42 -04:00
}
2020-01-27 20:11:15 -05:00
PendingAction = ActionType ;
2019-10-01 20:41:42 -04:00
}
2020-01-27 20:11:15 -05:00
void UPolygonOnMeshTool : : BeginDrawPolygon ( )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
check ( DrawPolygonMechanic = = nullptr ) ;
2019-10-01 20:41:42 -04:00
2020-01-27 20:11:15 -05:00
GetToolManager ( ) - > DisplayMessage ( LOCTEXT ( " PolygonOnMeshBeginDrawMessage " , " Click repeatedly on the plane to draw a polygon, and on start point to finish. " ) , EToolMessageLevel : : UserWarning ) ;
2019-10-01 20:41:42 -04:00
2020-01-27 20:11:15 -05:00
DrawPolygonMechanic = NewObject < UCollectSurfacePathMechanic > ( this ) ;
DrawPolygonMechanic - > Setup ( this ) ;
double SnapTol = ToolSceneQueriesUtil : : GetDefaultVisualAngleSnapThreshD ( ) ;
DrawPolygonMechanic - > SpatialSnapPointsFunc = [ this , SnapTol ] ( FVector3d Position1 , FVector3d Position2 )
2019-09-12 13:55:17 -04:00
{
2020-06-23 18:40:00 -04:00
return true & & ToolSceneQueriesUtil : : PointSnapQuery ( this - > CameraState , Position1 , Position2 , SnapTol ) ;
2020-01-27 20:11:15 -05:00
} ;
DrawPolygonMechanic - > SetDrawClosedLoopMode ( ) ;
DrawPolygonMechanic - > InitializePlaneSurface ( DrawPlaneWorld ) ;
2019-10-01 20:41:42 -04:00
}
2020-01-27 20:11:15 -05:00
void UPolygonOnMeshTool : : CompleteDrawPolygon ( )
2019-09-12 13:55:17 -04:00
{
2020-01-27 20:11:15 -05:00
check ( DrawPolygonMechanic ! = nullptr ) ;
GetToolManager ( ) - > DisplayMessage ( FText : : GetEmpty ( ) , EToolMessageLevel : : UserWarning ) ;
FFrame3d DrawFrame = DrawPlaneWorld ;
FPolygon2d TmpPolygon ;
for ( const FFrame3d & Point : DrawPolygonMechanic - > HitPath )
2019-09-12 13:55:17 -04:00
{
2020-01-27 20:11:15 -05:00
TmpPolygon . AppendVertex ( DrawFrame . ToPlaneUV ( Point . Origin ) ) ;
2019-09-12 13:55:17 -04:00
}
2020-01-27 20:11:15 -05:00
if ( TmpPolygon . IsClockwise ( ) = = true )
{
TmpPolygon . Reverse ( ) ;
}
// check for self-intersections and other invalids
LastDrawnPolygon = TmpPolygon ;
BasicProperties - > Shape = EPolygonType : : Custom ;
BasicProperties - > PolygonScale = 1.0 ;
UpdatePolygonType ( ) ;
Preview - > InvalidateResult ( ) ;
DrawPolygonMechanic - > Shutdown ( ) ;
DrawPolygonMechanic = nullptr ;
2019-09-12 13:55:17 -04:00
}
2019-09-26 00:12:45 -04:00
2019-10-01 20:41:42 -04:00
bool UPolygonOnMeshTool : : CanAccept ( ) const
{
2021-02-05 16:33:02 -04:00
return Super : : CanAccept ( ) & & Preview ! = nullptr & & Preview - > HaveValidNonEmptyResult ( ) ;
2019-10-01 20:41:42 -04:00
}
2019-10-02 12:05:44 -04:00
void UPolygonOnMeshTool : : GenerateAsset ( const TArray < FDynamicMeshOpResult > & Results )
2019-10-01 20:41:42 -04:00
{
2020-01-27 20:11:15 -05:00
GetToolManager ( ) - > BeginUndoTransaction ( LOCTEXT ( " PolygonOnMeshToolTransactionName " , " Cut Hole " ) ) ;
2019-10-01 20:41:42 -04:00
check ( Results . Num ( ) > 0 ) ;
2019-10-02 12:05:44 -04:00
check ( Results [ 0 ] . Mesh . Get ( ) ! = nullptr ) ;
2021-12-06 12:42:19 -05:00
UE : : ToolTarget : : CommitMeshDescriptionUpdateViaDynamicMesh ( Target , * Results [ 0 ] . Mesh . Get ( ) , true ) ;
2019-10-01 20:41:42 -04:00
GetToolManager ( ) - > EndUndoTransaction ( ) ;
}
2020-01-27 20:11:15 -05:00
bool UPolygonOnMeshTool : : HitTest ( const FRay & Ray , FHitResult & OutHit )
{
if ( DrawPolygonMechanic ! = nullptr )
{
FFrame3d HitPoint ;
2021-11-17 21:06:46 -05:00
if ( DrawPolygonMechanic - > IsHitByRay ( FRay3d ( Ray ) , HitPoint ) )
2020-01-27 20:11:15 -05:00
{
2021-11-17 21:06:46 -05:00
OutHit . Distance = FRay3d ( Ray ) . GetParameter ( HitPoint . Origin ) ;
2020-01-27 20:11:15 -05:00
OutHit . ImpactPoint = ( FVector ) HitPoint . Origin ;
OutHit . ImpactNormal = ( FVector ) HitPoint . Z ( ) ;
return true ;
}
return false ;
}
return false ;
}
FInputRayHit UPolygonOnMeshTool : : IsHitByClick ( const FInputDeviceRay & ClickPos )
{
FHitResult OutHit ;
if ( HitTest ( ClickPos . WorldRay , OutHit ) )
{
return FInputRayHit ( OutHit . Distance ) ;
}
return ( DrawPolygonMechanic ! = nullptr ) ? FInputRayHit ( TNumericLimits < float > : : Max ( ) ) : FInputRayHit ( ) ;
}
void UPolygonOnMeshTool : : OnClicked ( const FInputDeviceRay & ClickPos )
{
if ( DrawPolygonMechanic ! = nullptr )
{
2021-11-17 21:06:46 -05:00
if ( DrawPolygonMechanic - > TryAddPointFromRay ( ( FRay3d ) ClickPos . WorldRay ) )
2020-01-27 20:11:15 -05:00
{
if ( DrawPolygonMechanic - > IsDone ( ) )
{
CompleteDrawPolygon ( ) ;
//GetToolManager()->EmitObjectChange(this, MakeUnique<FDrawPolyPathStateChange>(CurrentCurveTimestamp), LOCTEXT("DrawPolyPathBeginOffset", "Set Offset"));
//OnCompleteSurfacePath();
}
else
{
//GetToolManager()->EmitObjectChange(this, MakeUnique<FDrawPolyPathStateChange>(CurrentCurveTimestamp), LOCTEXT("DrawPolyPathBeginPath", "Begin Path"));
}
}
}
}
FInputRayHit UPolygonOnMeshTool : : BeginHoverSequenceHitTest ( const FInputDeviceRay & PressPos )
{
FHitResult OutHit ;
if ( HitTest ( PressPos . WorldRay , OutHit ) )
{
return FInputRayHit ( OutHit . Distance ) ;
}
return ( DrawPolygonMechanic ! = nullptr ) ? FInputRayHit ( TNumericLimits < float > : : Max ( ) ) : FInputRayHit ( ) ;
}
bool UPolygonOnMeshTool : : OnUpdateHover ( const FInputDeviceRay & DevicePos )
{
if ( DrawPolygonMechanic ! = nullptr )
{
2021-11-17 21:06:46 -05:00
DrawPolygonMechanic - > UpdatePreviewPoint ( ( FRay3d ) DevicePos . WorldRay ) ;
2020-01-27 20:11:15 -05:00
}
return true ;
}
2019-10-01 20:41:42 -04:00
# undef LOCTEXT_NAMESPACE