RuntimeMeshSection.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 "Engine/Engine.h"
6 #include "RuntimeMeshCore.h"
7 #include "RuntimeMeshBuilder.h"
8 
9 enum class ERuntimeMeshBuffersToUpdate : uint8;
14 class UMaterialInterface;
15 
16 class RUNTIMEMESHCOMPONENT_API FRuntimeMeshSection
17 {
19  {
20  private:
21  const int32 Stride;
22  TArray<uint8> Data;
23  public:
24  FSectionVertexBuffer(int32 InStride) : Stride(InStride)
25  {
26 
27  }
28  virtual ~FSectionVertexBuffer() { }
29 
30  void SetData(TArray<uint8>& InVertices, bool bUseMove)
31  {
32  if (bUseMove)
33  {
34  Data = MoveTemp(InVertices);
35  }
36  else
37  {
38  Data = InVertices;
39  }
40  }
41 
42  template<typename VertexType>
43  void SetData(const TArray<VertexType>& InVertices)
44  {
45  if (InVertices.Num() == 0)
46  {
47  Data.Empty();
48  return;
49  }
50  check(InVertices.GetTypeSize() == GetStride());
51 
52  Data.SetNum(InVertices.GetTypeSize() * InVertices.Num());
53  FMemory::Memcpy(Data.GetData(), InVertices.GetData(), Data.Num());
54  }
55 
56  int32 GetStride() const
57  {
58  return Stride;
59  }
60 
61  int32 GetNumVertices() const
62  {
63  return Stride > 0 ? Data.Num() / Stride : 0;
64  }
65 
66  TArray<uint8>& GetData() { return Data; }
67 
68  void FillUpdateParams(FRuntimeMeshSectionVertexBufferParams& Params);
69 
70  friend FArchive& operator <<(FArchive& Ar, FSectionVertexBuffer& Buffer)
71  {
72  Buffer.Serialize(Ar);
73  return Ar;
74  }
75 
76  protected:
77  virtual void Serialize(FArchive& Ar)
78  {
80  {
81  FRuntimeMeshVertexStreamStructure VertexStructure;
82  Ar << const_cast<FRuntimeMeshVertexStreamStructure&>(VertexStructure);
83  }
84  Ar << const_cast<int32&>(Stride);
85  Ar << Data;
86  }
87  };
88 
90  {
92  : FSectionVertexBuffer(sizeof(FVector))
93  {
94 
95  }
96  };
97 
99  {
100  private:
102 
103  public:
104  FSectionTangentsVertexBuffer(bool bInUseHighPrecision)
105  : FSectionVertexBuffer(bInUseHighPrecision ? (sizeof(FPackedRGBA16N) * 2) : (sizeof(FPackedNormal) * 2))
106  , bUseHighPrecision(bInUseHighPrecision)
107  {
108 
109  }
110 
111  bool IsUsingHighPrecision() const { return bUseHighPrecision; }
112 
113  void FillUpdateParams(FRuntimeMeshSectionTangentVertexBufferParams& Params);
114 
115  virtual void Serialize(FArchive& Ar) override
116  {
118  {
119  Ar << bUseHighPrecision;
120  }
121  FSectionVertexBuffer::Serialize(Ar);
122  }
123  };
124 
126  {
127  private:
129  int32 UVCount;
130 
131  public:
132 
133  FSectionUVsVertexBuffer(bool bInUseHighPrecision, int32 InUVCount)
134  : FSectionVertexBuffer((bInUseHighPrecision ? sizeof(FVector2D) : sizeof(FVector2DHalf)) * InUVCount)
135  , bUseHighPrecision(bInUseHighPrecision), UVCount(InUVCount)
136  {
137 
138  }
139 
140  bool IsUsingHighPrecision() const { return bUseHighPrecision; }
141 
142  int32 NumUVs() const { return UVCount; }
143 
144  void FillUpdateParams(FRuntimeMeshSectionUVVertexBufferParams& Params);
145 
146  virtual void Serialize(FArchive& Ar) override
147  {
149  {
150  Ar << bUseHighPrecision;
151  Ar << UVCount;
152  }
153  FSectionVertexBuffer::Serialize(Ar);
154  }
155  };
156 
158  {
160  : FSectionVertexBuffer(sizeof(FColor))
161  {
162 
163  }
164  };
165 
167  {
168  private:
169  const bool b32BitIndices;
170  TArray<uint8> Data;
171  public:
172  FSectionIndexBuffer(bool bIn32BitIndices)
173  : b32BitIndices(bIn32BitIndices)
174  {
175 
176  }
177 
178  void SetData(TArray<uint8>& InIndices, bool bUseMove)
179  {
180  if (bUseMove)
181  {
182  Data = MoveTemp(InIndices);
183  }
184  else
185  {
186  Data = InIndices;
187  }
188  }
189 
190  template<typename IndexType>
191  void SetData(const TArray<IndexType>& InIndices)
192  {
193  check(InIndices.GetTypeSize() == GetStride());
194 
195  Data.SetNum(InIndices.GetTypeSize() * InIndices.Num());
196  FMemory::Memcpy(Data.GetData(), InIndices.GetData(), Data.Num());
197  }
198 
199  int32 GetStride() const
200  {
201  return b32BitIndices ? 4 : 2;
202  }
203 
204  bool Is32BitIndices() const
205  {
206  return b32BitIndices;
207  }
208 
209  int32 GetNumIndices() const
210  {
211  return Data.Num() / GetStride();
212  }
213 
214  TArray<uint8>& GetData() { return Data; }
215 
216  void FillUpdateParams(FRuntimeMeshSectionIndexBufferParams& Params);
217 
218  friend FArchive& operator <<(FArchive& Ar, FSectionIndexBuffer& Buffer)
219  {
220  Ar << const_cast<bool&>(Buffer.b32BitIndices);
221  Ar << Buffer.Data;
222  return Ar;
223  }
224  };
225 
226 
228 
231 
234 
237 
240 
243 
245 
247 
249 
251 
252  // TUniquePtr<FRuntimeMeshLockProvider> SyncRoot;
253 public:
254  FRuntimeMeshSection(FArchive& Ar);
255  FRuntimeMeshSection(bool bInUseHighPrecisionTangents, bool bInUseHighPrecisionUVs, int32 InNumUVs, bool b32BitIndices, EUpdateFrequency InUpdateFrequency/*, FRuntimeMeshLockProvider* InSyncRoot*/);
256 
257  // void SetNewLockProvider(FRuntimeMeshLockProvider* NewSyncRoot)
258  // {
259  // SyncRoot.Reset(NewSyncRoot);
260  // }
261 
262  // FRuntimeMeshLockProvider GetSyncRoot() { return SyncRoot->Get(); }
263 
264  bool IsCollisionEnabled() const { return bCollisionEnabled; }
265  bool IsVisible() const { return bIsVisible; }
266  bool ShouldRender() const { return IsVisible() && HasValidMeshData(); }
267  bool CastsShadow() const { return bCastsShadow; }
268  EUpdateFrequency GetUpdateFrequency() const { return UpdateFrequency; }
269  FBox GetBoundingBox() const { return LocalBoundingBox; }
270 
271  int32 GetNumVertices() const { return PositionBuffer.GetNumVertices(); }
272  int32 GetNumIndices() const { return IndexBuffer.GetNumIndices(); }
273 
274  bool HasValidMeshData() const {
275  if (IndexBuffer.GetNumIndices() <= 0)
276  return false;
277  if (PositionBuffer.GetNumVertices() <= 0)
278  return false;
279  if (TangentsBuffer.GetNumVertices() != 0 && TangentsBuffer.GetNumVertices() != PositionBuffer.GetNumVertices())
280  return false;
281  if (UVsBuffer.GetNumVertices() != 0 && UVsBuffer.GetNumVertices() != PositionBuffer.GetNumVertices())
282  return false;
283  if (ColorBuffer.GetNumVertices() != 0 && ColorBuffer.GetNumVertices() != PositionBuffer.GetNumVertices())
284  return false;
285  return true;
286  }
287 
288  void SetVisible(bool bNewVisible)
289  {
290  bIsVisible = bNewVisible;
291  }
292  void SetCastsShadow(bool bNewCastsShadow)
293  {
294  bCastsShadow = bNewCastsShadow;
295  }
296  void SetCollisionEnabled(bool bNewCollision)
297  {
298  bCollisionEnabled = bNewCollision;
299  }
300 
301  void UpdatePositionBuffer(TArray<uint8>& InVertices, bool bUseMove)
302  {
303  PositionBuffer.SetData(InVertices, bUseMove);
304  UpdateBoundingBox();
305  }
306 
307  template<typename VertexType>
308  void UpdatePositionBuffer(const TArray<VertexType>& InVertices, const FBox* BoundingBox = nullptr)
309  {
310  PositionBuffer.SetData(InVertices);
311 
312  if (BoundingBox)
313  {
314  LocalBoundingBox = *BoundingBox;
315  }
316  else
317  {
318  UpdateBoundingBox();
319  }
320  }
321 
322  void UpdateTangentsBuffer(TArray<uint8>& InVertices, bool bUseMove)
323  {
324  TangentsBuffer.SetData(InVertices, bUseMove);
325  }
326 
327  template<typename VertexType>
328  void UpdateTangentsBuffer(const TArray<VertexType>& InVertices)
329  {
330  TangentsBuffer.SetData(InVertices);
331  }
332 
333  void UpdateUVsBuffer(TArray<uint8>& InVertices, bool bUseMove)
334  {
335  UVsBuffer.SetData(InVertices, bUseMove);
336  }
337 
338  template<typename VertexType>
339  void UpdateUVsBuffer(const TArray<VertexType>& InVertices)
340  {
341  UVsBuffer.SetData(InVertices);
342  }
343 
344  void UpdateColorBuffer(TArray<uint8>& InVertices, bool bUseMove)
345  {
346  ColorBuffer.SetData(InVertices, bUseMove);
347  }
348 
349  template<typename VertexType>
350  void UpdateColorBuffer(const TArray<VertexType>& InVertices)
351  {
352  ColorBuffer.SetData(InVertices);
353  }
354 
355  void UpdateIndexBuffer(TArray<uint8>& InIndices, bool bUseMove)
356  {
357  IndexBuffer.SetData(InIndices, bUseMove);
358  }
359 
360  template<typename IndexType>
361  void UpdateIndexBuffer(const TArray<IndexType>& InIndices)
362  {
363  IndexBuffer.SetData(InIndices);
364  }
365 
366  template<typename IndexType>
367  void UpdateAdjacencyIndexBuffer(const TArray<IndexType>& InIndices)
368  {
369  AdjacencyIndexBuffer.SetData(InIndices);
370  }
371 
372  TSharedPtr<FRuntimeMeshAccessor> GetSectionMeshAccessor()
373  {
374  return MakeShared<FRuntimeMeshAccessor>(TangentsBuffer.IsUsingHighPrecision(), UVsBuffer.IsUsingHighPrecision(), UVsBuffer.NumUVs(), IndexBuffer.Is32BitIndices(),
375  &PositionBuffer.GetData(), &TangentsBuffer.GetData(), &UVsBuffer.GetData(), &ColorBuffer.GetData(), &IndexBuffer.GetData());
376  }
377 
378  TUniquePtr<FRuntimeMeshScopedUpdater> GetSectionMeshUpdater(const FRuntimeMeshDataPtr& ParentData, int32 SectionIndex, ESectionUpdateFlags UpdateFlags, FRuntimeMeshLockProvider* LockProvider, bool bIsReadonly)
379  {
380  return TUniquePtr<FRuntimeMeshScopedUpdater>(new FRuntimeMeshScopedUpdater(ParentData, SectionIndex, UpdateFlags, TangentsBuffer.IsUsingHighPrecision(), UVsBuffer.IsUsingHighPrecision(), UVsBuffer.NumUVs(), IndexBuffer.Is32BitIndices(),
381  &PositionBuffer.GetData(), &TangentsBuffer.GetData(), &UVsBuffer.GetData(), &ColorBuffer.GetData(), &IndexBuffer.GetData(), LockProvider, bIsReadonly));
382  }
383 
384  TSharedPtr<FRuntimeMeshIndicesAccessor> GetTessellationIndexAccessor()
385  {
386  return MakeShared<FRuntimeMeshIndicesAccessor>(AdjacencyIndexBuffer.Is32BitIndices(), &AdjacencyIndexBuffer.GetData());
387  }
388 
389 
390 
391 
392 
393 
394 
395 
396  bool CheckTangentBuffer(bool bInUseHighPrecision) const
397  {
398  return TangentsBuffer.IsUsingHighPrecision() == bInUseHighPrecision;
399  }
400 
401  bool CheckUVBuffer(bool bInUseHighPrecision, int32 InNumUVs) const
402  {
403  return UVsBuffer.IsUsingHighPrecision() == bInUseHighPrecision && UVsBuffer.NumUVs() == InNumUVs;
404  }
405 
406  bool CheckIndexBufferSize(bool b32BitIndices) const
407  {
408  return b32BitIndices == IndexBuffer.Is32BitIndices();
409  }
410 
411 
412 
413  TSharedPtr<struct FRuntimeMeshSectionCreationParams, ESPMode::NotThreadSafe> GetSectionCreationParams();
414 
415  TSharedPtr<struct FRuntimeMeshSectionUpdateParams, ESPMode::NotThreadSafe> GetSectionUpdateData(ERuntimeMeshBuffersToUpdate BuffersToUpdate);
416 
417  TSharedPtr<struct FRuntimeMeshSectionPropertyUpdateParams, ESPMode::NotThreadSafe> GetSectionPropertyUpdateData();
418 
419  void UpdateBoundingBox();
420  void SetBoundingBox(const FBox& InBoundingBox) { LocalBoundingBox = InBoundingBox; }
421 
422  int32 GetCollisionData(TArray<FVector>& OutPositions, TArray<FTriIndices>& OutIndices, TArray<FVector2D>& OutUVs);
423 
424 
425  friend FArchive& operator <<(FArchive& Ar, FRuntimeMeshSection& MeshData)
426  {
427  Ar << const_cast<EUpdateFrequency&>(MeshData.UpdateFrequency);
428 
430  {
431  Ar << MeshData.PositionBuffer;
432  Ar << MeshData.TangentsBuffer;
433  Ar << MeshData.UVsBuffer;
434  Ar << MeshData.ColorBuffer;
435  }
436  else
437  {
438  // This is a hack to read the old data and ignore it
439  Ar << MeshData.PositionBuffer;
440  Ar << MeshData.PositionBuffer;
441  Ar << MeshData.PositionBuffer;
442  }
443 
444 
445  Ar << MeshData.IndexBuffer;
446  Ar << MeshData.AdjacencyIndexBuffer;
447 
448  Ar << MeshData.LocalBoundingBox;
449 
450  Ar << MeshData.bCollisionEnabled;
451  Ar << MeshData.bIsVisible;
452  Ar << MeshData.bCastsShadow;
453 
454  // This is a hack to read the old data and ignore it
456  {
457  TArray<FVector> NullPositions;
458  TArray<uint8> NullIndices;
459  MeshData.PositionBuffer.SetData(NullPositions);
460  MeshData.IndexBuffer.SetData(NullIndices, false);
461  MeshData.AdjacencyIndexBuffer.SetData(NullIndices, false);
462  }
463 
464  return Ar;
465  }
466 };
467 
468 
469 
470 
472 using FRuntimeMeshSectionPtr = TSharedPtr<FRuntimeMeshSection, ESPMode::ThreadSafe>;
473 
474 
475 
476 
477 FORCEINLINE static FArchive& operator <<(FArchive& Ar, FRuntimeMeshSectionPtr& Section)
478 {
479  if (Ar.IsSaving())
480  {
481  bool bHasSection = Section.IsValid();
482  Ar << bHasSection;
483  if (bHasSection)
484  {
485  Ar << *Section.Get();
486  }
487  }
488  else if (Ar.IsLoading())
489  {
490  bool bHasSection;
491  Ar << bHasSection;
492  if (bHasSection)
493  {
494  Section = MakeShared<FRuntimeMeshSection, ESPMode::ThreadSafe>(Ar);
495  }
496  }
497  return Ar;
498 }
TUniquePtr< FRuntimeMeshScopedUpdater > GetSectionMeshUpdater(const FRuntimeMeshDataPtr &ParentData, int32 SectionIndex, ESectionUpdateFlags UpdateFlags, FRuntimeMeshLockProvider *LockProvider, bool bIsReadonly)
FSectionUVsVertexBuffer(bool bInUseHighPrecision, int32 InUVCount)
int32 GetNumIndices() const
void SetData(const TArray< VertexType > &InVertices)
void UpdateTangentsBuffer(const TArray< VertexType > &InVertices)
bool IsCollisionEnabled() const
FSectionPositionVertexBuffer PositionBuffer
void UpdateIndexBuffer(TArray< uint8 > &InIndices, bool bUseMove)
static FORCEINLINE FArchive & operator<<(FArchive &Ar, FRuntimeMeshSectionPtr &Section)
EUpdateFrequency
void UpdatePositionBuffer(TArray< uint8 > &InVertices, bool bUseMove)
void UpdateColorBuffer(const TArray< VertexType > &InVertices)
void UpdateTangentsBuffer(TArray< uint8 > &InVertices, bool bUseMove)
bool ShouldRender() const
TSharedPtr< FRuntimeMeshAccessor > GetSectionMeshAccessor()
bool CheckUVBuffer(bool bInUseHighPrecision, int32 InNumUVs) const
void UpdateUVsBuffer(const TArray< VertexType > &InVertices)
FSectionColorVertexBuffer ColorBuffer
FSectionTangentsVertexBuffer TangentsBuffer
void SetCastsShadow(bool bNewCastsShadow)
FSectionIndexBuffer AdjacencyIndexBuffer
FSectionUVsVertexBuffer UVsBuffer
TSharedPtr< FRuntimeMeshData, ESPMode::ThreadSafe > FRuntimeMeshDataPtr
void SetCollisionEnabled(bool bNewCollision)
virtual void Serialize(FArchive &Ar) override
FSectionIndexBuffer IndexBuffer
FBox GetBoundingBox() const
static const textual_icon check
Definition: model-views.h:260
ESectionUpdateFlags
const EUpdateFrequency UpdateFrequency
void SetData(TArray< uint8 > &InIndices, bool bUseMove)
void SetBoundingBox(const FBox &InBoundingBox)
TSharedPtr< FRuntimeMeshIndicesAccessor > GetTessellationIndexAccessor()
bool CheckTangentBuffer(bool bInUseHighPrecision) const
void SetData(TArray< uint8 > &InVertices, bool bUseMove)
void SetVisible(bool bNewVisible)
virtual void Serialize(FArchive &Ar) override
ERuntimeMeshBuffersToUpdate
EUpdateFrequency GetUpdateFrequency() const
static const FGuid GUID
void UpdatePositionBuffer(const TArray< VertexType > &InVertices, const FBox *BoundingBox=nullptr)
bool CheckIndexBufferSize(bool b32BitIndices) const
bool HasValidMeshData() const
int32 GetNumVertices() const
TSharedPtr< FRuntimeMeshSection, ESPMode::ThreadSafe > FRuntimeMeshSectionPtr
void UpdateAdjacencyIndexBuffer(const TArray< IndexType > &InIndices)
void UpdateUVsBuffer(TArray< uint8 > &InVertices, bool bUseMove)
void UpdateColorBuffer(TArray< uint8 > &InVertices, bool bUseMove)
void SetData(const TArray< IndexType > &InIndices)
void UpdateIndexBuffer(const TArray< IndexType > &InIndices)


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