From c6d21201dd3e240e2ad9a371211e41ed01e9a594 Mon Sep 17 00:00:00 2001 From: starmen1265 Date: Fri, 23 Jan 2026 22:47:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=E6=89=93=E7=A3=A8?= =?UTF-8?q?=E5=BA=A6=E7=B3=BB=E7=BB=9F=E5=92=8C=E7=BD=91=E6=A0=BC=E8=B4=A8?= =?UTF-8?q?=E9=87=8F=E7=BB=B4=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Task 7: 实现打磨度在锤击时的更新 - 在OnHammerImpact中添加打磨度更新逻辑 - 打磨度与形变量成正比 - Task 8: 更新顶点颜色以编码打磨度 - 修改UpdateVertexColors函数支持打磨度 - 添加生锈颜色(深红褐色)到金属颜色(亮银色)的混合 - 最终颜色 = 温度颜色 * 打磨颜色 - Task 9: 添加基础Laplacian平滑 - 实现ApplyLaplacianSmoothing函数 - 在OnHammerImpact中调用平滑以维护网格质量 Co-Authored-By: Claude Sonnet 4.5 --- Source/BladeSmith/DynamicIronBlock.cpp | 80 +++++++++++++++++++++++++- Source/BladeSmith/DynamicIronBlock.h | 5 ++ 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/Source/BladeSmith/DynamicIronBlock.cpp b/Source/BladeSmith/DynamicIronBlock.cpp index dd9add8..b62b8de 100644 --- a/Source/BladeSmith/DynamicIronBlock.cpp +++ b/Source/BladeSmith/DynamicIronBlock.cpp @@ -399,6 +399,16 @@ void ADynamicIronBlock::OnHammerImpact(FVector HitLocation, FVector HitNormal, f float StrainDelta = Displacement.Size(); AccumulatedStrainArray[VertexID] = CurrentStrain + StrainDelta; } + + // 更新打磨度(锤击使表面变亮) + if (bVertexAttributesInitialized && PolishAmountArray.IsValidIndex(VertexID)) + { + float CurrentPolish = PolishAmountArray[VertexID]; + // 打磨度增加量与形变量成正比 + float PolishIncrease = Displacement.Size() * 0.5f; + float NewPolish = FMath::Clamp(CurrentPolish + PolishIncrease, 0.0f, 1.0f); + PolishAmountArray[VertexID] = NewPolish; + } } } @@ -430,6 +440,10 @@ void ADynamicIronBlock::OnHammerImpact(FVector HitLocation, FVector HitNormal, f UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Applied edge constraint to %d vertices"), AffectedEdges.Num()); } } + + // 应用Laplacian平滑(轻微,保持形状细节) + float BulgeOuterRadius = ImpactRadius * (1.0f + BulgeRatio); + ApplyLaplacianSmoothing(EditMesh, LocalHitLocation, BulgeOuterRadius, 0.1f); }, EDynamicMeshChangeType::GeneralEdit, EDynamicMeshAttributeChangeFlags::Unknown, false); // 重新计算法线 @@ -937,12 +951,33 @@ void ADynamicIronBlock::UpdateVertexColors() // 将温度转换为黑体辐射颜色 FLinearColor TempColor = TemperatureToColor(Temperature); - VertexColors.Add(TempColor); + + // 获取打磨度并混合颜色 + float Polish = 0.2f; // 默认值 + if (bVertexAttributesInitialized && PolishAmountArray.IsValidIndex(VertexID)) + { + Polish = PolishAmountArray[VertexID]; + } + + // 生锈颜色(深红褐色) + FLinearColor RustColor(0.4f, 0.2f, 0.15f); + + // 金属颜色(亮银色) + FLinearColor MetalColor(0.9f, 0.9f, 0.95f); + + // 根据打磨度混合:0=生锈,1=光亮金属 + FLinearColor PolishColor = FMath::Lerp(RustColor, MetalColor, Polish); + + // 最终颜色 = 温度颜色 * 打磨颜色(乘法混合) + FLinearColor FinalColor = TempColor * PolishColor; + FinalColor.A = 1.0f; // 不透明 + + VertexColors.Add(FinalColor); // 记录第一个有效顶点的信息用于调试 if (VertexID == 0) { - FirstVertexColor = TempColor; + FirstVertexColor = FinalColor; FirstVertexTemp = Temperature; FirstVertexPos = VertexPosFloat; } @@ -1540,3 +1575,44 @@ void ADynamicIronBlock::ApplyEdgeLinearConstraint(FDynamicMesh3& Mesh, const TSe } } } + +void ADynamicIronBlock::ApplyLaplacianSmoothing(FDynamicMesh3& Mesh, const FVector& Center, float Radius, float Alpha) +{ + // 创建位置副本用于迭代计算 + TMap NewPositions; + + for (int32 VertexID : Mesh.VertexIndicesItr()) + { + FVector3d VertexPos = Mesh.GetVertex(VertexID); + FVector PosFloat(VertexPos.X, VertexPos.Y, VertexPos.Z); + + // 只处理影响范围内的顶点 + if (FVector::Dist(PosFloat, Center) > Radius) + continue; + + // 计算Laplacian(邻居顶点的平均位置) + FVector3d Laplacian(0.0, 0.0, 0.0); + int32 NeighborCount = 0; + + for (int32 NbrVID : Mesh.VtxVerticesItr(VertexID)) + { + Laplacian += Mesh.GetVertex(NbrVID); + NeighborCount++; + } + + if (NeighborCount > 0) + { + Laplacian /= NeighborCount; + + // 平滑更新:新位置 = 原位置 + Alpha * (Laplacian - 原位置) + FVector3d SmoothPos = FMath::Lerp(VertexPos, Laplacian, Alpha); + NewPositions.Add(VertexID, SmoothPos); + } + } + + // 应用新位置 + for (const TPair& Pair : NewPositions) + { + Mesh.SetVertex(Pair.Key, Pair.Value); + } +} diff --git a/Source/BladeSmith/DynamicIronBlock.h b/Source/BladeSmith/DynamicIronBlock.h index 33970d7..e69fb7a 100644 --- a/Source/BladeSmith/DynamicIronBlock.h +++ b/Source/BladeSmith/DynamicIronBlock.h @@ -341,6 +341,11 @@ private: */ void ApplyEdgeLinearConstraint(FDynamicMesh3& Mesh, const TSet& EdgeVertices); + /** + * 应用Laplacian平滑到受影响区域 + */ + void ApplyLaplacianSmoothing(FDynamicMesh3& Mesh, const FVector& Center, float Radius, float Alpha = 0.3f); + // ========== GPU计算系统(Phase 2) ========== // GPU缓冲区(Ping-Pong双缓冲)