添加 Source/FLESH/Public/SoftBodyPhysicsTool.h

This commit is contained in:
2025-04-21 18:08:55 +08:00
parent da4725d45b
commit 282975cf99

View File

@@ -0,0 +1,378 @@
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "PhysicsEngine/PhysicsConstraintComponent.h"
#include "SoftBodyPhysicsTool.generated.h"
// Forward declarations
class USkeletalMeshComponent;
class UStaticMeshComponent;
class UPhysicsConstraintComponent;
/**
* Soft body anchor point definition
*/
USTRUCT(BlueprintType)
struct FSoftBodyAnchorPoint
{
GENERATED_BODY()
// Anchor point location in local space
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
FVector Location;
// Anchor point radius
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
float Radius = 5.0f;
// Anchor point stiffness (0-1)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float Stiffness = 1.0f;
// Bone name to attach to (if any)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
FName BoneName;
// Constructor
FSoftBodyAnchorPoint()
: Location(FVector::ZeroVector)
{
}
// Constructor with parameters
FSoftBodyAnchorPoint(const FVector& InLocation, float InRadius = 5.0f, float InStiffness = 1.0f, FName InBoneName = NAME_None)
: Location(InLocation)
, Radius(InRadius)
, Stiffness(InStiffness)
, BoneName(InBoneName)
{
}
// Add == operator to support IndexOfByKey
bool operator==(const FSoftBodyAnchorPoint& Other) const
{
return Location.Equals(Other.Location) &&
FMath::IsNearlyEqual(Radius, Other.Radius) &&
FMath::IsNearlyEqual(Stiffness, Other.Stiffness) &&
BoneName == Other.BoneName;
}
};
/**
* Soft body line chain definition
*/
USTRUCT(BlueprintType)
struct FSoftBodyLineChain
{
GENERATED_BODY()
// Chain points in local space
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
TArray<FVector> Points;
// Chain stiffness (0-1)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float Stiffness = 0.5f;
// Chain thickness
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
float Thickness = 1.0f;
// Constructor
FSoftBodyLineChain()
{
}
// Constructor with parameters
FSoftBodyLineChain(const TArray<FVector>& InPoints, float InStiffness = 0.5f, float InThickness = 1.0f)
: Points(InPoints)
, Stiffness(InStiffness)
, Thickness(InThickness)
{
}
// Add == operator to support IndexOfByKey
bool operator==(const FSoftBodyLineChain& Other) const
{
if (Points.Num() != Other.Points.Num() ||
!FMath::IsNearlyEqual(Stiffness, Other.Stiffness) ||
!FMath::IsNearlyEqual(Thickness, Other.Thickness))
{
return false;
}
for (int32 i = 0; i < Points.Num(); ++i)
{
if (!Points[i].Equals(Other.Points[i]))
{
return false;
}
}
return true;
}
};
/**
* Soft body tetrahedron definition
*/
USTRUCT(BlueprintType)
struct FSoftBodyTetrahedron
{
GENERATED_BODY()
// Four corner points in local space
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
TArray<FVector> Points;
// Tetrahedron stiffness (0-1)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float Stiffness = 0.7f;
// Constructor
FSoftBodyTetrahedron()
{
Points.SetNum(4);
}
// Constructor with parameters
FSoftBodyTetrahedron(const TArray<FVector>& InPoints, float InStiffness = 0.7f)
: Stiffness(InStiffness)
{
if (InPoints.Num() >= 4)
{
Points.SetNum(4);
for (int32 i = 0; i < 4; ++i)
{
Points[i] = InPoints[i];
}
}
else
{
Points.SetNum(4);
}
}
// Add == operator to support IndexOfByKey
bool operator==(const FSoftBodyTetrahedron& Other) const
{
if (!FMath::IsNearlyEqual(Stiffness, Other.Stiffness))
{
return false;
}
for (int32 i = 0; i < 4; ++i)
{
if (!Points[i].Equals(Other.Points[i]))
{
return false;
}
}
return true;
}
};
/**
* Soft body plane constraint definition
*/
USTRUCT(BlueprintType)
struct FSoftBodyPlaneConstraint
{
GENERATED_BODY()
// Plane location in local space
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
FVector Location;
// Plane normal
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
FVector Normal;
// Constraint stiffness (0-1)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float Stiffness = 1.0f;
// Constructor
FSoftBodyPlaneConstraint()
: Location(FVector::ZeroVector)
, Normal(FVector::UpVector)
{
}
// Constructor with parameters
FSoftBodyPlaneConstraint(const FVector& InLocation, const FVector& InNormal, float InStiffness = 1.0f)
: Location(InLocation)
, Normal(InNormal)
, Stiffness(InStiffness)
{
}
// Add == operator to support IndexOfByKey
bool operator==(const FSoftBodyPlaneConstraint& Other) const
{
return Location.Equals(Other.Location) &&
Normal.Equals(Other.Normal) &&
FMath::IsNearlyEqual(Stiffness, Other.Stiffness);
}
};
/**
* Soft body simulation settings
*/
USTRUCT(BlueprintType)
struct FSoftBodySimulationSettings
{
GENERATED_BODY()
// Enable simulation
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
bool bEnableSimulation = true;
// Gravity strength multiplier
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "10.0"))
float GravityStrength = 1.0f;
// Minimum frame speed
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1000.0"))
float MinFrameSpeed = 0.0f;
// Maximum frame speed
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1000.0"))
float MaxFrameSpeed = 200.0f;
// External frame lerp
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float ExternalFrameLerp = 1.0f;
// Initial GPU influence
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "1.0"))
float InitialGPUInfluence = 0.5f;
// Substep time
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "0.0", ClampMax = "0.1"))
float SubstepTime = 0.01667f;
// Solver iterations
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics", meta = (ClampMin = "1", ClampMax = "10"))
int32 SolverIterations = 1;
// Recompute normals
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FLESH|Physics")
bool bRecomputeNormals = true;
// Constructor
FSoftBodySimulationSettings()
{
}
};
/**
* Soft body physics tool class
* Provides soft body physics simulation functionality
*/
UCLASS(BlueprintType)
class FLESH_API USoftBodyPhysicsTool : public UObject
{
GENERATED_BODY()
public:
// Constructor
USoftBodyPhysicsTool();
/**
* Initialize soft body physics for a skeletal mesh
* @param TargetMesh - Target skeletal mesh component
* @param SimulationSettings - Simulation settings
* @return Whether initialization was successful
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Physics")
bool InitializeSoftBodyPhysics(USkeletalMeshComponent* TargetMesh, const FSoftBodySimulationSettings& SimulationSettings);
/**
* Add an anchor point to the soft body
* @param AnchorPoint - Anchor point definition
* @return Whether the anchor was added successfully
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Physics")
bool AddAnchorPoint(const FSoftBodyAnchorPoint& AnchorPoint);
/**
* Add a line chain to the soft body
* @param LineChain - Line chain definition
* @return Whether the line chain was added successfully
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Physics")
bool AddLineChain(const FSoftBodyLineChain& LineChain);
/**
* Add a tetrahedron to the soft body
* @param Tetrahedron - Tetrahedron definition
* @return Whether the tetrahedron was added successfully
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Physics")
bool AddTetrahedron(const FSoftBodyTetrahedron& Tetrahedron);
/**
* Add a plane constraint to the soft body
* @param PlaneConstraint - Plane constraint definition
* @return Whether the plane constraint was added successfully
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Physics")
bool AddPlaneConstraint(const FSoftBodyPlaneConstraint& PlaneConstraint);
/**
* Update simulation settings
* @param SimulationSettings - New simulation settings
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Physics")
void UpdateSimulationSettings(const FSoftBodySimulationSettings& SimulationSettings);
/**
* Enable or disable simulation
* @param bEnable - Whether to enable simulation
*/
UFUNCTION(BlueprintCallable, Category = "FLESH|Physics")
void SetSimulationEnabled(bool bEnable);
private:
// Target skeletal mesh component
UPROPERTY()
TObjectPtr<USkeletalMeshComponent> TargetMeshComponent;
// Anchor point components
UPROPERTY()
TArray<TObjectPtr<UStaticMeshComponent>> AnchorComponents;
// Physics constraint components
UPROPERTY()
TArray<TObjectPtr<UPhysicsConstraintComponent>> ConstraintComponents;
// Current simulation settings
FSoftBodySimulationSettings CurrentSettings;
// Anchor points
TArray<FSoftBodyAnchorPoint> AnchorPoints;
// Line chains
TArray<FSoftBodyLineChain> LineChains;
// Tetrahedra
TArray<FSoftBodyTetrahedron> Tetrahedra;
// Plane constraints
TArray<FSoftBodyPlaneConstraint> PlaneConstraints;
// Internal methods
void CreatePhysicsConstraints();
void CreateAnchorConstraints(AActor* Owner);
void CreateLineChainConstraints(AActor* Owner);
void CreateTetrahedronConstraints(AActor* Owner);
void CreatePlaneConstraints(AActor* Owner);
void UpdatePhysicsConstraints();
void ClearPhysicsConstraints();
// Helper methods
FName FindClosestBone(const FVector& Point);
};