5 #include "CoreMinimal.h" 21 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Mesh Section - No Data"), STAT_RuntimeMesh_CreateMeshSection_NoData, STATGROUP_RuntimeMesh);
22 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Dual Buffer Mesh Section - No Data"), STAT_RuntimeMesh_CreateMeshSectionDualBuffer_NoData, STATGROUP_RuntimeMesh);
23 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Triple Buffer Mesh Section - No Data"), STAT_RuntimeMesh_CreateMeshSectionTripleBuffer_NoData, STATGROUP_RuntimeMesh);
25 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Mesh Section"), STAT_RuntimeMesh_CreateMeshSection, STATGROUP_RuntimeMesh);
26 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Mesh Section - With Bounding Box"), STAT_RuntimeMesh_CreateMeshSection_BoundingBox, STATGROUP_RuntimeMesh);
27 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Mesh Section Dual Buffer"), STAT_RuntimeMesh_CreateMeshSectionDualBuffer, STATGROUP_RuntimeMesh);
28 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Mesh Section Dual Buffer - With Bounding Box"), STAT_RuntimeMesh_CreateMeshSectionDualBuffer_BoundingBox, STATGROUP_RuntimeMesh);
29 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Mesh Section Triple Buffer"), STAT_RuntimeMesh_CreateMeshSectionTripleBuffer, STATGROUP_RuntimeMesh);
30 DECLARE_CYCLE_STAT(TEXT(
"RM - Create Mesh Section Triple Buffer - With Bounding Box"), STAT_RuntimeMesh_CreateMeshSectionTripleBuffer_BoundingBox, STATGROUP_RuntimeMesh);
32 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section - No Triangles"), STAT_RuntimeMesh_UpdateMeshSection_NoTriangles, STATGROUP_RuntimeMesh);
33 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section - No Triangles - With Bounding Box"), STAT_RuntimeMesh_UpdateMeshSection_NoTriangles_BoundingBox, STATGROUP_RuntimeMesh);
34 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section"), STAT_RuntimeMesh_UpdateMeshSection, STATGROUP_RuntimeMesh);
35 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section - With Bounding Box"), STAT_RuntimeMesh_UpdateMeshSection_BoundingBox, STATGROUP_RuntimeMesh);
37 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Dual Buffer - No Triangles"), STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_NoTriangles, STATGROUP_RuntimeMesh);
38 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Dual Buffer - No Triangles - With Bounding Box"), STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_NoTriangles_BoundingBox, STATGROUP_RuntimeMesh);
39 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Dual Buffer"), STAT_RuntimeMesh_UpdateMeshSectionDualBuffer, STATGROUP_RuntimeMesh);
40 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Dual Buffer - With Bounding Box"), STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_BoundingBox, STATGROUP_RuntimeMesh);
42 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Triple Buffer - No Triangles"), STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_NoTriangles, STATGROUP_RuntimeMesh);
43 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Triple Buffer - No Triangles - With Bounding Box"), STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_NoTriangles_BoundingBox, STATGROUP_RuntimeMesh);
44 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Triple Buffer"), STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer, STATGROUP_RuntimeMesh);
45 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Triple Buffer - With Bounding Box"), STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_BoundingBox, STATGROUP_RuntimeMesh);
47 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Primary Buffer"), STAT_RuntimeMesh_UpdateMeshSectionPrimaryBuffer, STATGROUP_RuntimeMesh);
48 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Primary Buffer - With Bounding Box"), STAT_RuntimeMesh_UpdateMeshSectionPrimaryBuffer_BoundingBox, STATGROUP_RuntimeMesh);
49 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Secondary Buffer"), STAT_RuntimeMesh_UpdateMeshSectionSecondaryBuffer, STATGROUP_RuntimeMesh);
50 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Tertiary Buffer"), STAT_RuntimeMesh_UpdateMeshSectionTertiaryBuffer, STATGROUP_RuntimeMesh);
51 DECLARE_CYCLE_STAT(TEXT(
"RM - Update Mesh Section Triangles"), STAT_RuntimeMesh_UpdateMeshSectionTriangles, STATGROUP_RuntimeMesh);
53 DECLARE_CYCLE_STAT(TEXT(
"RM - Set Section Tessellation Triangles"), STAT_RuntimeMesh_SetSectionTessellationTriangles, STATGROUP_RuntimeMesh);
55 DECLARE_CYCLE_STAT(TEXT(
"RM - Serialize Data"), STAT_RuntimeMesh_SerializationOperator, STATGROUP_RuntimeMesh);
61 class RUNTIMEMESHCOMPONENT_API
FRuntimeMeshData :
public TSharedFromThis<FRuntimeMeshData, ESPMode::ThreadSafe>
92 void CheckCreate(int32 NumUVs,
bool bIndexIsValid)
const;
96 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
102 void CheckUpdate(
bool bUseHighPrecisionTangents,
bool bUseHighPrecisionUVs, int32 NumUVs,
bool b32BitIndices, int32 SectionIndex,
bool bShouldCheckIndexType,
103 bool bCheckTangentVertexStream,
bool bCheckUVVertexStream)
const;
105 template<
typename TangentType,
typename UVType,
typename IndexType>
106 void CheckUpdate(int32 SectionIndex,
bool bShouldCheckIndexType,
bool bCheckTangentVertexStream,
bool bCheckUVVertexStream)
const 109 bool UVsAreHighPrecision;
111 GetUVVertexProperties<UVType>(UVsAreHighPrecision, NumUVs);
112 CheckUpdate(GetTangentIsHighPrecision<TangentType>(), UVsAreHighPrecision, NumUVs,
FRuntimeMeshIndexTraits<IndexType>::Is32Bit, SectionIndex, bShouldCheckIndexType, bCheckTangentVertexStream, bCheckUVVertexStream);
116 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
121 void CheckBoundingBox(
const FBox& Box)
const;
129 void EnterSerializedMode();
132 void CreateMeshSection(int32 SectionIndex,
bool bWantsHighPrecisionTangents,
bool bWantsHighPrecisionUVs, int32 NumUVs,
bool bWants32BitIndices,
bool bCreateCollision,
EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average);
134 template<
typename VertexType0,
typename IndexType>
135 void CreateMeshSection(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
bool bCreateCollision =
false,
138 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSection);
142 CheckCreateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>();
144 bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0>();
145 bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0>();
146 int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0>();
149 CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
151 auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
153 Mesh->EmptyVertices(InVertices0.Num());
158 Mesh->AddVertexByProperties<VertexType0>(InVertices0[
Index]);
161 Mesh->EmptyIndices(InTriangles.Num());
165 Mesh->AddIndex(InTriangles[
Index]);
171 template<
typename VertexType0,
typename IndexType>
172 void CreateMeshSection(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
const FBox& BoundingBox,
175 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSection_BoundingBox);
179 CheckCreateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>();
181 bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0>();
182 bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0>();
183 int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0>();
186 CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
188 auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
190 Mesh->EmptyVertices(InVertices0.Num());
195 Mesh->AddVertexByProperties<VertexType0>(InVertices0[
Index]);
198 Mesh->EmptyIndices(InTriangles.Num());
202 Mesh->AddIndex(InTriangles[
Index]);
205 Mesh->Commit(BoundingBox);
208 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
209 void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<IndexType>& InTriangles,
bool bCreateCollision =
false,
212 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionDualBuffer);
216 CheckCreateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>();
218 bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1>();
219 bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1>();
220 int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1>();
223 CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
225 auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
227 Mesh->EmptyVertices(InVertices0.Num());
232 Mesh->AddVertexByProperties<VertexType0, VertexType1>(InVertices0[
Index], InVertices1[
Index]);
235 Mesh->EmptyIndices(InTriangles.Num());
239 Mesh->AddIndex(InTriangles[
Index]);
245 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
246 void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<IndexType>& InTriangles,
const FBox& BoundingBox,
249 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionDualBuffer_BoundingBox);
253 CheckCreateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>();
255 bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1>();
256 bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1>();
257 int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1>();
260 CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
262 auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
264 Mesh->EmptyVertices(InVertices0.Num());
269 Mesh->AddVertexByProperties<VertexType0, VertexType1>(InVertices0[
Index], InVertices1[
Index]);
272 Mesh->EmptyIndices(InTriangles.Num());
276 Mesh->AddIndex(InTriangles[
Index]);
279 Mesh->Commit(BoundingBox);
282 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
283 void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2, TArray<IndexType>& InTriangles,
286 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionTripleBuffer);
290 CheckCreateLegacy<VertexType0, VertexType1, VertexType2, IndexType>();
292 bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1, VertexType2>();
293 bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1, VertexType2>();
294 int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1, VertexType2>();
297 CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
299 auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
301 Mesh->EmptyVertices(InVertices0.Num());
306 Mesh->AddVertexByProperties<VertexType0, VertexType1, VertexType2>(InVertices0[
Index], InVertices1[
Index], InVertices2[
Index]);
309 Mesh->EmptyIndices(InTriangles.Num());
313 Mesh->AddIndex(InTriangles[
Index]);
319 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
320 void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2, TArray<IndexType>& InTriangles,
323 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionTripleBuffer_BoundingBox);
327 CheckCreateLegacy<VertexType0, VertexType1, VertexType2, IndexType>();
329 bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1, VertexType2>();
330 bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1, VertexType2>();
331 int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1, VertexType2>();
334 CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
336 auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
338 Mesh->EmptyVertices(InVertices0.Num());
343 Mesh->AddVertexByProperties<VertexType0, VertexType1, VertexType2>(InVertices0[
Index], InVertices1[
Index], InVertices2[
Index]);
346 Mesh->EmptyIndices(InTriangles.Num());
350 Mesh->AddIndex(InTriangles[
Index]);
353 Mesh->Commit(BoundingBox);
358 template<
typename VertexType0>
361 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection_NoTriangles);
365 CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId,
false);
367 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
369 Mesh->SetNumVertices(InVertices0.Num());
374 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
380 template<
typename VertexType0>
383 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection_NoTriangles_BoundingBox);
387 CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId,
false);
388 CheckBoundingBox(BoundingBox);
390 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
392 Mesh->SetNumVertices(InVertices0.Num());
397 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
400 Mesh->Commit(BoundingBox);
403 template<
typename VertexType0,
typename IndexType>
406 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection);
410 CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>(SectionId,
true);
412 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
414 Mesh->SetNumVertices(InVertices0.Num());
419 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
422 Mesh->SetNumIndices(InTriangles.Num());
432 template<
typename VertexType0,
typename IndexType>
433 void UpdateMeshSection(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
436 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection_BoundingBox);
440 CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>(SectionId,
true);
441 CheckBoundingBox(BoundingBox);
443 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
445 Mesh->SetNumVertices(InVertices0.Num());
450 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
453 Mesh->SetNumIndices(InTriangles.Num());
460 Mesh->Commit(BoundingBox);
463 template<
typename VertexType0,
typename VertexType1>
467 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_NoTriangles);
471 CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, uint16>(SectionId,
false);
473 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
475 Mesh->SetNumVertices(InVertices0.Num());
480 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
481 if (InVertices1.Num() >
Index)
483 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
490 template<
typename VertexType0,
typename VertexType1>
494 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_NoTriangles_BoundingBox);
498 CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, uint16>(SectionId,
false);
499 CheckBoundingBox(BoundingBox);
501 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
503 Mesh->SetNumVertices(InVertices0.Num());
508 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
509 if (InVertices1.Num() >
Index)
511 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
515 Mesh->Commit(BoundingBox);
518 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
522 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer);
526 CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>(SectionId,
true);
528 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
530 Mesh->SetNumVertices(InVertices0.Num());
535 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
536 if (InVertices1.Num() >
Index)
538 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
542 Mesh->SetNumIndices(InTriangles.Num());
552 template<
typename VertexType0,
typename VertexType1,
typename IndexType>
553 void UpdateMeshSectionDualBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<IndexType>& InTriangles,
556 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_BoundingBox);
560 CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>(SectionId,
true);
561 CheckBoundingBox(BoundingBox);
563 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
565 Mesh->SetNumVertices(InVertices0.Num());
570 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
571 if (InVertices1.Num() >
Index)
573 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
577 Mesh->SetNumIndices(InTriangles.Num());
584 Mesh->Commit(BoundingBox);
587 template<
typename VertexType0,
typename VertexType1,
typename VertexType2>
591 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_NoTriangles);
595 CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, uint16>(SectionId,
false);
597 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
599 Mesh->SetNumVertices(InVertices0.Num());
604 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
605 if (InVertices1.Num() >
Index)
607 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
609 if (InVertices2.Num() >
Index)
611 Mesh->SetVertexProperties<VertexType2>(
Index, InVertices2[
Index]);
618 template<
typename VertexType0,
typename VertexType1,
typename VertexType2>
622 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_NoTriangles_BoundingBox);
626 CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, uint16>(SectionId,
false);
627 CheckBoundingBox(BoundingBox);
629 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
631 Mesh->SetNumVertices(InVertices0.Num());
636 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
637 if (InVertices1.Num() >
Index)
639 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
641 if (InVertices2.Num() >
Index)
643 Mesh->SetVertexProperties<VertexType2>(
Index, InVertices2[
Index]);
647 Mesh->Commit(BoundingBox);
650 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
654 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer);
658 CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, IndexType>(SectionId,
true);
660 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
662 Mesh->SetNumVertices(InVertices0.Num());
667 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
668 if (InVertices1.Num() >
Index)
670 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
672 if (InVertices2.Num() >
Index)
674 Mesh->SetVertexProperties<VertexType2>(
Index, InVertices2[
Index]);
678 Mesh->SetNumIndices(InTriangles.Num());
688 template<
typename VertexType0,
typename VertexType1,
typename VertexType2,
typename IndexType>
692 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_BoundingBox);
696 CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, IndexType>(SectionId,
true);
697 CheckBoundingBox(BoundingBox);
699 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
701 Mesh->SetNumVertices(InVertices0.Num());
706 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
707 if (InVertices1.Num() >
Index)
709 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
711 if (InVertices2.Num() >
Index)
713 Mesh->SetVertexProperties<VertexType2>(
Index, InVertices2[
Index]);
717 Mesh->SetNumIndices(InTriangles.Num());
724 Mesh->Commit(BoundingBox);
729 template<
typename VertexType0>
732 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionPrimaryBuffer);
736 CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId,
false);
738 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
740 Mesh->SetNumVertices(InVertices0.Num());
745 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
751 template<
typename VertexType0>
754 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionPrimaryBuffer_BoundingBox);
758 CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId,
false);
759 CheckBoundingBox(BoundingBox);
761 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
763 Mesh->SetNumVertices(InVertices0.Num());
768 Mesh->SetVertexProperties<VertexType0>(
Index, InVertices0[
Index]);
771 Mesh->Commit(BoundingBox);
774 template<
typename VertexType1>
777 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionSecondaryBuffer);
781 CheckUpdateLegacy<FRuntimeMeshNullVertex, VertexType1, FRuntimeMeshNullVertex, uint16>(SectionId,
false);
783 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
785 int32 NumVerts = FMath::Min(Mesh->NumVertices(), InVertices1.Num());
790 Mesh->SetVertexProperties<VertexType1>(
Index, InVertices1[
Index]);
796 template<
typename VertexType2>
799 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTertiaryBuffer);
803 CheckUpdateLegacy<FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, VertexType2, uint16>(SectionId,
false);
805 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
807 int32 NumVerts = FMath::Min(Mesh->NumVertices(), InVertices2.Num());
812 Mesh->SetVertexProperties<VertexType2>(
Index, InVertices2[
Index]);
818 template<
typename IndexType>
821 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTriangles);
825 CheckUpdateLegacy<FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>(SectionId,
true);
827 auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
829 Mesh->SetNumIndices(InTriangles.Num());
841 void CreateMeshSection(int32 SectionId,
const TSharedPtr<FRuntimeMeshBuilder>& MeshData,
bool bCreateCollision =
false,
844 void CreateMeshSectionByMove(int32 SectionId,
const TSharedPtr<FRuntimeMeshBuilder>& MeshData,
bool bCreateCollision =
false,
859 TUniquePtr<FRuntimeMeshScopedUpdater> GetSectionReadonly(int32 SectionId);
867 void CreateMeshSectionFromComponents(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
868 const TArray<FVector2D>& UV0,
const TArray<FVector2D>& UV1, TFunction<FColor(int32
Index)> ColorAccessor, int32 NumColors,
const TArray<FRuntimeMeshTangent>& Tangents,
871 void UpdateMeshSectionFromComponents(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
872 const TArray<FVector2D>& UV0,
const TArray<FVector2D>& UV1, TFunction<FColor(int32 Index)> ColorAccessor, int32 NumColors,
const TArray<FRuntimeMeshTangent>& Tangents,
ESectionUpdateFlags UpdateFlags);
879 void CreateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
880 const TArray<FVector2D>& UV0,
const TArray<FColor>& Colors,
const TArray<FRuntimeMeshTangent>& Tangents,
bool bCreateCollision =
false,
882 bool bUseHighPrecisionTangents =
false,
bool bUseHighPrecisionUVs =
true);
884 void CreateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
885 const TArray<FVector2D>& UV0,
const TArray<FVector2D>& UV1,
const TArray<FColor>& Colors,
const TArray<FRuntimeMeshTangent>& Tangents,
887 bool bUseHighPrecisionTangents =
false,
bool bUseHighPrecisionUVs =
true);
890 void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<FVector>& Normals,
const TArray<FVector2D>& UV0,
893 void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<FVector>& Normals,
const TArray<FVector2D>& UV0,
896 void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
899 void UpdateMeshSection(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
904 void CreateMeshSection_Blueprint(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
905 const TArray<FRuntimeMeshTangent>& Tangents,
const TArray<FVector2D>& UV0,
const TArray<FVector2D>& UV1,
const TArray<FLinearColor>& Colors,
906 bool bCreateCollision =
false,
bool bCalculateNormalTangent =
false,
bool bShouldCreateHardTangents =
false,
bool bGenerateTessellationTriangles =
false,
907 EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average,
bool bUseHighPrecisionTangents =
false,
bool bUseHighPrecisionUVs =
true);
909 void UpdateMeshSection_Blueprint(int32 SectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles,
const TArray<FVector>& Normals,
910 const TArray<FRuntimeMeshTangent>& Tangents,
const TArray<FVector2D>& UV0,
const TArray<FVector2D>& UV1,
const TArray<FLinearColor>& Colors,
911 bool bCalculateNormalTangent =
false,
bool bShouldCreateHardTangents =
false,
bool bGenerateTessellationTriangles =
false);
913 void CreateMeshSectionPacked_Blueprint(int32 SectionIndex,
const TArray<FRuntimeMeshBlueprintVertexSimple>& Vertices,
const TArray<int32>& Triangles,
914 bool bCreateCollision =
false,
bool bCalculateNormalTangent =
false,
bool bShouldCreateHardTangents =
false,
bool bGenerateTessellationTriangles =
false,
EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average,
915 bool bUseHighPrecisionTangents =
false,
bool bUseHighPrecisionUVs =
true);
917 void UpdateMeshSectionPacked_Blueprint(int32 SectionIndex,
const TArray<FRuntimeMeshBlueprintVertexSimple>& Vertices,
const TArray<int32>& Triangles,
918 bool bCalculateNormalTangent =
false,
bool bShouldCreateHardTangents =
false,
bool bGenerateTessellationTriangles =
false);
926 template<
typename IndexType>
929 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_SetSectionTessellationTriangles);
939 if (Triangles.Num() > 0)
941 Section->UpdateAdjacencyIndexBuffer(Triangles);
953 void ClearMeshSection(int32 SectionIndex);
956 void ClearAllMeshSections();
961 FBox GetSectionBoundingBox(int32 SectionIndex);
964 void SetMeshSectionVisible(int32 SectionIndex,
bool bNewVisibility);
967 bool IsMeshSectionVisible(int32 SectionIndex)
const;
971 void SetMeshSectionCastsShadow(int32 SectionIndex,
bool bNewCastsShadow);
974 bool IsMeshSectionCastingShadows(int32 SectionIndex)
const;
978 void SetMeshSectionCollisionEnabled(int32 SectionIndex,
bool bNewCollisionEnabled);
981 bool IsMeshSectionCollisionEnabled(int32 SectionIndex);
985 int32 GetNumSections()
const;
988 bool DoesSectionExist(int32 SectionIndex)
const;
991 int32 GetAvailableSectionIndex()
const;
993 int32 GetLastSectionIndex()
const;
996 TArray<int32> GetSectionIds()
const;
999 void SetMeshCollisionSection(int32 CollisionSectionIndex,
const TArray<FVector>& Vertices,
const TArray<int32>& Triangles);
1001 void ClearMeshCollisionSection(int32 CollisionSectionIndex);
1003 void ClearAllMeshCollisionSections();
1007 int32 AddConvexCollisionSection(TArray<FVector> ConvexVerts);
1009 void SetConvexCollisionSection(int32 ConvexSectionIndex, TArray<FVector> ConvexVerts);
1011 void RemoveConvexCollisionSection(int32 ConvexSectionIndex);
1013 void ClearConvexCollisionSections();
1015 void SetCollisionConvexMeshes(
const TArray<TArray<FVector>>& ConvexMeshes);
1020 void RemoveCollisionBox(int32 Index);
1022 void ClearCollisionBoxes();
1024 void SetCollisionBoxes(
const TArray<FRuntimeMeshCollisionBox>& NewBoxes);
1029 void RemoveCollisionSphere(int32 Index);
1031 void ClearCollisionSpheres();
1033 void SetCollisionSpheres(
const TArray<FRuntimeMeshCollisionSphere>& NewSpheres);
1038 void RemoveCollisionCapsule(int32 Index);
1040 void ClearCollisionCapsules();
1042 void SetCollisionCapsules(
const TArray<FRuntimeMeshCollisionCapsule>& NewCapsules);
1045 FBoxSphereBounds GetLocalBounds()
const;
1051 void Setup(TWeakObjectPtr<URuntimeMesh> InParentMeshObject);
1057 template<
typename TangentType,
typename UVType,
typename IndexType>
1062 bool bHighPrecisionUVs;
1064 GetUVVertexProperties<UVType>(bHighPrecisionUVs, NumUVs);
1069 FRuntimeMeshSectionPtr CreateOrResetSection(int32 SectionId,
bool bInUseHighPrecisionTangents,
bool bInUseHighPrecisionUVs,
1073 bool bHighPrecisionTangents,
bool bHighPrecisionUVs,
EUpdateFrequency UpdateFrequency);
1085 void UpdateSectionPropertiesInternal(int32 SectionIndex,
bool bUpdateRequiresProxyRecreateIfStatic);
1088 void UpdateLocalBounds();
1092 TSharedPtr<const FRuntimeMeshAccessor> GetReadonlyMeshAccessor(int32 SectionId);
1096 bool ContainsPhysicsTriMeshData(
bool InUseAllTriData)
const;
1097 bool GetPhysicsTriMeshData(
struct FTriMeshCollisionData* CollisionData,
bool InUseAllTriData);
1098 void CopyCollisionElementsToBodySetup(UBodySetup* Setup);
1099 void MarkCollisionDirty(
bool bSkipChangedFlag =
false);
1101 void MarkRenderStateDirty();
1102 void SendSectionPropertiesUpdate(int32 SectionIndex);
1104 int32 GetSectionFromCollisionFaceIndex(int32 FaceIndex)
const;
1106 int32 GetSectionAndFaceFromCollisionFaceIndex(int32 & FaceIndex)
const;
1109 void DoOnGameThread(FRuntimeMeshGameThreadTaskDelegate Func);
1116 SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_SerializationOperator);
FRuntimeMeshSectionPtr CreateOrResetSection(int32 SectionId, EUpdateFrequency UpdateFrequency)
void SetSectionTessellationTriangles(int32 SectionId, const TArray< IndexType > &Triangles)
TArray< FRuntimeMeshCollisionBox > CollisionBoxes
void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, const FBox &BoundingBox, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, const FBox &BoundingBox, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSectionPrimaryBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void CheckUpdateLegacy(int32 SectionIndex, bool bShouldCheckIndexType=true) const
void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSectionTertiaryBuffer(int32 SectionId, TArray< VertexType2 > &InVertices2, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FRuntimeMeshProxyPtr GetRenderProxy() const
TArray< FRuntimeMeshSectionPtr > MeshSections
std::ostream & operator<<(std::ostream &os, const textual_icon &i)
DECLARE_DELEGATE_OneParam(FRuntimeMeshGameThreadTaskDelegate, URuntimeMesh *)
FRuntimeMeshProxyPtr RenderProxy
TSharedPtr< FRuntimeMeshData, ESPMode::ThreadSafe > FRuntimeMeshDataPtr
TSharedRef< FRuntimeMeshData, ESPMode::ThreadSafe > FRuntimeMeshDataRef
void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TWeakObjectPtr< URuntimeMesh > ParentMeshObject
void CreateMeshSectionTripleBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TArray< FRuntimeMeshCollisionCapsule > CollisionCapsules
void CreateMeshSectionDualBuffer(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, TArray< IndexType > &InTriangles, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void CheckCreateLegacy() const
void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void CreateMeshSection(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TArray< FRuntimeMeshCollisionSphere > CollisionSpheres
TMap< int32, FRuntimeMeshCollisionConvexMesh > ConvexCollisionSections
TSharedPtr< FRuntimeMeshProxy, ESPMode::ThreadSafe > FRuntimeMeshProxyPtr
void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< IndexType > &InTriangles, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void CheckUpdate(int32 SectionIndex, bool bShouldCheckIndexType, bool bCheckTangentVertexStream, bool bCheckUVVertexStream) const
void UpdateMeshSectionDualBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TMap< int32, FRuntimeMeshCollisionSection > MeshCollisionSections
void UpdateMeshSectionPrimaryBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
ERuntimeMeshBuffersToUpdate
void UpdateMeshSectionTriangles(int32 SectionId, TArray< IndexType > &InTriangles, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray< VertexType0 > &InVertices0, TArray< VertexType1 > &InVertices1, TArray< VertexType2 > &InVertices2, const FBox &BoundingBox, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
TSharedPtr< FRuntimeMeshSection, ESPMode::ThreadSafe > FRuntimeMeshSectionPtr
FRuntimeMeshSectionPtr GetSection(int32 SectionIndex)
DECLARE_CYCLE_STAT(TEXT("RM - Create Mesh Section - No Data"), STAT_RuntimeMesh_CreateMeshSection_NoData, STATGROUP_RuntimeMesh)
TUniquePtr< FRuntimeMeshLockProvider > SyncRoot
void UpdateMeshSectionSecondaryBuffer(int32 SectionId, TArray< VertexType1 > &InVertices1, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
void CreateMeshSection(int32 SectionIndex, TArray< VertexType0 > &InVertices0, TArray< IndexType > &InTriangles, const FBox &BoundingBox, bool bCreateCollision=false, EUpdateFrequency UpdateFrequency=EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
FBoxSphereBounds LocalBounds