834 lines
24 KiB
C++
834 lines
24 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "AnimPreviewInstance.h"
|
|
#include "Animation/DebugSkelMeshComponent.h"
|
|
#include "Editor.h"
|
|
#include "IAnimationEditor.h"
|
|
#include "IPersonaToolkit.h"
|
|
#include "PoseSearchDatabaseEditor.h"
|
|
#include "PoseSearchDatabaseViewModel.h"
|
|
#include "PoseSearchDebuggerDatabaseRowData.h"
|
|
#include "PoseSearchDebuggerViewModel.h"
|
|
#include "Fonts/FontMeasure.h"
|
|
#include "Framework/Application/SlateApplication.h"
|
|
#include "Preferences/PersonaOptions.h"
|
|
#include "Styling/AppStyle.h"
|
|
#include "Subsystems/AssetEditorSubsystem.h"
|
|
#include "Widgets/Input/SHyperlink.h"
|
|
#include "Widgets/Text/STextBlock.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "PoseSearchDebugger"
|
|
|
|
namespace UE::PoseSearch::DebuggerDatabaseColumns
|
|
{
|
|
constexpr float ColumnWidthPadding = 10.f;
|
|
constexpr float ColumnSortWidthPadding = 20.f;
|
|
|
|
/** Column struct to represent each column in the debugger database */
|
|
struct IColumn : TSharedFromThis<IColumn>
|
|
{
|
|
explicit IColumn(int32 InSortIndex, bool InEnabled = true)
|
|
: SortIndex(InSortIndex)
|
|
, bEnabled(InEnabled)
|
|
{
|
|
ColumnId = FName(FString::Printf(TEXT("Column %d"), SortIndex));
|
|
}
|
|
|
|
virtual ~IColumn() = default;
|
|
|
|
FName ColumnId;
|
|
|
|
/** Sorted left to right based on this index */
|
|
int32 SortIndex = 0;
|
|
/** Current width, starts at 1 to be evenly spaced between all columns */
|
|
float Width = 1.0f;
|
|
/** Disabled selectively with view options */
|
|
bool bEnabled = false;
|
|
|
|
virtual FText GetLabel() const = 0;
|
|
virtual FText GetLabelTooltip() const { return GetLabel(); }
|
|
|
|
using FRowDataRef = TSharedRef<FDebuggerDatabaseRowData>;
|
|
using FSortPredicate = TFunction<bool(const FRowDataRef&, const FRowDataRef&)>;
|
|
|
|
virtual FSortPredicate GetSortPredicate() const = 0;
|
|
|
|
virtual TSharedRef<SWidget> GenerateWidget(const FRowDataRef& RowData) const = 0;
|
|
|
|
virtual float ComputeColumnWidth(TConstArrayView<FRowDataRef> Rows) const = 0;
|
|
};
|
|
|
|
/** Column struct to represent each column in the debugger database */
|
|
struct ITextColumn : IColumn
|
|
{
|
|
explicit ITextColumn(int32 InSortIndex, bool InEnabled = true)
|
|
: IColumn(InSortIndex, InEnabled)
|
|
{
|
|
}
|
|
|
|
virtual ~ITextColumn() = default;
|
|
|
|
virtual TSharedRef<SWidget> GenerateWidget(const FRowDataRef& RowData) const override
|
|
{
|
|
static FSlateFontInfo RowFont = FAppStyle::Get().GetFontStyle("DetailsView.CategoryTextStyle");
|
|
|
|
return SNew(STextBlock)
|
|
.Font(RowFont)
|
|
.Text_Lambda([this, RowData]() -> FText { return GetRowText(RowData); })
|
|
.ToolTipText_Lambda([this, RowData]() -> FText { return GetRowToolTipText(RowData); })
|
|
.Justification(ETextJustify::Center)
|
|
.ColorAndOpacity_Lambda([this, RowData] { return GetColorAndOpacity(RowData); });
|
|
}
|
|
|
|
protected:
|
|
virtual FText GetRowText(const FRowDataRef& Row) const = 0;
|
|
virtual FText GetRowToolTipText(const FRowDataRef& Row) const
|
|
{
|
|
return FText::GetEmpty();
|
|
}
|
|
virtual FSlateColor GetColorAndOpacity(const FRowDataRef& Row) const
|
|
{
|
|
return FSlateColor(FLinearColor::White);
|
|
}
|
|
|
|
virtual float ComputeColumnWidth(TConstArrayView<TSharedRef<FDebuggerDatabaseRowData>> Rows) const override
|
|
{
|
|
const TSharedRef<FSlateFontMeasure> FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
const FSlateFontInfo & CellTextStyle = FAppStyle::GetFontStyle("SmallText");
|
|
|
|
float MinWidth = FontMeasure->Measure(GetLabel(), CellTextStyle).X + ColumnWidthPadding;
|
|
|
|
for (const TSharedRef<FDebuggerDatabaseRowData>& Row : Rows)
|
|
{
|
|
MinWidth = FMath::Max((FontMeasure->Measure(GetRowText(Row), CellTextStyle).X + ColumnWidthPadding), MinWidth);
|
|
}
|
|
|
|
return MinWidth;
|
|
}
|
|
};
|
|
|
|
struct FPoseIdx : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelPoseIndex", "Pose Id");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipPoseIndex", "Index of the Pose in the Database");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PoseIdx < Row1->PoseIdx; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->PoseIdx, &FNumberFormattingOptions::DefaultNoGrouping());
|
|
}
|
|
};
|
|
|
|
struct FAssetIdx : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelAssetIndex", "Asset Id");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipAssetIndex", "Index of the Asset in the Database");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->DbAssetIdx < Row1->DbAssetIdx; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->DbAssetIdx, &FNumberFormattingOptions::DefaultNoGrouping());
|
|
}
|
|
};
|
|
|
|
|
|
struct FDatabaseName : IColumn
|
|
{
|
|
TSharedPtr<FDebuggerViewModel> DebuggerViewModel;
|
|
|
|
FDatabaseName(int32 InSortIndex, TSharedPtr<FDebuggerViewModel> InDebuggerViewModel)
|
|
: IColumn(InSortIndex)
|
|
, DebuggerViewModel(InDebuggerViewModel)
|
|
{
|
|
}
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelDatabaseName", "Database");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipDatabaseName", "Database Name");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->SharedData->DatabaseName < Row1->SharedData->DatabaseName; };
|
|
}
|
|
|
|
virtual TSharedRef<SWidget> GenerateWidget(const FRowDataRef& RowData) const override
|
|
{
|
|
return SNew(SHyperlink)
|
|
.Text_Lambda([RowData]() -> FText
|
|
{
|
|
return FText::FromString(RowData->SharedData->DatabaseName);
|
|
})
|
|
.TextStyle(&FCoreStyle::Get().GetWidgetStyle<FTextBlockStyle>("SmallText"))
|
|
.ToolTipText_Lambda([RowData]() -> FText
|
|
{
|
|
return FText::Format(
|
|
LOCTEXT("DatabaseHyperlinkTooltipFormat", "Open database '{0}'"),
|
|
FText::FromString(RowData->SharedData->DatabasePath));
|
|
})
|
|
.OnNavigate_Lambda([this, RowData]()
|
|
{
|
|
UObject* Asset = nullptr;
|
|
|
|
// Load asset
|
|
if (UPackage* Package = LoadPackage(NULL, *RowData->SharedData->DatabasePath, LOAD_NoRedirects))
|
|
{
|
|
Package->FullyLoad();
|
|
|
|
const FString AssetName = FPaths::GetBaseFilename(RowData->SharedData->DatabasePath);
|
|
Asset = FindObject<UObject>(Package, *AssetName);
|
|
}
|
|
else
|
|
{
|
|
// Fallback for unsaved assets
|
|
Asset = FindObject<UObject>(nullptr, *RowData->SharedData->DatabasePath);
|
|
}
|
|
|
|
// Open editor
|
|
if (Asset != nullptr)
|
|
{
|
|
if (UAssetEditorSubsystem* AssetEditorSS = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>())
|
|
{
|
|
AssetEditorSS->OpenEditorForAsset(Asset);
|
|
|
|
if (IAssetEditorInstance* Editor = AssetEditorSS->FindEditorForAsset(Asset, true))
|
|
{
|
|
if (Editor->GetEditorName() == FName("PoseSearchDatabaseEditor"))
|
|
{
|
|
FDatabaseEditor* DatabaseEditor = static_cast<FDatabaseEditor*>(Editor);
|
|
|
|
// Open asset paused and at specific time as seen on the pose search debugger.
|
|
DatabaseEditor->SetSelectedPoseIdx(RowData->PoseIdx, DebuggerViewModel->GetDrawQuery(), RowData->SharedData->QueryVector);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
virtual float ComputeColumnWidth(TConstArrayView<FRowDataRef> Rows) const override
|
|
{
|
|
const TSharedRef<FSlateFontMeasure> FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
const FSlateFontInfo & CellTextStyle = FAppStyle::GetFontStyle("SmallText");
|
|
|
|
float MinWidth = FontMeasure->Measure(GetLabel(), CellTextStyle).X + ColumnWidthPadding;
|
|
|
|
for (const TSharedRef<FDebuggerDatabaseRowData>& Row : Rows)
|
|
{
|
|
MinWidth = FMath::Max(FontMeasure->Measure(Row->SharedData->DatabaseName, CellTextStyle).X + ColumnWidthPadding, MinWidth);
|
|
}
|
|
|
|
return MinWidth;
|
|
}
|
|
};
|
|
|
|
struct FAssetName : IColumn
|
|
{
|
|
using IColumn::IColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelAssetName", "Asset");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipAssetName", "Animation Asset Name");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->AssetName < Row1->AssetName; };
|
|
}
|
|
|
|
virtual TSharedRef<SWidget> GenerateWidget(const FRowDataRef& RowData) const override
|
|
{
|
|
return SNew(SHyperlink)
|
|
.Text_Lambda([RowData]() -> FText { return FText::FromString(RowData->AssetName); })
|
|
.TextStyle(&FCoreStyle::Get().GetWidgetStyle<FTextBlockStyle>("SmallText"))
|
|
.ToolTipText_Lambda([RowData]() -> FText
|
|
{
|
|
return FText::Format(
|
|
LOCTEXT("AssetHyperlinkTooltipFormat", "Open asset '{0}'"),
|
|
FText::FromString(RowData->AssetPath));
|
|
})
|
|
.OnNavigate_Lambda([RowData]()
|
|
{
|
|
UObject* Asset = nullptr;
|
|
|
|
// Load asset
|
|
if (UPackage* Package = LoadPackage(NULL, *RowData->AssetPath, LOAD_NoRedirects))
|
|
{
|
|
Package->FullyLoad();
|
|
|
|
const FString AssetName = FPaths::GetBaseFilename(RowData->AssetPath);
|
|
Asset = FindObject<UObject>(Package, *AssetName);
|
|
}
|
|
else
|
|
{
|
|
// Fallback for unsaved assets
|
|
Asset = FindObject<UObject>(nullptr, *RowData->AssetPath);
|
|
}
|
|
|
|
// Open editor
|
|
if (Asset != nullptr)
|
|
{
|
|
if (UAssetEditorSubsystem* AssetEditorSS = GEditor->GetEditorSubsystem<UAssetEditorSubsystem>())
|
|
{
|
|
AssetEditorSS->OpenEditorForAsset(Asset);
|
|
|
|
if (IAssetEditorInstance* Editor = AssetEditorSS->FindEditorForAsset(Asset, true))
|
|
{
|
|
if (Editor->GetEditorName() == "AnimationEditor")
|
|
{
|
|
const IAnimationEditor* AnimationEditor = static_cast<IAnimationEditor*>(Editor);
|
|
const UDebugSkelMeshComponent* PreviewComponent = AnimationEditor->GetPersonaToolkit()->GetPreviewMeshComponent();
|
|
|
|
// Open asset paused and at specific time as seen on the pose search debugger.
|
|
PreviewComponent->PreviewInstance->SetPosition(RowData->AssetTime);
|
|
PreviewComponent->PreviewInstance->SetPlaying(false);
|
|
PreviewComponent->PreviewInstance->SetBlendSpacePosition(RowData->BlendParameters);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
virtual float ComputeColumnWidth(TConstArrayView<FRowDataRef> Rows) const override
|
|
{
|
|
const TSharedRef<FSlateFontMeasure> FontMeasure = FSlateApplication::Get().GetRenderer()->GetFontMeasureService();
|
|
const FSlateFontInfo & CellTextStyle = FAppStyle::GetFontStyle("SmallText");
|
|
|
|
float MinWidth = FontMeasure->Measure(GetLabel(), CellTextStyle).X + ColumnWidthPadding;
|
|
|
|
for (const TSharedRef<FDebuggerDatabaseRowData>& Row : Rows)
|
|
{
|
|
MinWidth = FMath::Max(FontMeasure->Measure(Row->AssetName, CellTextStyle).X, MinWidth);
|
|
}
|
|
|
|
return MinWidth;
|
|
}
|
|
};
|
|
|
|
struct FFrame : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelFrame", "Frame");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipFrame", "Frame number from the start of the Animation Asset");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->AnimFrame < Row1->AnimFrame; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->AnimFrame, &FNumberFormattingOptions::DefaultNoGrouping());
|
|
}
|
|
};
|
|
|
|
struct FTime : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTime", "Time");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipTime", "Time in seconds from the start of the Animation Asset");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->AssetTime < Row1->AssetTime; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->AssetTime, &FNumberFormattingOptions().SetUseGrouping(false).SetMaximumFractionalDigits(2));
|
|
}
|
|
};
|
|
|
|
struct FPercentage : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelPercentage", "Percent");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipPercentage", "Time in percentage from the start of the Animation Asset");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->AnimPercentage < Row1->AnimPercentage; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsPercent(Row->AnimPercentage, &FNumberFormattingOptions().SetMaximumFractionalDigits(2));
|
|
}
|
|
};
|
|
|
|
struct FCost : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelCost", "Cost");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipCost", "Total Cost of the associated Pose");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PoseCost < Row1->PoseCost; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
if (Row->PoseCost.IsValid())
|
|
{
|
|
return FText::AsNumber(Row->PoseCost);
|
|
}
|
|
else
|
|
{
|
|
return FText::FromString(TEXT("-"));
|
|
}
|
|
}
|
|
|
|
virtual FSlateColor GetColorAndOpacity(const FRowDataRef& Row) const override
|
|
{
|
|
return Row->CostColor;
|
|
}
|
|
};
|
|
|
|
struct FPCACost : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelPCACost", "PCA Cost");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipPCACost", "Total PCA Cost of the associated Pose");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PosePCACost < Row1->PosePCACost; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->PosePCACost);
|
|
}
|
|
|
|
virtual FSlateColor GetColorAndOpacity(const FRowDataRef& Row) const override
|
|
{
|
|
return Row->PCACostColor;
|
|
}
|
|
};
|
|
|
|
struct FChannelBreakdownCostColumn : ITextColumn
|
|
{
|
|
FChannelBreakdownCostColumn(int32 SortIndex, int32 InBreakdownCostIndex, const FText& InLabel)
|
|
: ITextColumn(SortIndex)
|
|
, Label(InLabel)
|
|
, BreakdownCostIndex(InBreakdownCostIndex)
|
|
{
|
|
}
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return Label;
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return FText::Format(LOCTEXT("ColumnLabelTooltipChannelBreakdownCost", "Breakdown Cost for the Channel '{0}'"), Label);
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [this](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool
|
|
{
|
|
return Row0->CostBreakdowns[BreakdownCostIndex] < Row1->CostBreakdowns[BreakdownCostIndex];
|
|
};
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
const float LabelCost = Row->CostBreakdowns[BreakdownCostIndex];
|
|
if (LabelCost != UE_MAX_FLT)
|
|
{
|
|
return FText::AsNumber(LabelCost);
|
|
}
|
|
return FText::FromString(TEXT("-"));
|
|
}
|
|
|
|
virtual FSlateColor GetColorAndOpacity(const FRowDataRef& Row) const override
|
|
{
|
|
return Row->CostBreakdownsColors[BreakdownCostIndex];
|
|
}
|
|
|
|
FText Label;
|
|
int32 BreakdownCostIndex = INDEX_NONE;
|
|
};
|
|
|
|
struct FCostModifier : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelCostModifier", "Bias");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipCostModifier", "Total Cost for all the Bias contributions");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PoseCost.GetCostAddend() < Row1->PoseCost.GetCostAddend(); };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->PoseCost.GetCostAddend());
|
|
}
|
|
};
|
|
|
|
struct FContinuingPoseCost : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelContinuingPoseCost", "ContinuingPoseCost");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipContinuingPoseCost", "Continuing Pose Cost Bias contribution");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PoseCost.GetContinuingPoseCostAddend() < Row1->PoseCost.GetContinuingPoseCostAddend(); };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->PoseCost.GetContinuingPoseCostAddend());
|
|
}
|
|
};
|
|
|
|
struct FContinuingInteractionCost : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelContinuingInteractionCost", "ContinuingInteractionCost");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipContinuingInteractionCost", "Continuing Interaction Cost Bias contribution");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PoseCost.GetContinuingInteractionCostAddend() < Row1->PoseCost.GetContinuingInteractionCostAddend(); };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->PoseCost.GetContinuingInteractionCostAddend());
|
|
}
|
|
};
|
|
|
|
struct FNotifyCost : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelNotifyCost", "NotifyCost");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipNotifyCost", "Notify Cost Bias contribution");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PoseCost.GetNotifyCostAddend() < Row1->PoseCost.GetNotifyCostAddend(); };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::AsNumber(Row->PoseCost.GetNotifyCostAddend());
|
|
}
|
|
};
|
|
|
|
|
|
struct FMirrored : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelMirrored", "Mirror");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipMirrored", "Mirror state of the associated Pose");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->bMirrored < Row1->bMirrored; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::Format(LOCTEXT("Mirrored", "{0}"), { Row->bMirrored } );
|
|
}
|
|
};
|
|
|
|
struct FLooping : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelLooping", "Loop");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipLooping", "Loop state of the associated Pose");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->bLooping < Row1->bLooping; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::Format(LOCTEXT("Looping", "{0}"), { Row->bLooping });
|
|
}
|
|
};
|
|
|
|
struct FBlendParameters : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelBlendParams", "Blend Params");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelBlendTooltipParams", "Blend Params used to sample the associated BlendSpace asset");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool
|
|
{
|
|
return (
|
|
Row0->BlendParameters[0] < Row1->BlendParameters[0] ||
|
|
Row0->BlendParameters[1] < Row1->BlendParameters[1]);
|
|
};
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
return FText::Format(LOCTEXT("Blend Parameters", "{0}, {1}"), FText::AsNumber(Row->BlendParameters[0]), FText::AsNumber(Row->BlendParameters[1]));
|
|
}
|
|
};
|
|
|
|
struct FPoseCandidateFlags : ITextColumn
|
|
{
|
|
using ITextColumn::ITextColumn;
|
|
|
|
virtual FText GetLabel() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelPoseCandidateFlags", "Flags");
|
|
}
|
|
|
|
virtual FText GetLabelTooltip() const override
|
|
{
|
|
return LOCTEXT("ColumnLabelTooltipPoseCandidateFlags", "Flags indicating why a Pose has been discarded");
|
|
}
|
|
|
|
virtual FSortPredicate GetSortPredicate() const override
|
|
{
|
|
return [](const FRowDataRef& Row0, const FRowDataRef& Row1) -> bool { return Row0->PoseCandidateFlags < Row1->PoseCandidateFlags; };
|
|
}
|
|
|
|
virtual FText GetRowText(const FRowDataRef& Row) const override
|
|
{
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::AnyDiscardedMask))
|
|
{
|
|
FString Sring;
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_PoseJumpThresholdTime))
|
|
{
|
|
Sring.Append("J ");
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_PoseReselectHistory))
|
|
{
|
|
Sring.Append("H ");
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_BlockTransition))
|
|
{
|
|
Sring.Append("B ");
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_PoseFilter))
|
|
{
|
|
Sring.Append("F ");
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_AssetIdxFilter))
|
|
{
|
|
Sring.Append("A ");
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_Search))
|
|
{
|
|
Sring.Append("S ");
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_AssetReselection))
|
|
{
|
|
Sring.Append("R ");
|
|
}
|
|
|
|
return FText::FromString(Sring);
|
|
}
|
|
|
|
return FText::GetEmpty();
|
|
}
|
|
|
|
virtual FText GetRowToolTipText(const FRowDataRef& Row) const override
|
|
{
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::AnyDiscardedMask))
|
|
{
|
|
FTextBuilder TextBuilder;
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_Reason_Tooltip", "Pose discarded because of:"));
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_PoseJumpThresholdTime))
|
|
{
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_PoseJumpThresholdTime_Tooltip", "(J) Pose Jump Threshold Time"));
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_PoseReselectHistory))
|
|
{
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_PoseReselectHistory_Tooltip", "(H) Pose Reselect History"));
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_BlockTransition))
|
|
{
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_BlockTransition_Tooltip", "(B) Block Transition"));
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_PoseFilter))
|
|
{
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_PoseFilter_Tooltip", "(F) Filter"));
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_AssetIdxFilter))
|
|
{
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_AssetIdxFilter_Tooltip", "(A) Asset Idx Filter"));
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_Search))
|
|
{
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_Search_Tooltip", "(S) Search"));
|
|
}
|
|
|
|
if (EnumHasAnyFlags(Row->PoseCandidateFlags, EPoseCandidateFlags::DiscardedBy_AssetReselection))
|
|
{
|
|
TextBuilder.AppendLine(LOCTEXT("DiscardedBy_AssetReselection_Tooltip", "(R) Disable Reselection"));
|
|
}
|
|
|
|
return TextBuilder.ToText();
|
|
}
|
|
|
|
return FText::GetEmpty();
|
|
}
|
|
};
|
|
|
|
} // namespace UE::PoseSearch::DebuggerDatabaseColumns
|
|
|
|
#undef LOCTEXT_NAMESPACE
|