Files
BladeSmith/Source/BladeSmith/DynamicIronBlock.h
T
starmen1265 07d2a322a4 feat: 添加调试可视化工具和性能优化
- Task 10: 添加调试可视化工具
  - DebugDrawFlowDirections() - 可视化材料流动方向
  - DebugDrawEdgeVertices() - 可视化边缘顶点
  - DebugPrintVertexAttributes() - 输出顶点属性统计信息

- Task 12: 性能优化和参数调优
  - 添加 bEnableAdaptiveOptimization 参数
  - 添加 MinSmoothingInterval 参数
  - 添加 LastHammerImpactTime 追踪
  - 在OnHammerImpact中应用自适应优化逻辑

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-23 22:49:06 +08:00

431 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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);
};