#pragma once #include "CoreMinimal.h" #include "Toolkits/AssetEditorToolkit.h" #include "Widgets/Docking/SDockTab.h" #include "BooleanCutTool.h" #include "EditorUndoClient.h" #include "Logging/LogMacros.h" class SDockTab; class SGraphEditor; class SPropertyTreeView; class SAssetBrowser; class SMatrixInputWidget; class FFLESHViewportClient; class FSceneViewport; class UVisceraNodeObject; class FDismembermentEditor; // Define log category DECLARE_LOG_CATEGORY_EXTERN(LogFLESHEditor, Log, All); /** * Bone tree item structure */ struct FBoneTreeItem : public TSharedFromThis { // Bone name FName BoneName; // Display name for UI FString DisplayName; // Bone type (e.g., "Root", "Limb", "Joint", etc.) FString BoneType; // Parent bone item TWeakPtr ParentItem; // Child bone items TArray> Children; // Constructor FBoneTreeItem(FName InBoneName, const FString& InDisplayName, const FString& InBoneType = TEXT("")) : BoneName(InBoneName) , DisplayName(InDisplayName) , BoneType(InBoneType) { } // Add a child bone void AddChild(TSharedPtr Child) { Children.Add(Child); Child->ParentItem = SharedThis(this); } }; /** * Viscera node item structure */ struct FVisceraNodeItem : public TSharedFromThis { // Node name FName NodeName; // Display name for UI FString DisplayName; // Node type (e.g., "SoftBody", "Anchor", "Collision", "Tetra", "LineChain", "Plane", etc.) FString NodeType; // Parent node item TWeakPtr ParentItem; // Child node items TArray> Children; // Physical properties TMap FloatProperties; TMap VectorProperties; TMap NameProperties; TMap BoolProperties; TArray PointsArray; // Constructor FVisceraNodeItem(FName InNodeName, const FString& InDisplayName, const FString& InNodeType = TEXT("")) : NodeName(InNodeName) , DisplayName(InDisplayName) , NodeType(InNodeType) { // Initialize default properties based on node type if (InNodeType.Equals(TEXT("SoftBody"))) { // Default SoftBody properties FloatProperties.Add(TEXT("GravityStrength"), 1.0f); FloatProperties.Add(TEXT("MinFrameSpeed"), 0.0f); FloatProperties.Add(TEXT("MaxFrameSpeed"), 200.0f); FloatProperties.Add(TEXT("ExternalFrameLerp"), 1.0f); FloatProperties.Add(TEXT("InitialGPUInfluence"), 0.5f); FloatProperties.Add(TEXT("SubstepTime"), 0.01667f); FloatProperties.Add(TEXT("SolverIterations"), 1.0f); BoolProperties.Add(TEXT("EnableSimulation"), true); BoolProperties.Add(TEXT("RecomputeNormals"), true); } else if (InNodeType.Equals(TEXT("Anchor"))) { // Default Anchor properties FloatProperties.Add(TEXT("Radius"), 5.0f); FloatProperties.Add(TEXT("Stiffness"), 1.0f); VectorProperties.Add(TEXT("Location"), FVector::ZeroVector); NameProperties.Add(TEXT("BoneName"), NAME_None); } else if (InNodeType.Equals(TEXT("LineChain"))) { // Default LineChain properties FloatProperties.Add(TEXT("Stiffness"), 0.5f); FloatProperties.Add(TEXT("Thickness"), 1.0f); // Default with two points PointsArray.Add(FVector(-10.0f, 0.0f, 0.0f)); PointsArray.Add(FVector(10.0f, 0.0f, 0.0f)); } else if (InNodeType.Equals(TEXT("Tetra"))) { // Default Tetra properties FloatProperties.Add(TEXT("Stiffness"), 0.7f); // Default tetrahedron points PointsArray.Add(FVector(0.0f, 0.0f, 0.0f)); PointsArray.Add(FVector(10.0f, 0.0f, 0.0f)); PointsArray.Add(FVector(0.0f, 10.0f, 0.0f)); PointsArray.Add(FVector(0.0f, 0.0f, 10.0f)); } else if (InNodeType.Equals(TEXT("Plane"))) { // Default Plane properties FloatProperties.Add(TEXT("Stiffness"), 1.0f); VectorProperties.Add(TEXT("Location"), FVector::ZeroVector); VectorProperties.Add(TEXT("Normal"), FVector::UpVector); } } // Add a child node void AddChild(TSharedPtr Child) { Children.Add(Child); Child->ParentItem = SharedThis(this); } // Set a float property void SetFloatProperty(FName PropertyName, float Value) { FloatProperties.Add(PropertyName, Value); } // Set a vector property void SetVectorProperty(FName PropertyName, const FVector& Value) { VectorProperties.Add(PropertyName, Value); } // Set a name property void SetNameProperty(FName PropertyName, FName Value) { NameProperties.Add(PropertyName, Value); } // Set a bool property void SetBoolProperty(FName PropertyName, bool Value) { BoolProperties.Add(PropertyName, Value); } // Add a point to the points array void AddPoint(const FVector& Point) { PointsArray.Add(Point); } // Clear all points void ClearPoints() { PointsArray.Empty(); } }; /** * FLESH Main Editor * Provides the main editing functionality for the dismemberment system */ class FLESHEDITOR_API FFLESHEditor : public FAssetEditorToolkit, public FEditorUndoClient { public: FFLESHEditor(); virtual ~FFLESHEditor(); // Initialize the editor void InitFLESHEditor(const EToolkitMode::Type Mode, const TSharedPtr& InitToolkitHost, UObject* InObject); // FAssetEditorToolkit interface virtual void RegisterTabSpawners(const TSharedRef& TabManager) override; virtual void UnregisterTabSpawners(const TSharedRef& TabManager) override; virtual FName GetToolkitFName() const override; virtual FText GetBaseToolkitName() const override; virtual FString GetWorldCentricTabPrefix() const override; virtual FLinearColor GetWorldCentricTabColorScale() const override; // End of FAssetEditorToolkit interface // FEditorUndoClient interface virtual void PostUndo(bool bSuccess) override; virtual void PostRedo(bool bSuccess) override; // Open the editor void OpenEditor(); // Get whether the editor is initialized bool IsEditorInitialized(); // Get the editing object UObject* GetEditingObject() const { return EditingObject; } // Add DismembermentEditor related tab spawners TSharedRef SpawnTab_LayerSystem(const FSpawnTabArgs& Args); TSharedRef SpawnTab_PhysicsSettings(const FSpawnTabArgs& Args); // Create DismembermentEditor related widgets TSharedRef CreateLayerSystemWidget(); TSharedRef CreatePhysicsSettingsWidget(); private: // Tab spawners TSharedRef SpawnTab_Viewport(const FSpawnTabArgs& Args); TSharedRef SpawnTab_Details(const FSpawnTabArgs& Args); TSharedRef SpawnTab_AssetBrowser(const FSpawnTabArgs& Args); TSharedRef SpawnTab_MatrixEditor(const FSpawnTabArgs& Args); TSharedRef SpawnTab_GraphEditor(const FSpawnTabArgs& Args); TSharedRef SpawnTab_Toolbar(const FSpawnTabArgs& Args); // Create viewport widget TSharedRef CreateViewportWidget(); // Create details panel TSharedRef CreateDetailsWidget(); // Create asset browser TSharedRef CreateAssetBrowserWidget(); // Create matrix editor TSharedRef CreateMatrixEditorWidget(); // Create graph editor TSharedRef CreateGraphEditorWidget(); // Create toolbar TSharedRef CreateToolbarWidget(); // Create command list void CreateCommandList(); // Extend toolbar with custom buttons void ExtendToolbar(); // Generate bone tree row TSharedRef OnGenerateBoneRow(TSharedPtr Item, const TSharedRef& OwnerTable); // Get bone children void OnGetBoneChildren(TSharedPtr Item, TArray>& OutChildren); // Bone selection changed void OnBoneSelectionChanged(TSharedPtr Item, ESelectInfo::Type SelectInfo); // Build bone hierarchy void BuildBoneHierarchy(); // Build viscera node tree void BuildVisceraNodeTree(); // Tree view generation methods TSharedRef OnGenerateNodeRow(TSharedPtr InItem, const TSharedRef& OwnerTable); void OnGetNodeChildren(TSharedPtr InItem, TArray>& OutChildren); void OnNodeSelectionChanged(TSharedPtr InItem, ESelectInfo::Type SelectInfo); // Context menu for node tree TSharedPtr OnGetNodeContextMenu(TSharedPtr InItem); // Add new viscera node void AddNewVisceraNode(const FString& NodeType, TSharedPtr ParentItem = nullptr); // Command handlers void OnOpenDismembermentGraphEditor(); void OnOpenAnatomicalLayerEditor(); void OnOpenBooleanCutTool(); void OnOpenBloodSystemEditor(); void OnImportCharacterModel(); void OnImportOrganModel(); void OnImportSkeletonModel(); void OnImportPhysicsAsset(); void OnTestMatrix(); void OnImportModel(); void OnSavePreset(); void OnLoadPreset(); // Viewport widget TSharedPtr ViewportWidget; // Details panel TSharedPtr DetailsWidget; // Asset browser TSharedPtr AssetBrowserWidget; // Matrix editor TSharedPtr MatrixEditorWidget; // Graph editor TSharedPtr GraphEditorWidget; // Toolbar TSharedPtr ToolbarWidget; // Bone tree view TSharedPtr>> BoneTreeView; // Node tree view TSharedPtr>> NodeTreeView; // Bone items array TArray> BoneItems; // Node items array TArray> NodeItems; // Cutting plane names TArray> CuttingPlaneNames; // Currently selected bone TSharedPtr SelectedBoneItem; // Currently selected node TSharedPtr SelectedNodeItem; // Command list TSharedPtr CommandList; // Flag to track if the editor is initialized bool bIsEditorInitialized; // Viewport client TSharedPtr ViewportClient; // Scene viewport TSharedPtr Viewport; // Viewport related methods FReply OnResetCameraClicked(); FReply OnToggleWireframeClicked(); FReply OnToggleBonesClicked(); // The object being edited UObject* EditingObject; // Tab IDs static const FName ViewportTabId; static const FName DetailsTabId; static const FName AssetBrowserTabId; static const FName MatrixEditorTabId; static const FName GraphEditorTabId; static const FName ToolbarTabId; static const FName LayerSystemTabId; static const FName PhysicsSettingsTabId; static const FName DismembermentGraphTabId; // Is the editor initialized? bool bIsInitialized; // New DismembermentEditor related Widgets TSharedPtr LayerSystemWidget; TSharedPtr PhysicsSettingsWidget; // Error handling method void HandleEditorError(const FText& ErrorMessage); };