07d2a322a4
- Task 10: 添加调试可视化工具 - DebugDrawFlowDirections() - 可视化材料流动方向 - DebugDrawEdgeVertices() - 可视化边缘顶点 - DebugPrintVertexAttributes() - 输出顶点属性统计信息 - Task 12: 性能优化和参数调优 - 添加 bEnableAdaptiveOptimization 参数 - 添加 MinSmoothingInterval 参数 - 添加 LastHammerImpactTime 追踪 - 在OnHammerImpact中应用自适应优化逻辑 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
431 lines
13 KiB
C++
431 lines
13 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
||
|
||
#pragma once
|
||
|
||
#include "CoreMinimal.h"
|
||
#include "DynamicMeshActor.h"
|
||
#include <atomic>
|
||
#include "DynamicIronBlock.generated.h"
|
||
|
||
/**
|
||
* 温度体素结构 - 存储单个体素的温度和塑性数据
|
||
*/
|
||
USTRUCT(BlueprintType)
|
||
struct FTemperatureVoxel
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
// 温度值(摄氏度)
|
||
UPROPERTY()
|
||
float Temperature;
|
||
|
||
// 塑性系数(0-1),由温度计算得出
|
||
UPROPERTY()
|
||
float PlasticityCoefficient;
|
||
|
||
// 标志位(bit 0: 是否为表面体素)
|
||
UPROPERTY()
|
||
uint8 Flags;
|
||
|
||
FTemperatureVoxel()
|
||
: Temperature(20.0f)
|
||
, PlasticityCoefficient(0.0f)
|
||
, Flags(0)
|
||
{}
|
||
};
|
||
|
||
/**
|
||
* 动态铁块Actor,继承自ADynamicMeshActor
|
||
* 用于模拟铁匠打铁游戏中的铁块,支持动态变形
|
||
* 包含基于体素的温度模拟系统
|
||
*/
|
||
UCLASS()
|
||
class BLADESMITH_API ADynamicIronBlock : public ADynamicMeshActor
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
public:
|
||
// 构造函数
|
||
ADynamicIronBlock();
|
||
|
||
// Box的大小
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block")
|
||
FVector BoxSize = FVector(100.0f, 100.0f, 100.0f);
|
||
// Box的细分数
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block")
|
||
FVector NumSubDivide = FVector(1.0f, 1.0f, 1.0f);
|
||
// BVH参数
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block")
|
||
bool bEnableFastBuild;
|
||
|
||
// 铁块材质
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block")
|
||
UMaterialInterface* IronMaterial;
|
||
|
||
// 形变衰减指数(控制边缘过渡的平滑度)- 材质物理特性
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Material Properties")
|
||
float FalloffExponent = 2.0f;
|
||
|
||
// 材料凸起比例(凸起区域半径相对于压缩区域的倍数)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Material Properties")
|
||
float BulgeRatio = 0.8f;
|
||
|
||
// 材料凸起强度(控制凸起高度,基于体积守恒)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Material Properties")
|
||
float BulgeStrength = 0.5f;
|
||
|
||
// 各向异性比(主方向/次方向流动强度比,1.0=均匀,>1.0=方向性)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Material Properties", meta = (ClampMin = "1.0", ClampMax = "10.0"))
|
||
float AnisotropyRatio = 3.0f;
|
||
|
||
// 是否启用边缘约束
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Material Properties")
|
||
bool bEnableEdgeConstraint = false;
|
||
|
||
// 边缘阈值(cm)- 用于检测边缘顶点
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Material Properties", meta = (ClampMin = "0.1", ClampMax = "5.0"))
|
||
float EdgeThreshold = 0.5f;
|
||
|
||
// ========== 性能参数 ==========
|
||
|
||
// 是否启用自适应优化(仅在锤击间隔较长时执行完整优化)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Performance")
|
||
bool bEnableAdaptiveOptimization = true;
|
||
|
||
// 最小平滑间隔(秒,低于此值跳过平滑)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Iron Block|Performance", meta = (ClampMin = "0.0", ClampMax = "1.0"))
|
||
float MinSmoothingInterval = 0.1f;
|
||
|
||
// ========== 温度系统参数 ==========
|
||
|
||
// 温度体素大小(毫米)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System", meta = (ClampMin = "3.0", ClampMax = "10.0"))
|
||
float TemperatureVoxelSize = 5.0f;
|
||
|
||
// 热传导系数
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System", meta = (ClampMin = "0.0", ClampMax = "1.0"))
|
||
float ThermalConductivity = 0.1f;
|
||
|
||
// 表面冷却速率
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System", meta = (ClampMin = "0.0", ClampMax = "1.0"))
|
||
float CoolingRate = 0.05f;
|
||
|
||
// 环境温度(摄氏度)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System")
|
||
float AmbientTemperature = 20.0f;
|
||
|
||
// 锻造温度下限(摄氏度)- 开始软化
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System")
|
||
float ForgeTemperatureMin = 800.0f;
|
||
|
||
// 锻造温度上限(摄氏度)- 完全软化
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System")
|
||
float ForgeTemperatureMax = 1200.0f;
|
||
|
||
// 是否启用温度系统
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System")
|
||
bool bEnableTemperatureSystem = true;
|
||
|
||
// ========== 自动加热功能 ==========
|
||
|
||
// 是否正在加热中
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System|Auto Heating")
|
||
bool bIsHeating = false;
|
||
|
||
// 自动加热间隔(秒)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System|Auto Heating", meta = (ClampMin = "0.1", ClampMax = "10.0"))
|
||
float HeatingInterval = 1.0f;
|
||
|
||
// 自动加热半径(厘米)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System|Auto Heating")
|
||
float HeatingRadius = 30.0f;
|
||
|
||
// 每次加热温度增量(摄氏度)
|
||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Temperature System|Auto Heating")
|
||
float HeatingTemperatureIncrease = 100.0f;
|
||
|
||
/**
|
||
* 测试函数 - 加热指定区域
|
||
* @param WorldCenter 加热中心位置(世界坐标)
|
||
* @param Radius 加热半径
|
||
* @param TemperatureIncrease 温度增量
|
||
*/
|
||
UFUNCTION(BlueprintCallable, Category = "Temperature System")
|
||
void HeatRegion(FVector WorldCenter, float Radius, float TemperatureIncrease);
|
||
|
||
/**
|
||
* 受击函数 - 模拟圆形铁锤锤击金属表面产生塑性形变
|
||
* @param HitLocation 锤击位置(世界坐标)
|
||
* @param HitNormal 锤击法线方向
|
||
* @param ImpactRadius 锤击影响半径
|
||
* @param ImpactDepth 锤击形变深度
|
||
* @param ImpactForce 锤击力度(0-1),影响形变深度
|
||
*/
|
||
UFUNCTION(BlueprintCallable, Category = "Hammer Impact")
|
||
void OnHammerImpact(FVector HitLocation, FVector HitNormal, float ImpactRadius, float ImpactDepth, float ImpactForce = 1.0f);
|
||
|
||
/**
|
||
* 调试函数 - 输出顶点颜色信息到日志和屏幕
|
||
*/
|
||
UFUNCTION(BlueprintCallable, Category = "Temperature System|Debug")
|
||
void DebugPrintVertexColors();
|
||
|
||
/**
|
||
* 调试函数 - 可视化材料流动方向
|
||
*/
|
||
UFUNCTION(BlueprintCallable, Category = "Hammer Impact|Debug")
|
||
void DebugDrawFlowDirections();
|
||
|
||
/**
|
||
* 调试函数 - 可视化边缘顶点
|
||
*/
|
||
UFUNCTION(BlueprintCallable, Category = "Hammer Impact|Debug")
|
||
void DebugDrawEdgeVertices();
|
||
|
||
/**
|
||
* 调试函数 - 输出顶点属性统计信息
|
||
*/
|
||
UFUNCTION(BlueprintCallable, Category = "Hammer Impact|Debug")
|
||
void DebugPrintVertexAttributes();
|
||
|
||
protected:
|
||
// 当游戏开始或生成时调用
|
||
virtual void BeginPlay() override;
|
||
|
||
// 每帧更新
|
||
virtual void Tick(float DeltaTime) override;
|
||
|
||
// Actor销毁时调用
|
||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||
|
||
// 初始化时调用,用于设置Box网格和BVH
|
||
virtual void OnConstruction(const FTransform& Transform) override;
|
||
|
||
private:
|
||
/**
|
||
* 创建Box网格并生成BVH
|
||
*/
|
||
void InitializeBoxMesh();
|
||
|
||
/**
|
||
* 生成BVH加速结构
|
||
*/
|
||
void GenerateBVH();
|
||
|
||
// ========== 温度系统数据 ==========
|
||
|
||
// 温度体素网格(CPU侧)
|
||
TArray<FTemperatureVoxel> TemperatureGrid;
|
||
|
||
// 温度网格分辨率
|
||
FIntVector TemperatureResolution;
|
||
|
||
// 动态材质实例(用于更新温度参数)
|
||
UPROPERTY()
|
||
UMaterialInstanceDynamic* DynamicMaterialInstance;
|
||
|
||
// ========== 温度系统方法 ==========
|
||
|
||
/**
|
||
* 计算温度网格分辨率(基于BoxSize和TemperatureVoxelSize)
|
||
*/
|
||
void CalculateTemperatureResolution();
|
||
|
||
/**
|
||
* 初始化温度体素网格
|
||
*/
|
||
void InitializeTemperatureGrid();
|
||
|
||
/**
|
||
* 获取体素索引
|
||
*/
|
||
FORCEINLINE int32 GetTemperatureIndex(int32 X, int32 Y, int32 Z) const
|
||
{
|
||
return X + Y * TemperatureResolution.X + Z * TemperatureResolution.X * TemperatureResolution.Y;
|
||
}
|
||
|
||
FORCEINLINE int32 GetTemperatureIndex(const FIntVector& Coord) const
|
||
{
|
||
return GetTemperatureIndex(Coord.X, Coord.Y, Coord.Z);
|
||
}
|
||
|
||
/**
|
||
* 检查体素坐标是否有效
|
||
*/
|
||
FORCEINLINE bool IsValidTemperatureCoord(int32 X, int32 Y, int32 Z) const
|
||
{
|
||
return X >= 0 && X < TemperatureResolution.X &&
|
||
Y >= 0 && Y < TemperatureResolution.Y &&
|
||
Z >= 0 && Z < TemperatureResolution.Z;
|
||
}
|
||
|
||
FORCEINLINE bool IsValidTemperatureCoord(const FIntVector& Coord) const
|
||
{
|
||
return IsValidTemperatureCoord(Coord.X, Coord.Y, Coord.Z);
|
||
}
|
||
|
||
/**
|
||
* 判断是否为表面体素
|
||
*/
|
||
bool IsSurfaceTemperatureVoxel(int32 X, int32 Y, int32 Z) const;
|
||
|
||
/**
|
||
* 从温度网格采样温度(三线性插值)
|
||
* @param LocalPosition 局部坐标位置
|
||
* @return 插值后的温度值
|
||
*/
|
||
float SampleTemperatureAtPosition(const FVector& LocalPosition) const;
|
||
|
||
/**
|
||
* 从温度网格采样塑性系数(三线性插值)
|
||
* @param LocalPosition 局部坐标位置
|
||
* @return 插值后的塑性系数
|
||
*/
|
||
float SamplePlasticityAtPosition(const FVector& LocalPosition) const;
|
||
|
||
/**
|
||
* 根据温度计算塑性系数
|
||
* @param Temperature 温度值
|
||
* @return 塑性系数(0-1)
|
||
*/
|
||
float CalculatePlasticityFromTemperature(float Temperature) const;
|
||
|
||
/**
|
||
* 更新体素的塑性系数(基于当前温度)
|
||
*/
|
||
void UpdatePlasticityCoefficient(FTemperatureVoxel& Voxel);
|
||
|
||
/**
|
||
* 温度到颜色的映射(黑体辐射近似)
|
||
* @param Temperature 温度值
|
||
* @return 颜色
|
||
*/
|
||
FLinearColor TemperatureToColor(float Temperature) const;
|
||
|
||
/**
|
||
* 计算平均温度
|
||
* @return 体素网格的平均温度
|
||
*/
|
||
float CalculateAverageTemperature() const;
|
||
|
||
/**
|
||
* 更新动态材质的温度参数
|
||
*/
|
||
void UpdateMaterialTemperature();
|
||
|
||
/**
|
||
* 更新网格顶点颜色(基于每个顶点的温度体素采样)
|
||
*/
|
||
void UpdateVertexColors();
|
||
|
||
// ========== 顶点属性层(阶段1) ==========
|
||
|
||
// 顶点属性存储 - 使用简单数组存储,避免复杂的模板前向声明
|
||
// 这些数组在网格初始化时创建,索引与顶点ID对应
|
||
TArray<FVector3f> InitialPositionsArray; // 初始位置(不变,用于无漂移纹理采样)
|
||
TArray<float> AccumulatedStrainArray; // 累积塑性应变
|
||
TArray<float> HardnessCoefficientArray; // 硬度系数(影响形变阻力)
|
||
TArray<float> PolishAmountArray; // 打磨度(0=生锈,1=光亮)
|
||
|
||
// 标志位:顶点属性是否已初始化
|
||
bool bVertexAttributesInitialized = false;
|
||
|
||
// 上次锤击时间(用于自适应优化)
|
||
float LastHammerImpactTime = 0.0f;
|
||
|
||
/**
|
||
* 初始化顶点属性层
|
||
*/
|
||
void InitializeVertexAttributes();
|
||
|
||
/**
|
||
* 释放顶点属性层
|
||
*/
|
||
void ReleaseVertexAttributes();
|
||
|
||
// ========== 各向异性形变辅助函数 ==========
|
||
|
||
/**
|
||
* 查找最近的自由边界方向
|
||
* 材料会优先朝向自由边界流动(阻力最小)
|
||
*/
|
||
FVector FindNearestFreeEdgeDirection(const FVector& LocalPos, const FVector& BoxHalfSize) const;
|
||
|
||
/**
|
||
* 计算材料流动的主方向
|
||
* 主方向 = 朝向边缘 + 垂直于锤击方向
|
||
*/
|
||
FVector CalculatePrimaryFlowDirection(const FVector& HammerDir, const FVector& ToNearestEdge) const;
|
||
|
||
/**
|
||
* 计算次要流动方向(垂直于主方向和锤击方向)
|
||
*/
|
||
FVector CalculateSecondaryFlowDirection(const FVector& HammerDir, const FVector& PrimaryFlow) const;
|
||
|
||
/**
|
||
* 检测并标记边缘顶点
|
||
*/
|
||
void MarkEdgeVertices(const FDynamicMesh3& Mesh, TSet<int32>& OutEdgeVertices) const;
|
||
|
||
/**
|
||
* 对边缘顶点应用线性约束
|
||
*/
|
||
void ApplyEdgeLinearConstraint(FDynamicMesh3& Mesh, const TSet<int32>& EdgeVertices);
|
||
|
||
/**
|
||
* 应用Laplacian平滑到受影响区域
|
||
*/
|
||
void ApplyLaplacianSmoothing(FDynamicMesh3& Mesh, const FVector& Center, float Radius, float Alpha = 0.3f);
|
||
|
||
// ========== GPU计算系统(Phase 2) ==========
|
||
|
||
// GPU缓冲区(Ping-Pong双缓冲)
|
||
FBufferRHIRef TemperatureBufferA; // 温度缓冲A
|
||
FBufferRHIRef TemperatureBufferB; // 温度缓冲B
|
||
FBufferRHIRef PlasticityBuffer; // 塑性系数缓冲
|
||
FBufferRHIRef SurfaceVoxelFlagsBuffer; // 表面体素标志缓冲
|
||
|
||
FUnorderedAccessViewRHIRef TemperatureUAV_A; // 温度缓冲A的UAV
|
||
FUnorderedAccessViewRHIRef TemperatureUAV_B; // 温度缓冲B的UAV
|
||
FUnorderedAccessViewRHIRef PlasticityUAV; // 塑性系数缓冲的UAV
|
||
|
||
FShaderResourceViewRHIRef TemperatureSRV_A; // 温度缓冲A的SRV
|
||
FShaderResourceViewRHIRef TemperatureSRV_B; // 温度缓冲B的SRV
|
||
FShaderResourceViewRHIRef SurfaceVoxelSRV; // 表面体素标志的SRV
|
||
|
||
bool bUseBufferA = true; // Ping-Pong标志
|
||
float TimeSinceLastUpdate = 0.0f; // 距离上次温度更新的时间
|
||
float TemperatureUpdateInterval = 1.0f; // 温度更新间隔(秒)
|
||
|
||
// 自动加热计时器
|
||
float TimeSinceLastHeating = 0.0f; // 距离上次自动加热的时间
|
||
|
||
// GPU缓冲区是否已准备好(线程安全标志)
|
||
std::atomic<bool> bGPUBuffersReady{false};
|
||
|
||
/**
|
||
* 创建GPU缓冲区
|
||
*/
|
||
void CreateGPUBuffers();
|
||
|
||
/**
|
||
* 释放GPU缓冲区
|
||
*/
|
||
void ReleaseGPUBuffers();
|
||
|
||
/**
|
||
* 上传温度数据到GPU
|
||
*/
|
||
void UploadTemperatureDataToGPU();
|
||
|
||
/**
|
||
* 从GPU下载温度数据
|
||
*/
|
||
void DownloadTemperatureDataFromGPU();
|
||
|
||
/**
|
||
* 调度GPU温度计算
|
||
* @param DeltaTime 时间步长
|
||
*/
|
||
void DispatchTemperatureCompute(float DeltaTime);
|
||
}; |