RuntimeMeshCore.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 "Components/MeshComponent.h"
7 #include "Runtime/Launch/Resources/Version.h"
8 #include "Stats/Stats.h"
9 #include "HAL/CriticalSection.h"
10 #include "RuntimeMeshCore.generated.h"
11 
12 DECLARE_STATS_GROUP(TEXT("RuntimeMesh"), STATGROUP_RuntimeMesh, STATCAT_Advanced);
13 
14 
15 #define RUNTIMEMESH_MAXTEXCOORDS MAX_TEXCOORDS
16 
17 #define RUNTIMEMESH_ENABLE_DEBUG_RENDERING (!(UE_BUILD_SHIPPING || UE_BUILD_TEST) || WITH_EDITOR)
18 
19 // Custom version for runtime mesh serialization
21 {
22  enum Type
23  {
24  Initial = 0,
29 
30  // This was a total overhaul of the component, and with it the serialization
32 
33  // This was the 4.19 RHI upgrades requiring an internal restructure
35 
37 
38  // -----<new versions can be added above this line>-------------------------------------------------
41  };
42 
43  // The GUID for this custom version
44  const static FGuid GUID = FGuid(0xEE48714B, 0x8A2C4652, 0x98BE40E6, 0xCB7EF0E6);
45 };
46 
47 
50 
51  template<typename T>
53  {
54  enum { IsValidIndexType = false };
55  enum { Is32Bit = false };
56  };
57 
58  template<>
59  struct FRuntimeMeshIndexTraits<uint16>
60  {
61  enum { IsValidIndexType = true };
62  enum { Is32Bit = false };
63  };
64 
65  template<>
66  struct FRuntimeMeshIndexTraits<uint32>
67  {
68  enum { IsValidIndexType = true };
69  enum { Is32Bit = true };
70  };
71 
72  template<>
74  {
75  enum { IsValidIndexType = true };
76  enum { Is32Bit = true };
77  };
78 
79 
80 enum class ERuntimeMeshBuffersToUpdate : uint8
81 {
82  None = 0x0,
83  PositionBuffer = 0x1,
84  TangentBuffer = 0x2,
85  UVBuffer = 0x4,
86  ColorBuffer = 0x8,
87 
89 
90  IndexBuffer = 0x10,
92 };
94 
95 /* Mobility status for a RuntimeMeshComponent */
96 UENUM(BlueprintType)
97 enum class ERuntimeMeshMobility : uint8
98 {
99  Movable,
100  Stationary,
101  Static
102 };
103 
104 /* Update frequency for a section. Used to optimize for update or render speed*/
105 UENUM(BlueprintType)
106 enum class EUpdateFrequency : uint8
107 {
108  /* Tries to skip recreating the scene proxy if possible. */
109  Average UMETA(DisplayName = "Average"),
110  /* Tries to skip recreating the scene proxy if possible and optimizes the buffers for frequent updates. */
111  Frequent UMETA(DisplayName = "Frequent"),
112  /* If the component is static it will try to use the static rendering path (this will force a recreate of the scene proxy) */
113  Infrequent UMETA(DisplayName = "Infrequent")
114 };
115 
116 /* Control flags for update actions */
118 {
119  None = 0x0,
120 
121  // /**
122  // * This will use move-assignment when copying the supplied vertices/triangles into the section.
123  // * This is faster as it doesn't require copying the data.
124  // *
125  // * CAUTION: This means that your copy of the arrays will be cleared!
126  // */
127  // MoveArrays = 0x1,
128 
135 
142 
148 
149 };
151 
152 /*
153 * Configuration flag for the collision cooking to prioritize cooking speed or collision performance.
154 */
155 UENUM(BlueprintType)
157 {
158  /*
159  * Favors runtime collision performance of cooking speed.
160  * This means that cooking a new mesh will be slower, but collision will be faster.
161  */
162  CollisionPerformance UMETA(DisplayName = "Collision Performance"),
163 
164  /*
165  * Favors cooking speed over collision performance.
166  * This means that cooking a new mesh will be faster, but collision will be slower.
167  */
168  CookingPerformance UMETA(DisplayName = "Cooking Performance"),
169 };
170 
171 
172 
177 USTRUCT(BlueprintType)
179 {
180  GENERATED_BODY()
181 
182 
183  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Tangent)
184  FVector TangentX;
185 
187  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Tangent)
188  bool bFlipTangentY;
189 
191  : TangentX(1.f, 0.f, 0.f)
192  , bFlipTangentY(false)
193  {}
194 
195  FRuntimeMeshTangent(float X, float Y, float Z, bool bInFlipTangentY = false)
196  : TangentX(X, Y, Z)
197  , bFlipTangentY(bInFlipTangentY)
198  {}
199 
200  FRuntimeMeshTangent(FVector InTangentX, bool bInFlipTangentY = false)
201  : TangentX(InTangentX)
202  , bFlipTangentY(bInFlipTangentY)
203  {}
204 
205  void ModifyNormal(FVector4& Normal) const { Normal.W = bFlipTangentY ? -1 : 1; }
206  void ModifyNormal(FPackedNormal& Normal) const { Normal.Vector.W = bFlipTangentY ? 0 : MAX_uint8; }
207  void ModifyNormal(FPackedRGBA16N& Normal) const { Normal.W = bFlipTangentY ? 0 : MAX_uint16; }
208 };
209 
210 
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
227 struct RUNTIMEMESHCOMPONENT_API FRuntimeMeshVertexStreamStructureElement
228 {
229  uint8 Offset;
230  uint8 Stride;
231  EVertexElementType Type;
232 
233  FRuntimeMeshVertexStreamStructureElement() : Offset(-1), Stride(-1), Type(EVertexElementType::VET_None) { }
234  FRuntimeMeshVertexStreamStructureElement(uint8 InOffset, uint8 InStride, EVertexElementType InType)
235  : Offset(InOffset), Stride(InStride), Type(InType) { }
236 
237  bool IsValid() const { return Offset >= 0 && Stride >= 0 && Type != EVertexElementType::VET_None; }
238 
239  bool operator==(const FRuntimeMeshVertexStreamStructureElement& Other) const;
240 
241  bool operator!=(const FRuntimeMeshVertexStreamStructureElement& Other) const;
242 
243  friend FArchive& operator <<(FArchive& Ar, FRuntimeMeshVertexStreamStructureElement& Element)
244  {
245  Ar << Element.Offset;
246  Ar << Element.Stride;
247 
248  int32 TypeValue = static_cast<int32>(Element.Type);
249  Ar << TypeValue;
250  Element.Type = static_cast<EVertexElementType>(TypeValue);
251 
252  return Ar;
253  }
254 };
255 
256 #define RUNTIMEMESH_VERTEXSTREAMCOMPONENT(VertexType, Member, MemberType) \
257  FRuntimeMeshVertexStreamStructureElement(STRUCT_OFFSET(VertexType,Member),sizeof(VertexType),MemberType)
258 
259 struct RUNTIMEMESHCOMPONENT_API FRuntimeMeshVertexStreamStructure
260 {
265  TArray<FRuntimeMeshVertexStreamStructureElement, TInlineAllocator<RUNTIMEMESH_MAXTEXCOORDS>> UVs;
266 
267  bool operator==(const FRuntimeMeshVertexStreamStructure& Other) const;
268 
269  bool operator!=(const FRuntimeMeshVertexStreamStructure& Other) const;
270 
271  bool HasAnyElements() const;
272 
273  bool HasUVs() const;
274 
275  uint8 CalculateStride() const;
276 
277  bool IsValid() const;
278 
279  bool HasNoOverlap(const FRuntimeMeshVertexStreamStructure& Other) const;
280 
281  static bool ValidTripleStream(const FRuntimeMeshVertexStreamStructure& Stream1, const FRuntimeMeshVertexStreamStructure& Stream2, const FRuntimeMeshVertexStreamStructure& Stream3);
282 
283  friend FArchive& operator <<(FArchive& Ar, FRuntimeMeshVertexStreamStructure& Structure)
284  {
285  Ar << Structure.Position;
286  Ar << Structure.Normal;
287  Ar << Structure.Tangent;
288  Ar << Structure.Color;
289  Ar << Structure.UVs;
290 
291  return Ar;
292  }
293 };
294 
295 
296 struct RUNTIMEMESHCOMPONENT_API FRuntimeMeshNullVertex
297 {
299  {
301  }
302 };
303 
304 template<typename VertexType>
306 {
307  return VertexType::GetVertexStructure();
308 }
309 
310 template<>
312 {
314  Structure.Position = FRuntimeMeshVertexStreamStructureElement(0, sizeof(FVector), VET_Float3);
315  return Structure;
316 }
317 
318 template<>
320 {
322  Structure.Color = FRuntimeMeshVertexStreamStructureElement(0, sizeof(FColor), VET_Color);
323  return Structure;
324 }
325 
326 
327 
328 
329 
330 struct RUNTIMEMESHCOMPONENT_API FRuntimeMeshLockProvider
331 {
333  virtual void Lock(bool bIgnoreThreadIfNullLock = false) = 0;
334  virtual void Unlock() = 0;
335  virtual bool IsThreadSafe() const { return false; }
336 };
337 
338 
339 
340 struct RUNTIMEMESHCOMPONENT_API FRuntimeMeshNullLockProvider : public FRuntimeMeshLockProvider
341 {
342 private:
344 public:
345  FRuntimeMeshNullLockProvider() { check(IsInGameThread()); }
347  virtual void Lock(bool bIgnoreThreadIfNullLock = false) override
348  {
349  bIsIgnoringLock = bIgnoreThreadIfNullLock;
350  if (!bIgnoreThreadIfNullLock)
351  {
352  check(IsInGameThread());
353  }
354  }
355  virtual void Unlock() override
356  {
357  if (!bIsIgnoringLock)
358  {
359  check(IsInGameThread());
360  }
361  }
362 };
363 
364 struct RUNTIMEMESHCOMPONENT_API FRuntimeMeshMutexLockProvider : public FRuntimeMeshLockProvider
365 {
366 private:
367  FCriticalSection SyncObject;
368 
369 public:
370 
371  FRuntimeMeshMutexLockProvider() { check(IsInGameThread()); }
373  virtual void Lock(bool bIgnoreThreadIfNullLock = false) override { SyncObject.Lock(); }
374  virtual void Unlock() override { SyncObject.Unlock(); }
375  virtual bool IsThreadSafe() const override { return true; }
376 };
377 
378 
379 class RUNTIMEMESHCOMPONENT_API FRuntimeMeshScopeLock
380 {
381 
382 private:
383  // Holds the synchronization object to aggregate and scope manage.
385 
386 public:
387 
393  FRuntimeMeshScopeLock(const FRuntimeMeshLockProvider* InSyncObject, bool bIsAlreadyLocked = false, bool bIgnoreThreadIfNullLock = false)
394  : SynchObject(const_cast<FRuntimeMeshLockProvider*>(InSyncObject))
395  {
396  check(SynchObject);
397  if (!bIsAlreadyLocked)
398  {
399  SynchObject->Lock(bIgnoreThreadIfNullLock);
400  }
401  }
402 
403  FRuntimeMeshScopeLock(const TUniquePtr<FRuntimeMeshLockProvider>& InSyncObject, bool bIsAlreadyLocked = false, bool bIgnoreThreadIfNullLock = false)
404  : SynchObject(InSyncObject.Get())
405  {
406  check(SynchObject);
407  if (!bIsAlreadyLocked)
408  {
409  SynchObject->Lock(bIgnoreThreadIfNullLock);
410  }
411  }
412 
415  {
416  Unlock();
417  }
418 
419  void Unlock()
420  {
421  if (SynchObject)
422  {
423  SynchObject->Unlock();
424  SynchObject = nullptr;
425  }
426  }
427 private:
428 
431 
433  FRuntimeMeshScopeLock(const FRuntimeMeshScopeLock& InScopeLock);
434 
437  {
438  return *this;
439  }
440 };
441 
442 
443 
444 
445 template<typename T>
447 {
448 private:
449  template<typename C, C> struct ChT;
450 
451  struct FallbackPosition { FVector Position; };
453  template<typename C> static char(&PositionCheck(ChT<FVector FallbackPosition::*, &C::Position>*))[1];
454  template<typename C> static char(&PositionCheck(...))[2];
455 
456  struct FallbackNormal { FPackedRGBA16N Normal; };
458  template<typename C> static char(&NormalCheck(ChT<FPackedRGBA16N FallbackNormal::*, &C::Normal>*))[1];
459  template<typename C> static char(&NormalCheck(...))[2];
460 
461  struct FallbackTangent { FPackedRGBA16N Tangent; };
463  template<typename C> static char(&TangentCheck(ChT<FPackedRGBA16N FallbackTangent::*, &C::Tangent>*))[1];
464  template<typename C> static char(&TangentCheck(...))[2];
465 
466  struct FallbackColor { FColor Color; };
467  struct DerivedColor : T, FallbackColor { };
468  template<typename C> static char(&ColorCheck(ChT<FColor FallbackColor::*, &C::Color>*))[1];
469  template<typename C> static char(&ColorCheck(...))[2];
470 
471  struct FallbackUV0 { FVector2D UV0; };
472  struct DerivedUV0 : T, FallbackUV0 { };
473  template<typename C> static char(&UV0Check(ChT<FVector2D FallbackUV0::*, &C::UV0>*))[1];
474  template<typename C> static char(&UV0Check(...))[2];
475 
476  struct FallbackUV1 { FVector2D UV1; };
477  struct DerivedUV1 : T, FallbackUV1 { };
478  template<typename C> static char(&UV1Check(ChT<FVector2D FallbackUV1::*, &C::UV1>*))[1];
479  template<typename C> static char(&UV1Check(...))[2];
480 
481  struct FallbackUV2 { FVector2D UV2; };
482  struct DerivedUV2 : T, FallbackUV2 { };
483  template<typename C> static char(&UV2Check(ChT<FVector2D FallbackUV2::*, &C::UV2>*))[1];
484  template<typename C> static char(&UV2Check(...))[2];
485 
486  struct FallbackUV3 { FVector2D UV3; };
487  struct DerivedUV3 : T, FallbackUV3 { };
488  template<typename C> static char(&UV3Check(ChT<FVector2D FallbackUV3::*, &C::UV3>*))[1];
489  template<typename C> static char(&UV3Check(...))[2];
490 
491  struct FallbackUV4 { FVector2D UV4; };
492  struct DerivedUV4 : T, FallbackUV4 { };
493  template<typename C> static char(&UV4Check(ChT<FVector2D FallbackUV4::*, &C::UV4>*))[1];
494  template<typename C> static char(&UV4Check(...))[2];
495 
496  struct FallbackUV5 { FVector2D UV5; };
497  struct DerivedUV5 : T, FallbackUV5 { };
498  template<typename C> static char(&UV5Check(ChT<FVector2D FallbackUV5::*, &C::UV5>*))[1];
499  template<typename C> static char(&UV5Check(...))[2];
500 
501  struct FallbackUV6 { FVector2D UV6; };
502  struct DerivedUV6 : T, FallbackUV6 { };
503  template<typename C> static char(&UV6Check(ChT<FVector2D FallbackUV6::*, &C::UV6>*))[1];
504  template<typename C> static char(&UV6Check(...))[2];
505 
506  struct FallbackUV7 { FVector2D UV7; };
507  struct DerivedUV7 : T, FallbackUV7 { };
508  template<typename C> static char(&UV7Check(ChT<FVector2D FallbackUV7::*, &C::UV7>*))[1];
509  template<typename C> static char(&UV7Check(...))[2];
510 
511  template<typename A, typename B>
512  struct IsSameType
513  {
514  static const bool Value = false;
515  };
516 
517  template<typename A>
518  struct IsSameType<A, A>
519  {
520  static const bool Value = true;
521  };
522 
523  template<bool HasNormal, bool HasTangent, typename Type>
525  {
526  static const bool Value = false;
527  };
528 
529  template<typename Type>
531  {
532  static const bool Value = IsSameType<decltype(DeclVal<T>().Normal), FPackedRGBA16N>::Value;
533  };
534 
535  template<bool HasNormal, typename Type>
536  struct TangentBasisHighPrecisionDetector<HasNormal, true, Type>
537  {
538  static const bool Value = IsSameType<decltype(DeclVal<T>().Tangent), FPackedRGBA16N>::Value;
539  };
540 
541  template<bool HasUV0, typename Type>
543  {
544  static const bool Value = false;
545  };
546 
547  template<typename Type>
549  {
550  static const bool Value = IsSameType<decltype(DeclVal<T>().UV0), FVector2D>::Value;
551  };
552 
553 
554 public:
555  static const bool HasPosition = sizeof(PositionCheck<DerivedPosition>(0)) == 2;
556  static const bool HasNormal = sizeof(NormalCheck<DerivedNormal>(0)) == 2;
557  static const bool HasTangent = sizeof(TangentCheck<DerivedTangent>(0)) == 2;
558  static const bool HasColor = sizeof(ColorCheck<DerivedColor>(0)) == 2;
559  static const bool HasUV0 = sizeof(UV0Check<DerivedUV0>(0)) == 2;
560  static const bool HasUV1 = sizeof(UV1Check<DerivedUV1>(0)) == 2;
561  static const bool HasUV2 = sizeof(UV2Check<DerivedUV2>(0)) == 2;
562  static const bool HasUV3 = sizeof(UV3Check<DerivedUV3>(0)) == 2;
563  static const bool HasUV4 = sizeof(UV4Check<DerivedUV4>(0)) == 2;
564  static const bool HasUV5 = sizeof(UV5Check<DerivedUV5>(0)) == 2;
565  static const bool HasUV6 = sizeof(UV6Check<DerivedUV6>(0)) == 2;
566  static const bool HasUV7 = sizeof(UV7Check<DerivedUV7>(0)) == 2;
567  static const int32 NumUVChannels =
568  (HasUV0 ? 1 : 0) +
569  (HasUV1 ? 1 : 0) +
570  (HasUV2 ? 1 : 0) +
571  (HasUV3 ? 1 : 0) +
572  (HasUV4 ? 1 : 0) +
573  (HasUV5 ? 1 : 0) +
574  (HasUV6 ? 1 : 0) +
575  (HasUV7 ? 1 : 0);
576 
577 
578 
579  static const bool HasHighPrecisionNormals = TangentBasisHighPrecisionDetector<HasNormal, HasTangent, T>::Value;
580  static const bool HasHighPrecisionUVs = UVChannelHighPrecisionDetector<HasUV0, T>::Value;
581 };
582 
583 
585 {
586  template<typename VertexType0>
588  {
590  }
591  template<typename VertexType0, typename VertexType1>
593  {
595  }
596  template<typename VertexType0, typename VertexType1, typename VertexType2>
598  {
600  }
601 
602 
603 
604  template<typename VertexType0>
606  {
608  }
609  template<typename VertexType0, typename VertexType1>
611  {
613  }
614  template<typename VertexType0, typename VertexType1, typename VertexType2>
616  {
618  }
619 
620 
621 
622  template<typename VertexType0>
623  static int32 NumUVs()
624  {
626  }
627  template<typename VertexType0, typename VertexType1>
628  static int32 NumUVs()
629  {
631  }
632  template<typename VertexType0, typename VertexType1, typename VertexType2>
633  static int32 NumUVs()
634  {
636  }
637 };
void ModifyNormal(FPackedNormal &Normal) const
virtual void Unlock() override
list Z
Definition: rmse.py:133
FRuntimeMeshTangent(float X, float Y, float Z, bool bInFlipTangentY=false)
bool operator==(const plane &lhs, const plane &rhs)
Definition: rendering.h:134
bool operator!=(failed, failed)
virtual bool IsThreadSafe() const override
void ModifyNormal(FVector4 &Normal) const
FRuntimeMeshScopeLock(const TUniquePtr< FRuntimeMeshLockProvider > &InSyncObject, bool bIsAlreadyLocked=false, bool bIgnoreThreadIfNullLock=false)
ENUM_CLASS_FLAGS(ERuntimeMeshBuffersToUpdate)
EUpdateFrequency
FRuntimeMeshVertexStreamStructureElement Position
ERuntimeMeshMobility
FRuntimeMeshVertexStreamStructure GetStreamStructure< FColor >()
virtual void Lock(bool bIgnoreThreadIfNullLock=false) override
std::ostream & operator<<(std::ostream &os, const textual_icon &i)
Definition: model-views.h:118
FRuntimeMeshLockProvider * SynchObject
FRuntimeMeshVertexStreamStructureElement Normal
virtual void Lock(bool bIgnoreThreadIfNullLock=false)=0
GLdouble f
FRuntimeMeshTangent(FVector InTangentX, bool bInFlipTangentY=false)
FRuntimeMeshScopeLock(const FRuntimeMeshLockProvider *InSyncObject, bool bIsAlreadyLocked=false, bool bIgnoreThreadIfNullLock=false)
void ModifyNormal(FPackedRGBA16N &Normal) const
FRuntimeMeshVertexStreamStructureElement(uint8 InOffset, uint8 InStride, EVertexElementType InType)
UTexture2D * Get(TUniquePtr< T > &Dtex)
static const FRuntimeMeshVertexStreamStructure GetVertexStructure()
TArray< FRuntimeMeshVertexStreamStructureElement, TInlineAllocator< RUNTIMEMESH_MAXTEXCOORDS > > UVs
static const textual_icon check
Definition: model-views.h:260
FRuntimeMeshVertexStreamStructure GetStreamStructure< FVector >()
IMGUI_API void Value(const char *prefix, bool b)
Definition: imgui.cpp:9538
ESectionUpdateFlags
virtual void Unlock() override
virtual void Lock(bool bIgnoreThreadIfNullLock=false) override
DECLARE_STATS_GROUP(TEXT("RuntimeMesh"), STATGROUP_RuntimeMesh, STATCAT_Advanced)
FRuntimeMeshVertexStreamStructureElement Color
list Y
Definition: rmse.py:132
virtual void Unlock()=0
ERuntimeMeshBuffersToUpdate
virtual bool IsThreadSafe() const
static const FGuid GUID
list X
Definition: rmse.py:131
FRuntimeMeshVertexStreamStructure GetStreamStructure()
FRuntimeMeshScopeLock & operator=(FRuntimeMeshScopeLock &InScopeLock)
ERuntimeMeshCollisionCookingMode
FRuntimeMeshVertexStreamStructureElement Tangent


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