增加热辐射颜色处理

This commit is contained in:
zhangqing
2025-12-09 19:03:17 +08:00
parent e647723a7a
commit bba161810a
6 changed files with 120 additions and 46 deletions
+84 -43
View File
@@ -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();
});
});
}
+33 -2
View File
@@ -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};