增加热辐射颜色处理
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
"Bash(dir:*)",
|
||||
"Bash(git add:*)",
|
||||
"Bash(git commit -m \"$(cat <<''EOF''\n实现DynamicIronBlock温度体素系统基础功能\n\n新增功能:\n- 添加FTemperatureVoxel结构体(温度、塑性系数、表面标志)\n- 实现自适应温度网格(5mm体素精度,基于BoxSize计算分辨率)\n- 实现三线性插值温度/塑性系数采样\n- 实现黑体辐射温度可视化(顶点颜色)\n- 添加HeatRegion蓝图测试函数\n- 添加OnHammerImpact锤击形变函数(体积守恒)\n\n技术细节:\n- Phase 1: CPU侧温度网格初始化,支持10cm-100cm+可变尺寸\n- Phase 3: 温度可视化系统(20°C灰色 → 1200°C白色)\n- 内存占用:30×30×30cm ≈ 1.7MB(60×60×60体素)\n\n待实现:Phase 2 GPU热传导计算\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nEOF\n)\")",
|
||||
"Bash(git commit:*)"
|
||||
"Bash(git commit:*)",
|
||||
"Bash(\"E:\\MiceCola\\work\\UE_5_6\\Engine\\Build\\BatchFiles\\Build.bat\" BladeSmithEditor Win64 Development -Project=\"C:\\MiceCola\\Indi\\BladeSmith\\BladeSmith.uproject\" -WaitMutex -FromMsBuild)",
|
||||
"Bash(cmd /c:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -66,6 +66,7 @@ void ADynamicIronBlock::Tick(float DeltaTime)
|
||||
return;
|
||||
}
|
||||
|
||||
// ========== 温度计算更新 ==========
|
||||
// 累积时间
|
||||
TimeSinceLastUpdate += DeltaTime;
|
||||
|
||||
@@ -78,9 +79,37 @@ void ADynamicIronBlock::Tick(float DeltaTime)
|
||||
// 重置计时器
|
||||
TimeSinceLastUpdate = 0.0f;
|
||||
|
||||
// 从GPU下载温度数据并更新顶点颜色
|
||||
// 从GPU下载温度数据并更新材质参数
|
||||
DownloadTemperatureDataFromGPU();
|
||||
// 注意:UpdateVertexColors()会在DownloadTemperatureDataFromGPU的回调中异步调用
|
||||
// 注意:UpdateMaterialTemperature()会在DownloadTemperatureDataFromGPU的回调中异步调用
|
||||
}
|
||||
|
||||
// ========== 自动加热功能 ==========
|
||||
if (bIsHeating)
|
||||
{
|
||||
// 累积加热时间
|
||||
TimeSinceLastHeating += DeltaTime;
|
||||
|
||||
// 每隔HeatingInterval进行一次加热
|
||||
if (TimeSinceLastHeating >= HeatingInterval)
|
||||
{
|
||||
// 获取铁块中心位置(世界坐标)
|
||||
FVector WorldCenter = GetActorLocation();
|
||||
|
||||
// 执行加热
|
||||
HeatRegion(WorldCenter, HeatingRadius, HeatingTemperatureIncrease);
|
||||
|
||||
// 重置加热计时器
|
||||
TimeSinceLastHeating = 0.0f;
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Auto heating applied at center, radius: %.2f cm, temp increase: %.2f °C"),
|
||||
HeatingRadius, HeatingTemperatureIncrease);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 如果加热被关闭,重置计时器
|
||||
TimeSinceLastHeating = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +182,7 @@ void ADynamicIronBlock::InitializeBoxMesh()
|
||||
// 如果设置了材质,创建动态材质实例并应用
|
||||
if (IronMaterial)
|
||||
{
|
||||
UMaterialInstanceDynamic* DynamicMaterialInstance = UMaterialInstanceDynamic::Create(IronMaterial, this);
|
||||
DynamicMaterialInstance = UMaterialInstanceDynamic::Create(IronMaterial, this);
|
||||
if (DynamicMaterialInstance)
|
||||
{
|
||||
DynMeshComp->SetMaterial(0, DynamicMaterialInstance);
|
||||
@@ -536,8 +565,8 @@ void ADynamicIronBlock::HeatRegion(FVector WorldCenter, float Radius, float Temp
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Temperature data uploaded to GPU after HeatRegion"));
|
||||
}
|
||||
|
||||
// 更新顶点颜色以显示温度变化
|
||||
UpdateVertexColors();
|
||||
// 更新材质温度参数以显示温度变化
|
||||
UpdateMaterialTemperature();
|
||||
}
|
||||
|
||||
float ADynamicIronBlock::SampleTemperatureAtPosition(const FVector& LocalPosition) const
|
||||
@@ -680,54 +709,66 @@ FLinearColor ADynamicIronBlock::TemperatureToColor(float Temperature) const
|
||||
}
|
||||
}
|
||||
|
||||
void ADynamicIronBlock::UpdateVertexColors()
|
||||
float ADynamicIronBlock::CalculateAverageTemperature() const
|
||||
{
|
||||
if (!bEnableTemperatureSystem || TemperatureGrid.Num() == 0)
|
||||
{
|
||||
return AmbientTemperature;
|
||||
}
|
||||
|
||||
float TotalTemperature = 0.0f;
|
||||
int32 ValidVoxels = 0;
|
||||
|
||||
// 遍历所有体素,累加温度
|
||||
for (const FTemperatureVoxel& Voxel : TemperatureGrid)
|
||||
{
|
||||
TotalTemperature += Voxel.Temperature;
|
||||
++ValidVoxels;
|
||||
}
|
||||
|
||||
// 计算平均温度
|
||||
return ValidVoxels > 0 ? (TotalTemperature / ValidVoxels) : AmbientTemperature;
|
||||
}
|
||||
|
||||
void ADynamicIronBlock::UpdateMaterialTemperature()
|
||||
{
|
||||
if (!bEnableTemperatureSystem || TemperatureGrid.Num() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UDynamicMeshComponent* DynMeshComp = GetDynamicMeshComponent();
|
||||
if (!DynMeshComp)
|
||||
if (!DynamicMaterialInstance)
|
||||
{
|
||||
UE_LOG(LogTemp, Warning, TEXT("DynamicIronBlock: Cannot update material temperature, dynamic material instance is null"));
|
||||
return;
|
||||
}
|
||||
|
||||
UDynamicMesh* DynMesh = DynMeshComp->GetDynamicMesh();
|
||||
if (!DynMesh)
|
||||
// 计算平均温度
|
||||
float AverageTemperature = CalculateAverageTemperature();
|
||||
|
||||
// 将温度映射到颜色
|
||||
FLinearColor TemperatureColor = TemperatureToColor(AverageTemperature);
|
||||
|
||||
// 设置材质参数
|
||||
DynamicMaterialInstance->SetScalarParameterValue(FName("Temperature"), AverageTemperature);
|
||||
DynamicMaterialInstance->SetVectorParameterValue(FName("TemperatureColor"), TemperatureColor);
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Material temperature updated - Avg: %.1f°C, Color: (%.2f, %.2f, %.2f)"),
|
||||
AverageTemperature, TemperatureColor.R, TemperatureColor.G, TemperatureColor.B);
|
||||
|
||||
// 在屏幕上显示温度信息(保留3秒)
|
||||
if (GEngine)
|
||||
{
|
||||
return;
|
||||
FString DebugMessage = FString::Printf(TEXT("Temperature: %.1f°C | Color: (R:%.2f, G:%.2f, B:%.2f)"),
|
||||
AverageTemperature, TemperatureColor.R, TemperatureColor.G, TemperatureColor.B);
|
||||
|
||||
GEngine->AddOnScreenDebugMessage(
|
||||
-1, // Key (-1 表示自动分配)
|
||||
3.0f, // 显示时长(秒)
|
||||
TemperatureColor.ToFColor(true), // 使用温度颜色
|
||||
DebugMessage
|
||||
);
|
||||
}
|
||||
|
||||
DynMesh->EditMesh([&](FDynamicMesh3& EditMesh)
|
||||
{
|
||||
// 启用顶点颜色(如果尚未启用)
|
||||
if (!EditMesh.HasVertexColors())
|
||||
{
|
||||
EditMesh.EnableVertexColors(FVector3f(0.2f, 0.2f, 0.2f));
|
||||
}
|
||||
|
||||
// 遍历所有顶点
|
||||
for (int32 VertexID : EditMesh.VertexIndicesItr())
|
||||
{
|
||||
// 获取顶点位置(局部坐标)
|
||||
FVector3d VertexPos = EditMesh.GetVertex(VertexID);
|
||||
FVector VertexPosFloat(VertexPos.X, VertexPos.Y, VertexPos.Z);
|
||||
|
||||
// 通过三线性插值获取该顶点的温度
|
||||
float Temperature = SampleTemperatureAtPosition(VertexPosFloat);
|
||||
|
||||
// 将温度映射到颜色
|
||||
FLinearColor VertexColor = TemperatureToColor(Temperature);
|
||||
|
||||
// 设置顶点颜色
|
||||
EditMesh.SetVertexColor(VertexID, FVector3f(VertexColor.R, VertexColor.G, VertexColor.B));
|
||||
}
|
||||
}, EDynamicMeshChangeType::GeneralEdit, EDynamicMeshAttributeChangeFlags::Unknown, false);
|
||||
|
||||
DynMeshComp->NotifyMeshUpdated();
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Vertex colors updated based on temperature"));
|
||||
}
|
||||
|
||||
// ========== GPU缓冲区管理实现 ==========
|
||||
@@ -904,8 +945,8 @@ void ADynamicIronBlock::DownloadTemperatureDataFromGPU()
|
||||
|
||||
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Temperature data downloaded from GPU"));
|
||||
|
||||
// 更新顶点颜色以反映新的温度
|
||||
UpdateVertexColors();
|
||||
// 更新材质温度参数以反映新的温度
|
||||
UpdateMaterialTemperature();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,6 +104,24 @@ public:
|
||||
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 加热中心位置(世界坐标)
|
||||
@@ -156,6 +174,10 @@ private:
|
||||
// 温度网格分辨率
|
||||
FIntVector TemperatureResolution;
|
||||
|
||||
// 动态材质实例(用于更新温度参数)
|
||||
UPROPERTY()
|
||||
UMaterialInstanceDynamic* DynamicMaterialInstance;
|
||||
|
||||
// ========== 温度系统方法 ==========
|
||||
|
||||
/**
|
||||
@@ -235,9 +257,15 @@ private:
|
||||
FLinearColor TemperatureToColor(float Temperature) const;
|
||||
|
||||
/**
|
||||
* 更新网格顶点颜色以显示温度
|
||||
* 计算平均温度
|
||||
* @return 体素网格的平均温度
|
||||
*/
|
||||
void UpdateVertexColors();
|
||||
float CalculateAverageTemperature() const;
|
||||
|
||||
/**
|
||||
* 更新动态材质的温度参数
|
||||
*/
|
||||
void UpdateMaterialTemperature();
|
||||
|
||||
// ========== GPU计算系统(Phase 2) ==========
|
||||
|
||||
@@ -259,6 +287,9 @@ private:
|
||||
float TimeSinceLastUpdate = 0.0f; // 距离上次温度更新的时间
|
||||
float TemperatureUpdateInterval = 1.0f; // 温度更新间隔(秒)
|
||||
|
||||
// 自动加热计时器
|
||||
float TimeSinceLastHeating = 0.0f; // 距离上次自动加热的时间
|
||||
|
||||
// GPU缓冲区是否已准备好(线程安全标志)
|
||||
std::atomic<bool> bGPUBuffersReady{false};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user