548 lines
20 KiB
C++
548 lines
20 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "ComponentVisualizer.h"
|
|
#include "Components/SplineComponent.h"
|
|
#include "Containers/Array.h"
|
|
#include "Containers/Set.h"
|
|
#include "Containers/UnrealString.h"
|
|
#include "CoreMinimal.h"
|
|
#include "Engine/EngineBaseTypes.h"
|
|
#include "GenericPlatform/ICursor.h"
|
|
#include "HitProxies.h"
|
|
#include "InputCoreTypes.h"
|
|
#include "Math/Axis.h"
|
|
#include "Math/Box.h"
|
|
#include "Math/InterpCurvePoint.h"
|
|
#include "Math/Matrix.h"
|
|
#include "Math/Quat.h"
|
|
#include "Math/Rotator.h"
|
|
#include "Math/UnrealMathSSE.h"
|
|
#include "Math/Vector.h"
|
|
#include "Misc/AssertionMacros.h"
|
|
#include "Templates/SharedPointer.h"
|
|
#include "UObject/GCObject.h"
|
|
#include "UObject/Object.h"
|
|
#include "UObject/ObjectMacros.h"
|
|
#include "UObject/UObjectGlobals.h"
|
|
|
|
#include "SplineComponentVisualizer.generated.h"
|
|
|
|
class AActor;
|
|
class FCanvas;
|
|
class FEditorViewportClient;
|
|
class FMenuBuilder;
|
|
class FPrimitiveDrawInterface;
|
|
class FProperty;
|
|
class FSceneView;
|
|
class FUICommandList;
|
|
class FViewport;
|
|
class SSplineGeneratorPanel;
|
|
class SWidget;
|
|
class SWindow;
|
|
class UActorComponent;
|
|
class USplineComponent;
|
|
class USplineMetadata;
|
|
struct FConvexVolume;
|
|
struct FViewportClick;
|
|
|
|
/** Tangent handle selection modes. */
|
|
UENUM()
|
|
enum class ESelectedTangentHandle
|
|
{
|
|
None,
|
|
Leave,
|
|
Arrive
|
|
};
|
|
|
|
/** Selection state data that will be captured by scoped transactions.*/
|
|
UCLASS(Transient)
|
|
class COMPONENTVISUALIZERS_API USplineComponentVisualizerSelectionState : public UObject
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
|
|
/** Checks LastKeyIndexSelected is valid given the number of splint points and returns its value. */
|
|
int32 GetVerifiedLastKeyIndexSelected(const int32 InNumSplinePoints) const;
|
|
|
|
/** Checks TangentHandle and TangentHandleType are valid and sets relevant output parameters. */
|
|
void GetVerifiedSelectedTangentHandle(const int32 InNumSplinePoints, int32& OutSelectedTangentHandle, ESelectedTangentHandle& OutSelectedTangentHandleType) const;
|
|
|
|
const FComponentPropertyPath GetSplinePropertyPath() const { return SplinePropertyPath; }
|
|
void SetSplinePropertyPath(const FComponentPropertyPath& InSplinePropertyPath) { SplinePropertyPath = InSplinePropertyPath; }
|
|
|
|
const TSet<int32>& GetSelectedKeys() const { return SelectedKeys; }
|
|
TSet<int32>& ModifySelectedKeys() { return SelectedKeys; }
|
|
|
|
int32 GetLastKeyIndexSelected() const { return LastKeyIndexSelected; }
|
|
void SetLastKeyIndexSelected(const int32 InLastKeyIndexSelected) { LastKeyIndexSelected = InLastKeyIndexSelected; }
|
|
|
|
int32 GetSelectedSegmentIndex() const { return SelectedSegmentIndex; }
|
|
void SetSelectedSegmentIndex(const int32 InSelectedSegmentIndex) { SelectedSegmentIndex = InSelectedSegmentIndex; }
|
|
|
|
int32 GetSelectedTangentHandle() const { return SelectedTangentHandle; }
|
|
void SetSelectedTangentHandle(const int32 InSelectedTangentHandle) { SelectedTangentHandle = InSelectedTangentHandle; }
|
|
|
|
int32 GetSelectedAttributeIndex() const { return SelectedAttributeIndex; }
|
|
FName GetSelectedAttributeName() const { return SelectedAttributeName; }
|
|
void SetSelectedAttribute(const int32 InSelectedAttributeIndex = INDEX_NONE, const FName& InSelectedAttributeName = NAME_None)
|
|
{
|
|
if (InSelectedAttributeIndex != INDEX_NONE)
|
|
{
|
|
// if we actually select an attribute point, don't persist other selection.
|
|
ClearSelectedKeys(); // necessary? maybe...
|
|
}
|
|
SelectedAttributeIndex = InSelectedAttributeIndex;
|
|
SelectedAttributeName = InSelectedAttributeName;
|
|
}
|
|
|
|
ESelectedTangentHandle GetSelectedTangentHandleType() const { return SelectedTangentHandleType; }
|
|
void SetSelectedTangentHandleType(const ESelectedTangentHandle InSelectedTangentHandle) { SelectedTangentHandleType = InSelectedTangentHandle; }
|
|
|
|
FVector GetSelectedSplinePosition() const { return SelectedSplinePosition; }
|
|
void SetSelectedSplinePosition(const FVector& InSelectedSplinePosition) { SelectedSplinePosition = InSelectedSplinePosition; }
|
|
|
|
FQuat GetCachedRotation() const { return CachedRotation; }
|
|
void SetCachedRotation(const FQuat& InCachedRotation) { CachedRotation = InCachedRotation; }
|
|
|
|
void Reset();
|
|
void ClearSelectedKeys();
|
|
void ClearSelectedSegmentIndex();
|
|
void ClearSelectedTangentHandle();
|
|
void ClearSelectedAttribute() { SetSelectedAttribute(); }
|
|
|
|
bool IsSplinePointSelected(const int32 InIndex) const;
|
|
|
|
protected:
|
|
/** Property path from the parent actor to the component */
|
|
UPROPERTY()
|
|
FComponentPropertyPath SplinePropertyPath;
|
|
|
|
/** Indices of keys we have selected */
|
|
UPROPERTY()
|
|
TSet<int32> SelectedKeys;
|
|
|
|
/** Index of the last key we selected */
|
|
UPROPERTY()
|
|
int32 LastKeyIndexSelected = INDEX_NONE;
|
|
|
|
/** Index of segment we have selected */
|
|
UPROPERTY()
|
|
int32 SelectedSegmentIndex = INDEX_NONE;
|
|
|
|
/** Index of tangent handle we have selected */
|
|
UPROPERTY()
|
|
int32 SelectedTangentHandle = INDEX_NONE;
|
|
|
|
/** The type of the selected tangent handle */
|
|
UPROPERTY()
|
|
ESelectedTangentHandle SelectedTangentHandleType = ESelectedTangentHandle::None;
|
|
|
|
/** Index of attribute handle we have selected */
|
|
UPROPERTY()
|
|
int32 SelectedAttributeIndex = INDEX_NONE;
|
|
|
|
UPROPERTY()
|
|
FName SelectedAttributeName = NAME_None;
|
|
|
|
/** Position on spline we have selected */
|
|
UPROPERTY()
|
|
FVector SelectedSplinePosition;
|
|
|
|
/** Cached rotation for this point */
|
|
UPROPERTY()
|
|
FQuat CachedRotation;
|
|
};
|
|
|
|
/** Base class for clickable spline editing proxies */
|
|
struct HSplineVisProxy : public HComponentVisProxy
|
|
{
|
|
DECLARE_HIT_PROXY();
|
|
|
|
HSplineVisProxy(const UActorComponent* InComponent)
|
|
: HComponentVisProxy(InComponent, HPP_Wireframe)
|
|
{}
|
|
|
|
virtual EMouseCursor::Type GetMouseCursor() override
|
|
{
|
|
return EMouseCursor::CardinalCross;
|
|
}
|
|
};
|
|
|
|
/** Proxy for a spline key */
|
|
struct HSplineKeyProxy : public HSplineVisProxy
|
|
{
|
|
DECLARE_HIT_PROXY();
|
|
|
|
HSplineKeyProxy(const UActorComponent* InComponent, int32 InKeyIndex)
|
|
: HSplineVisProxy(InComponent)
|
|
, KeyIndex(InKeyIndex)
|
|
{}
|
|
|
|
int32 KeyIndex;
|
|
|
|
virtual EMouseCursor::Type GetMouseCursor() override
|
|
{
|
|
return EMouseCursor::CardinalCross;
|
|
}
|
|
};
|
|
|
|
/** Proxy for spline attribute key (as opposed to a positional control point) */
|
|
struct HSplineAttributeKeyProxy : public HSplineVisProxy
|
|
{
|
|
DECLARE_HIT_PROXY();
|
|
|
|
HSplineAttributeKeyProxy(const UActorComponent* InComponent, int32 InKeyIndex)
|
|
: HSplineVisProxy(InComponent)
|
|
, KeyIndex(InKeyIndex)
|
|
{}
|
|
|
|
int32 KeyIndex;
|
|
|
|
virtual EMouseCursor::Type GetMouseCursor() override
|
|
{
|
|
return EMouseCursor::CardinalCross;
|
|
}
|
|
};
|
|
|
|
/** Proxy for a spline segment */
|
|
struct HSplineSegmentProxy : public HSplineVisProxy
|
|
{
|
|
DECLARE_HIT_PROXY();
|
|
|
|
HSplineSegmentProxy(const UActorComponent* InComponent, int32 InSegmentIndex)
|
|
: HSplineVisProxy(InComponent)
|
|
, SegmentIndex(InSegmentIndex)
|
|
{}
|
|
|
|
int32 SegmentIndex;
|
|
|
|
virtual EMouseCursor::Type GetMouseCursor() override
|
|
{
|
|
return EMouseCursor::CardinalCross;
|
|
}
|
|
};
|
|
|
|
/** Proxy for a tangent handle */
|
|
struct HSplineTangentHandleProxy : public HSplineVisProxy
|
|
{
|
|
DECLARE_HIT_PROXY();
|
|
|
|
HSplineTangentHandleProxy(const UActorComponent* InComponent, int32 InKeyIndex, bool bInArriveTangent)
|
|
: HSplineVisProxy(InComponent)
|
|
, KeyIndex(InKeyIndex)
|
|
, bArriveTangent(bInArriveTangent)
|
|
{}
|
|
|
|
int32 KeyIndex;
|
|
bool bArriveTangent;
|
|
|
|
virtual EMouseCursor::Type GetMouseCursor() override
|
|
{
|
|
return EMouseCursor::CardinalCross;
|
|
}
|
|
};
|
|
|
|
/** Accepted modes for snapping points. */
|
|
enum class ESplineComponentSnapMode
|
|
{
|
|
Snap,
|
|
AlignToTangent,
|
|
AlignPerpendicularToTangent
|
|
};
|
|
|
|
/** SplineComponent visualizer/edit functionality */
|
|
class COMPONENTVISUALIZERS_API FSplineComponentVisualizer : public FComponentVisualizer, public FGCObject
|
|
{
|
|
public:
|
|
FSplineComponentVisualizer();
|
|
virtual ~FSplineComponentVisualizer();
|
|
|
|
//~ Begin FComponentVisualizer Interface
|
|
virtual void OnRegister() override;
|
|
virtual bool ShouldShowForSelectedSubcomponents(const UActorComponent* Component) override;
|
|
virtual void DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI) override;
|
|
virtual bool VisProxyHandleClick(FEditorViewportClient* InViewportClient, HComponentVisProxy* VisProxy, const FViewportClick& Click) override;
|
|
/** Draw HUD on viewport for the supplied component */
|
|
virtual void DrawVisualizationHUD(const UActorComponent* Component, const FViewport* Viewport, const FSceneView* View, FCanvas* Canvas) override;
|
|
virtual void EndEditing() override;
|
|
virtual bool GetWidgetLocation(const FEditorViewportClient* ViewportClient, FVector& OutLocation) const override;
|
|
virtual bool GetCustomInputCoordinateSystem(const FEditorViewportClient* ViewportClient, FMatrix& OutMatrix) const override;
|
|
virtual bool HandleInputDelta(FEditorViewportClient* ViewportClient, FViewport* Viewport, FVector& DeltaTranslate, FRotator& DeltaRotate, FVector& DeltaScale) override;
|
|
virtual bool HandleInputKey(FEditorViewportClient* ViewportClient, FViewport* Viewport, FKey Key, EInputEvent Event) override;
|
|
/** Handle click modified by Alt, Ctrl and/or Shift. The input HitProxy may not be on this component. */
|
|
virtual bool HandleModifiedClick(FEditorViewportClient* InViewportClient, HHitProxy* HitProxy, const FViewportClick& Click) override;
|
|
/** Handle box select input */
|
|
virtual bool HandleBoxSelect(const FBox& InBox, FEditorViewportClient* InViewportClient, FViewport* InViewport) override;
|
|
/** Handle frustum select input */
|
|
virtual bool HandleFrustumSelect(const FConvexVolume& InFrustum, FEditorViewportClient* InViewportClient, FViewport* InViewport) override;
|
|
/** Return whether focus on selection should focus on bounding box defined by active visualizer */
|
|
virtual bool HasFocusOnSelectionBoundingBox(FBox& OutBoundingBox) override;
|
|
/** Pass snap input to active visualizer */
|
|
virtual bool HandleSnapTo(const bool bInAlign, const bool bInUseLineTrace, const bool bInUseBounds, const bool bInUsePivot, AActor* InDestination) override;
|
|
/** Gets called when the mouse tracking has stopped (dragging behavior) */
|
|
virtual void TrackingStopped(FEditorViewportClient* InViewportClient, bool bInDidMove) override;
|
|
/** Get currently edited component, this is needed to reset the active visualizer after undo/redo */
|
|
virtual UActorComponent* GetEditedComponent() const override;
|
|
virtual TSharedPtr<SWidget> GenerateContextMenu() const override;
|
|
virtual bool IsVisualizingArchetype() const override;
|
|
//~ End FComponentVisualizer Interface
|
|
|
|
/** Add menu sections to the context menu */
|
|
virtual void GenerateContextMenuSections(FMenuBuilder& InMenuBuilder) const;
|
|
|
|
/** Get the spline component we are currently editing */
|
|
USplineComponent* GetEditedSplineComponent() const;
|
|
|
|
const TSet<int32>& GetSelectedKeys() const { check(SelectionState); return SelectionState->GetSelectedKeys(); }
|
|
|
|
/** Select first or last spline point, returns true if the spline component being edited has changed */
|
|
bool HandleSelectFirstLastSplinePoint(USplineComponent* InSplineComponent, bool bFirstPoint);
|
|
|
|
/** Select all spline points, , returns true if the spline component being edited has changed */
|
|
bool HandleSelectAllSplinePoints(USplineComponent* InSplineComponent);
|
|
|
|
/** Select next or prev spline point, loops when last point is currently selected */
|
|
void OnSelectPrevNextSplinePoint(bool bNextPoint, bool bAddToSelection);
|
|
|
|
/** Sets the new cached rotation on the visualizer */
|
|
void SetCachedRotation(const FQuat& NewRotation);
|
|
protected:
|
|
|
|
/** Determine if any selected key index is out of range (perhaps because something external has modified the spline) */
|
|
bool IsAnySelectedKeyIndexOutOfRange(const USplineComponent* Comp) const;
|
|
|
|
/** Whether a single spline key is currently selected */
|
|
bool IsSingleKeySelected() const;
|
|
|
|
/** Whether a multiple spline keys are currently selected */
|
|
bool AreMultipleKeysSelected() const;
|
|
|
|
/** Whether any keys are currently selected */
|
|
bool AreKeysSelected() const;
|
|
|
|
/** Select spline point at specified index */
|
|
void SelectSplinePoint(int32 SelectIndex, bool bAddToSelection);
|
|
|
|
/** Transforms selected tangent by given translation */
|
|
bool TransformSelectedTangent(EPropertyChangeType::Type InPropertyChangeType, const FVector& InDeltaTranslate);
|
|
|
|
/** Transforms selected tangent by given translate, rotate and scale */
|
|
bool TransformSelectedKeys(EPropertyChangeType::Type InPropertyChangeType, const FVector& InDeltaTranslate, const FRotator& InDeltaRotate = FRotator::ZeroRotator, const FVector& InDeltaScale = FVector::ZeroVector);
|
|
|
|
/** Transforms selected attribute by given translation */
|
|
bool TransformSelectedAttribute(EPropertyChangeType::Type InPropertyChangeType, const FVector& InDeltaTranslate);
|
|
|
|
/** Update the key selection state of the visualizer */
|
|
virtual void ChangeSelectionState(int32 Index, bool bIsCtrlHeld);
|
|
|
|
/** Alt-drag: duplicates the selected spline key */
|
|
virtual bool DuplicateKeyForAltDrag(const FVector& InDrag);
|
|
|
|
/** Alt-drag: updates duplicated selected spline key */
|
|
virtual bool UpdateDuplicateKeyForAltDrag(const FVector& InDrag);
|
|
|
|
/** Return spline data for point on spline closest to input point */
|
|
virtual float FindNearest(const FVector& InLocalPos, int32 InSegmentStartIndex, FVector& OutSplinePos, FVector& OutSplineTangent) const;
|
|
|
|
/** Split segment using given world position */
|
|
virtual void SplitSegment(const FVector& InWorldPos, int32 InSegmentIndex, bool bCopyFromSegmentBeginIndex = true);
|
|
|
|
/** Update split segment based on drag offset */
|
|
virtual void UpdateSplitSegment(const FVector& InDrag);
|
|
|
|
/** Add segment to beginning or end of spline */
|
|
virtual void AddSegment(const FVector& InWorldPos, bool bAppend);
|
|
|
|
/** Add segment to beginning or end of spline */
|
|
virtual void UpdateAddSegment(const FVector& InWorldPos);
|
|
|
|
/** Alt-drag: duplicates the selected spline key */
|
|
virtual void ResetAllowDuplication();
|
|
|
|
/** Snapping: snap keys to axis position of last selected key */
|
|
virtual void SnapKeysToLastSelectedAxisPosition(const EAxis::Type InAxis, TArray<int32> InSnapKeys);
|
|
|
|
/** Snapping: snap key to selected actor */
|
|
virtual void SnapKeyToActor(const AActor* InActor, const ESplineComponentSnapMode SnapMode);
|
|
|
|
/** Snapping: generic method for snapping selected keys to given transform */
|
|
virtual void SnapKeyToTransform(const ESplineComponentSnapMode InSnapMode,
|
|
const FVector& InWorldPos,
|
|
const FVector& InWorldUpVector,
|
|
const FVector& InWorldForwardVector,
|
|
const FVector& InScale,
|
|
const USplineMetadata* InCopySplineMetadata = nullptr,
|
|
const int32 InCopySplineMetadataKey = 0);
|
|
|
|
/** Snapping: set snap to actor temporary mode */
|
|
virtual void SetSnapToActorMode(const bool bInIsSnappingToActor, const ESplineComponentSnapMode InSnapMode = ESplineComponentSnapMode::Snap);
|
|
|
|
/** Snapping: get snap to actor temporary mode */
|
|
virtual bool GetSnapToActorMode(ESplineComponentSnapMode& OutSnapMode) const;
|
|
|
|
/** Reset temporary modes after inputs are handled. */
|
|
virtual void ResetTempModes();
|
|
|
|
/** Updates the component and selected properties if the component has changed */
|
|
const USplineComponent* UpdateSelectedSplineComponent(HComponentVisProxy* VisProxy);
|
|
|
|
void OnDeleteKey();
|
|
bool CanDeleteKey() const;
|
|
|
|
/** Duplicates selected spline keys in place */
|
|
void OnDuplicateKey();
|
|
bool IsKeySelectionValid() const;
|
|
|
|
void OnAddKeyToSegment();
|
|
bool CanAddKeyToSegment() const;
|
|
|
|
void OnSnapKeyToNearestSplinePoint(ESplineComponentSnapMode InSnapMode);
|
|
|
|
void OnSnapKeyToActor(const ESplineComponentSnapMode InSnapMode);
|
|
|
|
void OnSnapAllToAxis(EAxis::Type InAxis);
|
|
|
|
void OnSnapSelectedToAxis(EAxis::Type InAxis);
|
|
|
|
void OnStraightenKey(int32 Direction);
|
|
void StraightenKey(int32 KeyToStraighten, int32 KeyToStraightenToward);
|
|
|
|
void OnToggleSnapTangentAdjustment();
|
|
bool IsSnapTangentAdjustment() const;
|
|
|
|
void OnLockAxis(EAxis::Type InAxis);
|
|
bool IsLockAxisSet(EAxis::Type InAxis) const;
|
|
|
|
void OnResetToAutomaticTangent(EInterpCurveMode Mode);
|
|
bool CanResetToAutomaticTangent(EInterpCurveMode Mode) const;
|
|
|
|
void OnSetKeyType(EInterpCurveMode Mode);
|
|
bool IsKeyTypeSet(EInterpCurveMode Mode) const;
|
|
|
|
void OnSetVisualizeRollAndScale();
|
|
bool IsVisualizingRollAndScale() const;
|
|
|
|
void OnSetDiscontinuousSpline();
|
|
bool IsDiscontinuousSpline() const;
|
|
|
|
void OnToggleClosedLoop();
|
|
bool IsClosedLoop() const;
|
|
|
|
void OnResetToDefault();
|
|
bool CanResetToDefault() const;
|
|
|
|
void OnAddAttributeKey();
|
|
bool CanAddAttributeKey() const;
|
|
|
|
void OnDeleteAttributeKey();
|
|
bool CanDeleteAttributeKey() const;
|
|
|
|
/** Select first or last spline point */
|
|
void OnSelectFirstLastSplinePoint(bool bFirstPoint);
|
|
|
|
/** Select all spline points, if no spline points selected yet the currently edited spline component will be set as well */
|
|
void OnSelectAllSplinePoints();
|
|
|
|
bool CanSelectSplinePoints() const;
|
|
|
|
/** Generate the submenu containing available selection actions */
|
|
void GenerateSelectSplinePointsSubMenu(FMenuBuilder& MenuBuilder) const;
|
|
|
|
/** Generate the submenu containing the available point types */
|
|
void GenerateSplinePointTypeSubMenu(FMenuBuilder& MenuBuilder) const;
|
|
|
|
/** Generate the submenu containing the available auto tangent types */
|
|
void GenerateTangentTypeSubMenu(FMenuBuilder& MenuBuilder) const;
|
|
|
|
/** Generate the submenu containing the available snap/align actions */
|
|
void GenerateSnapAlignSubMenu(FMenuBuilder& MenuBuilder) const;
|
|
|
|
/** Generate the submenu containing the lock axis types */
|
|
void GenerateLockAxisSubMenu(FMenuBuilder& MenuBuilder) const;
|
|
|
|
/** Extends the provided MenuBuilder with an Attribute section */
|
|
void GenerateAttributeMenuSection(FMenuBuilder& InMenuBuilder) const;
|
|
|
|
/** Generate the channel creator/selector widget. */
|
|
TSharedPtr<SWidget> GenerateChannelWidget() const;
|
|
TSharedPtr<SWidget> GenerateChannelCreatorWidget() const;
|
|
TSharedPtr<SWidget> GenerateChannelSelectorWidget() const;
|
|
|
|
/** Generate the attribute editor widget. */
|
|
TSharedPtr<SWidget> GenerateAttributeEditorWidget() const;
|
|
|
|
/** Helper function to set edited component we are currently editing */
|
|
void SetEditedSplineComponent(const USplineComponent* InSplineComponent);
|
|
|
|
void CreateSplineGeneratorPanel();
|
|
|
|
void OnDeselectedInEditor(TObjectPtr<USplineComponent> SplineComponent);
|
|
|
|
// FGCObject interface
|
|
virtual void AddReferencedObjects(FReferenceCollector& Collector);
|
|
virtual FString GetReferencerName() const override
|
|
{
|
|
return TEXT("FSplineComponentVisualizer");
|
|
}
|
|
// End of FGCObject interface
|
|
|
|
/** Output log commands */
|
|
TSharedPtr<FUICommandList> SplineComponentVisualizerActions;
|
|
|
|
/** Current selection state */
|
|
TObjectPtr<USplineComponentVisualizerSelectionState> SelectionState;
|
|
|
|
/** Whether we currently allow duplication when dragging */
|
|
bool bAllowDuplication;
|
|
|
|
/** Alt-drag: True when in process of duplicating a spline key. */
|
|
bool bDuplicatingSplineKey;
|
|
|
|
/** Alt-drag: True when in process of adding end segment. */
|
|
bool bUpdatingAddSegment;
|
|
|
|
/** Alt-drag: Delays duplicating control point to accumulate sufficient drag input offset. */
|
|
uint32 DuplicateDelay;
|
|
|
|
/** Alt-drag: Accumulates delayed drag offset. */
|
|
FVector DuplicateDelayAccumulatedDrag;
|
|
|
|
/** Alt-drag: Cached segment parameter for split segment at new control point */
|
|
float DuplicateCacheSplitSegmentParam;
|
|
|
|
/** Axis to fix when adding new spline points. Uses the value of the currently
|
|
selected spline point's X, Y, or Z value when fix is not equal to none. */
|
|
EAxis::Type AddKeyLockedAxis;
|
|
|
|
/** Snap: True when in process of snapping to actor which needs to be Ctrl-Selected. */
|
|
bool bIsSnappingToActor;
|
|
|
|
/** Snap: Snap to actor mode. */
|
|
ESplineComponentSnapMode SnapToActorMode;
|
|
|
|
FProperty* SplineCurvesProperty;
|
|
|
|
FDelegateHandle DeselectedInEditorDelegateHandle;
|
|
|
|
void UpdateSharedAttributeNames() const
|
|
{
|
|
if (const USplineComponent* SplineComp = GetEditedSplineComponent())
|
|
{
|
|
SharedAttributeNames.Empty();
|
|
SharedAttributeNames.Add(MakeShared<FName>(NAME_None));
|
|
Algo::Transform(SplineComp->GetFloatPropertyChannels(), SharedAttributeNames, [](const FName& Name)
|
|
{
|
|
return MakeShared<FName>(Name);
|
|
});
|
|
}
|
|
}
|
|
mutable TArray<TSharedPtr<FName>> SharedAttributeNames;
|
|
|
|
private:
|
|
TSharedPtr<SSplineGeneratorPanel> SplineGeneratorPanel;
|
|
static TWeakPtr<SWindow> WeakExistingWindow;
|
|
};
|