// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "InputCoreTypes.h" #include "Widgets/DeclarativeSyntaxSupport.h" #include "Input/Reply.h" #include "Widgets/SCompoundWidget.h" #include "Widgets/SWindow.h" #include "Widgets/Views/STableViewBase.h" #include "Widgets/Views/STableRow.h" #include "Widgets/Views/STreeView.h" #include "Widgets/SNullWidget.h" #include "EditorStyleSet.h" enum EFBXCompareSection { EFBXCompareSection_Skeleton = 0, EFBXCompareSection_References, EFBXCompareSection_Count }; class FCompMaterial { public: FCompMaterial(FName InMaterialSlotName, FName InImportedMaterialSlotName) : MaterialSlotName(InMaterialSlotName), ImportedMaterialSlotName(InImportedMaterialSlotName) {} FName MaterialSlotName; FName ImportedMaterialSlotName; }; class FCompJoint { public: FCompJoint() : Name(NAME_None), ParentIndex(INDEX_NONE) {} ~FCompJoint() { ChildIndexes.Empty(); } FName Name; int32 ParentIndex; TArray ChildIndexes; }; class FCompSkeleton { public: FCompSkeleton() : bSkeletonFitMesh(true) {} ~FCompSkeleton() { Joints.Empty(); } TArray Joints; bool bSkeletonFitMesh; }; class FCompMesh { public: ~FCompMesh() {} FCompSkeleton CompSkeleton; TArray ErrorMessages; TArray WarningMessages; }; class FSkeletonCompareData: public TSharedFromThis { public: FSkeletonCompareData() : CurrentJointIndex(INDEX_NONE), FbxJointIndex(INDEX_NONE), JointName(NAME_None), ParentJoint(nullptr), bMatchJoint(false), bChildConflict(false), bInitialAutoExpand(false) {} int32 CurrentJointIndex; int32 FbxJointIndex; FName JointName; TSharedPtr ParentJoint; bool bMatchJoint; bool bChildConflict; bool bInitialAutoExpand; TArray ChildJointIndexes; TArray> ChildJoints; }; class FCompareRowData: public TSharedFromThis { public: FCompareRowData() : RowIndex(INDEX_NONE), CurrentData(nullptr), FbxData(nullptr) {} virtual ~FCompareRowData() {} int32 RowIndex; FCompMesh* CurrentData; FCompMesh* FbxData; virtual TSharedRef ConstructCellCurrent() { return SNullWidget::NullWidget; }; virtual TSharedRef ConstructCellFbx() { return SNullWidget::NullWidget; }; }; class SCompareRowDataTableListViewRow: public SMultiColumnTableRow> { public: SLATE_BEGIN_ARGS(SCompareRowDataTableListViewRow) : _CompareRowData(nullptr) {} /** The item content. */ SLATE_ARGUMENT(TSharedPtr, CompareRowData) SLATE_END_ARGS() void Construct(const FArguments& InArgs, const TSharedRef& InOwnerTableView) { CompareRowData = InArgs._CompareRowData; // This is suppose to always be valid check(CompareRowData.IsValid()); SMultiColumnTableRow>::Construct( FSuperRowType::FArguments() .Style(FEditorStyle::Get(), "DataTableEditor.CellListViewRow"), InOwnerTableView); } /** Overridden from SMultiColumnTableRow. Generates a widget for this column of the list view. */ virtual TSharedRef GenerateWidgetForColumn(const FName& ColumnName) override { if (ColumnName == FName(TEXT("RowIndex"))) { return SNew(SBox) .Padding(FMargin(5.0f, 2.0f, 0.0f, 2.0f)) [SNew(STextBlock) .Text(FText::FromString(FString::FromInt(CompareRowData->RowIndex)))]; } else if (ColumnName == FName(TEXT("Current"))) { return CompareRowData->ConstructCellCurrent(); } else if (ColumnName == FName(TEXT("Fbx"))) { return CompareRowData->ConstructCellFbx(); } return SNullWidget::NullWidget; } private: /** The node info to build the tree view row from. */ TSharedPtr CompareRowData; }; /* * This dialog show the conflict between different skeleton */ class SFbxSkeltonConflictWindow: public SCompoundWidget { public: SLATE_BEGIN_ARGS(SFbxSkeltonConflictWindow) : _WidgetWindow(), _AssetReferencingSkeleton(nullptr), _SourceData(nullptr), _ResultData(nullptr), _SourceObject(nullptr), _bIsPreviewConflict(false) {} SLATE_ARGUMENT(TSharedPtr, WidgetWindow) SLATE_ARGUMENT(TArray>*, AssetReferencingSkeleton) SLATE_ARGUMENT(FCompMesh*, SourceData) SLATE_ARGUMENT(FCompMesh*, ResultData) SLATE_ARGUMENT(UObject*, SourceObject) SLATE_ARGUMENT(bool, bIsPreviewConflict) SLATE_END_ARGS() public: bool HasConflict(); bool bRevertReimport; void Construct(const FArguments& InArgs); virtual bool SupportsKeyboardFocus() const override { return true; } FReply OnDone() { if (WidgetWindow.IsValid()) { WidgetWindow.Pin()->RequestDestroyWindow(); } bRevertReimport = false; return FReply::Handled(); } virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent) override { if (InKeyEvent.GetKey() == EKeys::Escape) { return OnDone(); } return FReply::Unhandled(); } SFbxSkeltonConflictWindow() {} private: TWeakPtr WidgetWindow; // Meshes UObject* SourceObject; bool bIsPreviewConflict; ////////////////////////////////////////////////////////////////////////// // Collapse generic bool bShowSectionFlag[EFBXCompareSection_Count]; FReply SetSectionVisible(EFBXCompareSection SectionIndex); EVisibility IsSectionVisible(EFBXCompareSection SectionIndex); const FSlateBrush* GetCollapsableArrow(EFBXCompareSection SectionIndex) const; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // Compare data FCompMesh* SourceData; FCompMesh* ResultData; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // Skeleton Data TSharedPtr>> CompareTree; TArray> DisplaySkeletonTreeItem; TArray> CurrentSkeletonTreeItem; TArray> FbxSkeletonTreeItem; TArray> AssetReferencingSkeleton; void FilSkeletonTreeItem(); void RecursiveMatchJointInfo(TSharedPtr CurrentItem); void SetMatchJointInfo(); // Construct slate TSharedPtr ConstructSkeletonComparison(); TSharedPtr ConstructSkeletonReference(); // Slate events TSharedRef OnGenerateRowCompareTreeView(TSharedPtr RowData, const TSharedRef& Table); void OnGetChildrenRowCompareTreeView(TSharedPtr InParent, TArray>& OutChildren); TSharedRef OnGenerateRowAssetReferencingSkeleton(TSharedPtr InItem, const TSharedRef& OwnerTable); ////////////////////////////////////////////////////////////////////////// };