Files
UnrealEngineUWP/Engine/Source/Editor/Persona/Private/SAnimationEditorViewport.cpp
Lina Halper d4fa240f84 #ANIM: Added toolbar for preview/show ref pose
- Fixed ref pose to be edit mode

[CL 2607387 by Lina Halper in Main branch]
2015-07-01 09:36:43 -04:00

2036 lines
68 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "PersonaPrivatePCH.h"
#include "SAnimationEditorViewport.h"
#include "SAnimationScrubPanel.h"
#include "SAnimMontageScrubPanel.h"
#include "Runtime/Engine/Public/Slate/SceneViewport.h"
#include "SAnimViewportToolBar.h"
#include "AnimViewportMenuCommands.h"
#include "AnimViewportShowCommands.h"
#include "AnimViewportLODCommands.h"
#include "AnimViewportPlaybackCommands.h"
#include "AnimGraphDefinitions.h"
#include "AnimPreviewInstance.h"
#include "AnimationEditorViewportClient.h"
#include "ScopedTransaction.h"
#include "Editor/UnrealEd/Public/LODUtilities.h"
#include "DetailLayoutBuilder.h"
#include "STextComboBox.h"
#define LOCTEXT_NAMESPACE "PersonaViewportToolbar"
namespace EAnimationPlaybackSpeeds
{
// Speed scales for animation playback, must match EAnimationPlaybackSpeeds::Type
float Values[EAnimationPlaybackSpeeds::NumPlaybackSpeeds] = {0.1f, 0.25f, 0.5f, 1.0f, 2.0f, 5.0f, 10.0f};
};
//////////////////////////////////////////////////////////////////////////
// SAnimationEditorViewport
SAnimationEditorViewport::~SAnimationEditorViewport()
{
if(PersonaPtr.IsValid())
{
PersonaPtr.Pin()->UnregisterOnPostUndo(this);
}
}
void SAnimationEditorViewport::Construct(const FArguments& InArgs, TSharedPtr<class FPersona> InPersona, TSharedPtr<class SAnimationEditorViewportTabBody> InTabBody)
{
PersonaPtr = InPersona;
TabBodyPtr = InTabBody;
PersonaPtr.Pin()->RegisterOnPostUndo(FPersona::FOnPostUndo::CreateSP(this, &SAnimationEditorViewport::OnUndoRedo));
SEditorViewport::Construct(
SEditorViewport::FArguments()
.IsEnabled(FSlateApplication::Get().GetNormalExecutionAttribute())
.AddMetaData<FTagMetaData>(TEXT("Persona.Viewport"))
);
Client->VisibilityDelegate.BindSP(this, &SAnimationEditorViewport::IsVisible);
}
TSharedRef<FEditorViewportClient> SAnimationEditorViewport::MakeEditorViewportClient()
{
// Create an animation viewport client
LevelViewportClient = MakeShareable(new FAnimationViewportClient(PersonaPtr.Pin()->GetPreviewScene(), PersonaPtr, SharedThis(this)));
LevelViewportClient->ViewportType = LVT_Perspective;
LevelViewportClient->bSetListenerPosition = false;
LevelViewportClient->SetViewLocation(EditorViewportDefs::DefaultPerspectiveViewLocation);
LevelViewportClient->SetViewRotation(EditorViewportDefs::DefaultPerspectiveViewRotation);
return LevelViewportClient.ToSharedRef();
}
TSharedPtr<SWidget> SAnimationEditorViewport::MakeViewportToolbar()
{
return SNew(SAnimViewportToolBar, TabBodyPtr.Pin(), SharedThis(this))
.Cursor(EMouseCursor::Default);
}
void SAnimationEditorViewport::OnUndoRedo()
{
LevelViewportClient->Invalidate();
LevelViewportClient->PostUndo();
}
//////////////////////////////////////////////////////////////////////////
//
/** //@TODO MODES: Simple text entry popup used it to get 3 vector position*/
class STranslationInputWindow : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS( STranslationInputWindow )
: _X_Value(0.0f)
, _Y_Value(0.0f)
, _Z_Value(0.0f)
{}
SLATE_ARGUMENT( float, X_Value )
SLATE_ARGUMENT( float, Y_Value )
SLATE_ARGUMENT( float, Z_Value )
SLATE_EVENT( FOnTextCommitted, OnXModified )
SLATE_EVENT( FOnTextCommitted, OnYModified )
SLATE_EVENT( FOnTextCommitted, OnZModified )
SLATE_END_ARGS()
void Construct( const FArguments& InArgs )
{
FString XString = FString::Printf(TEXT("%0.2f"), InArgs._X_Value);
FString YString = FString::Printf(TEXT("%0.2f"), InArgs._Y_Value);
FString ZString = FString::Printf(TEXT("%0.2f"), InArgs._Z_Value);
this->ChildSlot
[
SNew(SBorder)
. BorderImage(FEditorStyle::GetBrush(TEXT("Menu.Background")))
. Padding(10)
[
SNew(SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Text(NSLOCTEXT("AnimationEditorViewport", "XValueLabel", "X:"))
]
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SEditableTextBox)
.MinDesiredWidth(10.0f)
.Text( FText::FromString(XString) )
.OnTextCommitted( InArgs._OnXModified )
]
]
+SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Text(NSLOCTEXT("AnimationEditorViewport", "YValueLabel", "Y:"))
]
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SEditableTextBox)
.MinDesiredWidth(10.0f)
.Text( FText::FromString(YString) )
.OnTextCommitted( InArgs._OnYModified )
]
]
+SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Text(NSLOCTEXT("AnimationEditorViewport", "ZValueLabel", "Z: "))
]
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SEditableTextBox)
.MinDesiredWidth(10.0f)
.Text( FText::FromString(ZString) )
.OnTextCommitted( InArgs._OnZModified )
]
]
]
];
}
};
//////////////////////////////////////////////////////////////////////////
// SAnimationEditorViewportTabBody
SAnimationEditorViewportTabBody::SAnimationEditorViewportTabBody()
: SelectedTurnTableSpeed(EAnimationPlaybackSpeeds::Normal)
, SelectedTurnTableMode(EPersonaTurnTableMode::Stopped)
, AnimationPlaybackSpeedMode(EAnimationPlaybackSpeeds::Normal)
{
}
SAnimationEditorViewportTabBody::~SAnimationEditorViewportTabBody()
{
CleanupPersonaReferences();
// Close viewport
if (LevelViewportClient.IsValid())
{
LevelViewportClient->Viewport = NULL;
}
// Release our reference to the viewport client
LevelViewportClient.Reset();
}
void SAnimationEditorViewportTabBody::CleanupPersonaReferences()
{
if (PersonaPtr.IsValid())
{
PersonaPtr.Pin()->UnregisterOnAnimChanged(this);
PersonaPtr.Reset();
}
}
bool SAnimationEditorViewportTabBody::CanUseGizmos() const
{
class UDebugSkelMeshComponent* Component = PersonaPtr.Pin()->PreviewComponent;
if (Component != NULL)
{
if (Component->bForceRefpose)
{
return false;
}
else if (Component->IsPreviewOn())
{
return true;
}
}
return false;
}
FText SAnimationEditorViewportTabBody::GetDisplayString() const
{
class UDebugSkelMeshComponent* Component = PersonaPtr.Pin()->PreviewComponent;
FString TargetSkeletonName = TargetSkeleton ? TargetSkeleton->GetName() : FName(NAME_None).ToString();
if (Component != NULL)
{
if (Component->bForceRefpose)
{
return LOCTEXT("ReferencePose", "Reference pose");
}
else if (Component->IsPreviewOn())
{
return FText::Format(LOCTEXT("Previewing", "Previewing {0}"), FText::FromString(Component->GetPreviewText()));
}
else if (Component->AnimBlueprintGeneratedClass != NULL)
{
const bool bWarnAboutBoneManip = !PersonaPtr.Pin()->IsModeCurrent(FPersonaModes::AnimBlueprintEditMode);
if (bWarnAboutBoneManip)
{
return FText::Format(LOCTEXT("PreviewingAnimBP_WarnDisabled", "Previewing {0}. \nBone manipulation is disabled in this mode. "), FText::FromString(Component->AnimBlueprintGeneratedClass->GetName()));
}
else
{
return FText::Format(LOCTEXT("PreviewingAnimBP", "Previewing {0}"), FText::FromString(Component->AnimBlueprintGeneratedClass->GetName()));
}
}
else if (Component->SkeletalMesh == NULL)
{
return FText::Format(LOCTEXT("NoMeshFound", "No skeletal mesh found for skeleton '{0}'"), FText::FromString(TargetSkeletonName));
}
else
{
return LOCTEXT("NothingToPlay", "Nothing to play");
}
}
else
{
return FText::Format(LOCTEXT("NoMeshFound", "No skeletal mesh found for skeleton '{0}'"), FText::FromString(TargetSkeletonName));
}
}
void SAnimationEditorViewportTabBody::RefreshViewport()
{
LevelViewportClient->Invalidate();
}
bool SAnimationEditorViewportTabBody::IsVisible() const
{
return ViewportWidget.IsValid();
}
void SAnimationEditorViewportTabBody::Construct(const FArguments& InArgs)
{
UICommandList = MakeShareable(new FUICommandList);
PersonaPtr = InArgs._Persona;
IsEditable = InArgs._IsEditable;
TargetSkeleton = InArgs._Skeleton;
bPreviewLockModeOn = 0;
LODSelection = LOD_Auto;
TSharedPtr<FPersona> SharedPersona = PersonaPtr.Pin();
check(SharedPersona.IsValid());
// register delegate for anim change notification
SharedPersona->RegisterOnAnimChanged(FPersona::FOnAnimChanged::CreateSP(this, &SAnimationEditorViewportTabBody::AnimChanged));
const FSlateFontInfo SmallLayoutFont( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 10 );
FAnimViewportMenuCommands::Register();
FAnimViewportShowCommands::Register();
FAnimViewportLODCommands::Register();
FAnimViewportPlaybackCommands::Register();
// Build toolbar widgets
UVChannelCombo = SNew(STextComboBox)
.OptionsSource(&UVChannels)
.OnSelectionChanged(this, &SAnimationEditorViewportTabBody::ComboBoxSelectionChanged);
ViewportWidget = SNew(SAnimationEditorViewport, InArgs._Persona, SharedThis(this));
TSharedPtr<SVerticalBox> ViewportContainer = nullptr;
this->ChildSlot
[
SAssignNew(ViewportContainer, SVerticalBox)
// Build our toolbar level toolbar
+SVerticalBox::Slot()
.FillHeight(1)
[
SNew(SOverlay)
// The viewport
+SOverlay::Slot()
[
ViewportWidget.ToSharedRef()
]
// The 'dirty/in-error' indicator text in the bottom-right corner
+SOverlay::Slot()
.Padding(8)
.VAlign(VAlign_Bottom)
.HAlign(HAlign_Right)
[
SNew(SButton)
.ButtonStyle(FEditorStyle::Get(), "NoBorder")
.Visibility(this, &SAnimationEditorViewportTabBody::GetViewportCornerTextVisibility)
.OnClicked(this, &SAnimationEditorViewportTabBody::ClickedOnViewportCornerText)
.Content()
[
SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SImage)
.Visibility(this, &SAnimationEditorViewportTabBody::GetViewportCornerImageVisibility)
.Image(this, &SAnimationEditorViewportTabBody::GetViewportCornerImage)
]
+SHorizontalBox::Slot()
.FillWidth(1)
[
SNew(STextBlock)
.TextStyle(FEditorStyle::Get(), "Persona.Viewport.BlueprintDirtyText")
.Text(this, &SAnimationEditorViewportTabBody::GetViewportCornerText)
.ToolTipText(this, &SAnimationEditorViewportTabBody::GetViewportCornerTooltip)
]
]
]
]
];
if(!SharedPersona->IsModeCurrent(FPersonaModes::AnimationEditMode) && ViewportContainer.IsValid())
{
ViewportContainer->AddSlot()
.AutoHeight()
[
SAssignNew(ScrubPanelContainer, SVerticalBox)
+SVerticalBox::Slot()
.AutoHeight()
[
SNew(SAnimationScrubPanel)
.Persona(PersonaPtr)
.ViewInputMin(this, &SAnimationEditorViewportTabBody::GetViewMinInput)
.ViewInputMax(this, &SAnimationEditorViewportTabBody::GetViewMaxInput)
.bAllowZoom(true)
]
];
UpdateScrubPanel(Cast<UAnimationAsset>(SharedPersona->GetPreviewAnimationAsset()));
}
LevelViewportClient = ViewportWidget->GetViewportClient();
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
// Load the view mode from config
AnimViewportClient->SetViewMode(AnimViewportClient->ConfigOption->ViewModeIndex);
UpdateShowFlagForMeshEdges();
UpdateViewportClientPlaybackScale();
OnSetTurnTableMode(SelectedTurnTableMode);
OnSetTurnTableSpeed(SelectedTurnTableSpeed);
BindCommands();
}
void SAnimationEditorViewportTabBody::BindCommands()
{
FUICommandList& CommandList = *UICommandList;
//Bind menu commands
const FAnimViewportMenuCommands& MenuActions = FAnimViewportMenuCommands::Get();
CommandList.MapAction(
MenuActions.Lock,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::SetPreviewMode, 1),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsPreviewModeOn, 1));
CommandList.MapAction(
MenuActions.Auto,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::SetPreviewMode, 0),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsPreviewModeOn, 0));
CommandList.MapAction(
MenuActions.CameraFollow,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::ToggleCameraFollow),
FCanExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::CanChangeCameraMode),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsCameraFollowEnabled));
CommandList.MapAction(
MenuActions.UseInGameBound,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::UseInGameBound),
FCanExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::CanUseInGameBound),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsUsingInGameBound));
TSharedRef<FAnimationViewportClient> EditorViewportClientRef = GetAnimationViewportClient();
CommandList.MapAction(
MenuActions.SetShowNormals,
FExecuteAction::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::ToggleShowNormals ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::IsSetShowNormalsChecked ) );
CommandList.MapAction(
MenuActions.SetShowTangents,
FExecuteAction::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::ToggleShowTangents ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::IsSetShowTangentsChecked ) );
CommandList.MapAction(
MenuActions.SetShowBinormals,
FExecuteAction::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::ToggleShowBinormals ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::IsSetShowBinormalsChecked ) );
CommandList.MapAction(
MenuActions.AnimSetDrawUVs,
FExecuteAction::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::ToggleDrawUVOverlay ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( EditorViewportClientRef, &FAnimationViewportClient::IsSetDrawUVOverlayChecked ) );
//Bind Show commands
const FAnimViewportShowCommands& ViewportShowMenuCommands = FAnimViewportShowCommands::Get();
CommandList.MapAction(
ViewportShowMenuCommands.ShowReferencePose,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::ShowReferencePose),
FCanExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::CanShowReferencePose),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowReferencePoseEnabled));
CommandList.MapAction(
ViewportShowMenuCommands.ShowRetargetBasePose,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::ShowRetargetBasePose),
FCanExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::CanShowRetargetBasePose),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowRetargetBasePoseEnabled));
CommandList.MapAction(
ViewportShowMenuCommands.ShowBound,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::ShowBound),
FCanExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::CanShowBound),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowBoundEnabled));
CommandList.MapAction(
ViewportShowMenuCommands.ShowPreviewMesh,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::ToggleShowPreviewMesh),
FCanExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::CanShowPreviewMesh),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowPreviewMeshEnabled));
CommandList.MapAction(
ViewportShowMenuCommands.ShowMorphTargets,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowMorphTargets),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingMorphTargets));
CommandList.MapAction(
ViewportShowMenuCommands.ShowBones,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowBones),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingBones));
CommandList.MapAction(
ViewportShowMenuCommands.ShowBoneNames,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowBoneNames),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingBoneNames));
CommandList.MapAction(
ViewportShowMenuCommands.ShowRawAnimation,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowRawAnimation),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingRawAnimation));
CommandList.MapAction(
ViewportShowMenuCommands.ShowNonRetargetedAnimation,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowNonRetargetedAnimation),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingNonRetargetedPose));
CommandList.MapAction(
ViewportShowMenuCommands.ShowAdditiveBaseBones,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowAdditiveBase),
FCanExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::IsPreviewingAnimation),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingAdditiveBase));
CommandList.MapAction(
ViewportShowMenuCommands.ShowSourceRawAnimation,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowSourceRawAnimation),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingSourceRawAnimation));
CommandList.MapAction(
ViewportShowMenuCommands.ShowBakedAnimation,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowBakedAnimation),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingBakedAnimation));
//Display info
CommandList.MapAction(
ViewportShowMenuCommands.ShowDisplayInfoBasic,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowDisplayInfo, (int32)EDisplayInfoMode::Basic),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingMeshInfo, (int32)EDisplayInfoMode::Basic));
CommandList.MapAction(
ViewportShowMenuCommands.ShowDisplayInfoDetailed,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowDisplayInfo, (int32)EDisplayInfoMode::Detailed),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingMeshInfo, (int32)EDisplayInfoMode::Detailed));
CommandList.MapAction(
ViewportShowMenuCommands.HideDisplayInfo,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowDisplayInfo, (int32)EDisplayInfoMode::None),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingMeshInfo, (int32)EDisplayInfoMode::None));
//Bone weight
CommandList.MapAction(
ViewportShowMenuCommands.ShowBoneWeight,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowBoneWeight),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingBoneWeight));
// Show sockets
CommandList.MapAction(
ViewportShowMenuCommands.ShowSockets,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowSockets),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingSockets));
// Set bone local axes mode
CommandList.MapAction(
ViewportShowMenuCommands.ShowLocalAxesNone,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLocalAxesMode, (int32)ELocalAxesMode::None),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLocalAxesModeSet, (int32)ELocalAxesMode::None));
CommandList.MapAction(
ViewportShowMenuCommands.ShowLocalAxesSelected,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLocalAxesMode, (int32)ELocalAxesMode::Selected),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLocalAxesModeSet, (int32)ELocalAxesMode::Selected));
CommandList.MapAction(
ViewportShowMenuCommands.ShowLocalAxesAll,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLocalAxesMode, (int32)ELocalAxesMode::All),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLocalAxesModeSet, (int32)ELocalAxesMode::All));
#if WITH_APEX_CLOTHING
//Clothing show options
CommandList.MapAction(
ViewportShowMenuCommands.DisableClothSimulation,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnDisableClothSimulation),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsDisablingClothSimulation));
//Apply wind
CommandList.MapAction(
ViewportShowMenuCommands.ApplyClothWind,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnApplyClothWind),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsApplyingClothWind));
//Cloth simulation normal
CommandList.MapAction(
ViewportShowMenuCommands.ShowClothSimulationNormals,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowClothSimulationNormals),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingClothSimulationNormals));
CommandList.MapAction(
ViewportShowMenuCommands.ShowClothGraphicalTangents,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowClothGraphicalTangents),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingClothGraphicalTangents));
CommandList.MapAction(
ViewportShowMenuCommands.ShowClothCollisionVolumes,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowClothCollisionVolumes),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingClothCollisionVolumes));
CommandList.MapAction(
ViewportShowMenuCommands.EnableCollisionWithAttachedClothChildren,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnEnableCollisionWithAttachedClothChildren),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsEnablingCollisionWithAttachedClothChildren));
CommandList.MapAction(
ViewportShowMenuCommands.ShowClothPhysicalMeshWire,
FExecuteAction::CreateSP( this, &SAnimationEditorViewportTabBody::OnShowClothPhysicalMeshWire ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( this, &SAnimationEditorViewportTabBody::IsShowingClothPhysicalMeshWire ) );
CommandList.MapAction(
ViewportShowMenuCommands.ShowClothMaxDistances,
FExecuteAction::CreateSP( this, &SAnimationEditorViewportTabBody::OnShowClothMaxDistances ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( this, &SAnimationEditorViewportTabBody::IsShowingClothMaxDistances ) );
CommandList.MapAction(
ViewportShowMenuCommands.ShowClothBackstop,
FExecuteAction::CreateSP( this, &SAnimationEditorViewportTabBody::OnShowClothBackstops ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( this, &SAnimationEditorViewportTabBody::IsShowingClothBackstops ) );
CommandList.MapAction(
ViewportShowMenuCommands.ShowClothFixedVertices,
FExecuteAction::CreateSP( this, &SAnimationEditorViewportTabBody::OnShowClothFixedVertices ),
FCanExecuteAction(),
FIsActionChecked::CreateSP( this, &SAnimationEditorViewportTabBody::IsShowingClothFixedVertices ) );
CommandList.MapAction(
ViewportShowMenuCommands.ShowAllSections,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetSectionsDisplayMode, (int32)UDebugSkelMeshComponent::ESectionDisplayMode::ShowAll),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsSectionsDisplayMode, (int32)UDebugSkelMeshComponent::ESectionDisplayMode::ShowAll));
CommandList.MapAction(
ViewportShowMenuCommands.ShowOnlyClothSections,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetSectionsDisplayMode, (int32)UDebugSkelMeshComponent::ESectionDisplayMode::ShowOnlyClothSections),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsSectionsDisplayMode, (int32)UDebugSkelMeshComponent::ESectionDisplayMode::ShowOnlyClothSections));
CommandList.MapAction(
ViewportShowMenuCommands.HideOnlyClothSections,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetSectionsDisplayMode, (int32)UDebugSkelMeshComponent::ESectionDisplayMode::HideOnlyClothSections),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsSectionsDisplayMode, (int32)UDebugSkelMeshComponent::ESectionDisplayMode::HideOnlyClothSections));
#endif// #if WITH_APEX_CLOTHING
//Bind LOD preview menu commands
const FAnimViewportLODCommands& ViewportLODMenuCommands = FAnimViewportLODCommands::Get();
//LOD Auto
CommandList.MapAction(
ViewportLODMenuCommands.LODAuto,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLODModel, LOD_Auto),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLODModelSelected, LOD_Auto));
//LOD 0
CommandList.MapAction(
ViewportLODMenuCommands.LOD0,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLODModel, LOD_0),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLODModelSelected, LOD_0));
//LOD 1
CommandList.MapAction(
ViewportLODMenuCommands.LOD1,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLODModel, LOD_1),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLODModelSelected, LOD_1));
//LOD 2
CommandList.MapAction(
ViewportLODMenuCommands.LOD2,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLODModel, LOD_2),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLODModelSelected, LOD_2));
//LOD 3
CommandList.MapAction(
ViewportLODMenuCommands.LOD3,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetLODModel, LOD_3),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsLODModelSelected, LOD_3));
CommandList.MapAction(
ViewportShowMenuCommands.ToggleGrid,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowGrid),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingGrid));
CommandList.MapAction(
ViewportShowMenuCommands.ToggleFloor,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowFloor),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingFloor));
CommandList.MapAction(
ViewportShowMenuCommands.AutoAlignFloorToMesh,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnToggleAutoAlignFloor),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsAutoAlignFloor));
CommandList.MapAction(
ViewportShowMenuCommands.ToggleSky,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnShowSky),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsShowingSky));
//Bind LOD preview menu commands
const FAnimViewportPlaybackCommands& ViewportPlaybackCommands = FAnimViewportPlaybackCommands::Get();
//Create a menu item for each playback speed in EAnimationPlaybackSpeeds
for(int32 i = 0; i < int(EAnimationPlaybackSpeeds::NumPlaybackSpeeds); ++i)
{
CommandList.MapAction(
ViewportPlaybackCommands.PlaybackSpeedCommands[i],
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetPlaybackSpeed, i),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsPlaybackSpeedSelected, i));
}
CommandList.MapAction(
ViewportShowMenuCommands.MuteAudio,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnMuteAudio),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsAudioMuted));
CommandList.MapAction(
ViewportShowMenuCommands.ProcessRootMotion,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnTogglePreviewRootMotion),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsPreviewingRootMotion));
// Turn Table Controls
for (int32 i = 0; i < int(EAnimationPlaybackSpeeds::NumPlaybackSpeeds); ++i)
{
CommandList.MapAction(
ViewportPlaybackCommands.TurnTableSpeeds[i],
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetTurnTableSpeed, i),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsTurnTableSpeedSelected, i));
}
CommandList.MapAction(
ViewportPlaybackCommands.PersonaTurnTablePlay,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetTurnTableMode, int32(EPersonaTurnTableMode::Playing)),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsTurnTableModeSelected, int32(EPersonaTurnTableMode::Playing)));
CommandList.MapAction(
ViewportPlaybackCommands.PersonaTurnTablePause,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetTurnTableMode, int32(EPersonaTurnTableMode::Paused)),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsTurnTableModeSelected, int32(EPersonaTurnTableMode::Paused)));
CommandList.MapAction(
ViewportPlaybackCommands.PersonaTurnTableStop,
FExecuteAction::CreateSP(this, &SAnimationEditorViewportTabBody::OnSetTurnTableMode, int32(EPersonaTurnTableMode::Stopped)),
FCanExecuteAction(),
FIsActionChecked::CreateSP(this, &SAnimationEditorViewportTabBody::IsTurnTableModeSelected, int32(EPersonaTurnTableMode::Stopped)));
}
void SAnimationEditorViewportTabBody::OnSetTurnTableSpeed(int32 SpeedIndex)
{
SelectedTurnTableSpeed = (EAnimationPlaybackSpeeds::Type)SpeedIndex;
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (PreviewComponent)
{
PreviewComponent->TurnTableSpeedScaling = EAnimationPlaybackSpeeds::Values[SelectedTurnTableSpeed];
}
}
bool SAnimationEditorViewportTabBody::IsTurnTableSpeedSelected(int32 SpeedIndex) const
{
return (SelectedTurnTableSpeed == SpeedIndex);
}
void SAnimationEditorViewportTabBody::OnSetTurnTableMode(int32 ModeIndex)
{
SelectedTurnTableMode = (EPersonaTurnTableMode::Type)ModeIndex;
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (PreviewComponent)
{
PreviewComponent->TurnTableMode = SelectedTurnTableMode;
if (SelectedTurnTableMode == EPersonaTurnTableMode::Stopped)
{
PreviewComponent->SetRelativeRotation(FRotator::ZeroRotator);
}
}
}
bool SAnimationEditorViewportTabBody::IsTurnTableModeSelected(int32 ModeIndex) const
{
return (SelectedTurnTableMode == ModeIndex);
}
bool SAnimationEditorViewportTabBody::IsPreviewModeOn(int32 PreviewMode) const
{
if (bPreviewLockModeOn && PreviewMode)
{
return true;
}
else if (!bPreviewLockModeOn && !PreviewMode)
{
return true;
}
return false;
}
void SAnimationEditorViewportTabBody::SetPreviewMode(int32 PreviewMode)
{
if (PreviewMode)
{
bPreviewLockModeOn = true;
}
else
{
bPreviewLockModeOn = false;
}
}
int32 SAnimationEditorViewportTabBody::GetLODModelCount() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent && PreviewComponent->SkeletalMesh )
{
return PreviewComponent->SkeletalMesh->GetImportedResource()->LODModels.Num();
}
return 0;
}
void SAnimationEditorViewportTabBody::OnShowBones()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisplayBones = !PreviewComponent->bDisplayBones;
PreviewComponent->MarkRenderStateDirty();
RefreshViewport();
}
}
void SAnimationEditorViewportTabBody::OnShowMorphTargets()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisableMorphTarget = !PreviewComponent->bDisableMorphTarget;
PreviewComponent->MarkRenderStateDirty();
RefreshViewport();
}
}
void SAnimationEditorViewportTabBody::OnShowBoneNames()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bShowBoneNames = !PreviewComponent->bShowBoneNames;
PreviewComponent->MarkRenderStateDirty();
RefreshViewport();
}
}
void SAnimationEditorViewportTabBody::OnShowRawAnimation()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisplayRawAnimation = !PreviewComponent->bDisplayRawAnimation;
PreviewComponent->MarkRenderStateDirty();
}
}
void SAnimationEditorViewportTabBody::OnShowNonRetargetedAnimation()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisplayNonRetargetedPose = !PreviewComponent->bDisplayNonRetargetedPose;
PreviewComponent->MarkRenderStateDirty();
}
}
void SAnimationEditorViewportTabBody::OnShowSourceRawAnimation()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisplaySourceAnimation = !PreviewComponent->bDisplaySourceAnimation;
PreviewComponent->MarkRenderStateDirty();
}
}
void SAnimationEditorViewportTabBody::OnShowBakedAnimation()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisplayBakedAnimation = !PreviewComponent->bDisplayBakedAnimation;
PreviewComponent->MarkRenderStateDirty();
}
}
void SAnimationEditorViewportTabBody::OnShowAdditiveBase()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisplayAdditiveBasePose = !PreviewComponent->bDisplayAdditiveBasePose;
PreviewComponent->MarkRenderStateDirty();
}
}
bool SAnimationEditorViewportTabBody::IsPreviewingAnimation() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return (PreviewComponent && PreviewComponent->PreviewInstance && (PreviewComponent->PreviewInstance == PreviewComponent->AnimScriptInstance));
}
bool SAnimationEditorViewportTabBody::IsShowingBones() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDisplayBones;
}
bool SAnimationEditorViewportTabBody::IsShowingMorphTargets() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDisableMorphTarget == false;
}
bool SAnimationEditorViewportTabBody::IsShowingBoneNames() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bShowBoneNames;
}
bool SAnimationEditorViewportTabBody::IsShowingRawAnimation() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDisplayRawAnimation;
}
bool SAnimationEditorViewportTabBody::IsShowingNonRetargetedPose() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDisplayNonRetargetedPose;
}
bool SAnimationEditorViewportTabBody::IsShowingAdditiveBase() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDisplayAdditiveBasePose;
}
bool SAnimationEditorViewportTabBody::IsShowingSourceRawAnimation() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDisplaySourceAnimation;
}
bool SAnimationEditorViewportTabBody::IsShowingBakedAnimation() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDisplayBakedAnimation;
}
void SAnimationEditorViewportTabBody::OnShowDisplayInfo(int32 DisplayInfoMode)
{
GetAnimationViewportClient()->OnSetShowMeshStats(DisplayInfoMode);
}
bool SAnimationEditorViewportTabBody::IsShowingMeshInfo(int32 DisplayInfoMode) const
{
return GetAnimationViewportClient()->GetShowMeshStats() == DisplayInfoMode;
}
void SAnimationEditorViewportTabBody::OnShowBoneWeight()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->SetShowBoneWeight( !PreviewComponent->bDrawBoneInfluences );
UpdateShowFlagForMeshEdges();
PreviewComponent->MarkRenderStateDirty();
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingBoneWeight() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDrawBoneInfluences;
}
void SAnimationEditorViewportTabBody::OnSetLocalAxesMode(int32 LocalAxesMode)
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->SetLocalAxesMode((ELocalAxesMode::Type)LocalAxesMode);
}
bool SAnimationEditorViewportTabBody::IsLocalAxesModeSet(int32 LocalAxesMode) const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->IsLocalAxesModeSet((ELocalAxesMode::Type)LocalAxesMode);
}
void SAnimationEditorViewportTabBody::OnShowSockets()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDrawSockets = !PreviewComponent->bDrawSockets;
PreviewComponent->MarkRenderStateDirty();
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingSockets() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->bDrawSockets;
}
void SAnimationEditorViewportTabBody::OnShowGrid()
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->OnToggleShowGrid();
}
bool SAnimationEditorViewportTabBody::IsShowingGrid() const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->IsShowingGrid();
}
void SAnimationEditorViewportTabBody::OnShowFloor()
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->OnToggleShowFloor();
}
bool SAnimationEditorViewportTabBody::IsShowingFloor() const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->IsShowingFloor();
}
void SAnimationEditorViewportTabBody::OnToggleAutoAlignFloor()
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->OnToggleAutoAlignFloor();
}
bool SAnimationEditorViewportTabBody::IsAutoAlignFloor() const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->IsAutoAlignFloor();
}
void SAnimationEditorViewportTabBody::OnShowSky()
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->OnToggleShowSky();
}
bool SAnimationEditorViewportTabBody::IsShowingSky() const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->IsShowingSky();
}
/** Function to set the current playback speed*/
void SAnimationEditorViewportTabBody::OnSetPlaybackSpeed(int32 PlaybackSpeedMode)
{
AnimationPlaybackSpeedMode = (EAnimationPlaybackSpeeds::Type)PlaybackSpeedMode;
UpdateViewportClientPlaybackScale();
}
bool SAnimationEditorViewportTabBody::IsPlaybackSpeedSelected(int32 PlaybackSpeedMode)
{
return PlaybackSpeedMode == AnimationPlaybackSpeedMode;
}
void SAnimationEditorViewportTabBody::ShowReferencePose()
{
PersonaPtr.Pin()->ShowReferencePose(IsShowReferencePoseEnabled() == false);
}
bool SAnimationEditorViewportTabBody::CanShowReferencePose() const
{
return PersonaPtr.Pin()->CanShowReferencePose();
}
bool SAnimationEditorViewportTabBody::IsShowReferencePoseEnabled() const
{
return PersonaPtr.Pin()->IsShowReferencePoseEnabled();
}
void SAnimationEditorViewportTabBody::ShowRetargetBasePose()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if(PreviewComponent && PreviewComponent->PreviewInstance)
{
PreviewComponent->PreviewInstance->bForceRetargetBasePose = !PreviewComponent->PreviewInstance->bForceRetargetBasePose;
}
}
bool SAnimationEditorViewportTabBody::CanShowRetargetBasePose() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->PreviewInstance;
}
bool SAnimationEditorViewportTabBody::IsShowRetargetBasePoseEnabled() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if(PreviewComponent && PreviewComponent->PreviewInstance)
{
return PreviewComponent->PreviewInstance->bForceRetargetBasePose;
}
return false;
}
void SAnimationEditorViewportTabBody::ShowBound()
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->ToggleShowBounds();
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if(PreviewComponent)
{
PreviewComponent->bDisplayBound = AnimViewportClient->EngineShowFlags.Bounds;
PreviewComponent->RecreateRenderState_Concurrent();
}
}
bool SAnimationEditorViewportTabBody::CanShowBound() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL;
}
bool SAnimationEditorViewportTabBody::IsShowBoundEnabled() const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->IsSetShowBoundsChecked();
}
void SAnimationEditorViewportTabBody::ToggleShowPreviewMesh()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
bool bCurrentlyVisible = IsShowPreviewMeshEnabled();
PreviewComponent->SetVisibility(!bCurrentlyVisible);
}
}
bool SAnimationEditorViewportTabBody::CanShowPreviewMesh() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL;
}
bool SAnimationEditorViewportTabBody::IsShowPreviewMeshEnabled() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return (PreviewComponent != NULL) && PreviewComponent->IsVisible();
}
void SAnimationEditorViewportTabBody::UseInGameBound()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (PreviewComponent != NULL)
{
PreviewComponent->UseInGameBounds(! PreviewComponent->IsUsingInGameBounds());
}
}
bool SAnimationEditorViewportTabBody::CanUseInGameBound() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL;
}
bool SAnimationEditorViewportTabBody::IsUsingInGameBound() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
return PreviewComponent != NULL && PreviewComponent->IsUsingInGameBounds();
}
void SAnimationEditorViewportTabBody::SetPreviewComponent(class UDebugSkelMeshComponent* PreviewComponent)
{
PreviewComponent->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::AlwaysTickPoseAndRefreshBones;
PreviewComponent->bCanHighlightSelectedSections = true;
//Set preview skeleton mesh component
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->SetPreviewMeshComponent(PreviewComponent);
AnimViewportClient->FocusViewportOnPreviewMesh();
// Adding the component to the PreviewScene can change AnimScriptInstance so we must re register it
// with the AnimBlueprint
UAnimBlueprint* SourceBlueprint = Cast<UAnimBlueprint>(PersonaPtr.Pin()->GetBlueprintObj());
if ( SourceBlueprint && PreviewComponent->IsAnimBlueprintInstanced() )
{
SourceBlueprint->SetObjectBeingDebugged(PreviewComponent->AnimScriptInstance);
}
PopulateNumUVChannels();
}
void SAnimationEditorViewportTabBody::AnimChanged(UAnimationAsset* AnimAsset)
{
UpdateScrubPanel(AnimAsset);
}
void SAnimationEditorViewportTabBody::ComboBoxSelectionChanged(TSharedPtr<FString> NewSelection, ESelectInfo::Type SelectInfo)
{
int32 NewUVSelection = UVChannels.Find(NewSelection);
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->SetUVChannelToDraw(NewUVSelection);
RefreshViewport();
}
void SAnimationEditorViewportTabBody::PopulateNumUVChannels()
{
NumUVChannels.Empty();
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
if (FSkeletalMeshResource* MeshResource = PreviewComponent->GetSkeletalMeshResource())
{
int32 NumLods = MeshResource->LODModels.Num();
NumUVChannels.AddZeroed(NumLods);
for(int32 LOD = 0; LOD < NumLods; ++LOD)
{
NumUVChannels[LOD] = MeshResource->LODModels[LOD].VertexBufferGPUSkin.GetNumTexCoords();
}
}
}
PopulateUVChoices();
}
void SAnimationEditorViewportTabBody::PopulateUVChoices()
{
// Fill out the UV channels combo.
UVChannels.Empty();
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
int32 CurrentLOD = FMath::Clamp(PreviewComponent->ForcedLodModel - 1, 0, NumUVChannels.Num() - 1);
if (NumUVChannels.IsValidIndex(CurrentLOD))
{
for (int32 UVChannelID = 0; UVChannelID < NumUVChannels[CurrentLOD]; ++UVChannelID)
{
UVChannels.Add( MakeShareable( new FString( FText::Format( NSLOCTEXT("AnimationEditorViewport", "UVChannel_ID", "UV Channel {0}"), FText::AsNumber( UVChannelID ) ).ToString() ) ) );
}
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
int32 CurrentUVChannel = AnimViewportClient->GetUVChannelToDraw();
if (!UVChannels.IsValidIndex(CurrentUVChannel))
{
CurrentUVChannel = 0;
}
AnimViewportClient->SetUVChannelToDraw(CurrentUVChannel);
if (UVChannelCombo.IsValid() && UVChannels.IsValidIndex(CurrentUVChannel))
{
UVChannelCombo->SetSelectedItem(UVChannels[CurrentUVChannel]);
}
}
}
}
void SAnimationEditorViewportTabBody::UpdateScrubPanel(UAnimationAsset* AnimAsset)
{
// We might not have a scrub panel if we're in animation mode.
if (ScrubPanelContainer.IsValid())
{
ScrubPanelContainer->ClearChildren();
bool bUseDefaultScrubPanel = true;
if (UAnimMontage* Montage = Cast<UAnimMontage>(AnimAsset))
{
ScrubPanelContainer->AddSlot()
.AutoHeight()
[
SNew(SAnimMontageScrubPanel)
.Persona(PersonaPtr)
.ViewInputMin(this, &SAnimationEditorViewportTabBody::GetViewMinInput)
.ViewInputMax(this, &SAnimationEditorViewportTabBody::GetViewMaxInput)
.bAllowZoom(true)
];
bUseDefaultScrubPanel = false;
}
if(bUseDefaultScrubPanel)
{
ScrubPanelContainer->AddSlot()
.AutoHeight()
[
SNew(SAnimationScrubPanel)
.Persona(PersonaPtr)
.ViewInputMin(this, &SAnimationEditorViewportTabBody::GetViewMinInput)
.ViewInputMax(this, &SAnimationEditorViewportTabBody::GetViewMaxInput)
.bAllowZoom(true)
];
}
}
}
float SAnimationEditorViewportTabBody::GetViewMinInput() const
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
UObject* PreviewAsset = PersonaPtr.Pin()->GetPreviewAnimationAsset();
if (PreviewAsset != NULL)
{
return 0.0f;
}
else if (PreviewComponent->AnimScriptInstance != NULL)
{
return FMath::Max<float>((float)(PreviewComponent->AnimScriptInstance->LifeTimer - 30.0), 0.0f);
}
}
return 0.f;
}
float SAnimationEditorViewportTabBody::GetViewMaxInput() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (PreviewComponent != NULL)
{
UObject* PreviewAsset = PersonaPtr.Pin()->GetPreviewAnimationAsset();
if ((PreviewAsset != NULL) && (PreviewComponent->PreviewInstance != NULL))
{
return PreviewComponent->PreviewInstance->GetLength();
}
else if (PreviewComponent->AnimScriptInstance != NULL)
{
return PreviewComponent->AnimScriptInstance->LifeTimer;
}
}
return 0.f;
}
void SAnimationEditorViewportTabBody::UpdateShowFlagForMeshEdges()
{
bool bDrawBonesInfluence = false;
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
bDrawBonesInfluence = PreviewComponent->bDrawBoneInfluences;
}
//@TODO: SNOWPOCALYPSE: broke UnlitWithMeshEdges
bool bShowMeshEdgesViewMode = false;
#if 0
bShowMeshEdgesViewMode = (CurrentViewMode == EAnimationEditorViewportMode::UnlitWithMeshEdges);
#endif
LevelViewportClient->EngineShowFlags.MeshEdges = (bDrawBonesInfluence || bShowMeshEdgesViewMode) ? 1 : 0;
}
bool SAnimationEditorViewportTabBody::IsLODModelSelected(ELODViewSelection LODSelectionType) const
{
return (LODSelection == LODSelectionType) ? true : false;
}
void SAnimationEditorViewportTabBody::OnSetLODModel(ELODViewSelection LODSelectionType)
{
LODSelection = LODSelectionType;
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->ForcedLodModel = LODSelection;
PopulateUVChoices();
}
}
FLinearColor SAnimationEditorViewportTabBody::GetViewportBackgroundColor() const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->GetBackgroundColor();
}
void SAnimationEditorViewportTabBody::SetViewportBackgroundColor(FLinearColor InColor)
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->SetBackgroundColor( InColor );
}
float SAnimationEditorViewportTabBody::GetBackgroundBrightness() const
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return AnimViewportClient->GetBrightnessValue();
}
void SAnimationEditorViewportTabBody::SetBackgroundBrightness(float Value)
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->SetBrightnessValue(Value);
RefreshViewport();
}
TSharedRef<FAnimationViewportClient> SAnimationEditorViewportTabBody::GetAnimationViewportClient() const
{
return StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
}
void SAnimationEditorViewportTabBody::ToggleCameraFollow()
{
// Switch to rotation mode
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->SetCameraFollow();
}
bool SAnimationEditorViewportTabBody::IsCameraFollowEnabled() const
{
// need a single selected bone in the skeletal tree
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
return (AnimViewportClient->IsSetCameraFollowChecked());
}
bool SAnimationEditorViewportTabBody::CanChangeCameraMode() const
{
//Not allowed to change camera type when we are in an ortho camera
return !LevelViewportClient->IsOrtho();
}
void SAnimationEditorViewportTabBody::SaveData(class SAnimationEditorViewportTabBody* OldViewport)
{
if ( PersonaPtr.IsValid() && OldViewport )
{
FPersonaModeSharedData& SharedData = PersonaPtr.Pin()->ModeSharedData;
TSharedRef<FAnimationViewportClient> OldAnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(OldViewport->LevelViewportClient.ToSharedRef());
// set camera set up
SharedData.ViewLocation = OldAnimViewportClient.Get().GetViewLocation();
SharedData.ViewRotation = OldAnimViewportClient.Get().GetViewRotation();
SharedData.LookAtLocation = OldAnimViewportClient.Get().GetLookAtLocation();
SharedData.OrthoZoom = OldAnimViewportClient.Get().GetOrthoZoom();
SharedData.bCameraLock = OldAnimViewportClient.Get().IsCameraLocked();
SharedData.bCameraFollow = OldAnimViewportClient.Get().IsSetCameraFollowChecked();
SharedData.bShowBound = OldAnimViewportClient.Get().IsSetShowBoundsChecked();
SharedData.LocalAxesMode = OldAnimViewportClient.Get().GetLocalAxesMode();
SharedData.ViewportType = OldAnimViewportClient.Get().ViewportType;
SharedData.PlaybackSpeedMode = OldViewport->AnimationPlaybackSpeedMode;
}
}
void SAnimationEditorViewportTabBody::RestoreData()
{
if ( PersonaPtr.IsValid() )
{
FPersonaModeSharedData& SharedData = PersonaPtr.Pin()->ModeSharedData;
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient.Get().SetViewportType((ELevelViewportType)SharedData.ViewportType);
AnimViewportClient.Get().SetViewLocation( SharedData.ViewLocation );
AnimViewportClient.Get().SetViewRotation( SharedData.ViewRotation );
AnimViewportClient.Get().SetShowBounds(SharedData.bShowBound);
AnimViewportClient.Get().SetLocalAxesMode((ELocalAxesMode::Type)SharedData.LocalAxesMode);
AnimViewportClient.Get().SetOrthoZoom(SharedData.OrthoZoom);
OnSetPlaybackSpeed(SharedData.PlaybackSpeedMode);
if (SharedData.bCameraLock)
{
AnimViewportClient.Get().SetLookAtLocation( SharedData.LookAtLocation );
}
else if(SharedData.bCameraFollow)
{
AnimViewportClient.Get().SetCameraFollow();
}
}
}
void SAnimationEditorViewportTabBody::UpdateViewportClientPlaybackScale()
{
TSharedRef<FAnimationViewportClient> AnimViewportClient = StaticCastSharedRef<FAnimationViewportClient>(LevelViewportClient.ToSharedRef());
AnimViewportClient->SetPlaybackScale(EAnimationPlaybackSpeeds::Values[AnimationPlaybackSpeedMode]);
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (PreviewComponent)
{
PreviewComponent->PlaybackSpeedScaling = EAnimationPlaybackSpeeds::Values[AnimationPlaybackSpeedMode];
}
}
void SAnimationEditorViewportTabBody::OnLODChanged()
{
int32 LodCount = 0;
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent && PreviewComponent->SkeletalMesh )
{
LodCount = PreviewComponent->SkeletalMesh->GetImportedResource()->LODModels.Num();
}
// If the currently selected LoD is invalid, revert to LOD_Auto
if ( LodCount < LODSelection )
{
OnSetLODModel( LOD_Auto );
}
if (PersonaPtr.Pin()->PersonaMeshDetailLayout)
{
PersonaPtr.Pin()->PersonaMeshDetailLayout->ForceRefreshDetails();
}
}
void SAnimationEditorViewportTabBody::OnMuteAudio()
{
GetAnimationViewportClient()->OnToggleMuteAudio();
}
bool SAnimationEditorViewportTabBody::IsAudioMuted()
{
return GetAnimationViewportClient()->IsAudioMuted();
}
void SAnimationEditorViewportTabBody::OnTogglePreviewRootMotion()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (PreviewComponent)
{
PreviewComponent->bPreviewRootMotion = !PreviewComponent->bPreviewRootMotion;
}
}
bool SAnimationEditorViewportTabBody::IsPreviewingRootMotion() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (PreviewComponent)
{
return PreviewComponent->bPreviewRootMotion;
}
return false;
}
#if WITH_APEX_CLOTHING
bool SAnimationEditorViewportTabBody::IsDisablingClothSimulation() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->bDisableClothSimulation;
}
return false;
}
void SAnimationEditorViewportTabBody::OnDisableClothSimulation()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDisableClothSimulation = !PreviewComponent->bDisableClothSimulation;
// if the user turns on cloth simulation option while displaying max distances, then turns off max distance option
if(!PreviewComponent->bDisableClothSimulation && PreviewComponent->bDisplayClothMaxDistances)
{
PreviewComponent->bDisplayClothMaxDistances = false;
}
// if the user turns on cloth simulation option while displaying back stops, then turns off back stops option
if (!PreviewComponent->bDisableClothSimulation && PreviewComponent->bDisplayClothBackstops)
{
PreviewComponent->bDisplayClothBackstops = false;
}
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsApplyingClothWind() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->IsWindEnabled();
}
return false;
}
void SAnimationEditorViewportTabBody::OnApplyClothWind()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bEnableWind = !PreviewComponent->IsWindEnabled();
GetAnimationViewportClient()->EnableWindActor(PreviewComponent->IsWindEnabled());
RefreshViewport();
}
}
void SAnimationEditorViewportTabBody::SetWindStrength(float SliderPos)
{
GetAnimationViewportClient()->SetWindStrength( SliderPos );
RefreshViewport();
}
float SAnimationEditorViewportTabBody::GetWindStrengthSliderValue() const
{
return GetAnimationViewportClient()->GetWindStrengthSliderValue();
}
FText SAnimationEditorViewportTabBody::GetWindStrengthLabel() const
{
return GetAnimationViewportClient()->GetWindStrengthLabel();
}
void SAnimationEditorViewportTabBody::OnShowClothSimulationNormals()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDisplayClothingNormals = !PreviewComponent->bDisplayClothingNormals;
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingClothSimulationNormals() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->bDisplayClothingNormals;
}
return false;
}
void SAnimationEditorViewportTabBody::OnShowClothGraphicalTangents()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDisplayClothingTangents = !PreviewComponent->bDisplayClothingTangents;
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingClothGraphicalTangents() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->bDisplayClothingTangents;
}
return false;
}
void SAnimationEditorViewportTabBody::OnShowClothCollisionVolumes()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDisplayClothingCollisionVolumes = !PreviewComponent->bDisplayClothingCollisionVolumes;
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingClothCollisionVolumes() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->bDisplayClothingCollisionVolumes;
}
return false;
}
void SAnimationEditorViewportTabBody::SetGravityScale(float SliderPos)
{
GetAnimationViewportClient()->SetGravityScale(SliderPos);
RefreshViewport();
}
float SAnimationEditorViewportTabBody::GetGravityScaleSliderValue() const
{
return GetAnimationViewportClient()->GetGravityScaleSliderValue();
}
FText SAnimationEditorViewportTabBody::GetGravityScaleLabel() const
{
return GetAnimationViewportClient()->GetGravityScaleLabel();
}
void SAnimationEditorViewportTabBody::OnEnableCollisionWithAttachedClothChildren()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bCollideWithAttachedChildren = !PreviewComponent->bCollideWithAttachedChildren;
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsEnablingCollisionWithAttachedClothChildren() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->bCollideWithAttachedChildren;
}
return false;
}
void SAnimationEditorViewportTabBody::OnShowClothPhysicalMeshWire()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDisplayClothPhysicalMeshWire = !PreviewComponent->bDisplayClothPhysicalMeshWire;
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingClothPhysicalMeshWire() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->bDisplayClothPhysicalMeshWire;
}
return false;
}
void SAnimationEditorViewportTabBody::OnShowClothMaxDistances()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDisplayClothMaxDistances = !PreviewComponent->bDisplayClothMaxDistances;
// disables cloth simulation and stop animation because showing max distances is only useful when the cloth is not moving
if(PreviewComponent->bDisplayClothMaxDistances)
{
PreviewComponent->bPrevDisableClothSimulation = PreviewComponent->bDisableClothSimulation;
PreviewComponent->bDisableClothSimulation = true;
PreviewComponent->InitAnim(false);
}
else
{
// restore previous state
PreviewComponent->bDisableClothSimulation = PreviewComponent->bPrevDisableClothSimulation;
}
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingClothMaxDistances() const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
return PreviewComponent->bDisplayClothMaxDistances;
}
return false;
}
void SAnimationEditorViewportTabBody::OnShowClothBackstops()
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if( PreviewComponent )
{
PreviewComponent->bDisplayClothBackstops = !PreviewComponent->bDisplayClothBackstops;
// disables cloth simulation and stop animation because showing back stops is only useful when the cloth is not moving
if (PreviewComponent->bDisplayClothBackstops)
{
PreviewComponent->bPrevDisableClothSimulation = PreviewComponent->bDisableClothSimulation;
PreviewComponent->bDisableClothSimulation = true;
PreviewComponent->InitAnim(false);
}
else
{
// restore previous state
PreviewComponent->bDisableClothSimulation = PreviewComponent->bPrevDisableClothSimulation;
}
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingClothBackstops() const
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
return PreviewComponent->bDisplayClothBackstops;
}
return false;
}
void SAnimationEditorViewportTabBody::OnShowClothFixedVertices()
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
PreviewComponent->bDisplayClothFixedVertices = !PreviewComponent->bDisplayClothFixedVertices;
RefreshViewport();
}
}
bool SAnimationEditorViewportTabBody::IsShowingClothFixedVertices() const
{
if (UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent)
{
return PreviewComponent->bDisplayClothFixedVertices;
}
return false;
}
void SAnimationEditorViewportTabBody::OnSetSectionsDisplayMode(int32 DisplayMode)
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (!PreviewComponent)
{
return;
}
PreviewComponent->SectionsDisplayMode = DisplayMode;
switch (DisplayMode)
{
case UDebugSkelMeshComponent::ESectionDisplayMode::ShowAll:
// restore to the original states
PreviewComponent->RestoreClothSectionsVisibility();
break;
case UDebugSkelMeshComponent::ESectionDisplayMode::ShowOnlyClothSections:
// disable all except clothing sections and shows only cloth sections
PreviewComponent->ToggleClothSectionsVisibility(true);
break;
case UDebugSkelMeshComponent::ESectionDisplayMode::HideOnlyClothSections:
// disables only clothing sections
PreviewComponent->ToggleClothSectionsVisibility(false);
break;
}
RefreshViewport();
}
bool SAnimationEditorViewportTabBody::IsSectionsDisplayMode(int32 DisplayMode) const
{
UDebugSkelMeshComponent* PreviewComponent = PersonaPtr.Pin()->PreviewComponent;
if (ensure(PreviewComponent))
{
return (PreviewComponent->SectionsDisplayMode == DisplayMode);
}
return false;
}
#endif // #if WITH_APEX_CLOTHING
EVisibility SAnimationEditorViewportTabBody::GetViewportCornerImageVisibility() const
{
TSharedPtr<FPersona> Persona = PersonaPtr.Pin();
return Persona->Recorder.InRecording()? EVisibility::Visible : EVisibility::Collapsed;
}
const FSlateBrush* SAnimationEditorViewportTabBody::GetViewportCornerImage() const
{
static int32 Count=0;
TSharedPtr<FPersona> Persona = PersonaPtr.Pin();
// if(Persona->Recorder.InRecording())
{
if(Count++ < 5)
{
return FEditorStyle::GetBrush("Persona.StopRecordAnimation");
}
else
{
if(Count == 10)
{
Count = 0;
}
return FEditorStyle::GetBrush("Persona.StopRecordAnimation_Alt");
}
}
// return NULL;
}
EVisibility SAnimationEditorViewportTabBody::GetViewportCornerTextVisibility() const
{
TSharedPtr<FPersona> Persona = PersonaPtr.Pin();
if (Persona->Recorder.InRecording())
{
return EVisibility::Visible;
}
else if (Persona->IsModeCurrent(FPersonaModes::AnimBlueprintEditMode))
{
if (UBlueprint* Blueprint = Persona->GetBlueprintObj())
{
const bool bUpToDate = (Blueprint->Status == BS_UpToDate) || (Blueprint->Status == BS_UpToDateWithWarnings);
return bUpToDate ? EVisibility::Collapsed : EVisibility::Visible;
}
}
return EVisibility::Collapsed;
}
FText SAnimationEditorViewportTabBody::GetViewportCornerText() const
{
TSharedPtr<FPersona> Persona = PersonaPtr.Pin();
if(Persona->Recorder.InRecording())
{
const FString& Name = Persona->Recorder.GetAnimationObject()->GetName();
float TimeRecorded = Persona->Recorder.GetTimeRecorded();
FNumberFormattingOptions NumberOption;
NumberOption.MaximumFractionalDigits = 2;
NumberOption.MinimumFractionalDigits = 2;
return FText::Format(LOCTEXT("AnimRecorder", "Recording '{0}' - Time {1} sec(s)]\nTo stop, click here. "),
FText::FromString(Name), FText::AsNumber(TimeRecorded, &NumberOption));
}
if (Persona->IsModeCurrent(FPersonaModes::AnimBlueprintEditMode))
{
if (UBlueprint* Blueprint = Persona->GetBlueprintObj())
{
switch (Blueprint->Status)
{
case BS_UpToDate:
case BS_UpToDateWithWarnings:
// Fall thru and return empty string
break;
case BS_Dirty:
return LOCTEXT("AnimBP_Dirty", "Preview out of date\nClick to recompile");
case BS_Error:
return LOCTEXT("AnimBP_CompileError", "Compile Error");
default:
return LOCTEXT("AnimBP_UnknownStatus", "Unknown Status");
}
}
}
return FText::GetEmpty();
}
FText SAnimationEditorViewportTabBody::GetViewportCornerTooltip() const
{
TSharedPtr<FPersona> Persona = PersonaPtr.Pin();
if(Persona->Recorder.InRecording())
{
return LOCTEXT("RecordingStatusTooltip", "Shows the status of animation recording.\nClick to stop the recording.");
}
if(Persona->IsModeCurrent(FPersonaModes::AnimBlueprintEditMode))
{
return LOCTEXT("BlueprintStatusTooltip", "Shows the status of the animation blueprint.\nClick to recompile a dirty blueprint");
}
return FText::GetEmpty();
}
FReply SAnimationEditorViewportTabBody::ClickedOnViewportCornerText()
{
TSharedPtr<FPersona> Persona = PersonaPtr.Pin();
// if it's recording, it won't be able to see the message
// so disable it
if (Persona->Recorder.InRecording())
{
Persona->Recorder.StopRecord(true);
}
else
{
Persona->RecompileAnimBlueprintIfDirty();
}
return FReply::Handled();
}
#undef LOCTEXT_NAMESPACE