RuntimeMeshData.h
Go to the documentation of this file.
1 // Copyright 2016-2018 Chris Conway (Koderz). All Rights Reserved.
2 
3 #pragma once
4 
5 #include "CoreMinimal.h"
6 #include "RuntimeMeshCore.h"
7 #include "RuntimeMeshCollision.h"
8 #include "RuntimeMeshSection.h"
9 #include "RuntimeMeshBlueprint.h"
10 
11 class URuntimeMesh;
12 class FRuntimeMeshProxy;
14 
15 using FRuntimeMeshProxyPtr = TSharedPtr<FRuntimeMeshProxy, ESPMode::ThreadSafe>;
16 
17 DECLARE_DELEGATE_OneParam(FRuntimeMeshGameThreadTaskDelegate, URuntimeMesh*);
18 
19 
20 
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);
24 
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);
31 
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);
36 
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);
41 
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);
46 
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);
52 
53 DECLARE_CYCLE_STAT(TEXT("RM - Set Section Tessellation Triangles"), STAT_RuntimeMesh_SetSectionTessellationTriangles, STATGROUP_RuntimeMesh);
54 
55 DECLARE_CYCLE_STAT(TEXT("RM - Serialize Data"), STAT_RuntimeMesh_SerializationOperator, STATGROUP_RuntimeMesh);
56 
57 
61 class RUNTIMEMESHCOMPONENT_API FRuntimeMeshData : public TSharedFromThis<FRuntimeMeshData, ESPMode::ThreadSafe>
62 {
64  TArray<FRuntimeMeshSectionPtr> MeshSections;
65 
66  /* Array of collision only mesh sections*/
67  TMap<int32, FRuntimeMeshCollisionSection> MeshCollisionSections;
68 
70  TMap<int32, FRuntimeMeshCollisionConvexMesh> ConvexCollisionSections;
71 
72  TArray<FRuntimeMeshCollisionBox> CollisionBoxes;
73  TArray<FRuntimeMeshCollisionSphere> CollisionSpheres;
74  TArray<FRuntimeMeshCollisionCapsule> CollisionCapsules;
75 
77  FBoxSphereBounds LocalBounds;
78 
80  TWeakObjectPtr<URuntimeMesh> ParentMeshObject;
81 
84 
85  TUniquePtr<FRuntimeMeshLockProvider> SyncRoot;
86 
87 public:
90 
91 private:
92  void CheckCreate(int32 NumUVs, bool bIndexIsValid) const;
93 
94  void CheckCreateLegacyInternal(const FRuntimeMeshVertexStreamStructure& Stream0Structure, const FRuntimeMeshVertexStreamStructure& Stream1Structure, const FRuntimeMeshVertexStreamStructure& Stream2Structure, bool bIsIndexValid) const;
95 
96  template<typename VertexType0, typename VertexType1, typename VertexType2, typename IndexType>
97  void CheckCreateLegacy() const
98  {
99  CheckCreateLegacyInternal(GetStreamStructure<VertexType0>(), GetStreamStructure<VertexType1>(), GetStreamStructure<VertexType2>(), FRuntimeMeshIndexTraits<IndexType>::IsValidIndexType);
100  }
101 
102  void CheckUpdate(bool bUseHighPrecisionTangents, bool bUseHighPrecisionUVs, int32 NumUVs, bool b32BitIndices, int32 SectionIndex, bool bShouldCheckIndexType,
103  bool bCheckTangentVertexStream, bool bCheckUVVertexStream) const;
104 
105  template<typename TangentType, typename UVType, typename IndexType>
106  void CheckUpdate(int32 SectionIndex, bool bShouldCheckIndexType, bool bCheckTangentVertexStream, bool bCheckUVVertexStream) const
107  {
108 #if DO_CHECK
109  bool UVsAreHighPrecision;
110  int32 NumUVs;
111  GetUVVertexProperties<UVType>(UVsAreHighPrecision, NumUVs);
112  CheckUpdate(GetTangentIsHighPrecision<TangentType>(), UVsAreHighPrecision, NumUVs, FRuntimeMeshIndexTraits<IndexType>::Is32Bit, SectionIndex, bShouldCheckIndexType, bCheckTangentVertexStream, bCheckUVVertexStream);
113 #endif
114  }
115 
116  template<typename VertexType0, typename VertexType1, typename VertexType2, typename IndexType>
117  void CheckUpdateLegacy(int32 SectionIndex, bool bShouldCheckIndexType = true) const
118  {
119  }
120 
121  void CheckBoundingBox(const FBox& Box) const;
122 
123 public:
124 
125  /*
126  This will put the RuntimeMesh into serialized mode where it becomes safe to access it from other threads.
127  Don't do this if you don't need it as it will make interacting with it slighly slower as it incurs thread locks.
128  */
129  void EnterSerializedMode();
130 
131 
132  void CreateMeshSection(int32 SectionIndex, bool bWantsHighPrecisionTangents, bool bWantsHighPrecisionUVs, int32 NumUVs, bool bWants32BitIndices, bool bCreateCollision, EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average);
133 
134  template<typename VertexType0, typename IndexType>
135  void CreateMeshSection(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles, bool bCreateCollision = false,
136  EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
137  {
138  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSection);
139 
140  FRuntimeMeshScopeLock Lock(SyncRoot);
141 
142  CheckCreateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>();
143 
144  bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0>();
145  bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0>();
146  int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0>();
147  bool bUsing32BitIndices = FRuntimeMeshIndexTraits<IndexType>::Is32Bit;
148 
149  CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
150 
151  auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
152 
153  Mesh->EmptyVertices(InVertices0.Num());
154 
155  // Copy the mesh data to the mesh builder
156  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
157  {
158  Mesh->AddVertexByProperties<VertexType0>(InVertices0[Index]);
159  }
160 
161  Mesh->EmptyIndices(InTriangles.Num());
162 
163  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
164  {
165  Mesh->AddIndex(InTriangles[Index]);
166  }
167 
168  Mesh->Commit();
169  }
170 
171  template<typename VertexType0, typename IndexType>
172  void CreateMeshSection(int32 SectionIndex, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles, const FBox& BoundingBox,
173  bool bCreateCollision = false, EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
174  {
175  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSection_BoundingBox);
176 
177  FRuntimeMeshScopeLock Lock(SyncRoot);
178 
179  CheckCreateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>();
180 
181  bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0>();
182  bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0>();
183  int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0>();
184  bool bUsing32BitIndices = FRuntimeMeshIndexTraits<IndexType>::Is32Bit;
185 
186  CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
187 
188  auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
189 
190  Mesh->EmptyVertices(InVertices0.Num());
191 
192  // Copy the mesh data to the mesh builder
193  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
194  {
195  Mesh->AddVertexByProperties<VertexType0>(InVertices0[Index]);
196  }
197 
198  Mesh->EmptyIndices(InTriangles.Num());
199 
200  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
201  {
202  Mesh->AddIndex(InTriangles[Index]);
203  }
204 
205  Mesh->Commit(BoundingBox);
206  }
207 
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,
210  EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
211  {
212  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionDualBuffer);
213 
214  FRuntimeMeshScopeLock Lock(SyncRoot);
215 
216  CheckCreateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>();
217 
218  bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1>();
219  bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1>();
220  int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1>();
221  bool bUsing32BitIndices = FRuntimeMeshIndexTraits<IndexType>::Is32Bit;
222 
223  CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
224 
225  auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
226 
227  Mesh->EmptyVertices(InVertices0.Num());
228 
229  // Copy the mesh data to the mesh builder
230  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
231  {
232  Mesh->AddVertexByProperties<VertexType0, VertexType1>(InVertices0[Index], InVertices1[Index]);
233  }
234 
235  Mesh->EmptyIndices(InTriangles.Num());
236 
237  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
238  {
239  Mesh->AddIndex(InTriangles[Index]);
240  }
241 
242  Mesh->Commit();
243  }
244 
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,
247  bool bCreateCollision = false, EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
248  {
249  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionDualBuffer_BoundingBox);
250 
251  FRuntimeMeshScopeLock Lock(SyncRoot);
252 
253  CheckCreateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>();
254 
255  bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1>();
256  bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1>();
257  int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1>();
258  bool bUsing32BitIndices = FRuntimeMeshIndexTraits<IndexType>::Is32Bit;
259 
260  CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
261 
262  auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
263 
264  Mesh->EmptyVertices(InVertices0.Num());
265 
266  // Copy the mesh data to the mesh builder
267  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
268  {
269  Mesh->AddVertexByProperties<VertexType0, VertexType1>(InVertices0[Index], InVertices1[Index]);
270  }
271 
272  Mesh->EmptyIndices(InTriangles.Num());
273 
274  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
275  {
276  Mesh->AddIndex(InTriangles[Index]);
277  }
278 
279  Mesh->Commit(BoundingBox);
280  }
281 
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,
284  bool bCreateCollision = false, EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
285  {
286  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionTripleBuffer);
287 
288  FRuntimeMeshScopeLock Lock(SyncRoot);
289 
290  CheckCreateLegacy<VertexType0, VertexType1, VertexType2, IndexType>();
291 
292  bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1, VertexType2>();
293  bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1, VertexType2>();
294  int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1, VertexType2>();
295  bool bUsing32BitIndices = FRuntimeMeshIndexTraits<IndexType>::Is32Bit;
296 
297  CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
298 
299  auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
300 
301  Mesh->EmptyVertices(InVertices0.Num());
302 
303  // Copy the mesh data to the mesh builder
304  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
305  {
306  Mesh->AddVertexByProperties<VertexType0, VertexType1, VertexType2>(InVertices0[Index], InVertices1[Index], InVertices2[Index]);
307  }
308 
309  Mesh->EmptyIndices(InTriangles.Num());
310 
311  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
312  {
313  Mesh->AddIndex(InTriangles[Index]);
314  }
315 
316  Mesh->Commit();
317  }
318 
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,
321  const FBox& BoundingBox, bool bCreateCollision = false, EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
322  {
323  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_CreateMeshSectionTripleBuffer_BoundingBox);
324 
325  FRuntimeMeshScopeLock Lock(SyncRoot);
326 
327  CheckCreateLegacy<VertexType0, VertexType1, VertexType2, IndexType>();
328 
329  bool bWantsHighPrecisionTangents = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionTangents<VertexType0, VertexType1, VertexType2>();
330  bool bWantsHighPrecisionUVs = FRuntimeMeshVertexTypeTraitsAggregator::IsUsingHighPrecisionUVs<VertexType0, VertexType1, VertexType2>();
331  int32 NumUVs = FRuntimeMeshVertexTypeTraitsAggregator::NumUVs<VertexType0, VertexType1, VertexType2>();
332  bool bUsing32BitIndices = FRuntimeMeshIndexTraits<IndexType>::Is32Bit;
333 
334  CreateMeshSection(SectionIndex, bWantsHighPrecisionTangents, bWantsHighPrecisionUVs, NumUVs, bUsing32BitIndices, bCreateCollision, UpdateFrequency);
335 
336  auto Mesh = BeginSectionUpdate(SectionIndex, UpdateFlags);
337 
338  Mesh->EmptyVertices(InVertices0.Num());
339 
340  // Copy the mesh data to the mesh builder
341  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
342  {
343  Mesh->AddVertexByProperties<VertexType0, VertexType1, VertexType2>(InVertices0[Index], InVertices1[Index], InVertices2[Index]);
344  }
345 
346  Mesh->EmptyIndices(InTriangles.Num());
347 
348  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
349  {
350  Mesh->AddIndex(InTriangles[Index]);
351  }
352 
353  Mesh->Commit(BoundingBox);
354  }
355 
356 
357 
358  template<typename VertexType0>
359  void UpdateMeshSection(int32 SectionId, TArray<VertexType0>& InVertices0, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
360  {
361  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection_NoTriangles);
362 
363  FRuntimeMeshScopeLock Lock(SyncRoot);
364 
365  CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId, false);
366 
367  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
368 
369  Mesh->SetNumVertices(InVertices0.Num());
370 
371  // Copy the mesh data to the mesh builder
372  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
373  {
374  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
375  }
376 
377  Mesh->Commit();
378  }
379 
380  template<typename VertexType0>
381  void UpdateMeshSection(int32 SectionId, TArray<VertexType0>& InVertices0, const FBox& BoundingBox, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
382  {
383  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection_NoTriangles_BoundingBox);
384 
385  FRuntimeMeshScopeLock Lock(SyncRoot);
386 
387  CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId, false);
388  CheckBoundingBox(BoundingBox);
389 
390  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
391 
392  Mesh->SetNumVertices(InVertices0.Num());
393 
394  // Copy the mesh data to the mesh builder
395  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
396  {
397  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
398  }
399 
400  Mesh->Commit(BoundingBox);
401  }
402 
403  template<typename VertexType0, typename IndexType>
404  void UpdateMeshSection(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
405  {
406  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection);
407 
408  FRuntimeMeshScopeLock Lock(SyncRoot);
409 
410  CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>(SectionId, true);
411 
412  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
413 
414  Mesh->SetNumVertices(InVertices0.Num());
415 
416  // Copy the mesh data to the mesh builder
417  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
418  {
419  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
420  }
421 
422  Mesh->SetNumIndices(InTriangles.Num());
423 
424  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
425  {
426  Mesh->SetIndex(Index, InTriangles[Index]);
427  }
428 
429  Mesh->Commit();
430  }
431 
432  template<typename VertexType0, typename IndexType>
433  void UpdateMeshSection(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<IndexType>& InTriangles,
434  const FBox& BoundingBox, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
435  {
436  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSection_BoundingBox);
437 
438  FRuntimeMeshScopeLock Lock(SyncRoot);
439 
440  CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>(SectionId, true);
441  CheckBoundingBox(BoundingBox);
442 
443  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
444 
445  Mesh->SetNumVertices(InVertices0.Num());
446 
447  // Copy the mesh data to the mesh builder
448  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
449  {
450  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
451  }
452 
453  Mesh->SetNumIndices(InTriangles.Num());
454 
455  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
456  {
457  Mesh->SetIndex(Index, InTriangles[Index]);
458  }
459 
460  Mesh->Commit(BoundingBox);
461  }
462 
463  template<typename VertexType0, typename VertexType1>
464  void UpdateMeshSectionDualBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1,
466  {
467  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_NoTriangles);
468 
469  FRuntimeMeshScopeLock Lock(SyncRoot);
470 
471  CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, uint16>(SectionId, false);
472 
473  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
474 
475  Mesh->SetNumVertices(InVertices0.Num());
476 
477  // Copy the mesh data to the mesh builder
478  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
479  {
480  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
481  if (InVertices1.Num() > Index)
482  {
483  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
484  }
485  }
486 
487  Mesh->Commit();
488  }
489 
490  template<typename VertexType0, typename VertexType1>
491  void UpdateMeshSectionDualBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1,
492  const FBox& BoundingBox, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
493  {
494  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_NoTriangles_BoundingBox);
495 
496  FRuntimeMeshScopeLock Lock(SyncRoot);
497 
498  CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, uint16>(SectionId, false);
499  CheckBoundingBox(BoundingBox);
500 
501  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
502 
503  Mesh->SetNumVertices(InVertices0.Num());
504 
505  // Copy the mesh data to the mesh builder
506  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
507  {
508  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
509  if (InVertices1.Num() > Index)
510  {
511  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
512  }
513  }
514 
515  Mesh->Commit(BoundingBox);
516  }
517 
518  template<typename VertexType0, typename VertexType1, typename IndexType>
519  void UpdateMeshSectionDualBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1,
520  TArray<IndexType>& InTriangles, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
521  {
522  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer);
523 
524  FRuntimeMeshScopeLock Lock(SyncRoot);
525 
526  CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>(SectionId, true);
527 
528  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
529 
530  Mesh->SetNumVertices(InVertices0.Num());
531 
532  // Copy the mesh data to the mesh builder
533  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
534  {
535  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
536  if (InVertices1.Num() > Index)
537  {
538  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
539  }
540  }
541 
542  Mesh->SetNumIndices(InTriangles.Num());
543 
544  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
545  {
546  Mesh->SetIndex(Index, InTriangles[Index]);
547  }
548 
549  Mesh->Commit();
550  }
551 
552  template<typename VertexType0, typename VertexType1, typename IndexType>
553  void UpdateMeshSectionDualBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<IndexType>& InTriangles,
554  const FBox& BoundingBox, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
555  {
556  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionDualBuffer_BoundingBox);
557 
558  FRuntimeMeshScopeLock Lock(SyncRoot);
559 
560  CheckUpdateLegacy<VertexType0, VertexType1, FRuntimeMeshNullVertex, IndexType>(SectionId, true);
561  CheckBoundingBox(BoundingBox);
562 
563  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
564 
565  Mesh->SetNumVertices(InVertices0.Num());
566 
567  // Copy the mesh data to the mesh builder
568  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
569  {
570  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
571  if (InVertices1.Num() > Index)
572  {
573  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
574  }
575  }
576 
577  Mesh->SetNumIndices(InTriangles.Num());
578 
579  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
580  {
581  Mesh->SetIndex(Index, InTriangles[Index]);
582  }
583 
584  Mesh->Commit(BoundingBox);
585  }
586 
587  template<typename VertexType0, typename VertexType1, typename VertexType2>
588  void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
590  {
591  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_NoTriangles);
592 
593  FRuntimeMeshScopeLock Lock(SyncRoot);
594 
595  CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, uint16>(SectionId, false);
596 
597  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
598 
599  Mesh->SetNumVertices(InVertices0.Num());
600 
601  // Copy the mesh data to the mesh builder
602  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
603  {
604  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
605  if (InVertices1.Num() > Index)
606  {
607  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
608  }
609  if (InVertices2.Num() > Index)
610  {
611  Mesh->SetVertexProperties<VertexType2>(Index, InVertices2[Index]);
612  }
613  }
614 
615  Mesh->Commit();
616  }
617 
618  template<typename VertexType0, typename VertexType1, typename VertexType2>
619  void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
620  const FBox& BoundingBox, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
621  {
622  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_NoTriangles_BoundingBox);
623 
624  FRuntimeMeshScopeLock Lock(SyncRoot);
625 
626  CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, uint16>(SectionId, false);
627  CheckBoundingBox(BoundingBox);
628 
629  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
630 
631  Mesh->SetNumVertices(InVertices0.Num());
632 
633  // Copy the mesh data to the mesh builder
634  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
635  {
636  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
637  if (InVertices1.Num() > Index)
638  {
639  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
640  }
641  if (InVertices2.Num() > Index)
642  {
643  Mesh->SetVertexProperties<VertexType2>(Index, InVertices2[Index]);
644  }
645  }
646 
647  Mesh->Commit(BoundingBox);
648  }
649 
650  template<typename VertexType0, typename VertexType1, typename VertexType2, typename IndexType>
651  void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
652  TArray<IndexType>& InTriangles, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
653  {
654  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer);
655 
656  FRuntimeMeshScopeLock Lock(SyncRoot);
657 
658  CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, IndexType>(SectionId, true);
659 
660  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
661 
662  Mesh->SetNumVertices(InVertices0.Num());
663 
664  // Copy the mesh data to the mesh builder
665  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
666  {
667  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
668  if (InVertices1.Num() > Index)
669  {
670  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
671  }
672  if (InVertices2.Num() > Index)
673  {
674  Mesh->SetVertexProperties<VertexType2>(Index, InVertices2[Index]);
675  }
676  }
677 
678  Mesh->SetNumIndices(InTriangles.Num());
679 
680  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
681  {
682  Mesh->SetIndex(Index, InTriangles[Index]);
683  }
684 
685  Mesh->Commit();
686  }
687 
688  template<typename VertexType0, typename VertexType1, typename VertexType2, typename IndexType>
689  void UpdateMeshSectionTripleBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, TArray<VertexType1>& InVertices1, TArray<VertexType2>& InVertices2,
690  TArray<IndexType>& InTriangles, const FBox& BoundingBox, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
691  {
692  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTripleBuffer_BoundingBox);
693 
694  FRuntimeMeshScopeLock Lock(SyncRoot);
695 
696  CheckUpdateLegacy<VertexType0, VertexType1, VertexType2, IndexType>(SectionId, true);
697  CheckBoundingBox(BoundingBox);
698 
699  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
700 
701  Mesh->SetNumVertices(InVertices0.Num());
702 
703  // Copy the mesh data to the mesh builder
704  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
705  {
706  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
707  if (InVertices1.Num() > Index)
708  {
709  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
710  }
711  if (InVertices2.Num() > Index)
712  {
713  Mesh->SetVertexProperties<VertexType2>(Index, InVertices2[Index]);
714  }
715  }
716 
717  Mesh->SetNumIndices(InTriangles.Num());
718 
719  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
720  {
721  Mesh->SetIndex(Index, InTriangles[Index]);
722  }
723 
724  Mesh->Commit(BoundingBox);
725  }
726 
727 
728 
729  template<typename VertexType0>
730  void UpdateMeshSectionPrimaryBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
731  {
732  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionPrimaryBuffer);
733 
734  FRuntimeMeshScopeLock Lock(SyncRoot);
735 
736  CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId, false);
737 
738  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
739 
740  Mesh->SetNumVertices(InVertices0.Num());
741 
742  // Copy the mesh data to the mesh builder
743  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
744  {
745  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
746  }
747 
748  Mesh->Commit();
749  }
750 
751  template<typename VertexType0>
752  void UpdateMeshSectionPrimaryBuffer(int32 SectionId, TArray<VertexType0>& InVertices0, const FBox& BoundingBox, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
753  {
754  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionPrimaryBuffer_BoundingBox);
755 
756  FRuntimeMeshScopeLock Lock(SyncRoot);
757 
758  CheckUpdateLegacy<VertexType0, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, uint16>(SectionId, false);
759  CheckBoundingBox(BoundingBox);
760 
761  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
762 
763  Mesh->SetNumVertices(InVertices0.Num());
764 
765  // Copy the mesh data to the mesh builder
766  for (int32 Index = 0; Index < InVertices0.Num(); Index++)
767  {
768  Mesh->SetVertexProperties<VertexType0>(Index, InVertices0[Index]);
769  }
770 
771  Mesh->Commit(BoundingBox);
772  }
773 
774  template<typename VertexType1>
775  void UpdateMeshSectionSecondaryBuffer(int32 SectionId, TArray<VertexType1>& InVertices1, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
776  {
777  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionSecondaryBuffer);
778 
779  FRuntimeMeshScopeLock Lock(SyncRoot);
780 
781  CheckUpdateLegacy<FRuntimeMeshNullVertex, VertexType1, FRuntimeMeshNullVertex, uint16>(SectionId, false);
782 
783  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
784 
785  int32 NumVerts = FMath::Min(Mesh->NumVertices(), InVertices1.Num());
786 
787  // Copy the mesh data to the mesh builder
788  for (int32 Index = 0; Index < NumVerts; Index++)
789  {
790  Mesh->SetVertexProperties<VertexType1>(Index, InVertices1[Index]);
791  }
792 
793  Mesh->Commit();
794  }
795 
796  template<typename VertexType2>
797  void UpdateMeshSectionTertiaryBuffer(int32 SectionId, TArray<VertexType2>& InVertices2, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
798  {
799  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTertiaryBuffer);
800 
801  FRuntimeMeshScopeLock Lock(SyncRoot);
802 
803  CheckUpdateLegacy<FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, VertexType2, uint16>(SectionId, false);
804 
805  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
806 
807  int32 NumVerts = FMath::Min(Mesh->NumVertices(), InVertices2.Num());
808 
809  // Copy the mesh data to the mesh builder
810  for (int32 Index = 0; Index < NumVerts; Index++)
811  {
812  Mesh->SetVertexProperties<VertexType2>(Index, InVertices2[Index]);
813  }
814 
815  Mesh->Commit();
816  }
817 
818  template<typename IndexType>
819  void UpdateMeshSectionTriangles(int32 SectionId, TArray<IndexType>& InTriangles, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None)
820  {
821  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_UpdateMeshSectionTriangles);
822 
823  FRuntimeMeshScopeLock Lock(SyncRoot);
824 
825  CheckUpdateLegacy<FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, FRuntimeMeshNullVertex, IndexType>(SectionId, true);
826 
827  auto Mesh = BeginSectionUpdate(SectionId, UpdateFlags);
828 
829  Mesh->SetNumIndices(InTriangles.Num());
830 
831  for (int32 Index = 0; Index < InTriangles.Num(); Index++)
832  {
833  Mesh->SetIndex(Index, InTriangles[Index]);
834  }
835 
836  Mesh->Commit();
837  }
838 
839 
840 
841  void CreateMeshSection(int32 SectionId, const TSharedPtr<FRuntimeMeshBuilder>& MeshData, bool bCreateCollision = false,
842  EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
843 
844  void CreateMeshSectionByMove(int32 SectionId, const TSharedPtr<FRuntimeMeshBuilder>& MeshData, bool bCreateCollision = false,
845  EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
846 
847 
848 
849  void UpdateMeshSection(int32 SectionId, const TSharedPtr<FRuntimeMeshBuilder>& MeshData, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
850 
851  void UpdateMeshSectionByMove(int32 SectionId, const TSharedPtr<FRuntimeMeshBuilder>& MeshData, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
852 
853 
854 
855 
856 
857  TUniquePtr<FRuntimeMeshScopedUpdater> BeginSectionUpdate(int32 SectionId, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
858 
859  TUniquePtr<FRuntimeMeshScopedUpdater> GetSectionReadonly(int32 SectionId);
860 
861 
862 private:
863  void EndSectionUpdate(FRuntimeMeshScopedUpdater* Updater, ERuntimeMeshBuffersToUpdate BuffersToUpdate, const FBox* BoundingBox = nullptr);
864 
865 
866 private:
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,
869  bool bCreateCollision, EUpdateFrequency UpdateFrequency, ESectionUpdateFlags UpdateFlags, bool bUseHighPrecisionTangents, bool bUseHighPrecisionUVs, bool bWantsSecondUV);
870 
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);
873 
874 public:
875 
876  // HORU :)
877  void UpdateMeshSectionColors(int32 SectionIndex, TArray<FColor>& Colors, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
878 
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,
881  EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None,
882  bool bUseHighPrecisionTangents = false, bool bUseHighPrecisionUVs = true);
883 
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,
886  bool bCreateCollision = false, EUpdateFrequency UpdateFrequency = EUpdateFrequency::Average, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None,
887  bool bUseHighPrecisionTangents = false, bool bUseHighPrecisionUVs = true);
888 
889 
890  void UpdateMeshSection(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<FVector>& Normals, const TArray<FVector2D>& UV0,
891  const TArray<FColor>& Colors, const TArray<FRuntimeMeshTangent>& Tangents, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
892 
893  void UpdateMeshSection(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<FVector>& Normals, const TArray<FVector2D>& UV0,
894  const TArray<FVector2D>& UV1, const TArray<FColor>& Colors, const TArray<FRuntimeMeshTangent>& Tangents, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
895 
896  void UpdateMeshSection(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles, const TArray<FVector>& Normals,
897  const TArray<FVector2D>& UV0, const TArray<FColor>& Colors, const TArray<FRuntimeMeshTangent>& Tangents, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
898 
899  void UpdateMeshSection(int32 SectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles, const TArray<FVector>& Normals,
900  const TArray<FVector2D>& UV0, const TArray<FVector2D>& UV1, const TArray<FColor>& Colors, const TArray<FRuntimeMeshTangent>& Tangents, ESectionUpdateFlags UpdateFlags = ESectionUpdateFlags::None);
901 
902 
903 
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);
908 
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);
912 
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);
916 
917  void UpdateMeshSectionPacked_Blueprint(int32 SectionIndex, const TArray<FRuntimeMeshBlueprintVertexSimple>& Vertices, const TArray<int32>& Triangles,
918  bool bCalculateNormalTangent = false, bool bShouldCreateHardTangents = false, bool bGenerateTessellationTriangles = false);
919 
920 
921 
922 
923 
924 
925 
926  template<typename IndexType>
927  void SetSectionTessellationTriangles(int32 SectionId, const TArray<IndexType>& Triangles)
928  {
929  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_SetSectionTessellationTriangles);
930 
931  FRuntimeMeshScopeLock Lock(SyncRoot);
932  CheckUpdate(false, false, 0, FRuntimeMeshIndexTraits<IndexType>::Is32Bit, SectionId, true, false, false);
933 
934  FRuntimeMeshSectionPtr Section = MeshSections[SectionId];
935 
937 
938  // Update indices if supplied
939  if (Triangles.Num() > 0)
940  {
941  Section->UpdateAdjacencyIndexBuffer(Triangles);
943  }
944 
945  // Finalize section update if we have anything to apply
946  if (BuffersToUpdate != ERuntimeMeshBuffersToUpdate::None)
947  {
948  UpdateSectionInternal(SectionId, BuffersToUpdate, ESectionUpdateFlags::None);
949  }
950  }
951 
953  void ClearMeshSection(int32 SectionIndex);
954 
956  void ClearAllMeshSections();
957 
958 
959 
961  FBox GetSectionBoundingBox(int32 SectionIndex);
962 
964  void SetMeshSectionVisible(int32 SectionIndex, bool bNewVisibility);
965 
967  bool IsMeshSectionVisible(int32 SectionIndex) const;
968 
969 
971  void SetMeshSectionCastsShadow(int32 SectionIndex, bool bNewCastsShadow);
972 
974  bool IsMeshSectionCastingShadows(int32 SectionIndex) const;
975 
976 
978  void SetMeshSectionCollisionEnabled(int32 SectionIndex, bool bNewCollisionEnabled);
979 
981  bool IsMeshSectionCollisionEnabled(int32 SectionIndex);
982 
983 
985  int32 GetNumSections() const;
986 
988  bool DoesSectionExist(int32 SectionIndex) const;
989 
991  int32 GetAvailableSectionIndex() const;
992 
993  int32 GetLastSectionIndex() const;
994 
995 
996  TArray<int32> GetSectionIds() const;
997 
998 
999  void SetMeshCollisionSection(int32 CollisionSectionIndex, const TArray<FVector>& Vertices, const TArray<int32>& Triangles);
1000 
1001  void ClearMeshCollisionSection(int32 CollisionSectionIndex);
1002 
1003  void ClearAllMeshCollisionSections();
1004 
1005 
1006 
1007  int32 AddConvexCollisionSection(TArray<FVector> ConvexVerts);
1008 
1009  void SetConvexCollisionSection(int32 ConvexSectionIndex, TArray<FVector> ConvexVerts);
1010 
1011  void RemoveConvexCollisionSection(int32 ConvexSectionIndex);
1012 
1013  void ClearConvexCollisionSections();
1014 
1015  void SetCollisionConvexMeshes(const TArray<TArray<FVector>>& ConvexMeshes);
1016 
1017 
1018  int32 AddCollisionBox(const FRuntimeMeshCollisionBox& NewBox);
1019 
1020  void RemoveCollisionBox(int32 Index);
1021 
1022  void ClearCollisionBoxes();
1023 
1024  void SetCollisionBoxes(const TArray<FRuntimeMeshCollisionBox>& NewBoxes);
1025 
1026 
1027  int32 AddCollisionSphere(const FRuntimeMeshCollisionSphere& NewSphere);
1028 
1029  void RemoveCollisionSphere(int32 Index);
1030 
1031  void ClearCollisionSpheres();
1032 
1033  void SetCollisionSpheres(const TArray<FRuntimeMeshCollisionSphere>& NewSpheres);
1034 
1035 
1036  int32 AddCollisionCapsule(const FRuntimeMeshCollisionCapsule& NewCapsule);
1037 
1038  void RemoveCollisionCapsule(int32 Index);
1039 
1040  void ClearCollisionCapsules();
1041 
1042  void SetCollisionCapsules(const TArray<FRuntimeMeshCollisionCapsule>& NewCapsules);
1043 
1044 
1045  FBoxSphereBounds GetLocalBounds() const;
1046 
1047 private:
1048 
1049  FRuntimeMeshSectionPtr GetSection(int32 SectionIndex) { return MeshSections[SectionIndex]; }
1050 
1051  void Setup(TWeakObjectPtr<URuntimeMesh> InParentMeshObject);
1052 
1053  FRuntimeMeshProxyPtr GetRenderProxy() const { return RenderProxy; }
1054 
1055 
1056  /* Creates an mesh section of a specified type at the specified index. */
1057  template<typename TangentType, typename UVType, typename IndexType>
1059  {
1060  static_assert(FRuntimeMeshIndexTraits<IndexType>::IsValidIndexType, "Indices can only be of type uint16, uint32, or int32");
1061 
1062  bool bHighPrecisionUVs;
1063  int32 NumUVs;
1064  GetUVVertexProperties<UVType>(bHighPrecisionUVs, NumUVs);
1065 
1066  return CreateOrResetSection(SectionId, GetTangentIsHighPrecision<TangentType>(), bHighPrecisionUVs, NumUVs, FRuntimeMeshIndexTraits<IndexType>::Is32Bit, UpdateFrequency);
1067  }
1068 
1069  FRuntimeMeshSectionPtr CreateOrResetSection(int32 SectionId, bool bInUseHighPrecisionTangents, bool bInUseHighPrecisionUVs,
1070  int32 InNumUVs, bool b32BitIndices, EUpdateFrequency UpdateFrequency);
1071 
1072  FRuntimeMeshSectionPtr CreateOrResetSectionForBlueprint(int32 SectionId, bool bWantsSecondUV,
1073  bool bHighPrecisionTangents, bool bHighPrecisionUVs, EUpdateFrequency UpdateFrequency);
1074 
1075  /* Finishes creating a section, including entering it for batch updating, or updating the RT directly */
1076  void CreateSectionInternal(int32 SectionIndex, ESectionUpdateFlags UpdateFlags);
1077 
1078  /* Finishes updating a section, including entering it for batch updating, or updating the RT directly */
1079  void UpdateSectionInternal(int32 SectionIndex, ERuntimeMeshBuffersToUpdate BuffersToUpdate, ESectionUpdateFlags UpdateFlags);
1080 
1081  /* Handles things like automatic tessellation and tangent calculation that is common to both section creation and update. */
1082  void HandleCommonSectionUpdateFlags(int32 SectionIndex, ESectionUpdateFlags UpdateFlags, ERuntimeMeshBuffersToUpdate& BuffersToUpdate);
1083 
1084  /* Finishes updating a sections properties, like visible/casts shadow, a*/
1085  void UpdateSectionPropertiesInternal(int32 SectionIndex, bool bUpdateRequiresProxyRecreateIfStatic);
1086 
1088  void UpdateLocalBounds();
1089 
1090  FRuntimeMeshProxyPtr EnsureProxyCreated(ERHIFeatureLevel::Type InFeatureLevel);
1091 
1092  TSharedPtr<const FRuntimeMeshAccessor> GetReadonlyMeshAccessor(int32 SectionId);
1093 
1094  void Initialize();
1095 
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);
1100 
1101  void MarkRenderStateDirty();
1102  void SendSectionPropertiesUpdate(int32 SectionIndex);
1103 
1104  int32 GetSectionFromCollisionFaceIndex(int32 FaceIndex) const;
1105 
1106  int32 GetSectionAndFaceFromCollisionFaceIndex(int32 & FaceIndex) const;
1107 
1108 
1109  void DoOnGameThread(FRuntimeMeshGameThreadTaskDelegate Func);
1110 
1111  void MarkChanged();
1112 
1113 
1114  friend FArchive& operator <<(FArchive& Ar, FRuntimeMeshData& MeshData)
1115  {
1116  SCOPE_CYCLE_COUNTER(STAT_RuntimeMesh_SerializationOperator);
1117 
1118  FRuntimeMeshScopeLock Lock(MeshData.SyncRoot, false, true);
1119 
1120  Ar << MeshData.MeshSections;
1121 
1122  Ar << MeshData.MeshCollisionSections;
1123  Ar << MeshData.ConvexCollisionSections;
1124 
1125  Ar << MeshData.CollisionBoxes;
1126  Ar << MeshData.CollisionSpheres;
1127  Ar << MeshData.CollisionCapsules;
1128 
1129  // Update all state since we don't know what really changed (or this could be an initial load)
1130  if (Ar.IsLoading())
1131  {
1132  MeshData.UpdateLocalBounds();
1133  }
1134  return Ar;
1135  }
1136 
1137  friend class URuntimeMesh;
1139 };
1140 
1141 using FRuntimeMeshDataRef = TSharedRef<FRuntimeMeshData, ESPMode::ThreadSafe>;
1142 using FRuntimeMeshDataPtr = TSharedPtr<FRuntimeMeshData, ESPMode::ThreadSafe>;
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)
EUpdateFrequency
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)
Definition: model-views.h:118
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)
ESectionUpdateFlags
void UpdateMeshSection(int32 SectionId, TArray< VertexType0 > &InVertices0, ESectionUpdateFlags UpdateFlags=ESectionUpdateFlags::None)
struct Index Index
Definition: sqlite3.c:11789
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


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:41