6 #include "EngineGlobals.h" 7 #include "Logging/TokenizedMessage.h" 8 #include "Logging/MessageLog.h" 9 #include "Misc/UObjectToken.h" 10 #include "StaticMeshResources.h" 11 #include "Engine/StaticMesh.h" 14 #include "PhysicsEngine/BodySetup.h" 16 #define LOCTEXT_NAMESPACE "RuntimeMeshLibrary" 18 DECLARE_CYCLE_STAT(TEXT(
"RML - Copy Static Mesh to Runtime Mesh"), STAT_RuntimeMeshLibrary_CopyStaticMeshToRuntimeMesh, STATGROUP_RuntimeMesh);
19 DECLARE_CYCLE_STAT(TEXT(
"RML - Calculate Tangents For Mesh"), STAT_RuntimeMeshLibrary_CalculateTangentsForMesh, STATGROUP_RuntimeMesh);
20 DECLARE_CYCLE_STAT(TEXT(
"RML - Get Static Mesh Section"), STAT_RuntimeMeshLibrary_GetStaticMeshSection, STATGROUP_RuntimeMesh);
24 const TArray<FVector2D>& UVs, TArray<FRuntimeMeshTangent>& Tangents,
bool bCreateSmoothNormals)
26 Normals.SetNum(Vertices.Num());
27 Tangents.SetNum(Vertices.Num());
29 [&Triangles](int32
Index) -> int32 {
return Triangles[
Index]; },
30 [&Vertices](int32
Index) -> FVector {
return Vertices[
Index]; },
31 [&UVs](int32
Index) -> FVector2D {
return UVs[
Index]; },
32 [&Normals, &Tangents](int32
Index, FVector TangentX, FVector TangentY, FVector TangentZ)
34 Normals[
Index] = TangentZ;
35 Tangents[
Index].TangentX = TangentX;
36 Tangents[
Index].bFlipTangentY = GetBasisDeterminantSign(TangentX, TangentY, TangentZ) < 0;
38 Vertices.Num(), UVs.Num(), Triangles.Num(), bCreateSmoothNormals);
44 [&Triangles](int32
Index) -> int32 {
return Triangles[
Index]; },
45 [&Vertices](int32
Index) -> FVector {
return Vertices[
Index].Position; },
46 [&Vertices](int32
Index) -> FVector2D {
return Vertices[
Index].UV0; },
47 [&Vertices](int32
Index, FVector TangentX, FVector TangentY, FVector TangentZ)
49 Vertices[
Index].Normal = TangentZ;
50 Vertices[
Index].Tangent.TangentX = TangentX;
51 Vertices[
Index].Tangent.bFlipTangentY = GetBasisDeterminantSign(TangentX, TangentY, TangentZ) < 0;
53 Vertices.Num(), Vertices.Num(), Triangles.Num(), bCreateSmoothNormals);
59 [&Triangles](int32
Index) -> int32 {
return Triangles[
Index]; },
60 [&Vertices](int32
Index) -> FVector {
return Vertices[
Index].Position; },
61 [&Vertices](int32
Index) -> FVector2D {
return Vertices[
Index].UV0; },
62 [&Vertices](int32
Index, FVector TangentX, FVector TangentY, FVector TangentZ)
64 Vertices[
Index].Normal = TangentZ;
65 Vertices[
Index].SetTangents(TangentX, TangentY, TangentZ);
67 Vertices.Num(), Vertices.Num(), Triangles.Num(), bCreateSmoothNormals);
73 [MeshAccessor](int32
Index) -> int32 {
return MeshAccessor->GetIndex(Index); },
74 [MeshAccessor](int32
Index) -> FVector {
return MeshAccessor->GetPosition(Index); },
75 [MeshAccessor](int32
Index) -> FVector2D {
return MeshAccessor->GetUV(Index); },
76 [MeshAccessor](int32
Index, FVector TangentX, FVector TangentY, FVector TangentZ)
78 MeshAccessor->SetTangents(Index, TangentX, TangentY, TangentZ);
80 MeshAccessor->NumVertices(), MeshAccessor->NumVertices(), MeshAccessor->NumIndices(), bCreateSmoothNormals);
88 TArray<int32> TessellationTriangles;
90 [&Vertices](int32
Index) -> FVector {
return Vertices[
Index]; },
91 [&UVs](int32
Index) -> FVector2D {
return UVs.Num() >
Index ? UVs[
Index] : FVector2D::ZeroVector; },
92 [&Triangles](int32
Index) -> int32 {
return Triangles[
Index]; },
93 [&TessellationTriangles](int32 NewSize) { TessellationTriangles.SetNum(NewSize); },
94 [&TessellationTriangles]() -> int32 {
return TessellationTriangles.Num(); },
95 [&TessellationTriangles](int32
Index, int32 NewValue) { TessellationTriangles[
Index] = NewValue; },
96 [&TessellationTriangles](int32
Index) -> int32 {
return TessellationTriangles[
Index]; });
97 return TessellationTriangles;
102 TArray<int32> TessellationTriangles;
104 [&Vertices](int32
Index) -> FVector {
return Vertices[
Index].Position; },
105 [&Vertices](int32
Index) -> FVector2D {
return Vertices[
Index].UV0; },
106 [&Triangles](int32
Index) -> int32 {
return Triangles[
Index]; },
107 [&TessellationTriangles](int32 NewSize) { TessellationTriangles.SetNum(NewSize); },
108 [&TessellationTriangles]() -> int32 {
return TessellationTriangles.Num(); },
109 [&TessellationTriangles](int32
Index, int32 NewValue) { TessellationTriangles[
Index] = NewValue; },
110 [&TessellationTriangles](int32
Index) -> int32 {
return TessellationTriangles[
Index]; });
111 return TessellationTriangles;
116 TArray<int32> TessellationTriangles;
118 [&Vertices](int32
Index) -> FVector {
return Vertices[
Index].Position; },
119 [&Vertices](int32
Index) -> FVector2D {
return Vertices[
Index].UV0; },
120 [&Triangles](int32
Index) -> int32 {
return Triangles[
Index]; },
121 [&TessellationTriangles](int32 NewSize) { TessellationTriangles.SetNum(NewSize); },
122 [&TessellationTriangles]() -> int32 {
return TessellationTriangles.Num(); },
123 [&TessellationTriangles](int32
Index, int32 NewValue) { TessellationTriangles[
Index] = NewValue; },
124 [&TessellationTriangles](int32
Index) -> int32 {
return TessellationTriangles[
Index]; });
125 return TessellationTriangles;
130 TArray<int32> TessellationTriangles;
132 [&MeshAccessor](int32
Index) -> FVector {
return MeshAccessor->GetPosition(
Index); },
133 [&MeshAccessor](int32
Index) -> FVector2D {
return MeshAccessor->GetUV(
Index); },
134 [&MeshAccessor](int32
Index) -> int32 {
return MeshAccessor->GetIndex(
Index); },
135 [&TessellationTriangles](int32 NewSize) { TessellationTriangles.SetNum(NewSize); },
136 [&TessellationTriangles]() -> int32 {
return TessellationTriangles.Num(); },
137 [&TessellationTriangles](int32
Index, int32 NewValue) { TessellationTriangles[
Index] = NewValue; },
138 [&TessellationTriangles](int32
Index) -> int32 {
return TessellationTriangles[
Index]; });
139 return TessellationTriangles;
144 OutTessellationIndices->EmptyIndices();
146 [&MeshAccessor](int32
Index) -> FVector {
return MeshAccessor->GetPosition(
Index); },
147 [&MeshAccessor](int32
Index) -> FVector2D {
return MeshAccessor->GetUV(
Index); },
148 [&MeshAccessor](int32
Index) -> int32 {
return MeshAccessor->GetIndex(
Index); },
149 [&OutTessellationIndices](int32 NewSize) { OutTessellationIndices->SetNumIndices(NewSize); },
150 [&OutTessellationIndices]() -> int32 {
return OutTessellationIndices->NumIndices(); },
151 [&OutTessellationIndices](int32
Index, int32 NewValue) { OutTessellationIndices->SetIndex(Index, NewValue); },
152 [&OutTessellationIndices](int32
Index) -> int32 {
return OutTessellationIndices->GetIndex(Index); });
159 TArray<FVector>& Normals, TArray<FVector2D>& UVs, TArray<FColor>& Colors, TArray<FRuntimeMeshTangent>& Tangents)
169 [&Vertices, &Normals, &Tangents](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32
171 int32 NewIndex = Vertices.Add(Position);
172 Normals.Add(TangentZ);
173 Tangents.Add(
FRuntimeMeshTangent(TangentX, GetBasisDeterminantSign(TangentX, TangentY, TangentZ) < 0));
176 [&UVs](int32
Index, int32 UVIndex, FVector2D UV)
179 UVs.SetNum(Index + 1);
184 Colors.SetNum(Index + 1);
187 [&Triangles](int32
Index)
189 Triangles.Add(Index);
202 [&Vertices](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32
206 [&Vertices](int32
Index, int32 UVIndex, FVector2D UV)
209 Vertices[
Index].UV0 = UV;
215 [&Triangles](int32
Index)
217 Triangles.Add(Index);
230 [&Vertices](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32
232 return Vertices.Add(FRuntimeMeshVertexSimple(Position, TangentX, TangentY, TangentZ));
234 [&Vertices](int32
Index, int32 UVIndex, FVector2D UV)
237 Vertices[
Index].UV0 = UV;
243 [&Triangles](int32
Index)
245 Triangles.Add(Index);
256 AdjacencyTriangles.Empty();
259 [&Vertices](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32
261 return Vertices.Add(FRuntimeMeshVertexSimple(Position, TangentX, TangentY, TangentZ));
263 [&Vertices](int32
Index, int32 UVIndex, FVector2D UV)
266 Vertices[
Index].UV0 = UV;
272 [&Triangles](int32
Index)
274 Triangles.Add(Index);
276 [&AdjacencyTriangles](int32
Index)
278 AdjacencyTriangles.Add(Index);
284 MeshAccessor->EmptyVertices();
285 MeshAccessor->EmptyIndices();
288 [&MeshAccessor](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32
290 int32 NewIndex = MeshAccessor->AddVertex(Position);
291 MeshAccessor->SetTangents(NewIndex, TangentX, TangentY, TangentZ);
294 [&MeshAccessor](int32
Index, int32 UVIndex, FVector2D UV)
296 MeshAccessor->SetUV(Index, UVIndex, UV);
300 MeshAccessor->SetColor(Index,
Color);
302 [&MeshAccessor](int32
Index)
304 MeshAccessor->AddIndex(Index);
311 void URuntimeMeshLibrary::GetStaticMeshSection(UStaticMesh* InMesh, int32 LODIndex, int32 SectionIndex,
const TSharedPtr<FRuntimeMeshAccessor>& MeshAccessor,
const TSharedPtr<FRuntimeMeshIndicesAccessor>& TessellationIndicesAccessor)
313 MeshAccessor->EmptyVertices();
314 MeshAccessor->EmptyIndices();
315 TessellationIndicesAccessor->EmptyIndices();
318 [&MeshAccessor](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32
320 int32 NewIndex = MeshAccessor->AddVertex(Position);
321 MeshAccessor->SetTangents(NewIndex, TangentX, TangentY, TangentZ);
324 [&MeshAccessor](int32
Index, int32 UVIndex, FVector2D UV)
326 MeshAccessor->SetUV(Index, UVIndex, UV);
330 MeshAccessor->SetColor(Index,
Color);
332 [&MeshAccessor](int32
Index)
334 MeshAccessor->AddIndex(Index);
336 [&TessellationIndicesAccessor](int32
Index)
338 TessellationIndicesAccessor->AddIndex(Index);
348 SCOPE_CYCLE_COUNTER(STAT_RuntimeMeshLibrary_CopyStaticMeshToRuntimeMesh);
349 if (StaticMeshComponent !=
nullptr &&
350 StaticMeshComponent->GetStaticMesh() !=
nullptr &&
351 RuntimeMesh !=
nullptr)
353 UStaticMesh* StaticMesh = StaticMeshComponent->GetStaticMesh();
359 int32 NumSections = StaticMesh->GetNumSections(LODIndex);
360 for (int32 SectionIndex = 0; SectionIndex < NumSections; SectionIndex++)
363 TSharedPtr<FRuntimeMeshBuilder> MeshData = MakeRuntimeMeshBuilder<FRuntimeMeshTangents, FVector2DHalf, uint32>();
364 TArray<uint8> AdjacencyTrianglesData;
365 TSharedPtr<FRuntimeMeshIndicesAccessor> AdjacencyTrianglesAccessor = MakeShared<FRuntimeMeshIndicesAccessor>(
true, &AdjacencyTrianglesData);
366 TArray<uint32> AdjacencyTriangles;
367 AdjacencyTriangles.SetNum(AdjacencyTrianglesData.Num() / 4);
368 FMemory::Memcpy(AdjacencyTriangles.GetData(), AdjacencyTrianglesData.GetData(), AdjacencyTrianglesData.Num());
388 for (int32 MatIndex = 0; MatIndex < StaticMeshComponent->GetNumMaterials(); MatIndex++)
390 RuntimeMesh->
SetSectionMaterial(MatIndex, StaticMeshComponent->GetMaterial(MatIndex));
406 if (StaticMesh->BodySetup !=
nullptr)
409 const int32 NumConvex = StaticMesh->BodySetup->AggGeom.ConvexElems.Num();
410 for (
int ConvexIndex = 0; ConvexIndex < NumConvex; ConvexIndex++)
413 FKConvexElem& MeshConvex = StaticMesh->BodySetup->AggGeom.ConvexElems[ConvexIndex];
421 TFunction<
void(int32 Index, FVector TangentX, FVector TangentY, FVector TangentZ)> TangentSetter, int32 NumVertices, int32 NumUVs, int32 NumIndices,
bool bCreateSmoothNormals)
423 SCOPE_CYCLE_COUNTER(STAT_RuntimeMeshLibrary_CalculateTangentsForMesh);
425 if (NumVertices == 0 || NumIndices == 0)
436 const int32 NumTris = NumIndices / 3;
439 TMultiMap<uint32, uint32> VertToTriMap;
441 TMultiMap<uint32, uint32> VertToTriSmoothMap;
444 TArray<FVector> FaceTangentX, FaceTangentY, FaceTangentZ;
445 FaceTangentX.AddUninitialized(NumTris);
446 FaceTangentY.AddUninitialized(NumTris);
447 FaceTangentZ.AddUninitialized(NumTris);
450 for (
int TriIdx = 0; TriIdx < NumTris; TriIdx++)
452 uint32 CornerIndex[3];
455 for (int32 CornerIdx = 0; CornerIdx < 3; CornerIdx++)
458 uint32 VertIndex = FMath::Min(IndexAccessor((TriIdx * 3) + CornerIdx), NumVertices - 1);
460 CornerIndex[CornerIdx] = VertIndex;
461 P[CornerIdx] = VertexAccessor(VertIndex);
464 TArray<uint32> VertOverlaps;
465 DuplicateVertexMap.MultiFind(VertIndex, VertOverlaps);
468 VertToTriMap.AddUnique(VertIndex, TriIdx);
469 VertToTriSmoothMap.AddUnique(VertIndex, TriIdx);
472 for (int32 OverlapIdx = 0; OverlapIdx < VertOverlaps.Num(); OverlapIdx++)
475 int32 OverlapVertIdx = VertOverlaps[OverlapIdx];
478 VertToTriSmoothMap.AddUnique(OverlapVertIdx, TriIdx);
481 TArray<uint32> OverlapTris;
482 VertToTriMap.MultiFind(OverlapVertIdx, OverlapTris);
483 for (int32 OverlapTriIdx = 0; OverlapTriIdx < OverlapTris.Num(); OverlapTriIdx++)
485 VertToTriSmoothMap.AddUnique(VertIndex, OverlapTris[OverlapTriIdx]);
491 const FVector Edge21 = P[1] - P[2];
492 const FVector Edge20 = P[0] - P[2];
493 const FVector TriNormal = (Edge21 ^ Edge20).GetSafeNormal();
496 if (NumUVs == NumVertices)
498 const FVector2D T1 = UVAccessor(CornerIndex[0]);
499 const FVector2D T2 = UVAccessor(CornerIndex[1]);
500 const FVector2D T3 = UVAccessor(CornerIndex[2]);
523 FMatrix ParameterToLocal(
524 FPlane(P[1].
X - P[0].
X, P[1].
Y - P[0].
Y, P[1].
Z - P[0].
Z, 0),
525 FPlane(P[2].X - P[0].X, P[2].Y - P[0].Y, P[2].Z - P[0].Z, 0),
526 FPlane(P[0].X, P[0].Y, P[0].Z, 0),
530 FMatrix ParameterToTexture(
531 FPlane(T2.X - T1.X, T2.Y - T1.Y, 0, 0),
532 FPlane(T3.X - T1.X, T3.Y - T1.Y, 0, 0),
533 FPlane(T1.X, T1.Y, 1, 0),
538 const FMatrix TextureToLocal = ParameterToTexture.Inverse() * ParameterToLocal;
540 FaceTangentX[TriIdx] = TextureToLocal.TransformVector(FVector(1, 0, 0)).GetSafeNormal();
541 FaceTangentY[TriIdx] = TextureToLocal.TransformVector(FVector(0, 1, 0)).GetSafeNormal();
545 FaceTangentX[TriIdx] = Edge20.GetSafeNormal();
546 FaceTangentY[TriIdx] = (FaceTangentX[TriIdx] ^ TriNormal).GetSafeNormal();
549 FaceTangentZ[TriIdx] = TriNormal;
554 TArray<FVector> VertexTangentXSum, VertexTangentYSum, VertexTangentZSum;
555 VertexTangentXSum.AddZeroed(NumVertices);
556 VertexTangentYSum.AddZeroed(NumVertices);
557 VertexTangentZSum.AddZeroed(NumVertices);
560 for (
int VertxIdx = 0; VertxIdx < NumVertices; VertxIdx++)
563 TArray<uint32> SmoothTris;
564 VertToTriSmoothMap.MultiFind(VertxIdx, SmoothTris);
566 for (
int i = 0;
i < SmoothTris.Num();
i++)
568 uint32 TriIdx = SmoothTris[
i];
569 VertexTangentZSum[VertxIdx] += FaceTangentZ[TriIdx];
573 TArray<uint32> TangentTris;
574 VertToTriMap.MultiFind(VertxIdx, TangentTris);
576 for (
int i = 0;
i < TangentTris.Num();
i++)
578 uint32 TriIdx = TangentTris[
i];
579 VertexTangentXSum[VertxIdx] += FaceTangentX[TriIdx];
580 VertexTangentYSum[VertxIdx] += FaceTangentY[TriIdx];
585 for (
int VertxIdx = 0; VertxIdx < NumVertices; VertxIdx++)
587 FVector& TangentX = VertexTangentXSum[VertxIdx];
588 FVector& TangentY = VertexTangentYSum[VertxIdx];
589 FVector& TangentZ = VertexTangentZSum[VertxIdx];
591 TangentX.Normalize();
593 TangentZ.Normalize();
596 TangentX -= TangentZ * (TangentZ | TangentX);
597 TangentX.Normalize();
598 TangentY.Normalize();
601 TangentSetter(VertxIdx, TangentX, TangentY, TangentZ);
606 TMap<int32, int32>& MeshToSectionVertMap, int32 VertexIndex, int32 NumUVChannels, TFunction<int32(FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ)> VertexCreator,
607 TFunction<
void(int32 VertexIndex, int32 UVIndex, FVector2D UV)> UVSetter, TFunction<
void(int32 VertexIndex, FColor
Color)> ColorSetter)
609 int32* FoundIndex = MeshToSectionVertMap.Find(VertexIndex);
610 if (FoundIndex !=
nullptr)
616 int32 NewVertexIndex = VertexCreator(
617 PosBuffer->VertexPosition(VertexIndex),
618 VertBuffer->VertexTangentX(VertexIndex),
619 VertBuffer->VertexTangentY(VertexIndex),
620 VertBuffer->VertexTangentZ(VertexIndex));
622 if (ColorBuffer && ColorBuffer->GetNumVertices() > (uint32)NewVertexIndex)
624 ColorSetter(NewVertexIndex, ColorBuffer->VertexColor(VertexIndex));
627 int32 NumTexCoordsToCopy = FMath::Min(NumUVChannels, (int32)VertBuffer->GetNumTexCoords());
628 for (int32 Index = 0; Index < NumTexCoordsToCopy; Index++)
630 UVSetter(NewVertexIndex, Index, VertBuffer->GetVertexUV(VertexIndex, Index));
633 MeshToSectionVertMap.Add(VertexIndex, NewVertexIndex);
634 return NewVertexIndex;
639 TFunction<int32(FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ)> VertexCreator,
640 TFunction<
void(int32 VertexIndex, int32 UVIndex, FVector2D UV)> UVSetter, TFunction<
void(int32 VertexIndex, FColor
Color)> ColorSetter, TFunction<
void(int32)> IndexCreator, TFunction<
void(int32)> AdjacencyIndexCreator)
642 SCOPE_CYCLE_COUNTER(STAT_RuntimeMeshLibrary_GetStaticMeshSection);
644 if (InMesh !=
nullptr)
647 if (!InMesh->bAllowCPUAccess)
649 FMessageLog(
"PIE").Warning()
650 ->AddToken(FTextToken::Create(LOCTEXT(
"GetSectionFromStaticMeshStart",
"Calling GetSectionFromStaticMesh on")))
651 ->AddToken(FUObjectToken::Create(InMesh))
652 ->AddToken(FTextToken::Create(LOCTEXT(
"GetSectionFromStaticMeshEnd",
"but 'Allow CPU Access' is not enabled. This is required for converting StaticMesh to ProceduralMeshComponent in cooked builds.")));
655 if ((InMesh->bAllowCPUAccess || GIsEditor) && InMesh->RenderData !=
nullptr && InMesh->RenderData->LODResources.IsValidIndex(LODIndex))
657 const FStaticMeshLODResources& LOD = InMesh->RenderData->LODResources[LODIndex];
658 if (LOD.Sections.IsValidIndex(SectionIndex))
661 TMap<int32, int32> MeshToSectionVertMap;
663 const FStaticMeshSection& Section = LOD.Sections[SectionIndex];
664 const uint32 OnePastLastIndex = Section.FirstIndex + Section.NumTriangles * 3;
665 FIndexArrayView Indices = LOD.IndexBuffer.GetArrayView();
668 for (uint32
i = Section.FirstIndex;
i < OnePastLastIndex;
i++)
670 uint32 MeshVertIndex = Indices[
i];
674 #if ENGINE_MAJOR_VERSION >= 4 && ENGINE_MINOR_VERSION >= 19 675 int32 SectionVertIndex =
GetNewIndexForOldVertIndex(&LOD.VertexBuffers.PositionVertexBuffer, &LOD.VertexBuffers.StaticMeshVertexBuffer, &LOD.VertexBuffers.ColorVertexBuffer, MeshToSectionVertMap, MeshVertIndex, NumSupportedUVs, VertexCreator, UVSetter, ColorSetter);
677 int32 SectionVertIndex =
GetNewIndexForOldVertIndex(&LOD.PositionVertexBuffer, &LOD.VertexBuffer, &LOD.ColorVertexBuffer, MeshToSectionVertMap, MeshVertIndex, NumSupportedUVs, VertexCreator, UVSetter, ColorSetter);
681 IndexCreator(SectionVertIndex);
686 if (LOD.bHasAdjacencyInfo && LOD.AdditionalIndexBuffers->AdjacencyIndexBuffer.GetNumIndices() > 0)
688 FIndexArrayView AdjacencyIndices = LOD.AdditionalIndexBuffers->AdjacencyIndexBuffer.GetArrayView();
691 uint32 StartIndex = Section.FirstIndex * 4;
692 uint32 NumIndices = Section.NumTriangles * 3 * 4;
694 for (uint32 Index = 0; Index < NumIndices; Index++)
696 AdjacencyIndexCreator(MeshToSectionVertMap[AdjacencyIndices[Index]]);
705 #undef LOCTEXT_NAMESPACE static void CalculateTangentsForMeshPacked(TArray< FRuntimeMeshBlueprintVertexSimple > &Vertices, const TArray< int32 > &Triangles, bool bCreateSmoothNormals=true)
static void CopyStaticMeshToRuntimeMeshComponent(UStaticMeshComponent *StaticMeshComponent, int32 LODIndex, URuntimeMeshComponent *RuntimeMeshComponent, bool bCreateCollision)
void CreateMeshSection(int32 SectionIndex, bool bWantsHighPrecisionTangents, bool bWantsHighPrecisionUVs, int32 NumUVs, bool bWants32BitIndices, bool bCreateCollision, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average)
static void CalculateTessellationIndices(int32 NumVertices, int32 NumIndices, TFunction< FVector(int32)> PositionAccessor, TFunction< FVector2D(int32)> UVAccessor, TFunction< int32(int32)> IndexAccessor, TFunction< void(int32)> OutIndicesSizeSetter, TFunction< int32()> OutIndicesSizeGetter, TFunction< void(int32, int32)> OutIndicesWriter, TFunction< int32(int32)> OutIndicesReader)
static TMultiMap< uint32, uint32 > FindDuplicateVerticesMap(TFunction< FVector(int32)> VertexAccessor, int32 NumVertices, float Tollerance=0.0)
void SetSectionTessellationTriangles(int32 SectionId, const TArray< int32 > &Triangles)
void SetSectionMaterial(int32 SectionId, UMaterialInterface *Material)
static TArray< int32 > GenerateTessellationIndexBufferPacked(const TArray< FRuntimeMeshBlueprintVertexSimple > &Vertices, const TArray< int32 > &Triangles)
void ClearAllMeshSections()
static int32 GetNewIndexForOldVertIndex(const FPositionVertexBuffer *PosBuffer, const FStaticMeshVertexBuffer *VertBuffer, const FColorVertexBuffer *ColorBuffer, TMap< int32, int32 > &MeshToSectionVertMap, int32 VertexIndex, int32 NumUVChannels, TFunction< int32(FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ)> VertexCreator, TFunction< void(int32 VertexIndex, int32 UVIndex, FVector2D UV)> UVSetter, TFunction< void(int32 VertexIndex, FColor Color)> ColorSetter)
static void CalculateTangentsForMesh(const TArray< FVector > &Vertices, const TArray< int32 > &Triangles, TArray< FVector > &Normals, const TArray< FVector2D > &UVs, TArray< FRuntimeMeshTangent > &Tangents, bool bCreateSmoothNormals=true)
static void CopyCollisionFromStaticMesh(UStaticMesh *StaticMesh, URuntimeMesh *RuntimeMesh)
static const textual_icon check
void ClearAllConvexCollisionSections()
int32 AddConvexCollisionSection(TArray< FVector > ConvexVerts)
static void CopyStaticMeshToRuntimeMesh(UStaticMeshComponent *StaticMeshComponent, int32 LODIndex, URuntimeMesh *RuntimeMesh, bool bCreateCollision)
static void GetStaticMeshSectionPacked(UStaticMesh *InMesh, int32 LODIndex, int32 SectionIndex, TArray< FRuntimeMeshBlueprintVertexSimple > &Vertices, TArray< int32 > &Triangles)
static TArray< int32 > GenerateTessellationIndexBuffer(const TArray< FVector > &Vertices, const TArray< int32 > &Triangles, TArray< FVector > &Normals, const TArray< FVector2D > &UVs, TArray< FRuntimeMeshTangent > &Tangents)
static void GetStaticMeshSection(UStaticMesh *InMesh, int32 LODIndex, int32 SectionIndex, TArray< FVector > &Vertices, TArray< int32 > &Triangles, TArray< FVector > &Normals, TArray< FVector2D > &UVs, TArray< FColor > &Colors, TArray< FRuntimeMeshTangent > &Tangents)
DECLARE_CYCLE_STAT(TEXT("RML - Copy Static Mesh to Runtime Mesh"), STAT_RuntimeMeshLibrary_CopyStaticMeshToRuntimeMesh, STATGROUP_RuntimeMesh)