dd16f0123a
功能改进: - 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>
290 lines
8.2 KiB
C++
290 lines
8.2 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;
|
||
|
||
// ========== 温度系统参数 ==========
|
||
|
||
// 温度体素大小(毫米)
|
||
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);
|
||
}; |