From ac458060ff2cd17a1de40a9b49dbca864c50d1bf Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Sun, 5 Jan 2025 12:45:10 +0800 Subject: [PATCH] vault backup: 2025-01-05 12:45:10 --- ...oceduralMeshComponent实时载入StaticMesh.md | 152 ++++++++++++++++++ .../Gameplay/PuerTS/Puerts(二)——打包笔记.md | 2 - 2 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 03-UnrealEngine/Gameplay/Gameplay/UProceduralMeshComponent实时载入StaticMesh.md diff --git a/03-UnrealEngine/Gameplay/Gameplay/UProceduralMeshComponent实时载入StaticMesh.md b/03-UnrealEngine/Gameplay/Gameplay/UProceduralMeshComponent实时载入StaticMesh.md new file mode 100644 index 0000000..a5e34d2 --- /dev/null +++ b/03-UnrealEngine/Gameplay/Gameplay/UProceduralMeshComponent实时载入StaticMesh.md @@ -0,0 +1,152 @@ +--- +title: Untitled +date: 2025-01-05 11:32:25 +excerpt: +tags: +rating: ⭐ +--- +# UProceduralMeshComponent +使用现在StaticMesh构建PMC,PMC的MaterialSection是正常的。 +1. UKismetProceduralMeshLibrary::CopyProceduralMeshFromStaticMeshComponent() + +```c++ +void UKismetProceduralMeshLibrary::CopyProceduralMeshFromStaticMeshComponent(UStaticMeshComponent* StaticMeshComponent, int32 LODIndex, UProceduralMeshComponent* ProcMeshComponent, bool bCreateCollision) +{ + if( StaticMeshComponent != nullptr && + StaticMeshComponent->GetStaticMesh() != nullptr && + ProcMeshComponent != nullptr ) + { + UStaticMesh* StaticMesh = StaticMeshComponent->GetStaticMesh(); + + //// MESH DATA + + int32 NumSections = StaticMesh->GetNumSections(LODIndex); + for (int32 SectionIndex = 0; SectionIndex < NumSections; SectionIndex++) + { + // Buffers for copying geom data + TArray Vertices; + TArray Triangles; + TArray Normals; + TArray UVs; + TArray UVs1; + TArray UVs2; + TArray UVs3; + TArray Tangents; + + // Get geom data from static mesh + GetSectionFromStaticMesh(StaticMesh, LODIndex, SectionIndex, Vertices, Triangles, Normals, UVs, Tangents); + + // Create section using data + TArray DummyColors; + ProcMeshComponent->CreateMeshSection_LinearColor(SectionIndex, Vertices, Triangles, Normals, UVs, UVs1, UVs2, UVs3, DummyColors, Tangents, bCreateCollision); + } + + //// SIMPLE COLLISION + + // Clear any existing collision hulls + ProcMeshComponent->ClearCollisionConvexMeshes(); + + if (StaticMesh->GetBodySetup() != nullptr) + { + // Iterate over all convex hulls on static mesh.. + const int32 NumConvex = StaticMesh->GetBodySetup()->AggGeom.ConvexElems.Num(); + for (int ConvexIndex = 0; ConvexIndex < NumConvex; ConvexIndex++) + { + // Copy convex verts to ProcMesh + FKConvexElem& MeshConvex = StaticMesh->GetBodySetup()->AggGeom.ConvexElems[ConvexIndex]; + ProcMeshComponent->AddCollisionConvexMesh(MeshConvex.VertexData); + } + } + + //// MATERIALS + + for (int32 MatIndex = 0; MatIndex < StaticMeshComponent->GetNumMaterials(); MatIndex++) + { + ProcMeshComponent->SetMaterial(MatIndex, StaticMeshComponent->GetMaterial(MatIndex)); + } + } +} +``` + +```c++ +void UKismetProceduralMeshLibrary::GetSectionFromStaticMesh(UStaticMesh* InMesh, int32 LODIndex, int32 SectionIndex, TArray& Vertices, TArray& Triangles, TArray& Normals, TArray& UVs, TArray& Tangents) +{ + if( InMesh != nullptr ) + { + if (!InMesh->bAllowCPUAccess) + { + FMessageLog("PIE").Warning() + ->AddToken(FTextToken::Create(LOCTEXT("GetSectionFromStaticMeshStart", "Calling GetSectionFromStaticMesh on"))) + ->AddToken(FUObjectToken::Create(InMesh)) + ->AddToken(FTextToken::Create(LOCTEXT("GetSectionFromStaticMeshEnd", "but 'Allow CPU Access' is not enabled. This is required for converting StaticMesh to ProceduralMeshComponent in cooked builds."))); + } + + if (InMesh->GetRenderData() != nullptr && InMesh->GetRenderData()->LODResources.IsValidIndex(LODIndex)) + { + const FStaticMeshLODResources& LOD = InMesh->GetRenderData()->LODResources[LODIndex]; + if (LOD.Sections.IsValidIndex(SectionIndex)) + { + // Empty output buffers + Vertices.Reset(); + Triangles.Reset(); + Normals.Reset(); + UVs.Reset(); + Tangents.Reset(); + + // Map from vert buffer for whole mesh to vert buffer for section of interest + TMap MeshToSectionVertMap; + + const FStaticMeshSection& Section = LOD.Sections[SectionIndex];//获取指定的MeshSection + const uint32 OnePastLastIndex = Section.FirstIndex + Section.NumTriangles * 3;//计算最后一个VertexIndex + FIndexArrayView Indices = LOD.IndexBuffer.GetArrayView();//获得IndexArray + + //遍历所有IndexBuffer,并且复制顶点 + for (uint32 i = Section.FirstIndex; i < OnePastLastIndex; i++) + { + uint32 MeshVertIndex = Indices[i];//取得VertexIndex + + // See if we have this vert already in our section vert buffer, and copy vert in if not + // 从VertexBuffers.StaticMeshVertexBuffer中读取并且添加Vertex Position、Normal、UVs、Tangents;构建MeshToSectionVertMap作为缓存,如果能在Map找到则直接返回Index。 + int32 SectionVertIndex = GetNewIndexForOldVertIndex(MeshVertIndex, MeshToSectionVertMap, LOD.VertexBuffers, Vertices, Normals, UVs, Tangents); + + // Add to index buffer + Triangles.Add(SectionVertIndex); + } + } + } + } +} + +static int32 GetNewIndexForOldVertIndex(int32 MeshVertIndex, TMap& MeshToSectionVertMap, const FStaticMeshVertexBuffers& VertexBuffers, TArray& Vertices, TArray& Normals, TArray& UVs, TArray& Tangents) +{ + int32* NewIndexPtr = MeshToSectionVertMap.Find(MeshVertIndex); + if (NewIndexPtr != nullptr) + { + return *NewIndexPtr; + } + else + { + // Copy position + int32 SectionVertIndex = Vertices.Add((FVector)VertexBuffers.PositionVertexBuffer.VertexPosition(MeshVertIndex)); + + // Copy normal + Normals.Add(FVector4(VertexBuffers.StaticMeshVertexBuffer.VertexTangentZ(MeshVertIndex))); + check(Normals.Num() == Vertices.Num()); + + // Copy UVs + UVs.Add(FVector2D(VertexBuffers.StaticMeshVertexBuffer.GetVertexUV(MeshVertIndex, 0))); + check(UVs.Num() == Vertices.Num()); + + // Copy tangents + FVector4 TangentX = (FVector4)VertexBuffers.StaticMeshVertexBuffer.VertexTangentX(MeshVertIndex); + FProcMeshTangent NewTangent(TangentX, TangentX.W < 0.f); + Tangents.Add(NewTangent); + check(Tangents.Num() == Vertices.Num()); + + MeshToSectionVertMap.Add(MeshVertIndex, SectionVertIndex); + + return SectionVertIndex; + } +} +``` +## CreateMeshSection_LinearColor \ No newline at end of file diff --git a/03-UnrealEngine/Gameplay/PuerTS/Puerts(二)——打包笔记.md b/03-UnrealEngine/Gameplay/PuerTS/Puerts(二)——打包笔记.md index c95bff0..a20c898 100644 --- a/03-UnrealEngine/Gameplay/PuerTS/Puerts(二)——打包笔记.md +++ b/03-UnrealEngine/Gameplay/PuerTS/Puerts(二)——打包笔记.md @@ -6,7 +6,5 @@ tags: rating: ⭐ --- # 打包流程 - 生成的js脚本不是ue资产文件(`*.asset`),需要手动设置打包。 - 到“项目设置/打包/Additional Not-Asset Directories to Package”,把Content下的“JavaScript”目录添加进去。 \ No newline at end of file