Files
BladeSmith/Source/BladeSmith/DynamicIronBlock.h
T
zhangqing dd16f0123a 实现温度系统CPU-GPU双向同步及调试功能
功能改进:
- HeatRegion后自动上传温度数据到GPU
- Tick中GPU计算后自动下载温度数据到CPU
- DownloadTemperatureDataFromGPU回调中自动更新顶点颜色

调试功能:
- HeatRegion后输出距离Hit点最近的4个体素温度
- 包含体素坐标、距离和温度信息,便于调试温度计算

配置优化:
- 温度更新间隔从0.1秒调整为1.0秒,降低性能开销

技术细节:
- 使用异步任务确保线程安全
- GPU数据上传前检查缓冲区就绪状态
- 完整的CPU↔GPU温度数据同步流程

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 18:15:19 +08:00

290 lines
8.2 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;
// ========== 温度系统参数 ==========
// 温度体素大小(毫米)
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;
/**
* 测试函数 - 加热指定区域
* @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);
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;
// ========== 温度系统方法 ==========
/**
* 计算温度网格分辨率(基于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;
/**
* 更新网格顶点颜色以显示温度
*/
void UpdateVertexColors();
// ========== 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; // 温度更新间隔(秒)
// 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);
};