This commit is contained in:
2025-04-17 23:59:17 +08:00
commit 88536f22da
57 changed files with 8094 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "AnatomicalStructureBrush.generated.h"
// Forward declarations
class USkeletalMesh;
class UStaticMesh;
/**
* Anatomical brush type enumeration
*/
UENUM(BlueprintType)
enum class EAnatomicalBrushType : uint8
{
Bone, // Bone brush
Muscle, // Muscle brush
Organ, // Organ brush
Vessel, // Blood vessel brush
Nerve, // Nerve brush
Custom // Custom brush
};
/**
* Anatomical brush settings
*/
USTRUCT(BlueprintType)
struct FAnatomicalBrushSettings
{
GENERATED_BODY()
// Brush type
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush")
EAnatomicalBrushType BrushType = EAnatomicalBrushType::Bone;
// Brush size
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush", meta = (ClampMin = "0.1", ClampMax = "100.0"))
float BrushSize = 10.0f;
// Brush strength
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float BrushStrength = 0.5f;
// Brush falloff
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float BrushFalloff = 0.5f;
// Brush material
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush")
TObjectPtr<UMaterialInterface> BrushMaterial = nullptr;
// Brush mesh
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush")
TObjectPtr<UStaticMesh> BrushMesh = nullptr;
// Enable physics
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush")
bool bEnablePhysics = true;
// Physics density
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush", meta = (EditCondition = "bEnablePhysics"))
float PhysicsDensity = 1.0f;
// Physics elasticity
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush", meta = (EditCondition = "bEnablePhysics"))
float PhysicsElasticity = 0.5f;
// Fracture threshold
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Brush", meta = (EditCondition = "bEnablePhysics"))
float FractureThreshold = 100.0f;
};
/**
* Anatomical structure brush tool class
* Used for creating and editing anatomical structures in the editor
*/
UCLASS(BlueprintType)
class FLESHEDITOR_API UAnatomicalStructureBrush : public UObject
{
GENERATED_BODY()
public:
// Constructor
UAnatomicalStructureBrush();
/**
* Initialize the brush
* @param InSettings - Brush settings
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Brush")
void Initialize(const FAnatomicalBrushSettings& InSettings);
/**
* Apply brush to skeletal mesh
* @param TargetMesh - Target skeletal mesh
* @param Location - Application location
* @param Direction - Application direction
* @param BoneName - Bone name, if specified, only apply to this bone
* @return Whether the application was successful
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Brush")
bool ApplyToSkeletalMesh(USkeletalMesh* TargetMesh, const FVector& Location, const FVector& Direction, FName BoneName = NAME_None);
/**
* Apply brush to static mesh
* @param TargetMesh - Target static mesh
* @param Location - Application location
* @param Direction - Application direction
* @return Whether the application was successful
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Brush")
bool ApplyToStaticMesh(UStaticMesh* TargetMesh, const FVector& Location, const FVector& Direction);
/**
* Set brush type
* @param BrushType - Brush type
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Brush")
void SetBrushType(EAnatomicalBrushType BrushType);
/**
* Set brush size
* @param Size - Brush size
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Brush")
void SetBrushSize(float Size);
/**
* Set brush strength
* @param Strength - Brush strength
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Brush")
void SetBrushStrength(float Strength);
/**
* Get brush settings
* @return Current brush settings
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Brush")
FAnatomicalBrushSettings GetBrushSettings() const;
private:
// Brush settings
UPROPERTY(EditAnywhere, Category = "FLESH|Brush")
FAnatomicalBrushSettings BrushSettings;
// Internal function for creating anatomical structure
UStaticMesh* CreateAnatomicalStructure(const FVector& Location, const FVector& Direction, float Size);
// Internal function for applying physics properties
void ApplyPhysicsProperties(UStaticMesh* Mesh);
};

View File

@@ -0,0 +1,211 @@
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "DismembermentCompiler.generated.h"
class UDismembermentGraphNode;
class UDismembermentGraph;
/**
* Compiled node data structure
*/
USTRUCT()
struct FCompiledNodeData
{
GENERATED_BODY()
// Node reference
UPROPERTY()
TObjectPtr<UDismembermentGraphNode> Node;
// Input nodes
UPROPERTY()
TArray<int32> InputNodeIndices;
// Output nodes
UPROPERTY()
TArray<int32> OutputNodeIndices;
// Execution order index
int32 ExecutionOrder;
// Constructor
FCompiledNodeData()
: Node(nullptr)
, ExecutionOrder(-1)
{
}
};
/**
* Dismemberment compiler class
* Compiles a dismemberment graph into executable logic
*/
UCLASS()
class FLESHEDITOR_API UDismembermentCompiler : public UObject
{
GENERATED_BODY()
public:
// Constructor
UDismembermentCompiler();
/**
* Compile a dismemberment graph
* @param InGraph - The graph to compile
* @return True if compilation was successful
*/
bool CompileGraph(UDismembermentGraph* InGraph);
/**
* Get the compiled node data
* @return Array of compiled node data
*/
const TArray<FCompiledNodeData>& GetCompiledNodeData() const { return CompiledNodeData; }
/**
* Get the execution order
* @return Array of node indices in execution order
*/
const TArray<int32>& GetExecutionOrder() const { return ExecutionOrder; }
/**
* Add a bone selection
* @param BoneName - Name of the bone to select
*/
void AddBoneSelection(const FName& BoneName);
/**
* Add a cut operation
* @param Location - Location of the cut
* @param Direction - Direction of the cut
* @param Width - Width of the cut
* @param Depth - Depth of the cut
* @param Material - Material to use for the cut surface
*/
void AddCutOperation(const FVector& Location, const FVector& Direction, float Width, float Depth, UMaterialInterface* Material);
/**
* Add a blood effect
* @param Location - Location of the blood effect
* @param BloodEffect - Niagara system for the blood effect
* @param BloodAmount - Amount of blood
* @param BloodPressure - Blood pressure
* @param CreateBloodPool - Whether to create a blood pool
* @param BloodPoolSize - Size of the blood pool
* @param BloodPoolMaterial - Material for the blood pool
*/
void AddBloodEffect(const FVector& Location, UNiagaraSystem* BloodEffect, float BloodAmount, float BloodPressure, bool CreateBloodPool, float BloodPoolSize, UMaterialInterface* BloodPoolMaterial);
/**
* Add a physics simulation
* @param Mass - Mass of the object
* @param LinearDamping - Linear damping
* @param AngularDamping - Angular damping
* @param EnableGravity - Whether to enable gravity
* @param SimulatePhysics - Whether to simulate physics
* @param GenerateOverlapEvents - Whether to generate overlap events
* @param PhysicalMaterial - Physical material to use
* @param ImpulseForce - Force of the impulse
* @param ImpulseRadius - Radius of the impulse
*/
void AddPhysicsSimulation(float Mass, float LinearDamping, float AngularDamping, bool EnableGravity, bool SimulatePhysics, bool GenerateOverlapEvents, UPhysicalMaterial* PhysicalMaterial, float ImpulseForce, float ImpulseRadius);
/**
* Add an organ
* @param OrganMesh - Mesh for the organ
* @param OrganMaterial - Material for the organ
* @param AttachBoneName - Name of the bone to attach to
* @param RelativeLocation - Relative location
* @param RelativeRotation - Relative rotation
* @param RelativeScale - Relative scale
* @param SimulatePhysics - Whether to simulate physics
* @param DamageMultiplier - Damage multiplier
* @param IsCriticalOrgan - Whether this is a critical organ
* @param BloodAmount - Amount of blood
*/
void AddOrgan(UStaticMesh* OrganMesh, UMaterialInterface* OrganMaterial, const FName& AttachBoneName, const FVector& RelativeLocation, const FRotator& RelativeRotation, const FVector& RelativeScale, bool SimulatePhysics, float DamageMultiplier, bool IsCriticalOrgan, float BloodAmount);
/**
* Add a wound effect
* @param WoundSize - Size of the wound
* @param WoundDepth - Depth of the wound
* @param WoundMaterial - Material for the wound
* @param WoundEffect - Effect for the wound
* @param CreateDecal - Whether to create a decal
* @param DecalMaterial - Material for the decal
* @param DecalSize - Size of the decal
* @param DecalLifetime - Lifetime of the decal
* @param AffectBoneHealth - Whether to affect bone health
* @param BoneDamage - Amount of bone damage
*/
void AddWoundEffect(float WoundSize, float WoundDepth, UMaterialInterface* WoundMaterial, UNiagaraSystem* WoundEffect, bool CreateDecal, UMaterialInterface* DecalMaterial, float DecalSize, float DecalLifetime, bool AffectBoneHealth, float BoneDamage);
private:
// The graph being compiled
UPROPERTY()
TObjectPtr<UDismembermentGraph> Graph;
// Compiled node data
UPROPERTY()
TArray<FCompiledNodeData> CompiledNodeData;
// Execution order
UPROPERTY()
TArray<int32> ExecutionOrder;
// Bone selections
UPROPERTY()
TArray<FName> BoneSelections;
// Cut operations
UPROPERTY()
TArray<FTransform> CutOperations;
// Cut materials
UPROPERTY()
TArray<TObjectPtr<UMaterialInterface>> CutMaterials;
// Cut widths
UPROPERTY()
TArray<float> CutWidths;
// Cut depths
UPROPERTY()
TArray<float> CutDepths;
// Blood effects
UPROPERTY()
TArray<FTransform> BloodEffectTransforms;
// Blood effect systems
UPROPERTY()
TArray<TObjectPtr<UNiagaraSystem>> BloodEffectSystems;
// Blood amounts
UPROPERTY()
TArray<float> BloodAmounts;
// Blood pressures
UPROPERTY()
TArray<float> BloodPressures;
// Create blood pools
UPROPERTY()
TArray<bool> CreateBloodPools;
// Blood pool sizes
UPROPERTY()
TArray<float> BloodPoolSizes;
// Blood pool materials
UPROPERTY()
TArray<TObjectPtr<UMaterialInterface>> BloodPoolMaterials;
// Topological sort the nodes
bool TopologicalSort();
// Visit node for topological sort
void VisitNode(int32 NodeIndex, TArray<bool>& Visited, TArray<bool>& TempMark, TArray<int32>& SortedNodes, bool& bHasCycle);
};

View File

@@ -0,0 +1,155 @@
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "DismembermentCompiler.h"
#include "DismembermentExecutor.generated.h"
class AActor;
class USkeletalMeshComponent;
class UDismembermentCompiler;
/**
* Dismemberment executor class
* Executes a compiled dismemberment graph
*/
UCLASS()
class FLESHEDITOR_API UDismembermentExecutor : public UObject
{
GENERATED_BODY()
public:
// Constructor
UDismembermentExecutor();
/**
* Initialize the executor with a compiler
* @param InCompiler - The compiler containing the compiled graph
*/
void Initialize(UDismembermentCompiler* InCompiler);
/**
* Execute the compiled graph on a target actor
* @param TargetActor - The actor to apply the dismemberment effects to
* @return True if execution was successful
*/
bool Execute(AActor* TargetActor);
/**
* Get the target actor
* @return The target actor
*/
AActor* GetTargetActor() const { return TargetActor; }
/**
* Get the target skeletal mesh component
* @return The target skeletal mesh component
*/
USkeletalMeshComponent* GetTargetSkeletalMesh() const { return TargetSkeletalMesh; }
/**
* Get the selected bones
* @return Array of selected bone names
*/
const TArray<FName>& GetSelectedBones() const { return SelectedBones; }
/**
* Add a bone to the selection
* @param BoneName - Name of the bone to add
*/
void AddSelectedBone(const FName& BoneName);
/**
* Apply a cut to the target
* @param Location - Location of the cut
* @param Direction - Direction of the cut
* @param Width - Width of the cut
* @param Depth - Depth of the cut
* @param Material - Material to use for the cut surface
* @return True if the cut was successful
*/
bool ApplyCut(const FVector& Location, const FVector& Direction, float Width, float Depth, UMaterialInterface* Material);
/**
* Spawn a blood effect
* @param Location - Location of the blood effect
* @param BloodEffect - Niagara system for the blood effect
* @param BloodAmount - Amount of blood
* @param BloodPressure - Blood pressure
* @param CreateBloodPool - Whether to create a blood pool
* @param BloodPoolSize - Size of the blood pool
* @param BloodPoolMaterial - Material for the blood pool
* @return True if the blood effect was created successfully
*/
bool SpawnBloodEffect(const FVector& Location, UNiagaraSystem* BloodEffect, float BloodAmount, float BloodPressure, bool CreateBloodPool, float BloodPoolSize, UMaterialInterface* BloodPoolMaterial);
/**
* Apply physics simulation
* @param Mass - Mass of the object
* @param LinearDamping - Linear damping
* @param AngularDamping - Angular damping
* @param EnableGravity - Whether to enable gravity
* @param SimulatePhysics - Whether to simulate physics
* @param GenerateOverlapEvents - Whether to generate overlap events
* @param PhysicalMaterial - Physical material to use
* @param ImpulseForce - Force of the impulse
* @param ImpulseRadius - Radius of the impulse
* @return True if the physics simulation was applied successfully
*/
bool ApplyPhysics(float Mass, float LinearDamping, float AngularDamping, bool EnableGravity, bool SimulatePhysics, bool GenerateOverlapEvents, UPhysicalMaterial* PhysicalMaterial, float ImpulseForce, float ImpulseRadius);
/**
* Spawn an organ
* @param OrganMesh - Mesh for the organ
* @param OrganMaterial - Material for the organ
* @param AttachBoneName - Name of the bone to attach to
* @param RelativeLocation - Relative location
* @param RelativeRotation - Relative rotation
* @param RelativeScale - Relative scale
* @param SimulatePhysics - Whether to simulate physics
* @param DamageMultiplier - Damage multiplier
* @param IsCriticalOrgan - Whether this is a critical organ
* @param BloodAmount - Amount of blood
* @return True if the organ was spawned successfully
*/
bool SpawnOrgan(UStaticMesh* OrganMesh, UMaterialInterface* OrganMaterial, const FName& AttachBoneName, const FVector& RelativeLocation, const FRotator& RelativeRotation, const FVector& RelativeScale, bool SimulatePhysics, float DamageMultiplier, bool IsCriticalOrgan, float BloodAmount);
/**
* Apply a wound effect
* @param WoundSize - Size of the wound
* @param WoundDepth - Depth of the wound
* @param WoundMaterial - Material for the wound
* @param WoundEffect - Effect for the wound
* @param CreateDecal - Whether to create a decal
* @param DecalMaterial - Material for the decal
* @param DecalSize - Size of the decal
* @param DecalLifetime - Lifetime of the decal
* @param AffectBoneHealth - Whether to affect bone health
* @param BoneDamage - Amount of bone damage
* @return True if the wound effect was applied successfully
*/
bool ApplyWoundEffect(float WoundSize, float WoundDepth, UMaterialInterface* WoundMaterial, UNiagaraSystem* WoundEffect, bool CreateDecal, UMaterialInterface* DecalMaterial, float DecalSize, float DecalLifetime, bool AffectBoneHealth, float BoneDamage);
private:
// The compiler containing the compiled graph
UPROPERTY()
TObjectPtr<UDismembermentCompiler> Compiler;
// The target actor
UPROPERTY()
TObjectPtr<AActor> TargetActor;
// The target skeletal mesh component
UPROPERTY()
TObjectPtr<USkeletalMeshComponent> TargetSkeletalMesh;
// Selected bones
UPROPERTY()
TArray<FName> SelectedBones;
// Find the target skeletal mesh component
bool FindTargetSkeletalMesh();
// Execute a node
bool ExecuteNode(int32 NodeIndex);
};

View File

@@ -0,0 +1,22 @@
#pragma once
#include "CoreMinimal.h"
#include "EdGraph/EdGraph.h"
#include "DismembermentGraph.generated.h"
/**
* Dismemberment graph for visual logic design
* Allows for node-based editing of dismemberment system logic
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraph : public UEdGraph
{
GENERATED_BODY()
public:
UDismembermentGraph();
// The asset that owns this graph
UPROPERTY()
class UDismembermentGraphAsset* OwningAsset;
};

View File

@@ -0,0 +1,80 @@
#pragma once
#include "CoreMinimal.h"
#include "Toolkits/AssetEditorToolkit.h"
#include "GraphEditor.h"
class UDismembermentGraphAsset;
class UDismembermentGraph;
class SDockTab;
/**
* Dismemberment graph editor
* Provides a Mutable-like node editor for dismemberment system logic
*/
class FLESHEDITOR_API FDismembermentGraphEditor : public FAssetEditorToolkit
{
public:
FDismembermentGraphEditor();
virtual ~FDismembermentGraphEditor();
// Initialize the editor
void InitDismembermentGraphEditor(const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost>& InitToolkitHost, UDismembermentGraphAsset* InAsset);
// FAssetEditorToolkit interface
virtual void RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
virtual void UnregisterTabSpawners(const TSharedRef<FTabManager>& 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
// Get the edited asset
UDismembermentGraphAsset* GetEditedAsset() const { return EditedAsset; }
// Get the graph editor widget
TSharedRef<SGraphEditor> GetGraphEditor() const { return GraphEditorWidget.ToSharedRef(); }
private:
// The asset being edited
UDismembermentGraphAsset* EditedAsset;
// The graph editor widget
TSharedPtr<SGraphEditor> GraphEditorWidget;
// Tab spawners
TSharedRef<SDockTab> SpawnTab_GraphCanvas(const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnTab_Properties(const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnTab_Palette(const FSpawnTabArgs& Args);
// Create graph editor widget
TSharedRef<SGraphEditor> CreateGraphEditorWidget();
// Graph editor commands
void CreateCommandList();
TSharedPtr<FUICommandList> GraphEditorCommands;
// Command handlers
void SelectAllNodes();
void DeleteSelectedNodes();
void CutSelectedNodes();
void CopySelectedNodes();
void PasteNodes();
void DuplicateSelectedNodes();
// Graph changed handler
void OnGraphChanged(const FEdGraphEditAction& Action);
// Node selection changed handler
void OnSelectedNodesChanged(const TSet<UObject*>& NewSelection);
// Compile the graph
void CompileGraph();
// Properties panel
TSharedPtr<class IDetailsView> PropertiesWidget;
// Node palette
TSharedPtr<class SDismembermentGraphPalette> PaletteWidget;
};

View File

@@ -0,0 +1,22 @@
#pragma once
#include "CoreMinimal.h"
#include "Factories/Factory.h"
#include "DismembermentGraphEditorFactory.generated.h"
/**
* Factory for creating dismemberment graph assets
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphEditorFactory : public UFactory
{
GENERATED_BODY()
public:
UDismembermentGraphEditorFactory();
// UFactory interface
virtual UObject* FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override;
virtual bool ShouldShowInNewMenu() const override;
// End of UFactory interface
};

View File

@@ -0,0 +1,43 @@
#pragma once
#include "CoreMinimal.h"
#include "EdGraph/EdGraphNode.h"
#include "DismembermentGraphNode.generated.h"
/**
* Base class for all dismemberment graph nodes
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphNode : public UEdGraphNode
{
GENERATED_BODY()
public:
UDismembermentGraphNode();
// Node title color
UPROPERTY(EditAnywhere, Category = "Appearance")
FLinearColor NodeTitleColor;
// Node category
UPROPERTY(EditAnywhere, Category = "Category")
FText NodeCategory;
// Node description
UPROPERTY(EditAnywhere, Category = "Description")
FText NodeDescription;
// UEdGraphNode interface
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
virtual FLinearColor GetNodeTitleColor() const override;
virtual FText GetTooltipText() const override;
virtual FText GetMenuCategory() const override;
// End of UEdGraphNode interface
// Compile this node into executable logic
virtual void CompileNode(class FDismembermentCompiler* Compiler);
// Execute this node
virtual void ExecuteNode(class FDismembermentExecutor* Executor);
};

View File

@@ -0,0 +1,46 @@
#pragma once
#include "CoreMinimal.h"
#include "DismembermentGraphNode.h"
#include "DismembermentGraphNodeBloodEffect.generated.h"
/**
* Node for creating blood effects in the dismemberment graph
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphNodeBloodEffect : public UDismembermentGraphNode
{
GENERATED_BODY()
public:
UDismembermentGraphNodeBloodEffect();
// Blood effect parameters
UPROPERTY(EditAnywhere, Category = "Blood Effect")
TObjectPtr<UNiagaraSystem> BloodEffect;
UPROPERTY(EditAnywhere, Category = "Blood Effect")
float BloodAmount;
UPROPERTY(EditAnywhere, Category = "Blood Effect")
float BloodPressure;
UPROPERTY(EditAnywhere, Category = "Blood Effect")
bool bCreateBloodPool;
UPROPERTY(EditAnywhere, Category = "Blood Effect", meta = (EditCondition = "bCreateBloodPool"))
float BloodPoolSize;
UPROPERTY(EditAnywhere, Category = "Blood Effect", meta = (EditCondition = "bCreateBloodPool"))
TObjectPtr<UMaterialInterface> BloodPoolMaterial;
// UEdGraphNode interface
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
// End of UEdGraphNode interface
// UDismembermentGraphNode interface
virtual void CompileNode(class FDismembermentCompiler* Compiler) override;
virtual void ExecuteNode(class FDismembermentExecutor* Executor) override;
// End of UDismembermentGraphNode interface
};

View File

@@ -0,0 +1,40 @@
#pragma once
#include "CoreMinimal.h"
#include "DismembermentGraphNode.h"
#include "DismembermentGraphNodeBoneSelect.generated.h"
/**
* Node for selecting bones in the dismemberment graph
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphNodeBoneSelect : public UDismembermentGraphNode
{
GENERATED_BODY()
public:
UDismembermentGraphNodeBoneSelect();
// Bone selection parameters
UPROPERTY(EditAnywhere, Category = "Bone Selection")
TArray<FName> BoneNames;
UPROPERTY(EditAnywhere, Category = "Bone Selection")
bool bUseRegex;
UPROPERTY(EditAnywhere, Category = "Bone Selection", meta = (EditCondition = "bUseRegex"))
FString BoneNamePattern;
UPROPERTY(EditAnywhere, Category = "Bone Selection")
bool bIncludeChildren;
// UEdGraphNode interface
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
// End of UEdGraphNode interface
// UDismembermentGraphNode interface
virtual void CompileNode(class FDismembermentCompiler* Compiler) override;
virtual void ExecuteNode(class FDismembermentExecutor* Executor) override;
// End of UDismembermentGraphNode interface
};

View File

@@ -0,0 +1,40 @@
#pragma once
#include "CoreMinimal.h"
#include "DismembermentGraphNode.h"
#include "DismembermentGraphNodeCut.generated.h"
/**
* Node for performing a cut operation in the dismemberment graph
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphNodeCut : public UDismembermentGraphNode
{
GENERATED_BODY()
public:
UDismembermentGraphNodeCut();
// Cut parameters
UPROPERTY(EditAnywhere, Category = "Cut Parameters")
float CutWidth;
UPROPERTY(EditAnywhere, Category = "Cut Parameters")
float CutDepth;
UPROPERTY(EditAnywhere, Category = "Cut Parameters")
bool bUseCustomMaterial;
UPROPERTY(EditAnywhere, Category = "Cut Parameters", meta = (EditCondition = "bUseCustomMaterial"))
TObjectPtr<UMaterialInterface> CustomCutMaterial;
// UEdGraphNode interface
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
// End of UEdGraphNode interface
// UDismembermentGraphNode interface
virtual void CompileNode(class FDismembermentCompiler* Compiler) override;
virtual void ExecuteNode(class FDismembermentExecutor* Executor) override;
// End of UDismembermentGraphNode interface
};

View File

@@ -0,0 +1,58 @@
#pragma once
#include "CoreMinimal.h"
#include "DismembermentGraphNode.h"
#include "DismembermentGraphNodeOrgan.generated.h"
/**
* Node for organ simulation in the dismemberment graph
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphNodeOrgan : public UDismembermentGraphNode
{
GENERATED_BODY()
public:
UDismembermentGraphNodeOrgan();
// Organ parameters
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
TObjectPtr<UStaticMesh> OrganMesh;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
TObjectPtr<UMaterialInterface> OrganMaterial;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
FName AttachBoneName;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
FVector RelativeLocation;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
FRotator RelativeRotation;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
FVector RelativeScale;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
bool bSimulatePhysics;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
float DamageMultiplier;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
bool bIsCriticalOrgan;
UPROPERTY(EditAnywhere, Category = "Organ Parameters")
float BloodAmount;
// UEdGraphNode interface
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
// End of UEdGraphNode interface
// UDismembermentGraphNode interface
virtual void CompileNode(class FDismembermentCompiler* Compiler) override;
virtual void ExecuteNode(class FDismembermentExecutor* Executor) override;
// End of UDismembermentGraphNode interface
};

View File

@@ -0,0 +1,55 @@
#pragma once
#include "CoreMinimal.h"
#include "DismembermentGraphNode.h"
#include "DismembermentGraphNodePhysics.generated.h"
/**
* Node for physics simulation in the dismemberment graph
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphNodePhysics : public UDismembermentGraphNode
{
GENERATED_BODY()
public:
UDismembermentGraphNodePhysics();
// Physics parameters
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
float Mass;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
float LinearDamping;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
float AngularDamping;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
bool bEnableGravity;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
bool bSimulatePhysics;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
bool bGenerateOverlapEvents;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
TObjectPtr<UPhysicalMaterial> PhysicalMaterial;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
float ImpulseForce;
UPROPERTY(EditAnywhere, Category = "Physics Parameters")
float ImpulseRadius;
// UEdGraphNode interface
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
// End of UEdGraphNode interface
// UDismembermentGraphNode interface
virtual void CompileNode(class FDismembermentCompiler* Compiler) override;
virtual void ExecuteNode(class FDismembermentExecutor* Executor) override;
// End of UDismembermentGraphNode interface
};

View File

@@ -0,0 +1,58 @@
#pragma once
#include "CoreMinimal.h"
#include "DismembermentGraphNode.h"
#include "DismembermentGraphNodeWound.generated.h"
/**
* Node for wound effects in the dismemberment graph
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphNodeWound : public UDismembermentGraphNode
{
GENERATED_BODY()
public:
UDismembermentGraphNodeWound();
// Wound parameters
UPROPERTY(EditAnywhere, Category = "Wound Parameters")
float WoundSize;
UPROPERTY(EditAnywhere, Category = "Wound Parameters")
float WoundDepth;
UPROPERTY(EditAnywhere, Category = "Wound Parameters")
TObjectPtr<UMaterialInterface> WoundMaterial;
UPROPERTY(EditAnywhere, Category = "Wound Parameters")
TObjectPtr<UNiagaraSystem> WoundEffect;
UPROPERTY(EditAnywhere, Category = "Wound Parameters")
bool bCreateDecal;
UPROPERTY(EditAnywhere, Category = "Wound Parameters", meta = (EditCondition = "bCreateDecal"))
TObjectPtr<UMaterialInterface> DecalMaterial;
UPROPERTY(EditAnywhere, Category = "Wound Parameters", meta = (EditCondition = "bCreateDecal"))
float DecalSize;
UPROPERTY(EditAnywhere, Category = "Wound Parameters", meta = (EditCondition = "bCreateDecal"))
float DecalLifetime;
UPROPERTY(EditAnywhere, Category = "Wound Parameters")
bool bAffectBoneHealth;
UPROPERTY(EditAnywhere, Category = "Wound Parameters", meta = (EditCondition = "bAffectBoneHealth"))
float BoneDamage;
// UEdGraphNode interface
virtual void AllocateDefaultPins() override;
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
// End of UEdGraphNode interface
// UDismembermentGraphNode interface
virtual void CompileNode(class FDismembermentCompiler* Compiler) override;
virtual void ExecuteNode(class FDismembermentExecutor* Executor) override;
// End of UDismembermentGraphNode interface
};

View File

@@ -0,0 +1,84 @@
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/Views/STableRow.h"
#include "Widgets/Views/STreeView.h"
class FDismembermentGraphEditor;
/**
* Node category structure for the palette
*/
struct FDismembermentGraphNodeCategory
{
// Category name
FText CategoryName;
// Child nodes
TArray<TSharedPtr<FDismembermentGraphNodeCategory>> Children;
// Node classes in this category
TArray<UClass*> NodeClasses;
// Constructor
FDismembermentGraphNodeCategory(const FText& InCategoryName)
: CategoryName(InCategoryName)
{
}
};
/**
* Node palette widget for the dismemberment graph editor
*/
class FLESHEDITOR_API SDismembermentGraphPalette : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SDismembermentGraphPalette) {}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs, TSharedPtr<FDismembermentGraphEditor> InGraphEditor);
private:
// The graph editor that owns this palette
TWeakPtr<FDismembermentGraphEditor> GraphEditor;
// Root categories
TArray<TSharedPtr<FDismembermentGraphNodeCategory>> RootCategories;
// Tree view widget
TSharedPtr<STreeView<TSharedPtr<FDismembermentGraphNodeCategory>>> CategoriesTreeView;
// Search box widget
TSharedPtr<class SSearchBox> SearchBox;
// Search filter
TSharedPtr<class FDismembermentGraphNodeSearchFilter> SearchFilter;
// Initialize the palette
void InitializePalette();
// Create a category tree item
TSharedRef<ITableRow> OnGenerateCategoryRow(TSharedPtr<FDismembermentGraphNodeCategory> Category, const TSharedRef<STableViewBase>& OwnerTable);
// Get child categories
void OnGetCategoryChildren(TSharedPtr<FDismembermentGraphNodeCategory> Category, TArray<TSharedPtr<FDismembermentGraphNodeCategory>>& OutChildren);
// Category is expanded
void OnCategoryExpansionChanged(TSharedPtr<FDismembermentGraphNodeCategory> Category, bool bExpanded);
// Search text changed
void OnSearchTextChanged(const FText& InFilterText);
// Create a node from the palette
FReply OnCreateNode(UClass* NodeClass, const FVector2D& ScreenPosition, const FVector2D& GraphPosition);
// Handle drag detected
FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent, UClass* NodeClass);
// Create default categories
void CreateDefaultCategories();
// Add a node class to the palette
void AddNodeClassToCategory(UClass* NodeClass, const FText& CategoryName);
};

View File

@@ -0,0 +1,168 @@
#pragma once
#include "CoreMinimal.h"
#include "EdGraph/EdGraphSchema.h"
#include "DismembermentGraphSchema.generated.h"
class UDismembermentGraphNode;
/**
* Connection response
*/
USTRUCT()
struct FDismembermentGraphConnectionResponse
{
GENERATED_BODY()
// Response type
UPROPERTY()
int32 Response;
// Response text
UPROPERTY()
FText Message;
// Pin names that would be broken
UPROPERTY()
TArray<FText> BreakingPins;
// Constructor
FDismembermentGraphConnectionResponse()
: Response(0)
{
}
};
/**
* Connection response types
*/
struct FDismembermentGraphConnectionResponse_K2
{
enum Type
{
// No error
OK = 0,
// Generic error
ERROR_INCOMPATIBLE = 1,
// Disallowed pin connection
ERROR_DISALLOWED = 2,
// Self-connection not allowed
ERROR_SELF_CONNECTION = 3,
// Cycle not allowed
ERROR_CYCLE = 4
};
};
/**
* Pin type
*/
USTRUCT()
struct FDismembermentGraphPinType
{
GENERATED_BODY()
// Pin category
UPROPERTY()
FName PinCategory;
// Constructor
FDismembermentGraphPinType()
{
}
// Constructor with category
FDismembermentGraphPinType(const FName& InPinCategory)
: PinCategory(InPinCategory)
{
}
// Equality operator
bool operator==(const FDismembermentGraphPinType& Other) const
{
return PinCategory == Other.PinCategory;
}
// Inequality operator
bool operator!=(const FDismembermentGraphPinType& Other) const
{
return !(*this == Other);
}
};
/**
* Dismemberment graph schema
*/
UCLASS()
class FLESHEDITOR_API UDismembermentGraphSchema : public UEdGraphSchema
{
GENERATED_BODY()
public:
// Pin categories
static const FName PC_Exec;
static const FName PC_Bone;
static const FName PC_Cut;
static const FName PC_Blood;
static const FName PC_Physics;
static const FName PC_Organ;
static const FName PC_Wound;
// UEdGraphSchema interface
virtual void GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const override;
virtual void GetContextMenuActions(UToolMenu* Menu, UGraphNodeContextMenuContext* Context) const override;
virtual const FPinConnectionResponse CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const override;
virtual bool TryCreateConnection(UEdGraphPin* A, UEdGraphPin* B) const override;
virtual bool ShouldHidePinDefaultValue(UEdGraphPin* Pin) const override;
virtual FLinearColor GetPinTypeColor(const FEdGraphPinType& PinType) const override;
virtual void BreakNodeLinks(UEdGraphNode& TargetNode) const override;
virtual void BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotification) const override;
virtual void BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const override;
virtual void DroppedAssetsOnGraph(const TArray<FAssetData>& Assets, const FVector2D& GraphPosition, UEdGraph* Graph) const override;
virtual void DroppedAssetsOnNode(const TArray<FAssetData>& Assets, const FVector2D& GraphPosition, UEdGraphNode* Node) const override;
virtual void DroppedAssetsOnPin(const TArray<FAssetData>& Assets, const FVector2D& GraphPosition, UEdGraphPin* Pin) const override;
virtual void GetAssetsNodeHoverMessage(const TArray<FAssetData>& Assets, const UEdGraphNode* HoverNode, FString& OutTooltipText, bool& OutOkIcon) const override;
virtual void GetAssetsPinHoverMessage(const TArray<FAssetData>& Assets, const UEdGraphPin* HoverPin, FString& OutTooltipText, bool& OutOkIcon) const override;
// End of UEdGraphSchema interface
/**
* Check if two pins can be connected
* @param PinA - First pin
* @param PinB - Second pin
* @param OutResponse - Connection response
* @return True if the pins can be connected
*/
bool CanConnectPins(const UEdGraphPin* PinA, const UEdGraphPin* PinB, FDismembermentGraphConnectionResponse& OutResponse) const;
/**
* Check if connecting two pins would create a cycle
* @param PinA - First pin
* @param PinB - Second pin
* @return True if connecting the pins would create a cycle
*/
bool WouldCreateCycle(const UEdGraphPin* PinA, const UEdGraphPin* PinB) const;
/**
* Get the pin type from a pin
* @param Pin - The pin to get the type from
* @return The pin type
*/
static FDismembermentGraphPinType GetPinType(const UEdGraphPin* Pin);
/**
* Get the pin type color
* @param PinType - The pin type
* @return The pin color
*/
static FLinearColor GetPinTypeColor(const FDismembermentGraphPinType& PinType);
/**
* Create a new node
* @param NodeClass - Class of the node to create
* @param ParentGraph - Graph to create the node in
* @param NodePosX - X position of the node
* @param NodePosY - Y position of the node
* @param bSelectNewNode - Whether to select the new node
* @return The created node
*/
static UDismembermentGraphNode* CreateNode(TSubclassOf<UDismembermentGraphNode> NodeClass, UEdGraph* ParentGraph, float NodePosX, float NodePosY, bool bSelectNewNode = true);
};

View File

@@ -0,0 +1,167 @@
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "DismembermentPreviewManager.generated.h"
// Add a log category declaration
DECLARE_LOG_CATEGORY_EXTERN(LogFLESHPreview, Log, All);
class UDismembermentGraphNode;
class USkeletalMeshComponent;
class AActor;
class UWorld;
class UNiagaraComponent;
class UDecalComponent;
class UStaticMeshComponent;
/**
* Preview manager for dismemberment effects
* Handles real-time preview of dismemberment nodes
*/
UCLASS()
class FLESHEDITOR_API UDismembermentPreviewManager : public UObject
{
GENERATED_BODY()
public:
// Constructor
UDismembermentPreviewManager();
/**
* Initialize the preview manager
* @param InWorld - The world to create the preview in
*/
void Initialize(TObjectPtr<UWorld> InWorld);
/**
* Clean up the preview manager
*/
void Cleanup();
/**
* Set the target actor for preview
* @param InActor - The actor to preview on
*/
void SetTargetActor(TObjectPtr<AActor> InActor);
/**
* Preview a node
* @param Node - The node to preview
* @return True if the preview was successful
*/
bool PreviewNode(TObjectPtr<UDismembermentGraphNode> Node);
/**
* Clear the current preview
*/
void ClearPreview();
/**
* Update the preview
* @param DeltaTime - Time since last update
*/
void Tick(float DeltaTime);
/**
* Get the target actor
* @return The target actor
*/
TObjectPtr<AActor> GetTargetActor() const { return TargetActor; }
/**
* Get the target skeletal mesh component
* @return The target skeletal mesh component
*/
TObjectPtr<USkeletalMeshComponent> GetTargetSkeletalMesh() const { return TargetSkeletalMesh; }
private:
// The world to create the preview in
UPROPERTY()
TObjectPtr<UWorld> World;
// The target actor
UPROPERTY()
TObjectPtr<AActor> TargetActor;
// The target skeletal mesh component
UPROPERTY()
TObjectPtr<USkeletalMeshComponent> TargetSkeletalMesh;
// The currently previewed node
UPROPERTY()
TObjectPtr<UDismembermentGraphNode> PreviewedNode;
// Preview components
UPROPERTY()
TArray<TObjectPtr<UNiagaraComponent>> PreviewNiagaraComponents;
UPROPERTY()
TArray<TObjectPtr<UDecalComponent>> PreviewDecalComponents;
UPROPERTY()
TArray<TObjectPtr<UStaticMeshComponent>> PreviewStaticMeshComponents;
// Preview cut plane mesh
UPROPERTY()
TObjectPtr<UStaticMeshComponent> PreviewCutPlaneMesh;
// Preview bone selections
UPROPERTY()
TArray<FName> PreviewBoneSelections;
// Preview cut locations
UPROPERTY()
TArray<FTransform> PreviewCutTransforms;
// Preview blood effect locations
UPROPERTY()
TArray<FTransform> PreviewBloodEffectTransforms;
// Preview organ locations
UPROPERTY()
TArray<FTransform> PreviewOrganTransforms;
// Preview wound locations
UPROPERTY()
TArray<FTransform> PreviewWoundTransforms;
// Find the target skeletal mesh component
bool FindTargetSkeletalMesh();
// Preview a cut node
bool PreviewCutNode(TObjectPtr<class UDismembermentGraphNodeCut> CutNode);
// Preview a bone select node
bool PreviewBoneSelectNode(TObjectPtr<class UDismembermentGraphNodeBoneSelect> BoneSelectNode);
// Preview a blood effect node
bool PreviewBloodEffectNode(TObjectPtr<class UDismembermentGraphNodeBloodEffect> BloodEffectNode);
// Preview a physics node
bool PreviewPhysicsNode(TObjectPtr<class UDismembermentGraphNodePhysics> PhysicsNode);
// Preview an organ node
bool PreviewOrganNode(TObjectPtr<class UDismembermentGraphNodeOrgan> OrganNode);
// Preview a wound node
bool PreviewWoundNode(TObjectPtr<class UDismembermentGraphNodeWound> WoundNode);
// Create a preview cut plane mesh
TObjectPtr<UStaticMeshComponent> CreatePreviewCutPlaneMesh(const FVector& Location, const FVector& Direction, float Width, float Depth, UMaterialInterface* Material);
// Create a preview blood effect
TObjectPtr<UNiagaraComponent> CreatePreviewBloodEffect(const FVector& Location, UNiagaraSystem* BloodEffect, float BloodAmount, float BloodPressure);
// Create a preview blood pool
TObjectPtr<UDecalComponent> CreatePreviewBloodPool(const FVector& Location, float Size, UMaterialInterface* Material);
// Create a preview organ
TObjectPtr<UStaticMeshComponent> CreatePreviewOrgan(UStaticMesh* OrganMesh, UMaterialInterface* OrganMaterial, const FName& AttachBoneName, const FVector& RelativeLocation, const FRotator& RelativeRotation, const FVector& RelativeScale);
// Create a preview wound
TObjectPtr<UDecalComponent> CreatePreviewWound(const FVector& Location, float Size, UMaterialInterface* Material);
// Clear all preview components
void ClearPreviewComponents();
};

View File

@@ -0,0 +1,68 @@
#pragma once
#include "CoreMinimal.h"
#include "SGraphNode.h"
class UDismembermentGraphNode;
/**
* Visual representation of a dismemberment graph node
*/
class FLESHEDITOR_API SDismembermentGraphNode : public SGraphNode
{
public:
SLATE_BEGIN_ARGS(SDismembermentGraphNode) {}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs, UEdGraphNode* InNode);
// SGraphNode interface
virtual void UpdateGraphNode() override;
virtual void CreatePinWidgets() override;
virtual void AddPin(const TSharedRef<SGraphPin>& PinToAdd) override;
virtual TSharedPtr<SToolTip> GetComplexTooltip() override;
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
// End of SGraphNode interface
protected:
// Get the dismemberment graph node
UDismembermentGraphNode* GetDismembermentGraphNode() const;
// Get the node title widget
TSharedRef<SWidget> GetNodeTitleWidget();
// Get the node body widget
TSharedRef<SWidget> GetNodeBodyWidget();
// Get the node preview widget
TSharedRef<SWidget> GetNodePreviewWidget();
// Node color
FSlateColor GetNodeColor() const;
// Node title color
FSlateColor GetNodeTitleColor() const;
// Node title text
FText GetNodeTitle() const;
// Node category text
FText GetNodeCategory() const;
// Node description text
FText GetNodeDescription() const;
// Is the node selected
bool IsNodeSelected() const;
// Is the node hovered
bool IsNodeHovered() const;
private:
// Is the node hovered
bool bIsHovered;
};

View File

@@ -0,0 +1,120 @@
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "EditorViewportClient.h"
#include "SEditorViewport.h"
class UDismembermentPreviewManager;
class USkeletalMesh;
class AActor;
class FPreviewScene;
class SDismembermentPreviewViewportClient;
/**
* Viewport for previewing dismemberment effects
*/
class FLESHEDITOR_API SDismembermentPreviewViewport : public SEditorViewport
{
public:
SLATE_BEGIN_ARGS(SDismembermentPreviewViewport)
{}
SLATE_END_ARGS()
/**
* Constructs the viewport widget
*/
void Construct(const FArguments& InArgs);
/**
* Destructor
*/
virtual ~SDismembermentPreviewViewport();
/**
* Set the preview manager
* @param InPreviewManager - The preview manager to use
*/
void SetPreviewManager(UDismembermentPreviewManager* InPreviewManager);
/**
* Set the preview skeletal mesh
* @param InSkeletalMesh - The skeletal mesh to preview
*/
void SetPreviewSkeletalMesh(USkeletalMesh* InSkeletalMesh);
/**
* Get the preview actor
* @return The preview actor
*/
AActor* GetPreviewActor() const;
/**
* Refresh the viewport
*/
void RefreshViewport();
protected:
// SEditorViewport interface
virtual TSharedRef<FEditorViewportClient> MakeEditorViewportClient() override;
virtual void OnFocusViewportToSelection() override;
virtual bool IsVisible() const override;
// End of SEditorViewport interface
private:
// The preview scene
TSharedPtr<FPreviewScene> PreviewScene;
// The viewport client
TSharedPtr<SDismembermentPreviewViewportClient> ViewportClient;
// The preview manager
TObjectPtr<UDismembermentPreviewManager> PreviewManager;
// The preview actor
TObjectPtr<AActor> PreviewActor;
// Create the preview actor
void CreatePreviewActor();
// Update the preview actor
void UpdatePreviewActor();
};
/**
* Viewport client for previewing dismemberment effects
*/
class SDismembermentPreviewViewportClient : public FEditorViewportClient
{
public:
/**
* Constructor
* @param InPreviewScene - The preview scene
* @param InViewportWidget - The viewport widget
*/
SDismembermentPreviewViewportClient(FPreviewScene* InPreviewScene, const TWeakPtr<SDismembermentPreviewViewport>& InViewportWidget);
/**
* Destructor
*/
virtual ~SDismembermentPreviewViewportClient();
// FEditorViewportClient interface
virtual void Tick(float DeltaSeconds) override;
virtual void Draw(const FSceneView* View, FPrimitiveDrawInterface* PDI) override;
virtual void DrawCanvas(FViewport& InViewport, FSceneView& View, FCanvas& Canvas) override;
// End of FEditorViewportClient interface
/**
* Set the preview manager
* @param InPreviewManager - The preview manager to use
*/
void SetPreviewManager(UDismembermentPreviewManager* InPreviewManager);
private:
// The viewport widget
TWeakPtr<SDismembermentPreviewViewport> ViewportWidget;
// The preview manager
TObjectPtr<UDismembermentPreviewManager> PreviewManager;
};

View File

@@ -0,0 +1,107 @@
#pragma once
#include "CoreMinimal.h"
#include "Toolkits/AssetEditorToolkit.h"
#include "Widgets/Docking/SDockTab.h"
class SDockTab;
class SGraphEditor;
class SPropertyTreeView;
class SAssetBrowser;
class SMatrixInputWidget;
/**
* FLESH Main Editor
* Provides the main editing functionality for the dismemberment system
*/
class FLESHEDITOR_API FFLESHEditor : public FAssetEditorToolkit
{
public:
FFLESHEditor();
virtual ~FFLESHEditor();
// Initialize the editor
void InitFLESHEditor(const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost>& InitToolkitHost);
// FAssetEditorToolkit interface
virtual void RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
virtual void UnregisterTabSpawners(const TSharedRef<FTabManager>& 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
// Open the editor
static void OpenEditor();
private:
// Tab spawners
TSharedRef<SDockTab> SpawnTab_Viewport(const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnTab_Details(const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnTab_AssetBrowser(const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnTab_MatrixEditor(const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnTab_GraphEditor(const FSpawnTabArgs& Args);
TSharedRef<SDockTab> SpawnTab_Toolbar(const FSpawnTabArgs& Args);
// Create viewport widget
TSharedRef<SWidget> CreateViewportWidget();
// Create details panel
TSharedRef<SWidget> CreateDetailsWidget();
// Create asset browser
TSharedRef<SWidget> CreateAssetBrowserWidget();
// Create matrix editor
TSharedRef<SWidget> CreateMatrixEditorWidget();
// Create graph editor
TSharedRef<SWidget> CreateGraphEditorWidget();
// Create toolbar
TSharedRef<SWidget> CreateToolbarWidget();
// Create command list
void CreateCommandList();
// Command handlers
void OnOpenDismembermentGraphEditor();
void OnOpenAnatomicalLayerEditor();
void OnOpenBooleanCutTool();
void OnOpenBloodSystemEditor();
void OnImportCharacterModel();
void OnImportOrganModel();
void OnImportSkeletonModel();
void OnImportPhysicsAsset();
void OnTestMatrix();
// Viewport widget
TSharedPtr<class SViewport> ViewportWidget;
// Details panel
TSharedPtr<class IDetailsView> DetailsWidget;
// Asset browser
TSharedPtr<SAssetBrowser> AssetBrowserWidget;
// Matrix editor
TSharedPtr<SMatrixInputWidget> MatrixEditorWidget;
// Graph editor
TSharedPtr<SGraphEditor> GraphEditorWidget;
// Toolbar
TSharedPtr<class SBorder> ToolbarWidget;
// Command list
TSharedPtr<FUICommandList> CommandList;
// 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;
};

View File

@@ -0,0 +1,41 @@
#pragma once
#include "CoreMinimal.h"
#include "Framework/Commands/Commands.h"
#include "FLESHEditorStyle.h"
/**
* FLESH Editor Commands
* Defines all commands for the FLESH editor
*/
class FFLESHEditorCommands : public TCommands<FFLESHEditorCommands>
{
public:
FFLESHEditorCommands()
: TCommands<FFLESHEditorCommands>(
TEXT("FLESHEditor"),
NSLOCTEXT("Contexts", "FLESHEditor", "FLESH Editor"),
NAME_None,
FFLESHEditorStyle::GetStyleSetName())
{
}
// TCommands interface
virtual void RegisterCommands() override;
// End of TCommands interface
// Open FLESH Editor command
TSharedPtr<FUICommandInfo> OpenFLESHEditor;
// Open Dismemberment Graph Editor command
TSharedPtr<FUICommandInfo> OpenDismembermentGraphEditor;
// Open Anatomical Layer Editor command
TSharedPtr<FUICommandInfo> OpenAnatomicalLayerEditor;
// Open Boolean Cut Tool command
TSharedPtr<FUICommandInfo> OpenBooleanCutTool;
// Open Blood System Editor command
TSharedPtr<FUICommandInfo> OpenBloodSystemEditor;
};

View File

@@ -0,0 +1,28 @@
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
/**
* FLESH Editor Module - Editor tools for the Fully Locational Evisceration System for Humanoids
*/
class FFLESHEditorModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
/** Singleton getter */
static FFLESHEditorModule& Get()
{
return FModuleManager::LoadModuleChecked<FFLESHEditorModule>("FLESHEditor");
}
/** Open FLESH Editor */
void OpenFLESHEditor();
private:
/** Plugin command list */
TSharedPtr<class FUICommandList> PluginCommands;
};

View File

@@ -0,0 +1,34 @@
#pragma once
#include "CoreMinimal.h"
#include "Styling/SlateStyle.h"
/**
* FLESH Editor Style
* Defines the visual style for the FLESH editor
*/
class FFLESHEditorStyle
{
public:
// Initialize the style
static void Initialize();
// Shutdown the style
static void Shutdown();
// Reload textures
static void ReloadTextures();
// Get the style set name
static FName GetStyleSetName();
// Get the instance
static const ISlateStyle& Get();
private:
// Create the style
static TSharedRef<FSlateStyleSet> Create();
// The instance
static TSharedPtr<FSlateStyleSet> StyleInstance;
};

View File

@@ -0,0 +1,72 @@
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "Widgets/Input/SNumericEntryBox.h"
#include "Widgets/Input/SButton.h"
#include "Widgets/Layout/SBox.h"
#include "Widgets/Layout/SGridPanel.h"
/**
* Matrix input widget for the FLESH editor
* Allows inputting transformation matrices for precise cutting operations
*/
class FLESHEDITOR_API SMatrixInputWidget : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SMatrixInputWidget)
: _Matrix(FMatrix::Identity)
, _OnMatrixChanged()
{}
/** The initial matrix value */
SLATE_ARGUMENT(FMatrix, Matrix)
/** Called when the matrix value changes */
SLATE_EVENT(FOnMatrixChanged, OnMatrixChanged)
SLATE_END_ARGS()
/** Constructs this widget */
void Construct(const FArguments& InArgs);
/** Sets the matrix value */
void SetMatrix(const FMatrix& InMatrix);
/** Gets the current matrix value */
FMatrix GetMatrix() const;
/** Resets the matrix to identity */
void ResetToIdentity();
/** Creates a rotation matrix from Euler angles */
void SetFromEulerAngles(float Roll, float Pitch, float Yaw);
/** Creates a translation matrix */
void SetFromTranslation(const FVector& Translation);
/** Creates a combined transformation matrix */
void SetFromTransform(const FTransform& Transform);
private:
/** The current matrix value */
FMatrix Matrix;
/** Called when the matrix value changes */
FOnMatrixChanged OnMatrixChanged;
/** The grid panel containing the matrix elements */
TSharedPtr<SGridPanel> GridPanel;
/** Array of numeric entry boxes for matrix elements */
TArray<TSharedPtr<SNumericEntryBox<float>>> NumericEntryBoxes;
/** Creates a numeric entry box for a matrix element */
TSharedPtr<SNumericEntryBox<float>> CreateMatrixElementWidget(int32 Row, int32 Col);
/** Called when a matrix element changes */
void OnMatrixElementChanged(float NewValue, int32 Row, int32 Col);
/** Updates the UI from the matrix value */
void UpdateUI();
};
/** Delegate for matrix value changes */
DECLARE_DELEGATE_OneParam(FOnMatrixChanged, const FMatrix&);