Merge Release-Engine-Staging to Test @ CL# 18240298

[CL 18241953 by Marc Audy in ue5-release-engine-test branch]
This commit is contained in:
Marc Audy
2021-11-18 14:37:34 -05:00
parent 547de96728
commit 0c3be2b6ad
6989 changed files with 134376 additions and 2050697 deletions
@@ -75,9 +75,6 @@
#include "ControlRigLocalVariableDetails.h"
#include "ControlRigInfluenceMapDetails.h"
#include "Animation/AnimSequence.h"
#include "Editor/SControlRigProfilingView.h"
#include "WorkspaceMenuStructure.h"
#include "WorkspaceMenuStructureModule.h"
#include "Subsystems/AssetEditorSubsystem.h"
#include "ControlRigParameterTrackEditor.h"
#include "ActorFactories/ActorFactorySkeletalMesh.h"
@@ -116,15 +113,11 @@
#include "AssetTypeActions_ControlRigPose.h"
#include "ControlRigBlueprintFactory.h"
#include "ControlRigPythonLogDetails.h"
#include "EditMode/SControlRigBaseListWidget.h"
#include "EditMode/SControlRigTweenWidget.h"
#include "EditMode/SControlRigSnapper.h"
#include "Dialogs/CustomDialog.h"
#include "Sequencer/MovieSceneControlRigSpaceChannel.h"
#include "SequencerChannelInterface.h"
#include "Framework/Notifications/NotificationManager.h"
#include "Widgets/Notifications/SNotificationList.h"
#include "Tools/SMotionTrailOptions.h"
#include "ICurveEditorModule.h"
#include "Channels/SCurveEditorKeyBarView.h"
#include "ControlRigSpaceChannelCurveModel.h"
@@ -134,57 +127,6 @@
DEFINE_LOG_CATEGORY(LogControlRigEditor);
const FName IControlRigEditorModule::ControlRigPoseTab = FName("ControlRigPoseTab");
const FName IControlRigEditorModule::ControlRigTweenTab = FName("ControlRigTweenTab");
const FName IControlRigEditorModule::ControlRigSnapperTab = FName("ControlRigSnapperTab");
const FName IControlRigEditorModule::ControlRigMotionTrailTab = FName("ControlRigMotionTrailTab");
TSharedRef<SDockTab> SpawnRigProfiler( const FSpawnTabArgs& Args )
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SControlRigProfilingView)
];
}
TSharedRef<SDockTab> SpawnPoseTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SControlRigBaseListWidget)
];
}
TSharedRef<SDockTab> SpawnTweenTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SControlRigTweenWidget)
];
}
TSharedRef<SDockTab> SpawnSnapperTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SControlRigSnapper)
];
}
TSharedRef<SDockTab> SpawnMotionTrailTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SMotionTrailOptions)
];
}
void FControlRigEditorModule::StartupModule()
{
@@ -285,45 +227,6 @@ void FControlRigEditorModule::StartupModule()
ReconstructAllNodesDelegateHandle = FBlueprintEditorUtils::OnReconstructAllNodesEvent.AddStatic(&FControlRigBlueprintUtils::HandleReconstructAllNodes);
RefreshAllNodesDelegateHandle = FBlueprintEditorUtils::OnRefreshAllNodesEvent.AddStatic(&FControlRigBlueprintUtils::HandleRefreshAllNodes);
#if WITH_EDITOR
if (FSlateApplication::IsInitialized())
{
FGlobalTabmanager::Get()->RegisterNomadTabSpawner("HierarchicalProfiler", FOnSpawnTab::CreateStatic(&SpawnRigProfiler))
.SetDisplayName(NSLOCTEXT("UnrealEditor", "HierarchicalProfilerTab", "Hierarchical Profiler"))
.SetTooltipText(NSLOCTEXT("UnrealEditor", "HierarchicalProfilerTooltip", "Open the Hierarchical Profiler tab."))
.SetGroup(WorkspaceMenu::GetMenuStructure().GetDeveloperToolsProfilingCategory())
.SetIcon(FSlateIcon(TEXT("ControlRigEditorStyle"), TEXT("HierarchicalProfiler.TabIcon")));
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(IControlRigEditorModule::ControlRigPoseTab, FOnSpawnTab::CreateStatic(&SpawnPoseTab))
.SetDisplayName(NSLOCTEXT("UnrealEditor", "ControlRigPoseTab", "Control Rig Pose"))
.SetTooltipText(NSLOCTEXT("UnrealEditor", "ControlRigPoseTabTooltip", "Open the Control Rig Pose tab."))
.SetMenuType(ETabSpawnerMenuType::Hidden)
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "FoliageEditMode.Settings"));//MZ todo replace with correct icon
FGlobalTabmanager::Get()->RegisterDefaultTabWindowSize(IControlRigEditorModule::ControlRigPoseTab, FVector2D(850, 800));
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(IControlRigEditorModule::ControlRigTweenTab, FOnSpawnTab::CreateStatic(&SpawnTweenTab))
.SetDisplayName(NSLOCTEXT("UnrealEditor", "ControlRigTweenTab", "Control Rig Tween"))
.SetTooltipText(NSLOCTEXT("UnrealEditor", "ControlRigTweenTooltip", "Open the Control Rig Tween tab."))
.SetMenuType(ETabSpawnerMenuType::Hidden)
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "SkeletonTree.BlendProfile")); //MZ todo replace with correct icon
FGlobalTabmanager::Get()->RegisterDefaultTabWindowSize(IControlRigEditorModule::ControlRigTweenTab, FVector2D(400, 100));
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(IControlRigEditorModule::ControlRigSnapperTab, FOnSpawnTab::CreateStatic(&SpawnSnapperTab))
.SetDisplayName(NSLOCTEXT("UnrealEditor", "ControlRigSnapperTab", "Control Rig Snapper"))
.SetTooltipText(NSLOCTEXT("UnrealEditor", "ControlRigSnapperTabTooltip", "Open the Control Rig Snapper tab."))
.SetMenuType(ETabSpawnerMenuType::Hidden)
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "Persona.Tabs.AnimSlotManager"));//MZ todo replace with correct icon SkeletonTree.SkeletonSocket
FGlobalTabmanager::Get()->RegisterDefaultTabWindowSize(IControlRigEditorModule::ControlRigSnapperTab, FVector2D(400, 400));
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(IControlRigEditorModule::ControlRigMotionTrailTab, FOnSpawnTab::CreateStatic(&SpawnMotionTrailTab))
.SetDisplayName(NSLOCTEXT("UnrealEditor", "MotionTrailTab", "Motion Trail"))
.SetTooltipText(NSLOCTEXT("UnrealEditor", "MotionTrailTabTooltip", "Open the Motion Trail tab."))
.SetMenuType(ETabSpawnerMenuType::Hidden)
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "Persona.Tabs.AnimSlotManager"));//MZ todo replace with correct icon SkeletonTree.SkeletonSocket
FGlobalTabmanager::Get()->RegisterDefaultTabWindowSize(IControlRigEditorModule::ControlRigMotionTrailTab, FVector2D(425, 575));
};
#endif
ICurveEditorModule& CurveEditorModule = FModuleManager::LoadModuleChecked<ICurveEditorModule>("CurveEditor");
FControlRigSpaceChannelCurveModel::ViewID = CurveEditorModule.RegisterView(FOnCreateCurveEditorView::CreateStatic(
[](TWeakPtr<FCurveEditor> WeakCurveEditor) -> TSharedRef<SCurveEditorView>
@@ -355,17 +258,6 @@ void FControlRigEditorModule::ShutdownModule()
CurveEditorModule->UnregisterView(FControlRigSpaceChannelCurveModel::ViewID);
}
#if WITH_EDITOR
if (FSlateApplication::IsInitialized())
{
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner("ControlRigProfiler");
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(IControlRigEditorModule::ControlRigPoseTab);
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(IControlRigEditorModule::ControlRigTweenTab);
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(IControlRigEditorModule::ControlRigSnapperTab);
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(IControlRigEditorModule::ControlRigMotionTrailTab);
}
#endif
//UThumbnailManager::Get().UnregisterCustomRenderer(UControlRigBlueprint::StaticClass());
//UActorFactorySkeletalMesh::UnregisterDelegatesForAssetClass(UControlRigBlueprint::StaticClass());
@@ -1026,7 +1026,7 @@ bool FRigTransformElementDetails::IsCurrentLocalEnabled() const
return true;
}
void FRigControlElementDetails_SetupBoolValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigControlElement* InControlElement, URigHierarchy* InHierarchy)
void FRigControlElementDetails_SetupBoolValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigElementKey& InKey, URigHierarchy* InHierarchy)
{
UEnum* ControlTypeEnum = StaticEnum<ERigControlType>();
UEnum* ValueTypeEnum = StaticEnum<ERigControlValueType>();
@@ -1034,7 +1034,6 @@ void FRigControlElementDetails_SetupBoolValueWidget(IDetailCategoryBuilder& InCa
const FString ValueTypeName = ValueTypeEnum->GetDisplayNameTextByValue((int64)InValueType).ToString();
const FText PropertyLabel = FText::FromString(FString::Printf(TEXT("%s Value"), *ValueTypeName));
TWeakObjectPtr<URigHierarchy> HierarchyPtr = InHierarchy;
const FRigElementKey Key = InControlElement->GetKey();
InCategory.AddCustomRow(PropertyLabel)
.NameContent()
@@ -1049,11 +1048,11 @@ void FRigControlElementDetails_SetupBoolValueWidget(IDetailCategoryBuilder& InCa
+ SVerticalBox::Slot()
[
SNew(SCheckBox)
.IsChecked_Lambda([HierarchyPtr, Key, InValueType]() -> ECheckBoxState
.IsChecked_Lambda([HierarchyPtr, InKey, InValueType]() -> ECheckBoxState
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
bool Value = HierarchyPtr->GetControlValue(ControlElement, InValueType).Get<bool>();
return Value ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
@@ -1061,11 +1060,11 @@ void FRigControlElementDetails_SetupBoolValueWidget(IDetailCategoryBuilder& InCa
}
return ECheckBoxState::Unchecked;
})
.OnCheckStateChanged_Lambda([HierarchyPtr, Key, InValueType](ECheckBoxState NewState)
.OnCheckStateChanged_Lambda([HierarchyPtr, InKey, InValueType](ECheckBoxState NewState)
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
const FRigControlValue Value = FRigControlValue::Make<bool>(NewState == ECheckBoxState::Checked);
HierarchyPtr->SetControlValue(ControlElement->GetKey(), Value, InValueType, true);
@@ -1081,11 +1080,11 @@ void FRigControlElementDetails_SetupBoolValueWidget(IDetailCategoryBuilder& InCa
})
]
]
.IsEnabled(TAttribute<bool>::Create(TAttribute<bool>::FGetter::CreateLambda([HierarchyPtr, Key, InValueType]()->bool
.IsEnabled(TAttribute<bool>::Create(TAttribute<bool>::FGetter::CreateLambda([HierarchyPtr, InKey, InValueType]()->bool
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return ControlElement->Settings.IsValueTypeEnabled(InValueType);
}
@@ -1094,21 +1093,26 @@ void FRigControlElementDetails_SetupBoolValueWidget(IDetailCategoryBuilder& InCa
})));
}
void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigControlElement* InControlElement, URigHierarchy* InHierarchy)
void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigElementKey& InKey, URigHierarchy* InHierarchy)
{
FRigControlElement* ControlElement = InHierarchy->Find<FRigControlElement>(InKey);
if(ControlElement == nullptr)
{
return;
}
UEnum* ControlTypeEnum = StaticEnum<ERigControlType>();
UEnum* ValueTypeEnum = StaticEnum<ERigControlValueType>();
const FString ValueTypeName = ValueTypeEnum->GetDisplayNameTextByValue((int64)InValueType).ToString();
const FText PropertyLabel = FText::FromString(FString::Printf(TEXT("%s Value"), *ValueTypeName));
TWeakObjectPtr<URigHierarchy> HierarchyPtr = InHierarchy;
const FRigElementKey Key = InControlElement->GetKey();
const TAttribute<bool> EnabledAttribute = TAttribute<bool>::Create(TAttribute<bool>::FGetter::CreateLambda([HierarchyPtr, Key, InValueType]()->bool
const TAttribute<bool> EnabledAttribute = TAttribute<bool>::Create(TAttribute<bool>::FGetter::CreateLambda([HierarchyPtr, InKey, InValueType]()->bool
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return ControlElement->Settings.IsValueTypeEnabled(InValueType);
}
@@ -1121,7 +1125,7 @@ void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& I
return EnabledAttribute.Get() ? EVisibility::Visible : EVisibility::Hidden;
}));
if (InControlElement->Settings.ControlEnum)
if (ControlElement->Settings.ControlEnum)
{
InCategory.AddCustomRow(PropertyLabel)
.Visibility(VisibilityAttribute)
@@ -1138,23 +1142,23 @@ void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& I
SNew(SVerticalBox)
+ SVerticalBox::Slot()
[
SNew(SEnumComboBox, InControlElement->Settings.ControlEnum)
.CurrentValue_Lambda([HierarchyPtr, Key, InValueType]() -> int32
SNew(SEnumComboBox, ControlElement->Settings.ControlEnum)
.CurrentValue_Lambda([HierarchyPtr, InKey, InValueType]() -> int32
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return HierarchyPtr->GetControlValue(ControlElement, InValueType).Get<int32>();
}
}
return 0;
})
.OnEnumSelectionChanged_Lambda([HierarchyPtr, Key, InValueType](int32 NewSelection, ESelectInfo::Type)
.OnEnumSelectionChanged_Lambda([HierarchyPtr, InKey, InValueType](int32 NewSelection, ESelectInfo::Type)
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
const FRigControlValue Value = FRigControlValue::Make<int32>(NewSelection);
HierarchyPtr->SetControlValue(ControlElement->GetKey(), Value, InValueType, true);
@@ -1193,13 +1197,13 @@ void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& I
SNew(SNumericEntryBox<int32>)
.Font(FEditorStyle::GetFontStyle(TEXT("MenuItem.Font")))
.AllowSpin(InValueType == ERigControlValueType::Current || InValueType == ERigControlValueType::Initial)
.MinSliderValue_Lambda([HierarchyPtr, Key, InValueType]() -> TOptional<int32>
.MinSliderValue_Lambda([HierarchyPtr, InKey, InValueType]() -> TOptional<int32>
{
if(InValueType == ERigControlValueType::Current || InValueType == ERigControlValueType::Initial)
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return ControlElement->Settings.MinimumValue.Get<int32>();
}
@@ -1207,13 +1211,13 @@ void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& I
}
return TOptional<int32>();
})
.MaxSliderValue_Lambda([HierarchyPtr, Key, InValueType]() -> TOptional<int32>
.MaxSliderValue_Lambda([HierarchyPtr, InKey, InValueType]() -> TOptional<int32>
{
if(InValueType == ERigControlValueType::Current || InValueType == ERigControlValueType::Initial)
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return ControlElement->Settings.MaximumValue.Get<int32>();
}
@@ -1221,24 +1225,24 @@ void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& I
}
return TOptional<int32>();
})
.Value_Lambda([HierarchyPtr, Key, InValueType]() -> int32
.Value_Lambda([HierarchyPtr, InKey, InValueType]() -> int32
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return HierarchyPtr->GetControlValue(ControlElement, InValueType).Get<int32>();
}
}
return 0;
})
.OnValueChanged_Lambda([HierarchyPtr, Key, InValueType](TOptional<int32> InNewSelection)
.OnValueChanged_Lambda([HierarchyPtr, InKey, InValueType](TOptional<int32> InNewSelection)
{
if(InNewSelection.IsSet())
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
const FRigControlValue Value = FRigControlValue::Make<int32>(InNewSelection.GetValue());
HierarchyPtr->SetControlValue(ControlElement->GetKey(), Value, InValueType, true);
@@ -1259,7 +1263,7 @@ void FRigControlElementDetails_SetupIntegerValueWidget(IDetailCategoryBuilder& I
}
}
void FRigControlElementDetails_SetupFloatValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigControlElement* InControlElement, URigHierarchy* InHierarchy)
void FRigControlElementDetails_SetupFloatValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigElementKey& InKey, URigHierarchy* InHierarchy)
{
UEnum* ControlTypeEnum = StaticEnum<ERigControlType>();
UEnum* ValueTypeEnum = StaticEnum<ERigControlValueType>();
@@ -1267,13 +1271,12 @@ void FRigControlElementDetails_SetupFloatValueWidget(IDetailCategoryBuilder& InC
const FString ValueTypeName = ValueTypeEnum->GetDisplayNameTextByValue((int64)InValueType).ToString();
const FText PropertyLabel = FText::FromString(FString::Printf(TEXT("%s Value"), *ValueTypeName));
TWeakObjectPtr<URigHierarchy> HierarchyPtr = InHierarchy;
const FRigElementKey Key = InControlElement->GetKey();
const TAttribute<bool> EnabledAttribute = TAttribute<bool>::Create(TAttribute<bool>::FGetter::CreateLambda([HierarchyPtr, Key, InValueType]()->bool
const TAttribute<bool> EnabledAttribute = TAttribute<bool>::Create(TAttribute<bool>::FGetter::CreateLambda([HierarchyPtr, InKey, InValueType]()->bool
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return ControlElement->Settings.IsValueTypeEnabled(InValueType);
}
@@ -1304,24 +1307,24 @@ void FRigControlElementDetails_SetupFloatValueWidget(IDetailCategoryBuilder& InC
SNew(SNumericEntryBox<float>)
.Font(FEditorStyle::GetFontStyle(TEXT("MenuItem.Font")))
.AllowSpin(InValueType == ERigControlValueType::Current || InValueType == ERigControlValueType::Initial)
.Value_Lambda([HierarchyPtr, Key, InValueType]() -> float
.Value_Lambda([HierarchyPtr, InKey, InValueType]() -> float
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return HierarchyPtr->GetControlValue(ControlElement, InValueType).Get<float>();
}
}
return 0.f;
})
.MinSliderValue_Lambda([HierarchyPtr, Key, InValueType]() -> TOptional<float>
.MinSliderValue_Lambda([HierarchyPtr, InKey, InValueType]() -> TOptional<float>
{
if(InValueType == ERigControlValueType::Current || InValueType == ERigControlValueType::Initial)
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return ControlElement->Settings.MinimumValue.Get<float>();
}
@@ -1329,13 +1332,13 @@ void FRigControlElementDetails_SetupFloatValueWidget(IDetailCategoryBuilder& InC
}
return TOptional<float>();
})
.MaxSliderValue_Lambda([HierarchyPtr, Key, InValueType]() -> TOptional<float>
.MaxSliderValue_Lambda([HierarchyPtr, InKey, InValueType]() -> TOptional<float>
{
if(InValueType == ERigControlValueType::Current || InValueType == ERigControlValueType::Initial)
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
return ControlElement->Settings.MaximumValue.Get<float>();
}
@@ -1343,13 +1346,13 @@ void FRigControlElementDetails_SetupFloatValueWidget(IDetailCategoryBuilder& InC
}
return TOptional<float>();
})
.OnValueChanged_Lambda([HierarchyPtr, Key, InValueType](TOptional<float> InNewSelection)
.OnValueChanged_Lambda([HierarchyPtr, InKey, InValueType](TOptional<float> InNewSelection)
{
if(InNewSelection.IsSet())
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
const FRigControlValue Value = FRigControlValue::Make<float>(InNewSelection.GetValue());
HierarchyPtr->SetControlValue(ControlElement->GetKey(), Value, InValueType, true);
@@ -1456,7 +1459,7 @@ FRigControlValue FRigControlElementDetails_PackageValue(const FEulerTransform& I
}
template<typename T>
void FRigControlElementDetails_SetupStructValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigControlElement* InControlElement, URigHierarchy* InHierarchy)
void FRigControlElementDetails_SetupStructValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigElementKey& InKey, URigHierarchy* InHierarchy)
{
UEnum* ControlTypeEnum = StaticEnum<ERigControlType>();
UEnum* ValueTypeEnum = StaticEnum<ERigControlValueType>();
@@ -1468,13 +1471,12 @@ void FRigControlElementDetails_SetupStructValueWidget(IDetailCategoryBuilder& In
const TSharedPtr<FStructOnScope> StructToDisplay = MakeShareable(new FStructOnScope(ValueStruct));
TWeakObjectPtr<URigHierarchy> HierarchyPtr = InHierarchy;
const FRigElementKey Key = InControlElement->GetKey();
const TAttribute<EVisibility> VisibilityAttribute = TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateLambda([HierarchyPtr, Key, InValueType, StructToDisplay, ValueStruct]()->EVisibility
const TAttribute<EVisibility> VisibilityAttribute = TAttribute<EVisibility>::Create(TAttribute<EVisibility>::FGetter::CreateLambda([HierarchyPtr, InKey, InValueType, StructToDisplay, ValueStruct]()->EVisibility
{
if(HierarchyPtr.IsValid())
{
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(Key))
if(FRigControlElement* ControlElement = HierarchyPtr->Find<FRigControlElement>(InKey))
{
// update the struct with the current control value
uint8* StructMemory = StructToDisplay->GetStructMemory();
@@ -1499,17 +1501,17 @@ void FRigControlElementDetails_SetupStructValueWidget(IDetailCategoryBuilder& In
TSharedPtr<SWidget> NameWidget, ValueWidget;
Row->GetDefaultWidgets(NameWidget, ValueWidget);
const FSimpleDelegate OnStructContentsChangedDelegate = FSimpleDelegate::CreateLambda([HierarchyPtr, Key, StructToDisplay, InValueType]()
const FSimpleDelegate OnStructContentsChangedDelegate = FSimpleDelegate::CreateLambda([HierarchyPtr, InKey, StructToDisplay, InValueType]()
{
if(HierarchyPtr.IsValid())
{
const FRigControlValue ControlValue = FRigControlElementDetails_PackageValue(*(T*)StructToDisplay->GetStructMemory());
HierarchyPtr->SetControlValue(Key, ControlValue, InValueType, true, true);
HierarchyPtr->SetControlValue(InKey, ControlValue, InValueType, true, true);
if(InValueType == ERigControlValueType::Initial)
{
if(UControlRigBlueprint* Blueprint = RigElementDetails_GetBlueprintFromHierarchy(HierarchyPtr.Get()))
{
Blueprint->Hierarchy->SetControlValue(Key, ControlValue, InValueType, true);
Blueprint->Hierarchy->SetControlValue(InKey, ControlValue, InValueType, true);
}
}
}
@@ -1520,9 +1522,15 @@ void FRigControlElementDetails_SetupStructValueWidget(IDetailCategoryBuilder& In
Handle->SetOnChildPropertyValueChanged(OnStructContentsChangedDelegate);
}
void FRigControlElementDetails_SetupValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigControlElement* InControlElement, URigHierarchy* InHierarchy)
void FRigControlElementDetails_SetupValueWidget(IDetailCategoryBuilder& InCategory, const TSharedRef<IPropertyUtilities>& InPropertyUtilities, ERigControlValueType InValueType, const FRigElementKey& InKey, URigHierarchy* InHierarchy)
{
switch(InControlElement->Settings.ControlType)
const FRigControlElement* ControlElement = InHierarchy->Find<FRigControlElement>(InKey);
if(ControlElement == nullptr)
{
return;
}
switch(ControlElement->Settings.ControlType)
{
case ERigControlType::Bool:
{
@@ -1530,48 +1538,48 @@ void FRigControlElementDetails_SetupValueWidget(IDetailCategoryBuilder& InCatego
{
return;
}
FRigControlElementDetails_SetupBoolValueWidget(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupBoolValueWidget(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::Integer:
{
FRigControlElementDetails_SetupIntegerValueWidget(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupIntegerValueWidget(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::Float:
{
FRigControlElementDetails_SetupFloatValueWidget(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupFloatValueWidget(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::Vector2D:
{
FRigControlElementDetails_SetupStructValueWidget<FVector2D>(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupStructValueWidget<FVector2D>(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::Position:
case ERigControlType::Scale:
{
FRigControlElementDetails_SetupStructValueWidget<FVector>(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupStructValueWidget<FVector>(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::Rotator:
{
FRigControlElementDetails_SetupStructValueWidget<FRotator>(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupStructValueWidget<FRotator>(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::TransformNoScale:
{
FRigControlElementDetails_SetupStructValueWidget<FTransformNoScale>(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupStructValueWidget<FTransformNoScale>(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::EulerTransform:
{
FRigControlElementDetails_SetupStructValueWidget<FEulerTransform>(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupStructValueWidget<FEulerTransform>(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
case ERigControlType::Transform:
{
FRigControlElementDetails_SetupStructValueWidget<FTransform>(InCategory, InPropertyUtilities, InValueType, InControlElement, InHierarchy);
FRigControlElementDetails_SetupStructValueWidget<FTransform>(InCategory, InPropertyUtilities, InValueType, InKey, InHierarchy);
break;
}
default:
@@ -1840,6 +1848,12 @@ void FRigControlElementDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBui
ControlCategory.AddProperty(PrimaryAxisHandle.ToSharedRef()).DisplayName(FText::FromString(TEXT("Primary Axis")));
}
if (bNeedsShapeProperties)
{
const TSharedPtr<IPropertyHandle> DrawLimitsHandle = SettingsHandle->GetChildHandle(TEXT("bDrawLimits"));
LimitsCategory.AddProperty(DrawLimitsHandle.ToSharedRef()).DisplayName(FText::FromString(TEXT("Draw Limits")));
}
TArray<FRigControlElement> ControlElements;
TArray<UDetailsViewWrapperObject*> ObjectPerControl;
for(TWeakObjectPtr<UDetailsViewWrapperObject> ObjectBeingCustomized : ObjectsBeingCustomized)
@@ -1857,7 +1871,17 @@ void FRigControlElementDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBui
// only setup value widgets if there is only ony control selected
if(ControlElements.Num() == 1)
{
FRigControlElementDetails_SetupValueWidget(ControlCategory, PropertyUtilities, ERigControlValueType::Current, &ControlElements[0], HierarchyBeingCustomized);
URigHierarchy* HierarchyBeingDebugged = HierarchyBeingCustomized;
if (UControlRig* DebuggedRig = Cast<UControlRig>(BlueprintBeingCustomized->GetObjectBeingDebugged()))
{
if(!DebuggedRig->IsSetupModeEnabled())
{
HierarchyBeingDebugged = DebuggedRig->GetHierarchy();
}
}
FRigControlElementDetails_SetupValueWidget(ControlCategory, PropertyUtilities, ERigControlValueType::Current, ControlElements[0].GetKey(), HierarchyBeingDebugged);
switch (ControlElements[0].Settings.ControlType)
{
@@ -1866,7 +1890,7 @@ void FRigControlElementDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBui
case ERigControlType::Integer:
case ERigControlType::Vector2D:
{
FRigControlElementDetails_SetupValueWidget(ControlCategory, PropertyUtilities, ERigControlValueType::Initial,&ControlElements[0], HierarchyBeingCustomized);
FRigControlElementDetails_SetupValueWidget(ControlCategory, PropertyUtilities, ERigControlValueType::Initial,ControlElements[0].GetKey(), HierarchyBeingCustomized);
break;
}
default:
@@ -1876,8 +1900,8 @@ void FRigControlElementDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBui
}
FRigControlElementDetails_SetupValueWidget(LimitsCategory, PropertyUtilities, ERigControlValueType::Minimum, &ControlElements[0], HierarchyBeingCustomized);
FRigControlElementDetails_SetupValueWidget(LimitsCategory, PropertyUtilities, ERigControlValueType::Maximum, &ControlElements[0], HierarchyBeingCustomized);
FRigControlElementDetails_SetupValueWidget(LimitsCategory, PropertyUtilities, ERigControlValueType::Minimum, ControlElements[0].GetKey(), HierarchyBeingCustomized);
FRigControlElementDetails_SetupValueWidget(LimitsCategory, PropertyUtilities, ERigControlValueType::Maximum, ControlElements[0].GetKey(), HierarchyBeingCustomized);
}
if (bNeedsShapeProperties)
@@ -671,7 +671,7 @@ bool UControlRigSequencerEditorLibrary::BakeToControlRig(UWorld* World, ULevelSe
bResult = MovieSceneToolHelpers::ExportToAnimSequence(TempAnimSequence, ExportOptions, MovieScene, Player, SkeletalMeshComp, Template, RootToLocalTransform);
if (bResult == false)
{
TempAnimSequence->MarkPendingKill();
TempAnimSequence->MarkAsGarbage();
if (OutActor)
{
World->DestroyActor(OutActor);
@@ -710,7 +710,7 @@ bool UControlRigSequencerEditorLibrary::BakeToControlRig(UWorld* World, ULevelSe
UControlRig* ControlRig = NewObject<UControlRig>(Track, InClass, FName(*ObjectName), RF_Transactional);
if (InClass != UFKControlRig::StaticClass() && !ControlRig->SupportsEvent(FRigUnit_InverseExecution::EventName))
{
TempAnimSequence->MarkPendingKill();
TempAnimSequence->MarkAsGarbage();
MovieScene->RemoveTrack(*Track);
if (OutActor)
{
@@ -787,7 +787,7 @@ bool UControlRigSequencerEditorLibrary::BakeToControlRig(UWorld* World, ULevelSe
ControlRigEditMode->SetObjects(ControlRig, nullptr, WeakSequencer.Pin());
}
TempAnimSequence->MarkPendingKill();
TempAnimSequence->MarkAsGarbage();
if (WeakSequencer.IsValid())
{
WeakSequencer.Pin()->ObjectImplicitlyAdded(ControlRig);
@@ -2091,5 +2091,47 @@ void UControlRigSequencerEditorLibrary::SetLocalControlRigTransforms(ULevelSeque
}
}
bool UControlRigSequencerEditorLibrary::ImportFBXToControlRigTrack(UWorld* World, ULevelSequence* Sequence, UMovieSceneControlRigParameterTrack* InTrack, UMovieSceneControlRigParameterSection* InSection,
const TArray<FString>& ControlRigNames,
UMovieSceneUserImportFBXControlRigSettings* ImportFBXControlRigSettings,
const FString& ImportFilename)
{
UMovieScene* MovieScene = Sequence->GetMovieScene();
if (!MovieScene || MovieScene->IsReadOnly() || !InTrack)
{
return false;
}
bool bValid = false;
ALevelSequenceActor* OutActor;
FMovieSceneSequencePlaybackSettings Settings;
FLevelSequenceCameraSettings CameraSettings;
ULevelSequencePlayer* Player = ULevelSequencePlayer::CreateLevelSequencePlayer(World, Sequence, Settings, OutActor);
Player->Initialize(Sequence, World->GetLevel(0), Settings, CameraSettings);
Player->State.AssignSequence(MovieSceneSequenceID::Root, *Sequence, *Player);
INodeAndChannelMappings* ChannelMapping = Cast<INodeAndChannelMappings>(InTrack);
if (ChannelMapping)
{
TArray<FFBXNodeAndChannels>* NodeAndChannels = ChannelMapping->GetNodeAndChannelMappings(InSection);
TArray<FName> SelectedControls;
for (const FString& StringName : ControlRigNames)
{
FName Name(*StringName);
SelectedControls.Add(Name);
}
bValid = MovieSceneToolHelpers::ImportFBXIntoControlRigChannels(MovieScene, ImportFilename, ImportFBXControlRigSettings,
NodeAndChannels, SelectedControls, MovieScene->GetTickResolution());
if (NodeAndChannels)
{
delete NodeAndChannels;
}
}
return bValid;
}
#undef LOCTEXT_NAMESPACE
@@ -67,7 +67,7 @@ void UControlRigThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint3
if (Pair.Value && Pair.Value->GetOuter())
{
Pair.Value->Rename(nullptr, GetTransientPackage());
Pair.Value->MarkPendingKill();
Pair.Value->MarkAsGarbage();
}
}
ShapeActors.Reset();
@@ -750,7 +750,7 @@ void UControlRigDetailPanelControlProxies::RemoveProxy(const FName& Name)
if (ExistingProxy)
{
ExistingProxy->Rename(nullptr, GetTransientPackage(), REN_ForceNoResetLoaders);
ExistingProxy->MarkPendingKill();
ExistingProxy->MarkAsGarbage();
}
AllProxies.Remove(Name);
}
@@ -763,7 +763,7 @@ void UControlRigDetailPanelControlProxies::RemoveAllProxies()
if (ExistingProxy)
{
ExistingProxy->Rename(nullptr, GetTransientPackage(), REN_ForceNoResetLoaders);
ExistingProxy->MarkPendingKill();
ExistingProxy->MarkAsGarbage();
}
}
AllProxies.Empty();
@@ -48,7 +48,7 @@
//#include "Animation/DebugSkelMeshComponent.h"
//#include "Persona/Private/AnimationEditorViewportClient.h"
#include "IPersonaPreviewScene.h"
#include "PersonaSelectionComponent.h"
#include "PersonaSelectionProxies.h"
#include "Framework/Application/SlateApplication.h"
#include "UnrealEdGlobals.h"
#include "Editor/UnrealEdEngine.h"
@@ -303,7 +303,7 @@ void FControlRigEditMode::SetObjects_Internal()
bool FControlRigEditMode::UsesToolkits() const
{
return IsInLevelEditor();
return true;
}
void FControlRigEditMode::Enter()
@@ -1135,10 +1135,37 @@ bool FControlRigEditMode::HandleClick(FEditorViewportClient* InViewportClient, H
return true;
}
}
else if(HPersonaSelectionHitProxy* CapsuleHitProxy = HitProxyCast<HPersonaSelectionHitProxy>(HitProxy))
else if (HPersonaBoneHitProxy* BoneHitProxy = HitProxyCast<HPersonaBoneHitProxy>(HitProxy))
{
static_cast<HPersonaSelectionHitProxy*>(HitProxy)->BroadcastClicked();
return true;
if (UControlRig* DebuggedControlRig = GetControlRig(false))
{
URigHierarchy* Hierarchy = DebuggedControlRig->GetHierarchy();
// Cache mapping?
for (int32 Index = 0; Index < Hierarchy->Num(); Index++)
{
const FRigElementKey ElementToSelect = Hierarchy->GetKey(Index);
if (ElementToSelect.Type == ERigElementType::Bone && ElementToSelect.Name == BoneHitProxy->BoneName)
{
if (FSlateApplication::Get().GetModifierKeys().IsShiftDown())
{
Hierarchy->GetController()->SelectElement(ElementToSelect, true);
}
else if (FSlateApplication::Get().GetModifierKeys().IsControlDown())
{
const bool bSelect = !Hierarchy->IsSelected(ElementToSelect);
Hierarchy->GetController()->SelectElement(ElementToSelect, bSelect);
}
else
{
TArray<FRigElementKey> NewSelection;
NewSelection.Add(ElementToSelect);
Hierarchy->GetController()->SetSelection(NewSelection);
}
return true;
}
}
}
}
// for now we show this menu all the time if body is selected
@@ -1567,7 +1594,7 @@ bool FControlRigEditMode::ShouldDrawWidget() const
bool FControlRigEditMode::IsCompatibleWith(FEditorModeID OtherModeID) const
{
return true;
return OtherModeID == FName(TEXT("EM_SequencerMode"), FNAME_Find) || OtherModeID == FName(TEXT("MotionTrailEditorMode"), FNAME_Find); /*|| OtherModeID == FName(TEXT("EditMode.ControlRigEditor"), FNAME_Find);*/
}
void FControlRigEditMode::AddReferencedObjects( FReferenceCollector& Collector )
@@ -2240,10 +2267,29 @@ void FControlRigEditMode::ResetTransforms(bool bSelectionOnly)
TArray<FRigElementKey> ControlsToReset = SelectedRigElements;
if (!bSelectionOnly)
{
ControlsToReset = ControlRig->GetHierarchy()->GetAllKeys(true, ERigElementType::Control);
TArray<FRigControlElement*> Controls;
ControlRig->GetControlsInOrder(Controls);
ControlsToReset.SetNum(0);
for (const FRigControlElement* Control : Controls)
{
ControlsToReset.Add(Control->GetKey());
}
}
bool bHasNonDefaultParent = false;
TArray<FRigElementKey> Parents;
for (const FRigElementKey& ControlKey : ControlsToReset)
{
FRigElementKey SpaceKey = ControlRig->GetHierarchy()->GetActiveParent(ControlKey);
Parents.Add(SpaceKey);
if (SpaceKey != ControlRig->GetHierarchy()->GetDefaultParentKey())
{
bHasNonDefaultParent = true;
}
}
FScopedTransaction Transaction(LOCTEXT("HierarchyResetTransforms", "Reset Transforms"));
for (const FRigElementKey& ControlToReset : ControlsToReset)
{
if (ControlToReset.Type == ERigElementType::Control)
@@ -2253,9 +2299,17 @@ void FControlRigEditMode::ResetTransforms(bool bSelectionOnly)
{
const FTransform InitialLocalTransform = ControlRig->GetHierarchy()->GetInitialLocalTransform(ControlToReset);
ControlRig->Modify();
if (bHasNonDefaultParent == true) //possibly not at default parent so switch to it
{
ControlRig->GetHierarchy()->SwitchToDefaultParent(ControlElement->GetKey());
}
ControlRig->GetHierarchy()->SetLocalTransform(ControlToReset, InitialLocalTransform);
ControlRig->ControlModified().Broadcast(ControlRig, ControlElement, EControlRigSetKey::DoNotCare);
if (bHasNonDefaultParent == false)
{
ControlRig->ControlModified().Broadcast(ControlRig, ControlElement, EControlRigSetKey::DoNotCare);
}
//@helge not sure what to do if the non-default parent
if (UControlRigBlueprint* Blueprint = Cast<UControlRigBlueprint>(ControlRig->GetClass()->ClassGeneratedBy))
{
Blueprint->Hierarchy->SetLocalTransform(ControlToReset, InitialLocalTransform);
@@ -2263,6 +2317,62 @@ void FControlRigEditMode::ResetTransforms(bool bSelectionOnly)
}
}
}
if (bHasNonDefaultParent == true) //now we have the initial pose setup we need to get the global transforms as specified now then set them in the current parent space
{
ControlRig->Evaluate_AnyThread();
//get global transforms
TArray<FTransform> GlobalTransforms;
for (const FRigElementKey& ControlToReset : ControlsToReset)
{
FRigControlElement* ControlElement = ControlRig->FindControl(ControlToReset.Name);
if (ControlElement && !ControlElement->Settings.bIsTransientControl)
{
FTransform GlobalTransform = ControlRig->GetHierarchy()->GetGlobalTransform(ControlToReset);
GlobalTransforms.Add(GlobalTransform);
}
}
//switch back to original parent space
int32 Index = 0;
for (const FRigElementKey& ControlToReset : ControlsToReset)
{
FRigControlElement* ControlElement = ControlRig->FindControl(ControlToReset.Name);
if (ControlElement && !ControlElement->Settings.bIsTransientControl)
{
ControlRig->GetHierarchy()->SwitchToParent(ControlToReset,Parents[Index]);
++Index;
}
}
//set global transforms in this space // do it twice since ControlsInOrder is not really always in order
for (int32 SetHack = 0; SetHack < 2; ++SetHack)
{
ControlRig->Evaluate_AnyThread();
Index = 0;
for (const FRigElementKey& ControlToReset : ControlsToReset)
{
FRigControlElement* ControlElement = ControlRig->FindControl(ControlToReset.Name);
if (ControlElement && !ControlElement->Settings.bIsTransientControl)
{
ControlRig->GetHierarchy()->SetGlobalTransform(ControlToReset, GlobalTransforms[Index]);
ControlRig->Evaluate_AnyThread();
++Index;
}
}
}
//send notifies
for (const FRigElementKey& ControlToReset : ControlsToReset)
{
FRigControlElement* ControlElement = ControlRig->FindControl(ControlToReset.Name);
if (ControlElement && !ControlElement->Settings.bIsTransientControl)
{
ControlRig->ControlModified().Broadcast(ControlRig, ControlElement, EControlRigSetKey::DoNotCare);
}
}
}
}
}
@@ -23,7 +23,9 @@ class UControlRigEditModeSettings : public UObject
, bOnlySelectRigControls(false)
, bLocalTransformsInEachLocalSpace(true)
, ShapeScale(1.0f)
{}
{
LastInViewportTweenWidgetLocation = FVector2D(EForceInit::ForceInitToZero);
}
// UObject interface
virtual void PreEditChange(FProperty* PropertyAboutToChange) override;
@@ -68,4 +70,7 @@ public:
/** The scale for Gizmos */
UPROPERTY(config, EditAnywhere, AdvancedDisplay, Category = "Animation")
float ShapeScale;
UPROPERTY(config)
FVector2D LastInViewportTweenWidgetLocation;
};
@@ -12,6 +12,14 @@
#include "SControlRigEditModeTools.h"
#include "ControlRigEditMode.h"
#include "Modules/ModuleManager.h"
#include "EditMode/SControlRigBaseListWidget.h"
#include "EditMode/SControlRigTweenWidget.h"
#include "EditMode/SControlRigSnapper.h"
#include "Tools/SMotionTrailOptions.h"
#include "Editor/SControlRigProfilingView.h"
#include "Toolkits/AssetEditorModeUILayer.h"
#include "Widgets/Docking/SDockTab.h"
#include "ControlRigEditModeSettings.h"
#define LOCTEXT_NAMESPACE "FControlRigEditModeToolkit"
@@ -21,8 +29,15 @@ namespace
const TArray<FName> AnimationPaletteNames = { AnimationName };
}
const FName FControlRigEditModeToolkit::PoseTabName = FName(TEXT("PoseTab"));
const FName FControlRigEditModeToolkit::MotionTrailTabName = FName(TEXT("MotionTrailTab"));
const FName FControlRigEditModeToolkit::SnapperTabName = FName(TEXT("SnapperTab"));
const FName FControlRigEditModeToolkit::TweenOverlayName = FName(TEXT("TweenOverlay"));
void FControlRigEditModeToolkit::Init(const TSharedPtr<IToolkitHost>& InitToolkitHost)
{
SAssignNew(ModeTools, SControlRigEditModeTools, SharedThis(this), EditMode, EditMode.GetWorld());
FPropertyEditorModule& PropertyEditorModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
FDetailsViewArgs DetailsViewArgs;
@@ -41,6 +56,15 @@ void FControlRigEditModeToolkit::Init(const TSharedPtr<IToolkitHost>& InitToolki
FModeToolkit::Init(InitToolkitHost);
}
FControlRigEditModeToolkit::~FControlRigEditModeToolkit()
{
if (FSlateApplication::IsInitialized())
{
RemoveAndDestroyTweenOverlay();
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner("ControlRigProfiler");
}
}
void FControlRigEditModeToolkit::GetToolPaletteNames(TArray<FName>& InPaletteName) const
{
@@ -69,6 +93,34 @@ void FControlRigEditModeToolkit::OnToolPaletteChanged(FName PaletteName)
}
void FControlRigEditModeToolkit::TryInvokeToolkitUI(const FName InName)
{
if (InName == MotionTrailTabName)
{
FTabId MotionTrailTabID(MotionTrailTabName);
FGlobalTabmanager::Get()->TryInvokeTab(MotionTrailTabID);
}
if (InName == PoseTabName)
{
TryInvokePoseTab();
}
if (InName == SnapperTabName)
{
TryInvokeSnapperTab();
}
else if (InName == TweenOverlayName)
{
if(TweenWidget)
{
RemoveAndDestroyTweenOverlay();
}
else
{
CreateAndShowTweenOverlay();
}
}
}
FText FControlRigEditModeToolkit::GetActiveToolDisplayName() const
{
return ModeTools->GetActiveToolName();
@@ -80,5 +132,172 @@ FText FControlRigEditModeToolkit::GetActiveToolMessage() const
return ModeTools->GetActiveToolMessage();
}
TSharedRef<SDockTab> SpawnPoseTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
[
SNew(SControlRigBaseListWidget)
];
}
TSharedRef<SDockTab> SpawnSnapperTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
[
SNew(SControlRigSnapper)
];
}
TSharedRef<SDockTab> SpawnMotionTrailTab(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
[
SNew(SMotionTrailOptions)
];
}
TSharedRef<SDockTab> SpawnRigProfiler(const FSpawnTabArgs& Args)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SControlRigProfilingView)
];
}
void FControlRigEditModeToolkit::CreateAndShowTweenOverlay()
{
FVector2D NewTweenWidgetLocation = GetDefault<UControlRigEditModeSettings>()->LastInViewportTweenWidgetLocation;
if (NewTweenWidgetLocation.IsZero())
{
const FVector2D ActiveViewportSize = GetToolkitHost()->GetActiveViewportSize();
NewTweenWidgetLocation.X = ActiveViewportSize.X / 2.0f;
NewTweenWidgetLocation.Y = ActiveViewportSize.Y - 100.0f;
}
UpdateTweenWidgetLocation(NewTweenWidgetLocation);
SAssignNew(TweenWidget, SHorizontalBox)
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
.VAlign(VAlign_Top)
.HAlign(HAlign_Left)
.Padding(TAttribute<FMargin>(this, &FControlRigEditModeToolkit::GetTweenWidgetPadding))
[
SNew(SControlRigTweenWidget)
.InOwningToolkit(SharedThis(this))
];
TryShowTweenOverlay();
}
void FControlRigEditModeToolkit::TryShowTweenOverlay()
{
if (TweenWidget)
{
GetToolkitHost()->AddViewportOverlayWidget(TweenWidget.ToSharedRef());
}
}
void FControlRigEditModeToolkit::RemoveAndDestroyTweenOverlay()
{
TryRemoveTweenOverlay();
if (TweenWidget)
{
TweenWidget.Reset();
}
}
void FControlRigEditModeToolkit::TryRemoveTweenOverlay()
{
if (IsHosted() && TweenWidget)
{
GetToolkitHost()->RemoveViewportOverlayWidget(TweenWidget.ToSharedRef());
}
}
void FControlRigEditModeToolkit::UpdateTweenWidgetLocation(const FVector2D InLocation)
{
const FVector2D ActiveViewportSize = GetToolkitHost()->GetActiveViewportSize();
FVector2D ScreenPos = InLocation;
const float EdgeFactor = 0.97f;
const float MinX = ActiveViewportSize.X * (1 - EdgeFactor);
const float MinY = ActiveViewportSize.Y * (1 - EdgeFactor);
const float MaxX = ActiveViewportSize.X * EdgeFactor;
const float MaxY = ActiveViewportSize.Y * EdgeFactor;
const bool bOutside = ScreenPos.X < MinX || ScreenPos.X > MaxX || ScreenPos.Y < MinY || ScreenPos.Y > MaxY;
if (bOutside)
{
// reset the location if it was placed out of bounds
ScreenPos.X = ActiveViewportSize.X / 2.0f;
ScreenPos.Y = ActiveViewportSize.Y - 100.0f;
}
InViewportTweenWidgetLocation = ScreenPos;
UControlRigEditModeSettings* ControlRigEditModeSettings = GetMutableDefault<UControlRigEditModeSettings>();
ControlRigEditModeSettings->LastInViewportTweenWidgetLocation = ScreenPos;
ControlRigEditModeSettings->SaveConfig();
}
FMargin FControlRigEditModeToolkit::GetTweenWidgetPadding() const
{
return FMargin(InViewportTweenWidgetLocation.X, InViewportTweenWidgetLocation.Y, 0, 0);
}
void FControlRigEditModeToolkit::RequestModeUITabs()
{
FModeToolkit::RequestModeUITabs();
if (ModeUILayer.IsValid())
{
TSharedPtr<FAssetEditorModeUILayer> ModeUILayerPtr = ModeUILayer.Pin();
TSharedRef<FWorkspaceItem> MenuGroup = ModeUILayerPtr->GetModeMenuCategory().ToSharedRef();
FMinorTabConfig PoseTabInfo;
PoseTabInfo.OnSpawnTab = FOnSpawnTab::CreateStatic(&SpawnPoseTab);
PoseTabInfo.TabLabel = LOCTEXT("ControlRigPoseTab", "Control Rig Pose");
PoseTabInfo.TabTooltip = LOCTEXT("ControlRigPoseTabTooltip", "Show Poses.");
ModeUILayerPtr->SetModePanelInfo(UAssetEditorUISubsystem::BottomRightTabID, PoseTabInfo);
FMinorTabConfig SnapperTabInfo;
SnapperTabInfo.OnSpawnTab = FOnSpawnTab::CreateStatic(&SpawnSnapperTab);
SnapperTabInfo.TabLabel = LOCTEXT("ControlRigSnapperTab", "Control Rig Snapper");
SnapperTabInfo.TabTooltip = LOCTEXT("ControlRigSnapperTabTooltip", "Snap child objects to a parent object over a set of frames.");
ModeUILayerPtr->SetModePanelInfo(UAssetEditorUISubsystem::TopRightTabID, SnapperTabInfo);
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(MotionTrailTabName, FOnSpawnTab::CreateStatic(&SpawnMotionTrailTab))
.SetDisplayName(LOCTEXT("MotionTrailTab", "Motion Trail"))
.SetTooltipText(LOCTEXT("MotionTrailTabTooltip", "Display motion trails for animated objects."))
.SetGroup(MenuGroup)
.SetIcon(FSlateIcon(TEXT("ControlRigEditorStyle"), TEXT("HierarchicalProfiler.TabIcon")));
FGlobalTabmanager::Get()->RegisterNomadTabSpawner("HierarchicalProfiler", FOnSpawnTab::CreateStatic(&SpawnRigProfiler))
.SetDisplayName(LOCTEXT("HierarchicalProfilerTab", "Hierarchical Profiler"))
.SetTooltipText(LOCTEXT("HierarchicalProfilerTooltip", "Open the Hierarchical Profiler tab."))
.SetGroup(MenuGroup)
.SetIcon(FSlateIcon(TEXT("ControlRigEditorStyle"), TEXT("HierarchicalProfiler.TabIcon")));
}
};
void FControlRigEditModeToolkit::InvokeUI()
{
FModeToolkit::InvokeUI();
// TODO: any future default tabs will go here
}
void FControlRigEditModeToolkit::TryInvokeSnapperTab()
{
TSharedPtr<FAssetEditorModeUILayer> ModeUILayerPtr = ModeUILayer.Pin();
ModeUILayerPtr->GetTabManager()->TryInvokeTab(UAssetEditorUISubsystem::TopRightTabID);
}
void FControlRigEditModeToolkit::TryInvokePoseTab()
{
TSharedPtr<FAssetEditorModeUILayer> ModeUILayerPtr = ModeUILayer.Pin();
ModeUILayerPtr->GetTabManager()->TryInvokeTab(UAssetEditorUISubsystem::BottomRightTabID);
}
#undef LOCTEXT_NAMESPACE
@@ -14,11 +14,12 @@
class FControlRigEditModeToolkit : public FModeToolkit
{
public:
friend class SControlRigTweenWidget;
FControlRigEditModeToolkit(FControlRigEditMode& InEditMode)
: EditMode(InEditMode)
{
SAssignNew(ModeTools, SControlRigEditModeTools, EditMode, EditMode.GetWorld());
}
/** IToolkit interface */
@@ -35,7 +36,7 @@ public:
return false;
}
virtual void Init(const TSharedPtr<IToolkitHost>& InitToolkitHost) override;
~FControlRigEditModeToolkit();
/** Mode Toolbar Palettes **/
virtual void GetToolPaletteNames(TArray<FName>& InPaletteName) const override;
virtual FText GetToolPaletteDisplayName(FName PaletteName) const override;
@@ -46,10 +47,38 @@ public:
virtual FText GetActiveToolMessage() const override;
virtual void OnToolPaletteChanged(FName PaletteName) override;
void TryInvokeToolkitUI(const FName InName);
public:
static const FName PoseTabName;
static const FName MotionTrailTabName;
static const FName TweenOverlayName;
static const FName SnapperTabName;
protected:
void CreateAndShowTweenOverlay();
void TryShowTweenOverlay();
void RemoveAndDestroyTweenOverlay();
void TryRemoveTweenOverlay();
void UpdateTweenWidgetLocation(const FVector2D InLocation);
FMargin GetTweenWidgetPadding() const;
/* FModeToolkit Interface */
virtual void RequestModeUITabs() override;
virtual void InvokeUI() override;
private:
void TryInvokeSnapperTab();
void TryInvokePoseTab();
private:
/** The edit mode we are bound to */
FControlRigEditMode& EditMode;
TSharedPtr<SWidget> TweenWidget;
FVector2D InViewportTweenWidgetLocation;
/** The tools widget */
TSharedPtr<SControlRigEditModeTools> ModeTools;
};
@@ -248,19 +248,18 @@ public:
SLATE_BEGIN_ARGS(SControlRigPoseAnimSelectionToolbar) {}
SLATE_ARGUMENT(SControlRigBaseListWidget*, OwningControlRigWidget)
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
void MakeControlRigAssetDialog(FControlRigAssetType Type, bool bSelectAll);
bool CanExecuteMakeControlRigAsset();
//void ToggleFilter(FControlRigAssetType Type);
//bool IsOnToggleFilter(FControlRigAssetType Type) const;
//It's parent so will always be there..
SControlRigBaseListWidget* OwningControlRigWidget;
};
@@ -281,7 +280,8 @@ void SControlRigPoseAnimSelectionToolbar::Construct(const FArguments& InArgs)
FToolBarBuilder ToolbarBuilder(TSharedPtr<const FUICommandList>(), FMultiBoxCustomization::None, TSharedPtr<FExtender>(), true);
ToolbarBuilder.SetLabelVisibility(EVisibility::Visible);
FUIAction CreatePoseDialog(
FExecuteAction::CreateRaw(this, &SControlRigPoseAnimSelectionToolbar::MakeControlRigAssetDialog, FControlRigAssetType::ControlRigPose,false));
FExecuteAction::CreateRaw(this, &SControlRigPoseAnimSelectionToolbar::MakeControlRigAssetDialog, FControlRigAssetType::ControlRigPose,false),
FCanExecuteAction::CreateRaw(this, &SControlRigPoseAnimSelectionToolbar::CanExecuteMakeControlRigAsset));
/*
FUIAction CreatePoseFromAllDialog(
FExecuteAction::CreateRaw(this, &SControlRigPoseAnimSelectionToolbar::MakeControlRigAssetDialog, FControlRigAssetType::ControlRigPose,true));
@@ -413,28 +413,33 @@ void SControlRigPoseAnimSelectionToolbar::Construct(const FArguments& InArgs)
void SControlRigPoseAnimSelectionToolbar::MakeControlRigAssetDialog(FControlRigAssetType Type, bool bSelectAll)
{
FControlRigEditMode* ControlRigEditMode = static_cast<FControlRigEditMode*>(GLevelEditorModeTools().GetActiveMode(FControlRigEditMode::ModeName));
if (ControlRigEditMode && ControlRigEditMode->GetControlRig(true))
if (!ControlRigEditMode)
{
UControlRig* ControlRig = ControlRigEditMode->GetControlRig(true);
if (ControlRig)
return;
}
UControlRig* ControlRig = ControlRigEditMode->GetControlRig(true);
if (!ControlRig)
{
return;
}
TArray<FName> SelectedControls = ControlRig->CurrentControlSelection();
if (SelectedControls.Num() <= 0)
{
FText ConfirmDelete = LOCTEXT("ConfirmNoSelectedControls", "You are saving a Pose with no selected Controls - are you sure?");
FSuppressableWarningDialog::FSetupInfo Info(ConfirmDelete, LOCTEXT("SavePose", "Save Pose"), "SavePose_Warning");
Info.ConfirmText = LOCTEXT("SavePose_Yes", "Yes");
Info.CancelText = LOCTEXT("SavePose_No", "No");
FSuppressableWarningDialog SavePose(Info);
if (SavePose.ShowModal() == FSuppressableWarningDialog::Cancel)
{
TArray<FName> SelectedControls = ControlRig->CurrentControlSelection();
if (SelectedControls.Num() <= 0)
{
FText ConfirmDelete = LOCTEXT("ConfirmNoSelectedControls", "You are saving a Pose with no selected Controls - are you sure?");
FSuppressableWarningDialog::FSetupInfo Info(ConfirmDelete, LOCTEXT("SavePose", "Save Pose"), "SavePose_Warning");
Info.ConfirmText = LOCTEXT("SavePose_Yes", "Yes");
Info.CancelText = LOCTEXT("SavePose_No", "No");
FSuppressableWarningDialog SavePose(Info);
if (SavePose.ShowModal() == FSuppressableWarningDialog::Cancel)
{
return;
}
}
return;
}
}
FCreateControlAssetDelegate GetNameCallback = FCreateControlAssetDelegate::CreateLambda([this, Type, bSelectAll](FString AssetName)
{
if (OwningControlRigWidget)
@@ -469,6 +474,23 @@ void SControlRigPoseAnimSelectionToolbar::MakeControlRigAssetDialog(FControlRigA
FCreateControlAssetRigDialog::GetControlAssetParams(Type, GetNameCallback);
}
bool SControlRigPoseAnimSelectionToolbar::CanExecuteMakeControlRigAsset()
{
FControlRigEditMode* ControlRigEditMode = static_cast<FControlRigEditMode*>(GLevelEditorModeTools().GetActiveMode(FControlRigEditMode::ModeName));
if (!ControlRigEditMode)
{
return false;
}
UControlRig* ControlRig = ControlRigEditMode->GetControlRig(true);
if (!ControlRig)
{
return false;
}
return true;
}
/*
void SControlRigPoseAnimSelectionToolbar::ToggleFilter(FControlRigAssetType Type)
{
@@ -25,7 +25,6 @@
#include "Rigs/FKControlRig.h"
#include "SControlRigBaseListWidget.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "SControlRigTweenWidget.h"
#include "IControlRigEditorModule.h"
#include "Framework/Docking/TabManager.h"
#include "ControlRigEditorStyle.h"
@@ -38,6 +37,7 @@
#include "Widgets/Notifications/SNotificationList.h"
#include "Framework/Notifications/NotificationManager.h"
#include "ScopedTransaction.h"
#include "ControlRigEditModeToolkit.h"
#define LOCTEXT_NAMESPACE "ControlRigRootCustomization"
@@ -238,10 +238,10 @@ const URigHierarchy* SControlRigEditModeTools::GetHierarchy() const
return nullptr;
}
void SControlRigEditModeTools::Construct(const FArguments& InArgs, FControlRigEditMode& InEditMode,UWorld* InWorld)
void SControlRigEditModeTools::Construct(const FArguments& InArgs, TSharedPtr<FControlRigEditModeToolkit> InOwningToolkit, FControlRigEditMode& InEditMode,UWorld* InWorld)
{
bIsChangingRigHierarchy = false;
OwningToolkit = InOwningToolkit;
// initialize settings view
FDetailsViewArgs DetailsViewArgs;
{
@@ -896,11 +896,12 @@ void SControlRigEditModeTools::CustomizeToolBarPalette(FToolBarBuilder& ToolBarB
FSlateIcon(TEXT("ControlRigEditorStyle"), TEXT("ControlRig.OnlySelectControls")),
EUserInterfaceActionType::ToggleButton
);
ToolBarBuilder.AddSeparator();
//POSES
ToolBarBuilder.AddToolBarButton(
FExecuteAction::CreateSP(this, &SControlRigEditModeTools::MakePoseDialog),
FExecuteAction::CreateRaw(OwningToolkit.Pin().Get(), &FControlRigEditModeToolkit::TryInvokeToolkitUI, FControlRigEditModeToolkit::PoseTabName),
NAME_None,
LOCTEXT("Poses", "Poses"),
LOCTEXT("PosesTooltip", "Show Poses"),
@@ -911,7 +912,7 @@ void SControlRigEditModeTools::CustomizeToolBarPalette(FToolBarBuilder& ToolBarB
// Tweens
ToolBarBuilder.AddToolBarButton(
FExecuteAction::CreateSP(this, &SControlRigEditModeTools::MakeTweenDialog),
FExecuteAction::CreateRaw(OwningToolkit.Pin().Get(), &FControlRigEditModeToolkit::TryInvokeToolkitUI, FControlRigEditModeToolkit::TweenOverlayName),
NAME_None,
LOCTEXT("Tweens", "Tweens"),
LOCTEXT("TweensTooltip", "Create Tweens"),
@@ -921,7 +922,7 @@ void SControlRigEditModeTools::CustomizeToolBarPalette(FToolBarBuilder& ToolBarB
// Snap
ToolBarBuilder.AddToolBarButton(
FExecuteAction::CreateSP(this, &SControlRigEditModeTools::MakeSnapperDialog),
FExecuteAction::CreateRaw(OwningToolkit.Pin().Get(), &FControlRigEditModeToolkit::TryInvokeToolkitUI, FControlRigEditModeToolkit::SnapperTabName),
NAME_None,
LOCTEXT("Snapper", "Snapper"),
LOCTEXT("SnapperTooltip", "Snap child objects to a parent object over a set of frames"),
@@ -931,13 +932,14 @@ void SControlRigEditModeTools::CustomizeToolBarPalette(FToolBarBuilder& ToolBarB
// Motion Trail
ToolBarBuilder.AddToolBarButton(
FExecuteAction::CreateSP(this, &SControlRigEditModeTools::MakeMotionTrailDialog),
FExecuteAction::CreateRaw(OwningToolkit.Pin().Get(), &FControlRigEditModeToolkit::TryInvokeToolkitUI, FControlRigEditModeToolkit::MotionTrailTabName),
NAME_None,
LOCTEXT("MotionTrails", "Trails"),
LOCTEXT("MotionTrailsTooltip", "Display motion trails for animated objects"),
FSlateIcon(TEXT("ControlRigEditorStyle"), TEXT("ControlRig.EditableMotionTrails")),
EUserInterfaceActionType::Button
);
//Pivot
ToolBarBuilder.AddToolBarButton(
FUIAction(
@@ -967,44 +969,6 @@ void SControlRigEditModeTools::CustomizeToolBarPalette(FToolBarBuilder& ToolBarB
FSlateIcon(TEXT("ControlRigEditorStyle"), TEXT("ControlRig.TemporaryPivot")),
EUserInterfaceActionType::ToggleButton
);
ToolBarBuilder.AddSeparator();
}
void SControlRigEditModeTools::MakePoseDialog()
{
FControlRigEditMode* ControlRigEditMode = static_cast<FControlRigEditMode*>(ModeTools->GetActiveMode(FControlRigEditMode::ModeName));
if (ControlRigEditMode)
{
FGlobalTabmanager::Get()->TryInvokeTab(IControlRigEditorModule::ControlRigPoseTab);
}
}
void SControlRigEditModeTools::MakeTweenDialog()
{
FControlRigEditMode* ControlRigEditMode = static_cast<FControlRigEditMode*>(ModeTools->GetActiveMode(FControlRigEditMode::ModeName));
if (ControlRigEditMode)
{
FGlobalTabmanager::Get()->TryInvokeTab(IControlRigEditorModule::ControlRigTweenTab);
}
}
void SControlRigEditModeTools::MakeSnapperDialog()
{
FControlRigEditMode* ControlRigEditMode = static_cast<FControlRigEditMode*>(ModeTools->GetActiveMode(FControlRigEditMode::ModeName));
if (ControlRigEditMode)
{
FGlobalTabmanager::Get()->TryInvokeTab(IControlRigEditorModule::ControlRigSnapperTab);
}
}
void SControlRigEditModeTools::MakeMotionTrailDialog()
{
FControlRigEditMode* ControlRigEditMode = static_cast<FControlRigEditMode*>(GLevelEditorModeTools().GetActiveMode(FControlRigEditMode::ModeName));
if (ControlRigEditMode)
{
FGlobalTabmanager::Get()->TryInvokeTab(IControlRigEditorModule::ControlRigMotionTrailTab);
}
}
void SControlRigEditModeTools::ToggleEditPivotMode()
@@ -20,6 +20,7 @@ class UControlRig;
class URigHierarchy;
class FToolBarBuilder;
class FEditorModeTools;
class FControlRigEditModeToolkit;
class SControlRigEditModeTools : public SCompoundWidget, public IDetailKeyframeHandler
{
@@ -27,7 +28,7 @@ public:
SLATE_BEGIN_ARGS(SControlRigEditModeTools) {}
SLATE_END_ARGS();
void Construct(const FArguments& InArgs, FControlRigEditMode& InEditMode, UWorld* InWorld);
void Construct(const FArguments& InArgs, TSharedPtr<FControlRigEditModeToolkit> InOwningToolkit, FControlRigEditMode& InEditMode, UWorld* InWorld);
/** Set the objects to be displayed in the details panel */
void SetDetailsObjects(const TArray<TWeakObjectPtr<>>& InObjects);
@@ -94,11 +95,6 @@ private:
private:
/** Toolbar functions and windows*/
void MakePoseDialog();
void MakeTweenDialog();
void MakeSnapperDialog();
void MakeMotionTrailDialog();
void ToggleEditPivotMode();
//TODO may put back void MakeSelectionSetDialog();
@@ -109,6 +105,9 @@ private:
const FRigTreeDisplaySettings& GetDisplaySettings() const { return DisplaySettings; }
bool bIsChangingRigHierarchy;
// The toolkit that created this UI
TWeakPtr<FControlRigEditModeToolkit> OwningToolkit;
public:
/** Modes Panel Header Information **/
void CustomizeToolBarPalette(FToolBarBuilder& ToolBarBuilder);
@@ -19,6 +19,8 @@
#include "LevelSequence.h"
#include "LevelSequenceEditorBlueprintLibrary.h"
#include "ILevelSequenceEditorToolkit.h"
#include "Viewports/InViewportUIDragOperation.h"
#include "ControlRigEditModeToolkit.h"
#define LOCTEXT_NAMESPACE "ControlRigTweenWidget"
@@ -27,36 +29,44 @@ void SControlRigTweenWidget::Construct(const FArguments& InArgs)
PoseBlendValue = 0.0f;
bIsBlending = false;
bSliderStartedTransaction = false;
OwningToolkit = InArgs._InOwningToolkit;
ChildSlot
[
SNew(SBorder)
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.Padding(FMargin(20.0f))
.BorderImage(FAppStyle::Get().GetBrush("EditorViewport.OverlayBrush"))
.Padding(20.f)
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
.HAlign(HAlign_Center)
[
SNew(SSpinBox<float>)
.Value(this, &SControlRigTweenWidget::OnGetPoseBlendValueFloat)
.ToolTipText(LOCTEXT("TweenTooltip", "Key at current frame between previous(-1.0) and next(1.0) poses. Use Ctrl drag for under and over shoot."))
.MinValue(-2.0f)
.MaxValue(2.0f)
.MinSliderValue(-1.0f)
.MaxSliderValue(1.0f)
.SliderExponent(1)
.Delta(0.005f)
.MinDesiredWidth(100.0f)
.SupportDynamicSliderMinValue(true)
.SupportDynamicSliderMaxValue(true)
.OnValueChanged(this, &SControlRigTweenWidget::OnPoseBlendChanged)
.OnValueCommitted(this, &SControlRigTweenWidget::OnPoseBlendCommited)
.OnBeginSliderMovement(this, &SControlRigTweenWidget::OnBeginSliderMovement)
.OnEndSliderMovement(this, &SControlRigTweenWidget::OnEndSliderMovement)
]
+ SVerticalBox::Slot()
.AutoHeight()
.HAlign(HAlign_Center)
.Padding(0.0f, 0.0f, 0.0f, 5.0f)
[
SNew(STextBlock)
.TextStyle(FAppStyle::Get(), "NormalText.Important")
.Text(LOCTEXT("TweenController", "Tween Controller"))
]
+ SVerticalBox::Slot()
.AutoHeight()
.HAlign(HAlign_Center)
[
SNew(SSpinBox<float>)
.Value(this, &SControlRigTweenWidget::OnGetPoseBlendValueFloat)
.ToolTipText(LOCTEXT("TweenTooltip", "Key at current frame between previous(-1.0) and next(1.0) poses. Use Ctrl drag for under and over shoot."))
.MinValue(-2.0f)
.MaxValue(2.0f)
.MinSliderValue(-1.0f)
.MaxSliderValue(1.0f)
.SliderExponent(1)
.Delta(0.005f)
.MinDesiredWidth(100.0f)
.SupportDynamicSliderMinValue(true)
.SupportDynamicSliderMaxValue(true)
.OnValueChanged(this, &SControlRigTweenWidget::OnPoseBlendChanged)
.OnValueCommitted(this, &SControlRigTweenWidget::OnPoseBlendCommited)
.OnBeginSliderMovement(this, &SControlRigTweenWidget::OnBeginSliderMovement)
.OnEndSliderMovement(this, &SControlRigTweenWidget::OnEndSliderMovement)
]
]
];
}
@@ -110,6 +120,38 @@ void SControlRigTweenWidget::OnEndSliderMovement(float NewValue)
WeakSequencer = nullptr;
}
FReply SControlRigTweenWidget::OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
// Need to remember where within a tab we grabbed
const FVector2D TabGrabScreenSpaceOffset = MouseEvent.GetScreenSpacePosition() - MyGeometry.GetAbsolutePosition();
FOnInViewportUIDropped OnUIDropped = FOnInViewportUIDropped::CreateSP(this, &SControlRigTweenWidget::FinishDraggingWidget);
// Start dragging.
TSharedRef<FInViewportUIDragOperation> DragDropOperation =
FInViewportUIDragOperation::New(
SharedThis(this),
TabGrabScreenSpaceOffset,
GetDesiredSize(),
OnUIDropped
);
if (OwningToolkit.IsValid())
{
OwningToolkit.Pin()->TryRemoveTweenOverlay();
}
return FReply::Handled().BeginDragDrop(DragDropOperation);
return FReply::Unhandled();
}
void SControlRigTweenWidget::FinishDraggingWidget(const FVector2D InLocation)
{
if (OwningToolkit.IsValid())
{
OwningToolkit.Pin()->UpdateTweenWidgetLocation(InLocation);
OwningToolkit.Pin()->TryShowTweenOverlay();
}
}
void SControlRigTweenWidget::OnPoseBlendCommited(float ChangedVal, ETextCommit::Type Type)
{
UControlRig* ControlRig = GetControlRig();
@@ -18,12 +18,13 @@
class UControlRig;
class ISequencer;
class FControlRigEditModeToolkit;
class SControlRigTweenWidget : public SCompoundWidget
{
SLATE_BEGIN_ARGS(SControlRigTweenWidget) {}
SLATE_ARGUMENT(UControlRigPoseAsset*, PoseAsset)
SLATE_ARGUMENT(TSharedPtr<FControlRigEditModeToolkit>, InOwningToolkit)
SLATE_END_ARGS()
~SControlRigTweenWidget()
{
@@ -44,6 +45,13 @@ private:
void OnEndSliderMovement(float NewValue);
float OnGetPoseBlendValueFloat() const { return PoseBlendValue; }
FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override
{
return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton);
};
FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent);
void FinishDraggingWidget(const FVector2D InLocation);
void SetupControls();
float PoseBlendValue;
bool bIsBlending;
@@ -52,5 +60,6 @@ private:
FControlsToTween ControlsToTween;
TWeakPtr<ISequencer> WeakSequencer;
TWeakPtr<FControlRigEditModeToolkit> OwningToolkit;
};
@@ -255,7 +255,7 @@ FControlRigEditor::~FControlRigEditor()
if (UWorld* PreviewWorld = GetPersonaToolkit()->GetPreviewScene()->GetWorld())
{
PreviewWorld->MarkObjectsPendingKill();
PreviewWorld->MarkPendingKill();
PreviewWorld->MarkAsGarbage();
}
if (PersonaToolkit.IsValid())
@@ -535,8 +535,6 @@ void FControlRigEditor::InitControlRigEditor(const EToolkitMode::Type Mode, cons
}
}, TStatId(), NULL, ENamedThreads::GameThread);
UpdateCapsules();
CreateRigHierarchyToGraphDragAndDropMenu();
}
@@ -1116,7 +1114,7 @@ void FControlRigEditor::GetCustomDebugObjects(TArray<FCustomDebugObject>& DebugL
{
if (InObject != nullptr)
{
if (InObject->IsPendingKillOrUnreachable())
if (!IsValidChecked(InObject) || InObject->IsUnreachable())
{
return true;
}
@@ -1713,7 +1711,7 @@ void FControlRigEditor::ClearDetailObject(bool bChangeUISelectionState)
UDetailsViewWrapperObject* WrapperObject = WrapperObjectPtr.Get();
WrapperObject->RemoveFromRoot();
WrapperObject->Rename(nullptr, GetTransientPackage(), REN_ForceNoResetLoaders | REN_DoNotDirty | REN_DontCreateRedirectors | REN_NonTransactional);
WrapperObject->MarkPendingKill();
WrapperObject->MarkAsGarbage();
}
}
WrapperObjects.Reset();
@@ -2790,18 +2788,14 @@ void FControlRigEditor::HandleControlRigExecutedEvent(UControlRig* InControlRig,
const FRigElementKey Key = WrapperObject->GetContent<FRigBaseElement>().GetKey();
FRigBaseElement* Element = Hierarchy->Find(Key);
if(FRigTransformElement* TransformElement = Cast<FRigTransformElement>(Element))
{
// compute all transforms
Hierarchy->GetTransform(TransformElement, ERigTransformType::CurrentGlobal);
Hierarchy->GetTransform(TransformElement, ERigTransformType::CurrentLocal);
Hierarchy->GetTransform(TransformElement, ERigTransformType::InitialGlobal);
Hierarchy->GetTransform(TransformElement, ERigTransformType::InitialLocal);
}
if(FRigControlElement* ControlElement = Cast<FRigControlElement>(Element))
{
// compute all transforms
Hierarchy->GetTransform(ControlElement, ERigTransformType::CurrentGlobal);
Hierarchy->GetTransform(ControlElement, ERigTransformType::CurrentLocal);
Hierarchy->GetTransform(ControlElement, ERigTransformType::InitialGlobal);
Hierarchy->GetTransform(ControlElement, ERigTransformType::InitialLocal);
Hierarchy->GetControlOffsetTransform(ControlElement, ERigTransformType::CurrentGlobal);
Hierarchy->GetControlOffsetTransform(ControlElement, ERigTransformType::CurrentLocal);
Hierarchy->GetControlOffsetTransform(ControlElement, ERigTransformType::InitialGlobal);
@@ -2810,9 +2804,23 @@ void FControlRigEditor::HandleControlRigExecutedEvent(UControlRig* InControlRig,
Hierarchy->GetControlShapeTransform(ControlElement, ERigTransformType::CurrentLocal);
Hierarchy->GetControlShapeTransform(ControlElement, ERigTransformType::InitialGlobal);
Hierarchy->GetControlShapeTransform(ControlElement, ERigTransformType::InitialLocal);
}
WrapperObject->SetContent<FRigBaseElement>(*Element);
WrapperObject->SetContent<FRigControlElement>(*ControlElement);
}
else if(FRigTransformElement* TransformElement = Cast<FRigTransformElement>(Element))
{
// compute all transforms
Hierarchy->GetTransform(TransformElement, ERigTransformType::CurrentGlobal);
Hierarchy->GetTransform(TransformElement, ERigTransformType::CurrentLocal);
Hierarchy->GetTransform(TransformElement, ERigTransformType::InitialGlobal);
Hierarchy->GetTransform(TransformElement, ERigTransformType::InitialLocal);
WrapperObject->SetContent<FRigTransformElement>(*TransformElement);
}
else
{
WrapperObject->SetContent<FRigBaseElement>(*Element);
}
}
}
}
@@ -3021,29 +3029,6 @@ void FControlRigEditor::Tick(float DeltaTime)
{
EditMode->bDrawHierarchyBones = bDrawHierarchyBones;
}
// check if we are supposed to have bones in our map
if ((EditMode->ConfigOption != nullptr) && (ControlRig != nullptr))
{
EBoneDrawMode::Type BoneDrawMode = (EBoneDrawMode::Type)EditMode->ConfigOption->DefaultBoneDrawSelection;
const bool bBonesExpectedInCapsules = BoneDrawMode != EBoneDrawMode::None;
bool bBonesFoundInCapsules = false;
for(const TPair<int32, int32>& Pair : CapsuleToHierarchyIndex)
{
const int32 HierarchyIndex = Pair.Value;
if(ControlRig->GetHierarchy()->GetKey(HierarchyIndex).Type == ERigElementType::Bone)
{
bBonesFoundInCapsules = true;
break;
}
}
if(bBonesExpectedInCapsules != bBonesFoundInCapsules)
{
UpdateCapsules();
}
}
}
if(WeakGroundActorPtr.IsValid())
@@ -3647,7 +3632,6 @@ void FControlRigEditor::OnToolbarDrawNullsChanged(ECheckBoxState InNewValue)
if (UControlRigEditModeSettings* Settings = GetMutableDefault<UControlRigEditModeSettings>())
{
Settings->bDisplayNulls = InNewValue == ECheckBoxState::Checked;
UpdateCapsules();
}
}
@@ -3857,101 +3841,6 @@ void FControlRigEditor::HandlePreviewSceneCreated(const TSharedRef<IPersonaPrevi
}
}
UPersonaSelectionComponent* SelectionComponent = InPersonaPreviewScene->GetSelectionComponent();
check(SelectionComponent != nullptr);
// make sure the selection component ticks after the skeletal mesh comp
SelectionComponent->AddTickPrerequisiteComponent(EditorSkelComp);
SelectionComponent->OnUpdateCapsules().BindLambda([this](UPersonaSelectionComponent*, const TArray<int32>& InIndices, TArray<FPersonaSelectionCapsule>& OutCapsules)
{
if(UControlRig* DebuggedControlRig = Cast<UControlRig>(GetBlueprintObj()->GetObjectBeingDebugged()))
{
URigHierarchy* Hierarchy = DebuggedControlRig->GetHierarchy();
check(Hierarchy != nullptr);
for(int32 Index = 0; Index < InIndices.Num(); Index++)
{
const int32 CapsuleIndex = InIndices[Index];
const int32 HierarchyIndex = CapsuleToHierarchyIndex.FindChecked(CapsuleIndex);
if (!Hierarchy->IsValidIndex(HierarchyIndex) || !OutCapsules.IsValidIndex(CapsuleIndex))
{
UpdateCapsules();
return;
}
check(Hierarchy->IsValidIndex(HierarchyIndex));
check(OutCapsules.IsValidIndex(CapsuleIndex));
FPersonaSelectionCapsule& OutCapsule = OutCapsules[CapsuleIndex];
OutCapsule.Transform = Hierarchy->GetGlobalTransform(HierarchyIndex);
OutCapsule.Radius = 10.f;
OutCapsule.HalfHeight = 5.f;
if(Hierarchy->GetKey(HierarchyIndex).Type == ERigElementType::Bone)
{
const int32 ParentIndex = Hierarchy->GetFirstParent(HierarchyIndex);
FVector Start, End;
if (ParentIndex >= 0)
{
Start = Hierarchy->GetGlobalTransform(ParentIndex).GetLocation();
End = OutCapsule.Transform.GetLocation();
}
else
{
Start = FVector::ZeroVector;
End = OutCapsule.Transform.GetLocation();
}
UPersonaSelectionComponent::ComputeCapsuleFromBonePositions(
Start,
End,
100.f,
DebuggedControlRig->GetDebugBoneRadiusMultiplier(),
OutCapsule);
}
}
}
});
// setup the capsules in the preview scene
SelectionComponent->OnClicked().BindLambda([this] (UPersonaSelectionComponent*, int32 InCapsuleIndex, const FPersonaSelectionCapsule& InCapsule)
{
const int32 HierarchyIndex = CapsuleToHierarchyIndex.FindChecked(InCapsuleIndex);
if (UControlRigBlueprint* ControlRigBP = GetControlRigBlueprint())
{
URigHierarchy* Hierarchy = ControlRigBP->Hierarchy;
const FRigElementKey ElementToSelect = Hierarchy->GetKey(HierarchyIndex);
if (FSlateApplication::Get().GetModifierKeys().IsShiftDown())
{
Hierarchy->GetController()->SelectElement(ElementToSelect, true);
}
else if (FSlateApplication::Get().GetModifierKeys().IsControlDown())
{
const bool bSelect = !Hierarchy->IsSelected(ElementToSelect);
Hierarchy->GetController()->SelectElement(ElementToSelect, bSelect);
}
else
{
TArray<FRigElementKey> NewSelection;
NewSelection.Add(ElementToSelect);
Hierarchy->GetController()->SetSelection(NewSelection);
}
/*
if (FControlRigEditMode* EditMode = GetEditMode())
{
EditMode->RequestToRecreateControlShapeActors();
}
*/
}
});
UpdateCapsules();
}
void FControlRigEditor::UpdateControlRig()
@@ -4756,7 +4645,6 @@ void FControlRigEditor::OnHierarchyChanged()
}
CacheNameLists();
UpdateCapsules();
}
@@ -6117,66 +6005,6 @@ bool FControlRigEditor::IsHaltedAtBreakpoint() const
return HaltedAtNode != nullptr;
}
void FControlRigEditor::UpdateCapsules()
{
if(!PersonaToolkit.IsValid())
{
return;
}
TSharedRef<IPersonaPreviewScene> CurrentPreviewScene = GetPersonaToolkit()->GetPreviewScene();
UPersonaSelectionComponent* SelectionComponent = CurrentPreviewScene->GetSelectionComponent();
check(SelectionComponent != nullptr);
SelectionComponent->Reset();
CapsuleToHierarchyIndex.Reset();
bool bCreateCapsulesForBones = false;
if (FControlRigEditorEditMode* EditMode = GetEditMode())
{
if (EditMode->ConfigOption)
{
EBoneDrawMode::Type BoneDrawMode = (EBoneDrawMode::Type)EditMode->ConfigOption->DefaultBoneDrawSelection;
bCreateCapsulesForBones = BoneDrawMode != EBoneDrawMode::None;
}
}
if(UControlRig* DebuggedControlRig = Cast<UControlRig>(GetBlueprintObj()->GetObjectBeingDebugged()))
{
URigHierarchy* Hierarchy = DebuggedControlRig->GetHierarchy();
for(int32 Index = 0; Index < Hierarchy->Num(); Index++)
{
const FRigElementKey Key = Hierarchy->GetKey(Index);
switch(Key.Type)
{
case ERigElementType::Null:
{
if(GetToolbarDrawNulls() == ECheckBoxState::Checked)
{
const int32 CapsuleIndex = SelectionComponent->Add();
CapsuleToHierarchyIndex.Add(CapsuleIndex, Index);
}
break;
}
case ERigElementType::Bone:
{
if(bCreateCapsulesForBones)
{
const int32 CapsuleIndex = SelectionComponent->Add();
CapsuleToHierarchyIndex.Add(CapsuleIndex, Index);
}
break;
}
default:
{
break;
}
}
}
}
}
void FControlRigEditor::FrameSelection()
{
if (SGraphEditor* GraphEd = FocusedGraphEdPtr.Pin().Get())
@@ -383,8 +383,6 @@ private:
bool IsHaltedAtBreakpoint() const;
void UpdateCapsules();
void FrameSelection();
protected:
@@ -488,7 +486,6 @@ protected:
bool bSuspendDetailsPanelRefresh;
TMap<int32, int32> CapsuleToHierarchyIndex;
TArray<TStrongObjectPtr<UDetailsViewWrapperObject>> WrapperObjects;
TWeakObjectPtr<AStaticMeshActor> WeakGroundActorPtr;
@@ -99,7 +99,9 @@ void FControlRigEditorEditMode::Render(const FSceneView* View, FViewport* Viewpo
const float Radius = FMath::Clamp(BoneLength * 0.05f, 0.1f, 10000.f);
//Render Sphere for bone end point and a cone between it and its parent.
PDI->SetHitProxy(new HPersonaBoneHitProxy(BoneElement->GetIndex(), BoneElement->GetName()));
SkeletalDebugRendering::DrawWireBone(PDI, Start, End, LineColor, SDPG_Foreground, Radius);
PDI->SetHitProxy(nullptr);
return true;
});
}
@@ -28,6 +28,8 @@ FRigElementKey SRigSpacePickerWidget::InValidKey;
void SRigSpacePickerWidget::Construct(const FArguments& InArgs)
{
GEditor->RegisterForUndo(this);
bShowDefaultSpaces = InArgs._ShowDefaultSpaces;
bShowFavoriteSpaces = InArgs._ShowFavoriteSpaces;
bShowAdditionalSpaces = InArgs._ShowAdditionalSpaces;
@@ -187,6 +189,8 @@ void SRigSpacePickerWidget::Construct(const FArguments& InArgs)
SRigSpacePickerWidget::~SRigSpacePickerWidget()
{
GEditor->UnregisterForUndo(this);
if(HierarchyModifiedHandle.IsValid())
{
if(Hierarchy)
@@ -212,12 +216,10 @@ void SRigSpacePickerWidget::SetControls(
Hierarchy = InHierarchy;
ControlKeys = InControls;
if(Hierarchy)
if (Hierarchy && HierarchyModifiedHandle.IsValid() == false)
{
HierarchyModifiedHandle = Hierarchy->OnModified().AddSP(this, &SRigSpacePickerWidget::OnHierarchyModified);
}
UpdateActiveSpaces();
RepopulateItemSpaces();
}
@@ -790,29 +792,7 @@ FRigElementKey SRigSpacePickerWidget::GetActiveSpace_Private(URigHierarchy* InHi
{
if(InHierarchy)
{
const TArray<FRigElementWeight> ParentWeights = InHierarchy->GetParentWeightArray(InControlKey);
if(ParentWeights.Num() > 0)
{
const TArray<FRigElementKey> ParentKeys = InHierarchy->GetParents(InControlKey);
check(ParentKeys.Num() == ParentWeights.Num());
for(int32 ParentIndex=0;ParentIndex<ParentKeys.Num();ParentIndex++)
{
if(ParentWeights[ParentIndex].IsAlmostZero())
{
continue;
}
if(ParentIndex == 0)
{
if(!IsDefaultSpace(ParentKeys[ParentIndex]))
{
return URigHierarchy::GetDefaultParentKey();
}
}
return ParentKeys[ParentIndex];
}
}
return InHierarchy->GetActiveParent(InControlKey);
}
return URigHierarchy::GetDefaultParentKey();
}
@@ -1024,6 +1004,15 @@ bool SRigSpacePickerWidget::IsDefaultSpace(const FRigElementKey& InKey) const
return false;
}
void SRigSpacePickerWidget::PostUndo(bool bSuccess)
{
RefreshContents();
}
void SRigSpacePickerWidget::PostRedo(bool bSuccess)
{
RefreshContents();
}
//////////////////////////////////////////////////////////////
/// SRigSpacePickerBakeWidget
///////////////////////////////////////////////////////////
@@ -10,6 +10,7 @@
#include "Rigs/RigSpaceHierarchy.h"
#include "IStructureDetailsView.h"
#include "Misc/FrameNumber.h"
#include "EditorUndoClient.h"
#include "SRigSpacePickerWidget.generated.h"
USTRUCT()
@@ -50,7 +51,7 @@ DECLARE_DELEGATE_RetVal_TwoParams(TArray<FRigElementKey>, FRigSpacePickerGetAddi
DECLARE_DELEGATE_RetVal_ThreeParams(FReply, SRigSpacePickerOnBake, URigHierarchy*, TArray<FRigElementKey> /* Controls */, FRigSpacePickerBakeSettings);
/** Widget allowing picking of a space source for space switching */
class CONTROLRIGEDITOR_API SRigSpacePickerWidget : public SCompoundWidget
class CONTROLRIGEDITOR_API SRigSpacePickerWidget : public SCompoundWidget, public FEditorUndoClient
{
public:
@@ -108,6 +109,11 @@ public:
FRigSpacePickerActiveSpaceChanged& OnActiveSpaceChanged() { return ActiveSpaceChangedEvent; }
FRigSpacePickerSpaceListChanged& OnSpaceListChanged() { return SpaceListChangedEvent; }
void RefreshContents();
// FEditorUndoClient interface
virtual void PostUndo(bool bSuccess);
virtual void PostRedo(bool bSuccess);
// End FEditorUndoClient interface
private:
@@ -49,6 +49,7 @@
#include "IKeyArea.h"
#include "ISequencer.h"
#include "CurveModel.h"
#include "CurveEditor.h"
#include "ControlRigEditorModule.h"
#include "SequencerSettings.h"
#include "Framework/Application/SlateApplication.h"
@@ -81,6 +82,8 @@
#define LOCTEXT_NAMESPACE "FControlRigParameterTrackEditor"
TAutoConsoleVariable<bool> CVarSelectedKeysSelectControls(TEXT("ControlRig.Sequencer.SelectedKeysSelectControls"), false, TEXT("When true when we select a key in Sequencer it will select the Control, by default false."));
static USkeletalMeshComponent* AcquireSkeletalMeshFromObject(UObject* BoundObject, TSharedPtr<ISequencer> SequencerPtr)
{
if (AActor* Actor = Cast<AActor>(BoundObject))
@@ -349,6 +352,20 @@ void FControlRigParameterTrackEditor::BindControlRig(UControlRig* ControlRig)
UMovieSceneControlRigParameterTrack* Track = FindTrack(ControlRig);
if (Track)
{
for (UMovieSceneSection* BaseSection : Track->GetAllSections())
{
if (UMovieSceneControlRigParameterSection* Section = Cast< UMovieSceneControlRigParameterSection>(BaseSection))
{
if (Section->GetControlRig())
{
TArray<FSpaceControlNameAndChannel>& SpaceChannels = Section->GetSpaceChannels();
for (FSpaceControlNameAndChannel& Channel : SpaceChannels)
{
HandleOnSpaceAdded(Section, Channel.ControlName, &(Channel.SpaceCurve));
}
}
}
}
Track->SpaceChannelAdded().AddRaw(this, &FControlRigParameterTrackEditor::HandleOnSpaceAdded);
}
}
@@ -912,8 +929,8 @@ void FControlRigParameterTrackEditor::BakeToControlRig(UClass* InClass, FGuid Ob
bool bResult = MovieSceneToolHelpers::ExportToAnimSequence(TempAnimSequence, AnimSeqExportOption, OwnerMovieScene, ParentSequencer.Get(), SkelMeshComp, Template, RootToLocalTransform);
if (bResult == false)
{
TempAnimSequence->MarkPendingKill();
AnimSeqExportOption->MarkPendingKill();
TempAnimSequence->MarkAsGarbage();
AnimSeqExportOption->MarkAsGarbage();
return;
}
@@ -947,8 +964,8 @@ void FControlRigParameterTrackEditor::BakeToControlRig(UClass* InClass, FGuid Ob
UControlRig* ControlRig = NewObject<UControlRig>(Track, InClass, FName(*ObjectName), RF_Transactional);
if (InClass != UFKControlRig::StaticClass() && !ControlRig->SupportsEvent(FRigUnit_InverseExecution::EventName))
{
TempAnimSequence->MarkPendingKill();
AnimSeqExportOption->MarkPendingKill();
TempAnimSequence->MarkAsGarbage();
AnimSeqExportOption->MarkAsGarbage();
OwnerMovieScene->RemoveTrack(*Track);
return;
}
@@ -1021,8 +1038,8 @@ void FControlRigParameterTrackEditor::BakeToControlRig(UClass* InClass, FGuid Ob
}
BindControlRig(ControlRig);
TempAnimSequence->MarkPendingKill();
AnimSeqExportOption->MarkPendingKill();
TempAnimSequence->MarkAsGarbage();
AnimSeqExportOption->MarkAsGarbage();
GetSequencer()->NotifyMovieSceneDataChanged(EMovieSceneDataChangeType::MovieSceneStructureItemAdded);
@@ -1428,10 +1445,152 @@ void FControlRigParameterTrackEditor::OnAddTransformKeysForSelectedObjects(EMovi
}
}
//function to evaluate a Control and Set it on the ControlRig
static void EvaluateThisControl(UMovieSceneControlRigParameterSection* Section, const FName& ControlName, const FFrameTime& FrameTime)
{
if (!Section)
{
return;
}
UControlRig* ControlRig = Section->GetControlRig();
if (!ControlRig)
{
return;
}
if(FRigControlElement* ControlElement = ControlRig->FindControl(ControlName))
{
FControlRigInteractionScope InteractionScope(ControlRig);
//eval any space for this channel, if not additive section
if (Section->GetBlendType().Get() != EMovieSceneBlendType::Additive)
{
TOptional<FMovieSceneControlRigSpaceBaseKey> SpaceKey = Section->EvaluateSpaceChannel(FrameTime, ControlName);
if (SpaceKey.IsSet())
{
URigHierarchy* RigHierarchy = ControlRig->GetHierarchy();
switch (SpaceKey.GetValue().SpaceType)
{
case EMovieSceneControlRigSpaceType::Parent:
RigHierarchy->SwitchToDefaultParent(ControlElement->GetKey());
break;
case EMovieSceneControlRigSpaceType::World:
RigHierarchy->SwitchToWorldSpace(ControlElement->GetKey());
break;
case EMovieSceneControlRigSpaceType::ControlRig:
URigHierarchy::TElementDependencyMap Dependencies = RigHierarchy->GetDependenciesForVM(ControlRig->GetVM());
RigHierarchy->SwitchToParent(ControlElement->GetKey(), SpaceKey.GetValue().ControlRigElement, false, true, Dependencies, nullptr);
break;
}
}
}
const bool bSetupUndo = false;
switch (ControlElement->Settings.ControlType)
{
case ERigControlType::Bool:
{
if (Section->GetBlendType().Get() != EMovieSceneBlendType::Additive)
{
TOptional <bool> Value = Section->EvaluateBoolParameter(FrameTime, ControlName);
if (Value.IsSet())
{
ControlRig->SetControlValue<bool>(ControlName, Value.GetValue(), true, EControlRigSetKey::Never, bSetupUndo);
}
}
break;
}
case ERigControlType::Integer:
{
if (Section->GetBlendType().Get() != EMovieSceneBlendType::Additive)
{
if (ControlElement->Settings.ControlEnum)
{
TOptional<uint8> Value = Section->EvaluateEnumParameter(FrameTime, ControlName);
if (Value.IsSet())
{
int32 IVal = (int32)Value.GetValue();
ControlRig->SetControlValue<int32>(ControlName, IVal, true, EControlRigSetKey::Never, bSetupUndo);
}
}
else
{
TOptional <int32> Value = Section->EvaluateIntegerParameter(FrameTime, ControlName);
if (Value.IsSet())
{
ControlRig->SetControlValue<int32>(ControlName, Value.GetValue(), true, EControlRigSetKey::Never, bSetupUndo);
}
}
}
break;
}
case ERigControlType::Float:
{
TOptional <float> Value = Section->EvaluateScalarParameter(FrameTime, ControlName);
if (Value.IsSet())
{
ControlRig->SetControlValue<float>(ControlName, Value.GetValue(), true, EControlRigSetKey::Never, bSetupUndo);
}
break;
}
case ERigControlType::Vector2D:
{
TOptional <FVector2D> Value = Section->EvaluateVector2DParameter(FrameTime, ControlName);
if (Value.IsSet())
{
ControlRig->SetControlValue<FVector2D>(ControlName, Value.GetValue(), true, EControlRigSetKey::Never, bSetupUndo);
}
break;
}
case ERigControlType::Position:
case ERigControlType::Scale:
case ERigControlType::Rotator:
{
TOptional <FVector> Value = Section->EvaluateVectorParameter(FrameTime, ControlName);
if (Value.IsSet())
{
FVector3f FloatVal = Value.GetValue();
ControlRig->SetControlValue<FVector3f>(ControlName, FloatVal, true, EControlRigSetKey::Never, bSetupUndo);
}
break;
}
case ERigControlType::Transform:
case ERigControlType::TransformNoScale:
case ERigControlType::EulerTransform:
{
TOptional <FTransform> Value = Section->EvaluateTransformParameter(FrameTime, ControlName);
if (Value.IsSet())
{
if (ControlElement->Settings.ControlType == ERigControlType::Transform)
{
ControlRig->SetControlValue<FRigControlValue::FTransform_Float>(ControlName, Value.GetValue(), true, EControlRigSetKey::Never, bSetupUndo);
}
else if (ControlElement->Settings.ControlType == ERigControlType::TransformNoScale)
{
FTransformNoScale NoScale = Value.GetValue();
ControlRig->SetControlValue<FRigControlValue::FTransformNoScale_Float>(ControlName, NoScale, true, EControlRigSetKey::Never, bSetupUndo);
}
else if (ControlElement->Settings.ControlType == ERigControlType::EulerTransform)
{
FEulerTransform Euler = Value.GetValue();
ControlRig->SetControlValue<FRigControlValue::FEulerTransform_Float>(ControlName, Euler, true, EControlRigSetKey::Never, bSetupUndo);
}
}
break;
}
}
//note we don't need to evaluate the control rig, setting the value is enough
}
}
//When a channel is changed via Sequencer we need to call SetControlValue on it so that Control Rig can handle seeing that this is a change, but just on this value
//and then send back a key even if needed, which happens with IK/FK switches. Hopefully new IK/FK system will remove need for this at some point.
void FControlRigParameterTrackEditor::OnChannelChanged(const FMovieSceneChannelMetaData* MetaData, UMovieSceneSection* InSection)
{
UMovieSceneControlRigParameterSection* Section = Cast<UMovieSceneControlRigParameterSection>(InSection);
if (Section && Section->GetControlRig() && MetaData)
TSharedPtr<ISequencer> SequencerPtr = GetSequencer();
if (Section && Section->GetControlRig() && MetaData && SequencerPtr.IsValid())
{
Section->ControlsToSet.Empty();
TArray<FString> StringArray;
@@ -1441,9 +1600,8 @@ void FControlRigParameterTrackEditor::OnChannelChanged(const FMovieSceneChannelM
{
FName ControlName(*StringArray[0]);
Section->ControlsToSet.Add(ControlName);
FControlRigInteractionScope InteractionScope(Section->GetControlRig());
GetSequencer()->ForceEvaluate(); //now run sequencer...
Section->GetControlRig()->Evaluate_AnyThread();
FFrameTime Time = SequencerPtr->GetLocalTime().Time;
EvaluateThisControl(Section,ControlName, Time);
Section->ControlsToSet.Empty();
TOptional<FFrameNumber> Optional;
@@ -1559,12 +1717,14 @@ void FControlRigParameterTrackEditor::OnSequencerDataChanged(EMovieSceneDataChan
}
}
void FControlRigParameterTrackEditor::OnCurveDisplayChanged(FCurveModel* CurveModel, bool bDisplayed)
void FControlRigParameterTrackEditor::OnCurveDisplayChanged(FCurveModel* CurveModel, bool bDisplayed, const FCurveEditor* InCurveEditor)
{
if (bIsDoingSelection)
//if already doing a selection or the curve editor isn't doing a direct selection, for example sequencer filtering removed the curve, we dont' update control selection
if (bIsDoingSelection || (InCurveEditor && InCurveEditor->IsDoingDirectSelection() == false))
{
return;
}
TGuardValue<bool> Guard(bIsDoingSelection, true);
FScopedTransaction ScopedTransaction(LOCTEXT("SelectControlTransaction", "Select Control"), !GIsTransacting);
@@ -1703,7 +1863,8 @@ void FControlRigParameterTrackEditor::OnSelectionChanged(TArray<UMovieSceneTrack
UControlRig* ControlRig = nullptr;
TArray<const IKeyArea*> KeyAreas;
GetSequencer()->GetSelectedKeyAreas(KeyAreas);
const bool UseSelectedKeys = CVarSelectedKeysSelectControls.GetValueOnGameThread();
GetSequencer()->GetSelectedKeyAreas(KeyAreas, UseSelectedKeys);
FScopedTransaction ScopedTransaction(LOCTEXT("SelectControlTransaction", "Select Control"), !GIsTransacting);
if (KeyAreas.Num() <= 0)
@@ -2122,7 +2283,8 @@ void FControlRigParameterTrackEditor::HandleControlSelected(UControlRig* Subject
GetSequencer()->ResumeSelectionBroadcast();
TArray<const IKeyArea*> KeyAreas;
GetSequencer()->GetSelectedKeyAreas(KeyAreas);
const bool UseSelectedKeys = CVarSelectedKeysSelectControls.GetValueOnGameThread();
GetSequencer()->GetSelectedKeyAreas(KeyAreas, UseSelectedKeys);
SelectRigsAndControls(Subject, KeyAreas);
//Force refresh now, not later
@@ -2258,11 +2420,33 @@ void FControlRigParameterTrackEditor::GetControlRigKeys(UControlRig* InControlRi
case ERigControlType::Scale:
case ERigControlType::Rotator:
{
bool bKeyX = bSetKey;
bool bKeyY = bSetKey;
bool bKeyZ = bSetKey;
if (ControlElement->Settings.ControlType == ERigControlType::Position)
{
bKeyX = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::TranslationX);
bKeyY = EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::TranslationY);
bKeyZ = EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::TranslationZ);
}
else if(ControlElement->Settings.ControlType == ERigControlType::Rotator)
{
bKeyX = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::RotationX);
bKeyY = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::RotationY);
bKeyZ = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::RotationZ);
}
else //scale
{
bKeyX = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::ScaleX);
bKeyY = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::ScaleY);
bKeyZ = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::ScaleZ);
}
FVector3f Val = ControlValue.Get<FVector3f>();
pChannelIndex->GeneratedKeyIndex = OutGeneratedKeys.Num();
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, Val.X, bSetKey));
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, Val.Y, bSetKey));
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, Val.Z, bSetKey));
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, Val.X, bKeyX));
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, Val.Y, bKeyY));
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, Val.Z, bKeyZ));
break;
}
@@ -2330,7 +2514,7 @@ void FControlRigParameterTrackEditor::GetControlRigKeys(UControlRig* InControlRi
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, CurrentVector.Y, bKeyY));
OutGeneratedKeys.Add(FMovieSceneChannelValueSetter::Create<FMovieSceneFloatChannel>(ChannelIndex++, CurrentVector.Z, bKeyZ));
FRotator CurrentRotator = Rotation;
FRotator3f CurrentRotator = FRotator3f(Rotation);
bKeyX = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::RotationX);
bKeyY = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::RotationY);
bKeyZ = bSetKey && EnumHasAnyFlags(ChannelsToKey, EControlRigContextChannelToKey::RotationZ);
@@ -2673,7 +2857,7 @@ bool FControlRigParameterTrackEditor::ModifyOurGeneratedKeysByCurrentAndWeight(U
}
FVector3f CurrentPos = Val.Val.GetTranslation();
FRotator CurrentRot = Val.Val.GetRotation().Rotator();
FRotator3f CurrentRot = FRotator3f(Val.Val.GetRotation().Rotator());
GeneratedTotalKeys[ChannelIndex]->ModifyByCurrentAndWeight(Proxy, KeyTime, (void *)&CurrentPos.X, Weight);
GeneratedTotalKeys[ChannelIndex + 1]->ModifyByCurrentAndWeight(Proxy, KeyTime, (void *)&CurrentPos.Y, Weight);
GeneratedTotalKeys[ChannelIndex + 2]->ModifyByCurrentAndWeight(Proxy, KeyTime, (void *)&CurrentPos.Z, Weight);
@@ -2709,13 +2893,17 @@ void FControlRigParameterTrackEditor::BuildTrackContextMenu(FMenuBuilder& MenuBu
return;
}
UMovieSceneControlRigParameterSection* SectionToKey = Cast<UMovieSceneControlRigParameterSection>(Track->FindOrAddSection(0, bSectionAdded));
UMovieSceneControlRigParameterSection* SectionToKey = Cast<UMovieSceneControlRigParameterSection>(Track->GetSectionToKey());
if (SectionToKey == nullptr)
{
SectionToKey = Cast<UMovieSceneControlRigParameterSection>(Track->FindOrAddSection(0, bSectionAdded));
}
if (!SectionToKey)
{
return;
}
TArray<FFBXNodeAndChannels>* NodeAndChannels = Track->GetNodeAndChannelMappings();
TArray<FFBXNodeAndChannels>* NodeAndChannels = Track->GetNodeAndChannelMappings(SectionToKey);
MenuBuilder.BeginSection("Import To Control Rig", NSLOCTEXT("Sequencer", "ImportToControlRig", "Import To Control Rig"));
{

Some files were not shown because too many files have changed in this diff Show More