2020-08-11 01:36:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "DrawAndRevolveTool.h"
# include "BaseBehaviors/SingleClickBehavior.h"
# include "BaseBehaviors/MouseHoverBehavior.h"
# include "CompositionOps/CurveSweepOp.h"
# include "Generators/SweepGenerator.h"
# include "InteractiveToolManager.h" // To use SceneState.ToolManager
# include "Mechanics/ConstructionPlaneMechanic.h"
2020-09-01 14:07:48 -04:00
# include "Mechanics/CurveControlPointsMechanic.h"
2020-08-11 01:36:57 -04:00
# include "Properties/MeshMaterialProperties.h"
2021-06-02 15:58:00 -04:00
# include "ModelingObjectsCreationAPI.h"
2022-03-17 14:03:58 -04:00
# include "SceneManagement.h" // FPrimitiveDrawInterface
2020-08-11 01:36:57 -04:00
# include "Selection/ToolSelectionUtil.h"
# include "ToolSceneQueriesUtil.h"
# include "ToolSetupUtil.h"
2022-09-28 01:06:15 -04:00
# include UE_INLINE_GENERATED_CPP_BY_NAME(DrawAndRevolveTool)
2021-03-09 19:33:56 -04:00
using namespace UE : : Geometry ;
2020-08-11 01:36:57 -04:00
# define LOCTEXT_NAMESPACE "UDrawAndRevolveTool"
2021-10-26 13:33:36 -04:00
const FText InitializationModeMessage = LOCTEXT ( " CurveInitialization " , " Draw a path and revolve it around the purple axis. Left-click to place path vertices, and click on the last or first vertex to complete the path. Hold Shift to invert snapping behavior. " ) ;
const FText EditModeMessage = LOCTEXT ( " CurveEditing " , " Click points to select them, Shift+click to modify selection. Ctrl+click a segment to add a point, or select an endpoint and Ctrl+click to add new endpoint. Backspace deletes selected points. Hold Shift to invert snapping behavior. " ) ;
2020-09-01 14:07:48 -04:00
2020-08-11 01:36:57 -04:00
// Tool builder
bool UDrawAndRevolveToolBuilder : : CanBuildTool ( const FToolBuilderState & SceneState ) const
{
2021-06-02 15:58:00 -04:00
return true ;
2020-08-11 01:36:57 -04:00
}
UInteractiveTool * UDrawAndRevolveToolBuilder : : BuildTool ( const FToolBuilderState & SceneState ) const
{
UDrawAndRevolveTool * NewTool = NewObject < UDrawAndRevolveTool > ( SceneState . ToolManager ) ;
NewTool - > SetWorld ( SceneState . World ) ;
return NewTool ;
}
// Operator factory
TUniquePtr < FDynamicMeshOperator > URevolveOperatorFactory : : MakeNewOperator ( )
{
TUniquePtr < FCurveSweepOp > CurveSweepOp = MakeUnique < FCurveSweepOp > ( ) ;
// Assemble profile curve
2020-09-01 14:07:48 -04:00
CurveSweepOp - > ProfileCurve . Reserve ( RevolveTool - > ControlPointsMechanic - > GetNumPoints ( ) + 2 ) ; // extra space for top/bottom caps
RevolveTool - > ControlPointsMechanic - > ExtractPointPositions ( CurveSweepOp - > ProfileCurve ) ;
CurveSweepOp - > bProfileCurveIsClosed = RevolveTool - > ControlPointsMechanic - > GetIsLoop ( ) ;
2020-08-11 01:36:57 -04:00
// If we are capping the top and bottom, we just add a couple extra vertices and mark the curve as being closed
2021-10-26 13:33:36 -04:00
if ( ! CurveSweepOp - > bProfileCurveIsClosed & & RevolveTool - > Settings - > bClosePathToAxis )
2020-08-11 01:36:57 -04:00
{
// Project first and last points onto the revolution axis.
2020-09-01 14:07:48 -04:00
FVector3d FirstPoint = CurveSweepOp - > ProfileCurve [ 0 ] ;
FVector3d LastPoint = CurveSweepOp - > ProfileCurve . Last ( ) ;
double DistanceAlongAxis = RevolveTool - > RevolutionAxisDirection . Dot ( LastPoint - RevolveTool - > RevolutionAxisOrigin ) ;
2020-08-11 01:36:57 -04:00
FVector3d ProjectedPoint = RevolveTool - > RevolutionAxisOrigin + ( RevolveTool - > RevolutionAxisDirection * DistanceAlongAxis ) ;
CurveSweepOp - > ProfileCurve . Add ( ProjectedPoint ) ;
2020-09-01 14:07:48 -04:00
DistanceAlongAxis = RevolveTool - > RevolutionAxisDirection . Dot ( FirstPoint - RevolveTool - > RevolutionAxisOrigin ) ;
2020-08-11 01:36:57 -04:00
ProjectedPoint = RevolveTool - > RevolutionAxisOrigin + ( RevolveTool - > RevolutionAxisDirection * DistanceAlongAxis ) ;
CurveSweepOp - > ProfileCurve . Add ( ProjectedPoint ) ;
CurveSweepOp - > bProfileCurveIsClosed = true ;
}
RevolveTool - > Settings - > ApplyToCurveSweepOp ( * RevolveTool - > MaterialProperties ,
RevolveTool - > RevolutionAxisOrigin , RevolveTool - > RevolutionAxisDirection , * CurveSweepOp ) ;
return CurveSweepOp ;
}
2020-09-01 14:07:48 -04:00
2020-08-11 01:36:57 -04:00
// Tool itself
2020-09-01 14:07:48 -04:00
void UDrawAndRevolveTool : : RegisterActions ( FInteractiveToolActionSet & ActionSet )
{
ActionSet . RegisterAction ( this , ( int32 ) EStandardToolActions : : BaseClientDefinedActionID + 1 ,
2021-03-24 16:38:48 -04:00
TEXT ( " DeletePointBackspaceKey " ) ,
2020-09-01 14:07:48 -04:00
LOCTEXT ( " DeletePointUIName " , " Delete Point " ) ,
LOCTEXT ( " DeletePointTooltip " , " Delete currently selected point(s) " ) ,
EModifierKey : : None , EKeys : : BackSpace ,
2021-03-24 16:38:48 -04:00
[ this ] ( ) { OnPointDeletionKeyPress ( ) ; } ) ;
ActionSet . RegisterAction ( this , ( int32 ) EStandardToolActions : : BaseClientDefinedActionID + 2 ,
TEXT ( " DeletePointDeleteKey " ) ,
LOCTEXT ( " DeletePointUIName " , " Delete Point " ) ,
LOCTEXT ( " DeletePointTooltip " , " Delete currently selected point(s) " ) ,
EModifierKey : : None , EKeys : : Delete ,
[ this ] ( ) { OnPointDeletionKeyPress ( ) ; } ) ;
2020-09-01 14:07:48 -04:00
}
2021-03-24 16:38:48 -04:00
void UDrawAndRevolveTool : : OnPointDeletionKeyPress ( )
2020-09-01 14:07:48 -04:00
{
if ( ControlPointsMechanic )
{
ControlPointsMechanic - > DeleteSelectedPoints ( ) ;
}
}
2020-08-11 01:36:57 -04:00
bool UDrawAndRevolveTool : : CanAccept ( ) const
{
2021-02-05 16:33:02 -04:00
return Preview ! = nullptr & & Preview - > HaveValidNonEmptyResult ( ) ;
2020-08-11 01:36:57 -04:00
}
void UDrawAndRevolveTool : : Setup ( )
{
UInteractiveTool : : Setup ( ) ;
2021-02-08 17:02:09 -04:00
SetToolDisplayName ( LOCTEXT ( " ToolName " , " Revolve PolyPath " ) ) ;
2020-09-01 14:07:48 -04:00
GetToolManager ( ) - > DisplayMessage ( InitializationModeMessage , EToolMessageLevel : : UserNotification ) ;
2020-08-11 01:36:57 -04:00
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
OutputTypeProperties = NewObject < UCreateMeshObjectTypeProperties > ( this ) ;
OutputTypeProperties - > RestoreProperties ( this ) ;
OutputTypeProperties - > InitializeDefault ( ) ;
OutputTypeProperties - > WatchProperty ( OutputTypeProperties - > OutputType , [ this ] ( FString ) { OutputTypeProperties - > UpdatePropertyVisibility ( ) ; } ) ;
AddToolPropertySource ( OutputTypeProperties ) ;
2020-08-11 01:36:57 -04:00
Settings = NewObject < URevolveToolProperties > ( this , TEXT ( " Revolve Tool Settings " ) ) ;
Settings - > RestoreProperties ( this ) ;
2020-09-01 14:07:48 -04:00
Settings - > bAllowedToEditDrawPlane = true ;
2020-08-11 01:36:57 -04:00
AddToolPropertySource ( Settings ) ;
MaterialProperties = NewObject < UNewMeshMaterialProperties > ( this ) ;
AddToolPropertySource ( MaterialProperties ) ;
MaterialProperties - > RestoreProperties ( this ) ;
2020-09-01 14:07:48 -04:00
ControlPointsMechanic = NewObject < UCurveControlPointsMechanic > ( this ) ;
ControlPointsMechanic - > Setup ( this ) ;
ControlPointsMechanic - > SetWorld ( TargetWorld ) ;
ControlPointsMechanic - > OnPointsChanged . AddLambda ( [ this ] ( ) {
if ( Preview )
{
Preview - > InvalidateResult ( ) ;
}
2021-04-27 11:06:18 -04:00
bool bAllowedToEditDrawPlane = ( ControlPointsMechanic - > GetNumPoints ( ) = = 0 ) ;
if ( Settings - > bAllowedToEditDrawPlane ! = bAllowedToEditDrawPlane )
{
Settings - > bAllowedToEditDrawPlane = bAllowedToEditDrawPlane ;
NotifyOfPropertyChangeByTool ( Settings ) ;
}
2020-09-01 14:07:48 -04:00
} ) ;
// This gets called when we enter/leave curve initialization mode
ControlPointsMechanic - > OnModeChanged . AddLambda ( [ this ] ( ) {
if ( ControlPointsMechanic - > IsInInteractiveIntialization ( ) )
{
// We're back to initializing so hide the preview
if ( Preview )
{
Preview - > Cancel ( ) ;
Preview = nullptr ;
}
GetToolManager ( ) - > DisplayMessage ( InitializationModeMessage , EToolMessageLevel : : UserNotification ) ;
}
else
{
StartPreview ( ) ;
GetToolManager ( ) - > DisplayMessage ( EditModeMessage , EToolMessageLevel : : UserNotification ) ;
}
} ) ;
ControlPointsMechanic - > SetSnappingEnabled ( Settings - > bEnableSnapping ) ;
2020-08-11 01:36:57 -04:00
2020-10-09 22:42:26 -04:00
UpdateRevolutionAxis ( ) ;
2020-08-11 01:36:57 -04:00
2022-10-01 02:07:54 -04:00
FViewCameraState InitialCameraState ;
GetToolManager ( ) - > GetContextQueriesAPI ( ) - > GetCurrentViewState ( InitialCameraState ) ;
if ( FVector : : DistSquared ( InitialCameraState . Position , Settings - > DrawPlaneOrigin ) > FarDrawPlaneThreshold * FarDrawPlaneThreshold )
{
bHasFarPlaneWarning = true ;
GetToolManager ( ) - > DisplayMessage (
LOCTEXT ( " FarDrawPlane " , " The axis of revolution is far from the camera. Note that you can ctrl-click to place the axis on a visible surface. " ) ,
EToolMessageLevel : : UserWarning ) ;
}
2020-08-11 01:36:57 -04:00
// The plane mechanic lets us update the plane in which we draw the profile curve, as long as we haven't
// started adding points to it already.
2020-10-09 22:42:26 -04:00
FFrame3d ProfileDrawPlane ( Settings - > DrawPlaneOrigin , Settings - > DrawPlaneOrientation . Quaternion ( ) ) ;
2020-08-11 01:36:57 -04:00
PlaneMechanic = NewObject < UConstructionPlaneMechanic > ( this ) ;
PlaneMechanic - > Setup ( this ) ;
PlaneMechanic - > Initialize ( TargetWorld , ProfileDrawPlane ) ;
2020-09-01 14:07:48 -04:00
PlaneMechanic - > UpdateClickPriority ( ControlPointsMechanic - > ClickBehavior - > GetPriority ( ) . MakeHigher ( ) ) ;
2020-08-11 01:36:57 -04:00
PlaneMechanic - > CanUpdatePlaneFunc = [ this ] ( )
{
2020-09-01 14:07:48 -04:00
return ControlPointsMechanic - > GetNumPoints ( ) = = 0 ;
2020-08-11 01:36:57 -04:00
} ;
PlaneMechanic - > OnPlaneChanged . AddLambda ( [ this ] ( ) {
2020-10-09 22:42:26 -04:00
Settings - > DrawPlaneOrigin = ( FVector ) PlaneMechanic - > Plane . Origin ;
Settings - > DrawPlaneOrientation = ( ( FQuat ) PlaneMechanic - > Plane . Rotation ) . Rotator ( ) ;
2021-04-27 11:06:18 -04:00
NotifyOfPropertyChangeByTool ( Settings ) ;
2020-09-01 14:07:48 -04:00
if ( ControlPointsMechanic )
{
ControlPointsMechanic - > SetPlane ( PlaneMechanic - > Plane ) ;
}
2020-10-09 22:42:26 -04:00
UpdateRevolutionAxis ( ) ;
2022-10-01 02:07:54 -04:00
if ( bHasFarPlaneWarning ) // if the user has changed the plane, no longer need a warning
{
bHasFarPlaneWarning = false ;
GetToolManager ( ) - > DisplayMessage ( FText ( ) , EToolMessageLevel : : UserWarning ) ;
}
2020-08-11 01:36:57 -04:00
} ) ;
2020-09-01 14:07:48 -04:00
ControlPointsMechanic - > SetPlane ( PlaneMechanic - > Plane ) ;
ControlPointsMechanic - > SetInteractiveInitialization ( true ) ;
2020-09-24 00:43:27 -04:00
ControlPointsMechanic - > SetAutoRevertToInteractiveInitialization ( true ) ;
// For things to behave nicely, we expect to revolve at least a two point
// segment if it's not a loop, and a three point segment if it is. Revolving
// a two-point loop to make a double sided thing is a pain to support because
// it forces us to deal with manifoldness issues that we would really rather
// not worry about (we'd have to duplicate vertices to stay manifold)
ControlPointsMechanic - > SetMinPointsToLeaveInteractiveInitialization ( 3 , 2 ) ;
2020-08-11 01:36:57 -04:00
}
2020-10-09 22:42:26 -04:00
/** Uses the settings currently stored in the properties object to update the revolution axis. */
void UDrawAndRevolveTool : : UpdateRevolutionAxis ( )
2020-08-11 01:36:57 -04:00
{
2021-03-30 21:25:22 -04:00
RevolutionAxisOrigin = ( FVector3d ) Settings - > DrawPlaneOrigin ;
RevolutionAxisDirection = ( FVector3d ) Settings - > DrawPlaneOrientation . RotateVector ( FVector ( 1 , 0 , 0 ) ) ;
2020-09-01 14:07:48 -04:00
const int32 AXIS_SNAP_TARGET_ID = 1 ;
ControlPointsMechanic - > RemoveSnapLine ( AXIS_SNAP_TARGET_ID ) ;
ControlPointsMechanic - > AddSnapLine ( AXIS_SNAP_TARGET_ID , FLine3d ( RevolutionAxisOrigin , RevolutionAxisDirection ) ) ;
2020-08-11 01:36:57 -04:00
}
void UDrawAndRevolveTool : : Shutdown ( EToolShutdownType ShutdownType )
{
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
OutputTypeProperties - > SaveProperties ( this ) ;
2020-08-11 01:36:57 -04:00
Settings - > SaveProperties ( this ) ;
MaterialProperties - > SaveProperties ( this ) ;
PlaneMechanic - > Shutdown ( ) ;
2020-09-01 14:07:48 -04:00
ControlPointsMechanic - > Shutdown ( ) ;
2020-08-11 01:36:57 -04:00
if ( Preview )
{
if ( ShutdownType = = EToolShutdownType : : Accept )
{
2022-08-25 11:51:02 -04:00
Preview - > PreviewMesh - > CalculateTangents ( ) ; // Copy tangents from the PreviewMesh
2020-08-11 01:36:57 -04:00
GenerateAsset ( Preview - > Shutdown ( ) ) ;
}
else
{
Preview - > Cancel ( ) ;
}
}
}
2021-06-02 15:58:00 -04:00
void UDrawAndRevolveTool : : GenerateAsset ( const FDynamicMeshOpResult & OpResult )
2020-08-11 01:36:57 -04:00
{
2021-06-02 15:58:00 -04:00
if ( OpResult . Mesh - > TriangleCount ( ) < = 0 )
2021-01-19 14:14:05 -04:00
{
return ;
}
2020-08-11 01:36:57 -04:00
2021-10-26 13:33:36 -04:00
GetToolManager ( ) - > BeginUndoTransaction ( LOCTEXT ( " RevolveToolTransactionName " , " Path Revolve Tool " ) ) ;
2020-10-09 22:42:26 -04:00
2021-06-02 15:58:00 -04:00
FCreateMeshObjectParams NewMeshObjectParams ;
NewMeshObjectParams . TargetWorld = TargetWorld ;
NewMeshObjectParams . Transform = ( FTransform ) OpResult . Transform ;
NewMeshObjectParams . BaseName = TEXT ( " Revolve " ) ;
NewMeshObjectParams . Materials . Add ( MaterialProperties - > Material . Get ( ) ) ;
NewMeshObjectParams . SetMesh ( OpResult . Mesh . Get ( ) ) ;
ModelingTools: add support for creating Volumes directly from DrawPolygon, DrawRevolve, DrawPolyPath, and AddPrimitive, CombineMeshes, CutMeshWithMesh, PlaneCut, BaseCreateFromSelected Tools. Improve support for Editing volumes, eg handling mesh/volume interactions, and add configurable auto-simplification for volumes to avoid painful Editor hangs.
- Move ToolTarget implementations, DynamicMeshToVolume to ModelingComponentsEditorOnly module
- move VolumeToDynamicMesh, DynamicMeshProvider/Commiter interfaces to ModelingComponents module
- Add UCreateMeshObjectTypeProperties property set to expose mesh/volume options
- Add FCreateMeshObjectParams::TypeHintClass to allow AVolume type (or other UClass hints) to be passed to creation APIs
- Add UE::ToolTarget::ConfigureCreateMeshObjectParams() util function in ModelingToolTargetUtil, tries to determine output type in a FCreateMeshObjectParams based on input ToolTarget
- Add UEditorModelingObjectsCreationAPI::CreateVolume() implementation
- Add UEditorModelingObjectsCreationAPI::FilterMaterials() that strips out any internal materials and replaces with WorldGridMaterial. This occurs when (eg) subtracting a Volume from a StaticMesh, because the temporary volume mesh gets assigned internal materials, but the Tools don't know this. Use in EditorModelingObjectsCreationAPI when creating new objects. UStaticMeshComponentToolTarget also does this filtering in ::CommitMaterialSetUpdate().
- Add ::ComponentTypeSupportsCollision() function to ComponentCollisionUtil, use to avoid checks/ensures for Volume targets
- Add support for automatic mesh simplification in DynamicMeshToVolume. Add CVar to VolumeDynamicMeshToolTarget.h to control max triangle count (default 500). Apply auto-simplify when creating or updating an AVolume. This prevents the Editor from blocking for long periods on meshes that are too high-res for volumes (even 500 is quite high).
- DynamicMeshToVolume now emits polygroup-faces that contain holes (ie multiple boundary loops) as a set of triangles, rather than emitting separate overlapping faces for each boundary loop
#rb none
#rnx
#jira none
#preflight 60ba50632c42ea0001cb54c5
[CL 16561742 by Ryan Schmidt in ue5-main branch]
2021-06-04 16:04:03 -04:00
OutputTypeProperties - > ConfigureCreateMeshObjectParams ( NewMeshObjectParams ) ;
2021-06-02 15:58:00 -04:00
FCreateMeshObjectResult Result = UE : : Modeling : : CreateMeshObject ( GetToolManager ( ) , MoveTemp ( NewMeshObjectParams ) ) ;
if ( Result . IsOK ( ) & & Result . NewActor ! = nullptr )
2020-08-11 01:36:57 -04:00
{
2021-06-02 15:58:00 -04:00
ToolSelectionUtil : : SetNewActorSelection ( GetToolManager ( ) , Result . NewActor ) ;
2020-08-11 01:36:57 -04:00
}
GetToolManager ( ) - > EndUndoTransaction ( ) ;
}
void UDrawAndRevolveTool : : StartPreview ( )
{
URevolveOperatorFactory * RevolveOpCreator = NewObject < URevolveOperatorFactory > ( ) ;
RevolveOpCreator - > RevolveTool = this ;
// Normally we wouldn't give the object a name, but since we may destroy the preview using undo,
// the ability to reuse the non-cleaned up memory is useful. Careful if copy-pasting this!
Preview = NewObject < UMeshOpPreviewWithBackgroundCompute > ( RevolveOpCreator , " RevolveToolPreview " ) ;
Preview - > Setup ( TargetWorld , RevolveOpCreator ) ;
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 ) ;
2020-08-11 01:36:57 -04:00
2020-10-09 22:42:26 -04:00
Preview - > ConfigureMaterials ( MaterialProperties - > Material . Get ( ) ,
2020-08-11 01:36:57 -04:00
ToolSetupUtil : : GetDefaultWorkingMaterial ( GetToolManager ( ) ) ) ;
2021-10-18 14:21:53 -04:00
Preview - > PreviewMesh - > EnableWireframe ( MaterialProperties - > bShowWireframe ) ;
2020-08-11 01:36:57 -04:00
2021-02-05 16:33:02 -04:00
Preview - > OnMeshUpdated . AddLambda (
[ this ] ( const UMeshOpPreviewWithBackgroundCompute * UpdatedPreview )
{
UpdateAcceptWarnings ( UpdatedPreview - > HaveEmptyResult ( ) ? EAcceptWarning : : EmptyForbidden : EAcceptWarning : : NoWarning ) ;
}
) ;
2020-08-11 01:36:57 -04:00
Preview - > SetVisibility ( true ) ;
Preview - > InvalidateResult ( ) ;
}
void UDrawAndRevolveTool : : OnPropertyModified ( UObject * PropertySet , FProperty * Property )
{
2020-10-09 22:42:26 -04:00
FFrame3d ProfileDrawPlane ( Settings - > DrawPlaneOrigin , Settings - > DrawPlaneOrientation . Quaternion ( ) ) ;
ControlPointsMechanic - > SetPlane ( ProfileDrawPlane ) ;
PlaneMechanic - > SetPlaneWithoutBroadcast ( ProfileDrawPlane ) ;
UpdateRevolutionAxis ( ) ;
2020-08-11 01:36:57 -04:00
2020-09-01 14:07:48 -04:00
ControlPointsMechanic - > SetSnappingEnabled ( Settings - > bEnableSnapping ) ;
2020-08-11 01:36:57 -04:00
if ( Preview )
{
if ( Property & & ( Property - > GetFName ( ) = = GET_MEMBER_NAME_CHECKED ( UNewMeshMaterialProperties , Material ) ) )
{
2020-10-09 22:42:26 -04:00
Preview - > ConfigureMaterials ( MaterialProperties - > Material . Get ( ) ,
2020-08-11 01:36:57 -04:00
ToolSetupUtil : : GetDefaultWorkingMaterial ( GetToolManager ( ) ) ) ;
}
2021-10-18 14:21:53 -04:00
Preview - > PreviewMesh - > EnableWireframe ( MaterialProperties - > bShowWireframe ) ;
2020-08-11 01:36:57 -04:00
Preview - > InvalidateResult ( ) ;
}
}
void UDrawAndRevolveTool : : OnTick ( float DeltaTime )
{
if ( PlaneMechanic ! = nullptr )
{
PlaneMechanic - > Tick ( DeltaTime ) ;
}
if ( Preview )
{
Preview - > Tick ( DeltaTime ) ;
}
}
void UDrawAndRevolveTool : : Render ( IToolsContextRenderAPI * RenderAPI )
{
GetToolManager ( ) - > GetContextQueriesAPI ( ) - > GetCurrentViewState ( CameraState ) ;
2022-10-01 02:07:54 -04:00
if ( bHasFarPlaneWarning & & FVector : : DistSquared ( CameraState . Position , Settings - > DrawPlaneOrigin ) < FarDrawPlaneThreshold * FarDrawPlaneThreshold )
{
// if camera is now closer to the axis, no longer need a warning
bHasFarPlaneWarning = false ;
GetToolManager ( ) - > DisplayMessage ( FText ( ) , EToolMessageLevel : : UserWarning ) ;
}
2020-08-11 01:36:57 -04:00
if ( PlaneMechanic ! = nullptr )
{
PlaneMechanic - > Render ( RenderAPI ) ;
// Draw the axis of rotation
float PdiScale = CameraState . GetPDIScalingFactor ( ) ;
FPrimitiveDrawInterface * PDI = RenderAPI - > GetPrimitiveDrawInterface ( ) ;
FColor AxisColor ( 240 , 16 , 240 ) ;
double AxisThickness = 1.0 * PdiScale ;
double AxisHalfLength = ToolSceneQueriesUtil : : CalculateDimensionFromVisualAngleD ( CameraState , RevolutionAxisOrigin , 90 ) ;
FVector3d StartPoint = RevolutionAxisOrigin - ( RevolutionAxisDirection * ( AxisHalfLength * PdiScale ) ) ;
FVector3d EndPoint = RevolutionAxisOrigin + ( RevolutionAxisDirection * ( AxisHalfLength * PdiScale ) ) ;
PDI - > DrawLine ( ( FVector ) StartPoint , ( FVector ) EndPoint , AxisColor , SDPG_Foreground ,
AxisThickness , 0.0f , true ) ;
}
2020-09-01 14:07:48 -04:00
if ( ControlPointsMechanic ! = nullptr )
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
ControlPointsMechanic - > Render ( RenderAPI ) ;
2020-08-11 01:36:57 -04:00
}
}
# undef LOCTEXT_NAMESPACE
2022-09-28 01:06:15 -04:00