UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MeshAttributeArray.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "Containers/Array.h"
9#include "Containers/Map.h"
11#include "CoreMinimal.h"
13#include "HAL/PlatformCrt.h"
15#include "Math/Vector.h"
16#include "Math/Vector2D.h"
17#include "Math/Vector4.h"
19#include "MeshTypes.h"
21#include "Misc/Crc.h"
22#include "Misc/EnumClassFlags.h"
23#include "Misc/TVariant.h"
26#include "Templates/EnableIf.h"
27#include "Templates/IsArray.h"
28#include "Templates/Tuple.h"
29#include "Templates/UniquePtr.h"
33#include "UObject/NameTypes.h"
36
37struct FElementID;
38
39
47<
51 float,
52 int32,
53 bool,
54 FName,
56>;
57
58
62template <typename Tuple> struct TVariantFromTuple;
63
64template <typename... Ts> struct TVariantFromTuple<TTuple<Ts...>> { using Type = TVariant<FEmptyVariantState, Ts...>; };
65
66
70template <typename T> struct TIsBulkSerializable { static const bool Value = true; };
71template <> struct TIsBulkSerializable<FName> { static const bool Value = false; };
72template <> struct TIsBulkSerializable<FTransform> { static const bool Value = false; };
73
74
82template <typename AttributeType>
84{
85public:
89
91 template <typename T> friend typename TEnableIf<!TIsBulkSerializable<T>::Value, FArchive>::Type& operator<<( FArchive& Ar, TMeshAttributeArrayBase<T>& Array );
92 template <typename T> friend typename TEnableIf<TIsBulkSerializable<T>::Value, FArchive>::Type& operator<<( FArchive& Ar, TMeshAttributeArrayBase<T>& Array );
93
95 inline int32 Num() const { return Container.Num() / Extent; }
96
98 UE_DEPRECATED(5.0, "This method will be removed.")
99 inline const AttributeType* GetData() const { return Container.GetData(); }
100
102 inline void Initialize(const int32 ElementCount, const AttributeType& Default)
103 {
104 Container.Reset(ElementCount * Extent);
105 if (ElementCount > 0)
106 {
107 Insert(ElementCount - 1, Default);
108 }
109 }
110
111 void SetNum(const int32 ElementCount, const AttributeType& Default)
112 {
113 if (int32(ElementCount * Extent) < Container.Num())
114 {
115 // Setting to a lower number; just truncate the container
116 Container.SetNum(ElementCount * Extent);
117 }
118 else
119 {
120 // Setting to a higher number; grow the container, inserting default value to end.
121 Insert(ElementCount - 1, Default);
122 }
123 }
124
126 {
127 return FCrc::MemCrc32(Container.GetData(), Container.Num() * sizeof(AttributeType), Crc);
128 }
129
131 void Insert(const int32 Index, const AttributeType& Default);
132
134 void SetToDefault(const int32 Index, const AttributeType& Default)
135 {
136 for (uint32 I = 0; I < Extent; ++I)
137 {
138 Container[Index * Extent + I] = Default;
139 }
140 }
141
143 void Remap(const TSparseArray<int32>& IndexRemap, const AttributeType& Default);
144
146 UE_DEPRECATED(5.0, "Please use GetElementBase() instead.")
147 inline const AttributeType& operator[](const int32 Index) const { return Container[Index]; }
148
149 UE_DEPRECATED(5.0, "Please use GetElementBase() instead.")
150 inline AttributeType& operator[](const int32 Index) { return Container[Index]; }
151
152 inline const AttributeType* GetElementBase(const int32 Index) const { return &Container[Index * Extent]; }
153 inline AttributeType* GetElementBase(const int32 Index) { return &Container[Index * Extent]; }
154
155 inline uint32 GetExtent() const { return Extent; }
156
157protected:
160
163};
164
165// We have to manually implement this or else the default behavior will just hash FName ComparisonIndex and Number,
166// which aren't deterministic
167template<>
169{
170 for (const FName& Item : Container)
171 {
172 const FString ItemStr = Item.ToString();
173 Crc = FCrc::MemCrc32(*ItemStr, ItemStr.Len() * sizeof(TCHAR), Crc);
174 }
175 return Crc;
176}
177
178template <typename AttributeType>
180{
181 int32 EndIndex = (Index + 1) * Extent;
182 if (EndIndex > Container.Num())
183 {
184 // If the index is off the end of the container, add as many elements as required to make it the last valid index.
185 int32 StartIndex = Container.AddUninitialized(EndIndex - Container.Num());
186 AttributeType* Data = Container.GetData() + StartIndex;
187
188 // Construct added elements with the default value passed in
189
190 while (StartIndex < EndIndex)
191 {
192 new(Data) AttributeType(Default);
193 StartIndex++;
194 Data++;
195 }
196 }
197}
198
199template <typename AttributeType>
201{
203
204 for (typename TSparseArray<int32>::TConstIterator It(IndexRemap); It; ++It)
205 {
206 const int32 OldElementIndex = It.GetIndex();
207 const int32 NewElementIndex = IndexRemap[OldElementIndex];
208
210 AttributeType* DestElementBase = NewAttributeArray.GetElementBase(NewElementIndex);
211 AttributeType* SrcElementBase = GetElementBase(OldElementIndex);
212 for (uint32 Index = 0; Index < Extent; ++Index)
213 {
215 }
216 }
217
219}
220
221template <typename T>
223{
224 if (Ar.IsLoading() &&
226 Ar.CustomVer(FUE5MainStreamObjectVersion::GUID) < FUE5MainStreamObjectVersion::MeshDescriptionNewFormat)
227 {
228 Array.Extent = 1;
229 }
230 else
231 {
232 Ar << Array.Extent;
233 }
234
235 // A little bit prior to skeletal meshes storing their model data as mesh description, FTransform attributes were added but marked,
236 // by default, as bulk-serializable, even though FTransform doesn't support it. Therefore, this serialization path only worked on empty
237 // FTransform attributes. However, there are still static mesh assets in the wild that contain empty FTransform attributes, and we need
238 // to be able to successfully load them -- hence this check.
239 if constexpr (std::is_same_v<T, FTransform>)
240 {
241 if (Ar.IsLoading())
242 {
243 // This version check works because saved UStaticMesh assets set this on their archive, which is then inherited by the
244 // mesh description bulk storage.
246 if (PossiblySavedVersion && PossiblySavedVersion->Version < FFortniteMainBranchObjectVersion::MeshDescriptionForSkeletalMesh)
247 {
248 Array.Container.BulkSerialize( Ar );
249 return Ar;
250 }
251 }
252 }
253
254 // Serialize types which aren't bulk serializable, which need to be serialized element-by-element
255 Ar << Array.Container;
256 return Ar;
257}
258
259template <typename T>
261{
262 if (Ar.IsLoading() &&
264 Ar.CustomVer(FUE5MainStreamObjectVersion::GUID) < FUE5MainStreamObjectVersion::MeshDescriptionNewFormat)
265 {
266 Array.Extent = 1;
267 }
268 else
269 {
270 Ar << Array.Extent;
271 }
272
274 {
275 // Legacy path for old format attribute arrays. BulkSerialize has a different format from regular serialization.
276 Ar << Array.Container;
277 }
278 else
279 {
280 // Serialize types which are bulk serializable, i.e. which can be memcpy'd in bulk
281 Array.Container.BulkSerialize( Ar );
282 }
283
284 return Ar;
285}
286
287
292{
293 None = 0,
294 Lerpable = (1 << 0),
295 AutoGenerated = (1 << 1),
296 Mergeable = (1 << 2),
297 Transient = (1 << 3),
298 IndexReference = (1 << 4),
299 Mandatory = (1 << 5),
300};
301
303
304
318{
319public:
327
329 virtual ~FMeshAttributeArraySetBase() = default;
331 virtual void Insert(const int32 Index) = 0;
332 virtual void Remove(const int32 Index) = 0;
333 virtual void Initialize(const int32 Count) = 0;
334 virtual void SetNumElements(const int32 Count) = 0;
335 virtual uint32 GetHash() const = 0;
336 virtual void Serialize(FArchive& Ar) = 0;
337 virtual void Remap(const TSparseArray<int32>& IndexRemap) = 0;
338
339// UE_DEPRECATED(5.0, "Please use GetNumChannels().")
340 virtual int32 GetNumIndices() const = 0;
341// UE_DEPRECATED(5.0, "Please use SetNumChannels().")
342 virtual void SetNumIndices(const int32 NumIndices) = 0;
343// UE_DEPRECATED(5.0, "Please use InsertChannel().")
344 virtual void InsertIndex(const int32 Index) = 0;
345// UE_DEPRECATED(5.0, "Please use RemoveChannel().")
346 virtual void RemoveIndex(const int32 Index) = 0;
347
348 virtual int32 GetNumChannels() const = 0;
349 virtual void SetNumChannels(const int32 NumChannels) = 0;
350 virtual void InsertChannel(const int32 Index) = 0;
351 virtual void RemoveChannel(const int32 Index) = 0;
352
354 template <typename T>
355 inline bool HasType() const
356 {
358 }
359
361 inline uint32 GetType() const { return Type; }
362
364 inline uint32 GetExtent() const { return Extent; }
365
367 inline EMeshAttributeFlags GetFlags() const { return Flags; }
368
371
373 inline int32 GetNumElements() const { return NumElements; }
374
375protected:
378
381
384
387};
388
389
393template <typename AttributeType>
395{
396 static_assert(!TIsArray<AttributeType>::Value, "TMeshAttributeArraySet must take a simple type.");
397
399
400public:
402 inline explicit TMeshAttributeArraySet(const int32 Extent = 1)
404 {}
405
412
415 {
417 }
418
420 virtual void Insert(const int32 Index) override
421 {
423 {
425 }
426
427 NumElements = FMath::Max(NumElements, Index + 1);
428 }
429
431 virtual void Remove(const int32 Index) override
432 {
434 {
435 ArrayForChannel.SetToDefault(Index, DefaultValue);
436 }
437 }
438
440 virtual void Initialize(const int32 Count) override
441 {
444 {
446 }
447 }
448
450 virtual void SetNumElements(const int32 Count) override
451 {
454 {
456 }
457 }
458
459 virtual uint32 GetHash() const override
460 {
461 uint32 CrcResult = 0;
463 {
465 }
466 return CrcResult;
467 }
468
470 virtual void Serialize(FArchive& Ar) override
471 {
472 Ar << (*this);
473 }
474
476 virtual void Remap(const TSparseArray<int32>& IndexRemap) override
477 {
479 {
480 ArrayForChannel.Remap(IndexRemap, DefaultValue);
482 }
483 }
484
485 UE_DEPRECATED(5.0, "Please use GetNumChannels().")
486 virtual inline int32 GetNumIndices() const override { return GetNumChannels(); }
487
489 virtual inline int32 GetNumChannels() const override { return ArrayForChannels.Num(); }
490
491 UE_DEPRECATED(5.0, "Please use SetNumChannels().")
492 virtual void SetNumIndices(const int32 NumIndices) override { SetNumChannels(NumIndices); }
493
495 virtual void SetNumChannels(const int32 NumChannels) override
496 {
497 if (NumChannels < ArrayForChannels.Num())
498 {
499 ArrayForChannels.SetNum(NumChannels);
500 return;
501 }
502
503 while (ArrayForChannels.Num() < NumChannels)
504 {
507 }
508 }
509
510 UE_DEPRECATED(5.0, "Please use InsertChannel().")
511 virtual void InsertIndex(const int32 Index) override
512 {
514 }
515
522
523 UE_DEPRECATED(5.0, "Please use RemoveChannel().")
524 virtual void RemoveIndex(const int32 Index) override
525 {
527 }
528
530 virtual void RemoveChannel(const int32 Index) override
531 {
532 ArrayForChannels.RemoveAt(Index);
533 }
534
535
536 UE_DEPRECATED(5.0, "Please use GetArrayForChannel().")
537 inline const TMeshAttributeArrayBase<AttributeType>& GetArrayForIndex( const int32 Index ) const { return ArrayForChannels[ Index ]; }
538 UE_DEPRECATED(5.0, "Please use GetArrayForChannel().")
540
544
546 inline AttributeType GetDefaultValue() const { return DefaultValue; }
547
550 {
551 Ar << AttributeArraySet.NumElements;
552 Ar << AttributeArraySet.ArrayForChannels;
553 Ar << AttributeArraySet.DefaultValue;
554 Ar << AttributeArraySet.Flags;
555
556 return Ar;
557 }
558
559protected:
562
564 AttributeType DefaultValue;
565};
566
567
571template <typename AttributeType>
573{
575
576public:
581
588
591 {
593 }
594
596 virtual void Insert(const int32 Index) override
597 {
599 {
601 }
602
603 NumElements = FMath::Max(NumElements, Index + 1);
604 }
605
607 virtual void Remove(const int32 Index) override
608 {
610 {
611 ArrayForChannel.SetToDefault(Index, DefaultValue);
612 }
613 }
614
616 virtual void Initialize(const int32 Count) override
617 {
620 {
622 }
623 }
624
626 virtual void SetNumElements(const int32 Count) override
627 {
630 {
632 }
633 }
634
635 virtual uint32 GetHash() const override
636 {
637 uint32 CrcResult = 0;
639 {
641 }
642 return CrcResult;
643 }
644
646 virtual void Serialize(FArchive& Ar) override
647 {
648 Ar << (*this);
649 }
650
652 virtual void Remap(const TSparseArray<int32>& IndexRemap) override
653 {
655 {
656 ArrayForChannel.Remap(IndexRemap, DefaultValue);
658 }
659 }
660
661 UE_DEPRECATED(5.0, "Please use GetNumChannels().")
662 virtual inline int32 GetNumIndices() const override { return GetNumChannels(); }
663
665 virtual inline int32 GetNumChannels() const override { return ArrayForChannels.Num(); }
666
667 UE_DEPRECATED(5.0, "Please use SetNumChannels().")
668 virtual void SetNumIndices(const int32 NumIndices) override { SetNumChannels(NumIndices); }
669
671 virtual void SetNumChannels(const int32 NumChannels) override
672 {
673 if (NumChannels < ArrayForChannels.Num())
674 {
675 ArrayForChannels.SetNum(NumChannels);
676 return;
677 }
678
679 while (ArrayForChannels.Num() < NumChannels)
680 {
683 }
684 }
685
686 UE_DEPRECATED(5.0, "Please use InsertChannel().")
687 virtual void InsertIndex(const int32 Index) override
688 {
690 }
691
698
699 UE_DEPRECATED(5.0, "Please use RemoveChannel().")
700 virtual void RemoveIndex(const int32 Index) override
701 {
703 }
704
706 virtual void RemoveChannel(const int32 Index) override
707 {
708 ArrayForChannels.RemoveAt(Index);
709 }
710
714
716 inline AttributeType GetDefaultValue() const { return DefaultValue; }
717
720 {
721 Ar << AttributeArraySet.NumElements;
722 Ar << AttributeArraySet.ArrayForChannels;
723 Ar << AttributeArraySet.DefaultValue;
724 Ar << AttributeArraySet.Flags;
725
726 return Ar;
727 }
728
729protected:
732
734 AttributeType DefaultValue;
735};
736
737
748template <typename T>
750{
751 using AttributeType = T;
752 using RealAttributeType = std::conditional_t<TIsDerivedFrom<AttributeType, FElementID>::Value, int32, AttributeType>;
753};
754
755template <typename T>
757{
758 static const uint32 MinExpectedExtent = 1;
759 static const uint32 MaxExpectedExtent = 1;
760 using RefType = T;
761 using ConstRefType = const T;
762 using NonConstRefType = std::remove_cv_t<T>;
763};
764
765template <typename T>
774
775template <typename T>
784
785
794template <typename T>
799
800template <typename T, SIZE_T N>
802{
803 static const uint32 Extent = N;
804};
805
806template <typename T>
808{
809 static const uint32 Extent = 0;
810};
811
812
813
819template <typename ElementIDType, typename AttributeType>
821
822template <typename ElementIDType, typename AttributeType>
824
825template <typename AttributeType>
827
828template <typename AttributeType>
830
831
832// This is the default implementation which handles simple attributes, i.e. those of a simple type T.
833// There are partial specializations which handle compound attributes below, i.e. those accessed via TArrayView<T> or TAttributeArray<T>
834template <typename ElementIDType, typename AttributeType>
836{
837 template <typename T, typename U> friend class TMeshAttributesRef;
838
839public:
842
845 : ArrayPtr(InArrayPtr)
846 {}
847
849 template <typename SrcAttributeType,
850 typename DestAttributeType = AttributeType,
851 typename TEnableIf<std::is_const_v<DestAttributeType>, int>::Type = 0,
852 typename TEnableIf<!std::is_const_v<SrcAttributeType>, int>::Type = 0>
856
858 template <typename IDType = ElementIDType,
859 typename TEnableIf<!std::is_same_v<IDType, int32>, int>::Type = 0>
863
865 template <typename SrcAttributeType,
866 typename DestAttributeType = AttributeType,
867 typename IDType = ElementIDType,
868 typename TEnableIf<!std::is_same_v<IDType, int32>, int>::Type = 0,
869 typename TEnableIf<std::is_const_v<DestAttributeType>, int>::Type = 0,
870 typename TEnableIf<!std::is_const_v<SrcAttributeType>, int>::Type = 0>
874
877 AttributeType& operator[](const ElementIDType ElementID) const
878 {
879 return static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).GetElementBase(ElementID.GetValue())[0];
880 }
881
884 AttributeType Get(const ElementIDType ElementID, const int32 Channel = 0) const
885 {
886 return static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementID.GetValue())[0];
887 }
888
889 AttributeType& operator[](int32 ElementIndex) const
890 {
891 return static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).GetElementBase(ElementIndex)[0];
892 }
893
894 AttributeType Get(int32 ElementIndex, const int32 Channel = 0) const
895 {
896 return static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementIndex)[0];
897 }
898
899 TArrayView<AttributeType> GetArrayView(int32 ElementIndex, const int32 Channel = 0) const
900 {
901 return TArrayView<AttributeType>(static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementIndex), 1);
902 }
903
905 {
906 if (ArrayPtr == nullptr || GetNumElements() == 0)
907 {
909 }
910
911 AttributeType* Element = static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(AttributeChannel).GetElementBase(0);
912 return TArrayView<AttributeType>(Element, GetNumElements());
913 }
914
916 bool IsValid() const { return (ArrayPtr != nullptr); }
917
919 AttributeType GetDefaultValue() const { return static_cast<ArrayType*>(ArrayPtr)->GetDefaultValue(); }
920
921 UE_DEPRECATED(5.0, "Please use GetNumChannels().")
923 {
924 return static_cast<ArrayType*>(ArrayPtr)->ArrayType::GetNumChannels(); // note: override virtual dispatch
925 }
926
929 {
930 return static_cast<ArrayType*>(ArrayPtr)->ArrayType::GetNumChannels(); // note: override virtual dispatch
931 }
932
935 {
936 return ArrayPtr->GetNumElements();
937 }
938
940 EMeshAttributeFlags GetFlags() const { return ArrayPtr->GetFlags(); }
941
943 uint32 GetExtent() const { return 1; }
944
947 void Set(const ElementIDType ElementID, const AttributeType& Value) const
948 {
949 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).GetElementBase(ElementID.GetValue())[0] = Value;
950 }
951
954 void Set(const ElementIDType ElementID, const int32 Channel, const AttributeType& Value) const
955 {
956 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementID.GetValue())[0] = Value;
957 }
958
959 void Set(int32 ElementIndex, const AttributeType& Value) const
960 {
961 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).GetElementBase(ElementIndex)[0] = Value;
962 }
963
964 void Set(int32 ElementIndex, const int32 Channel, const AttributeType& Value) const
965 {
966 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementIndex)[0] = Value;
967 }
968
970 {
971 check(Value.Num() == 1);
972 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).GetElementBase(ElementIndex)[0] = Value[0];
973 }
974
975 void SetArrayView(int32 ElementIndex, const int32 Channel, TArrayView<const AttributeType> Value) const
976 {
977 check(Value.Num() == 1);
978 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementIndex)[0] = Value[0];
979 }
980
983
984 UE_DEPRECATED(5.0, "Please use SetNumChannels().")
985 void SetNumIndices(const int32 NumChannels) const
986 {
987 static_cast<ArrayType*>(ArrayPtr)->ArrayType::SetNumChannels(NumChannels); // note: override virtual dispatch
988 }
989
991 void SetNumChannels(const int32 NumChannels) const
992 {
993 static_cast<ArrayType*>(ArrayPtr)->ArrayType::SetNumChannels(NumChannels); // note: override virtual dispatch
994 }
995
996 UE_DEPRECATED(5.0, "Please use InsertChannel().")
998 {
999 static_cast<ArrayType*>(ArrayPtr)->ArrayType::InsertChannel(Index); // note: override virtual dispatch
1000 }
1001
1003 void InsertChannel(const int32 Channel) const
1004 {
1005 static_cast<ArrayType*>(ArrayPtr)->ArrayType::InsertChannel(Channel); // note: override virtual dispatch
1006 }
1007
1008 UE_DEPRECATED(5.0, "Please use RemoveChannel().")
1010 {
1011 static_cast<ArrayType*>(ArrayPtr)->ArrayType::RemoveChannel(Index); // note: override virtual dispatch
1012 }
1013
1015 void RemoveChannel(const int32 Channel) const
1016 {
1017 static_cast<ArrayType*>(ArrayPtr)->ArrayType::RemoveChannel(Channel); // note: override virtual dispatch
1018 }
1019
1020private:
1021 BaseArrayType* ArrayPtr;
1022};
1023
1024template <typename ElementIDType, typename AttributeType>
1026{
1027 check(Src.IsValid());
1028 const TMeshAttributeArrayBase<AttributeType>& SrcArray = static_cast<const ArrayType*>(Src.ArrayPtr)->GetArrayForChannel(SrcChannel);
1029 TMeshAttributeArrayBase<AttributeType>& DestArray = static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(DestChannel);
1030 const int32 Num = FMath::Min(SrcArray.Num(), DestArray.Num());
1031 for (int32 Index = 0; Index < Num; Index++)
1032 {
1033 DestArray.GetElementBase(Index)[0] = SrcArray.GetElementBase(Index)[0];
1034 }
1035}
1036
1037
1038template <typename ElementIDType, typename AttributeType>
1040{
1041 template <typename T, typename U> friend class TMeshAttributesRef;
1042
1043public:
1047
1050 : ArrayPtr(InArrayPtr),
1051 Extent(InExtent)
1052 {}
1053
1055 template <typename SrcAttributeType,
1056 typename DestAttributeType = AttributeType,
1057 typename TEnableIf<std::is_const_v<DestAttributeType>, int>::Type = 0,
1058 typename TEnableIf<!std::is_const_v<SrcAttributeType>, int>::Type = 0>
1060 : ArrayPtr(InRef.ArrayPtr),
1061 Extent(InRef.Extent)
1062 {}
1063
1065 template <typename IDType = ElementIDType,
1066 typename TEnableIf<!std::is_same_v<IDType, int32>, int>::Type = 0>
1068 : ArrayPtr(InRef.ArrayPtr),
1069 Extent(InRef.Extent)
1070 {}
1071
1073 template <typename SrcAttributeType,
1074 typename DestAttributeType = AttributeType,
1075 typename IDType = ElementIDType,
1076 typename TEnableIf<!std::is_same_v<IDType, int32>, int>::Type = 0,
1077 typename TEnableIf<std::is_const_v<DestAttributeType>, int>::Type = 0,
1078 typename TEnableIf<!std::is_const_v<SrcAttributeType>, int>::Type = 0>
1080 : ArrayPtr(InRef.ArrayPtr),
1081 Extent(InRef.Extent)
1082 {}
1083
1084
1088 {
1089 if (Extent > 0)
1090 {
1091 AttributeType* Element = static_cast<BoundedArrayType*>(ArrayPtr)->GetArrayForChannel(0).GetElementBase(ElementID.GetValue());
1092 return TArrayView<AttributeType>(Element, Extent);
1093 }
1094 else
1095 {
1096 return static_cast<UnboundedArrayType*>(ArrayPtr)->GetArrayForChannel(0).Get(ElementID.GetValue());
1097 }
1098 }
1099
1102 TArrayView<AttributeType> Get(const ElementIDType ElementID, const int32 Channel = 0) const
1103 {
1104 if (Extent > 0)
1105 {
1106 AttributeType* Element = static_cast<BoundedArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementID.GetValue());
1107 return TArrayView<AttributeType>(Element, Extent);
1108 }
1109 else
1110 {
1111 return static_cast<UnboundedArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).Get(ElementID.GetValue());
1112 }
1113 }
1114
1116 {
1117 if (Extent > 0)
1118 {
1119 AttributeType* Element = static_cast<BoundedArrayType*>(ArrayPtr)->GetArrayForChannel(0).GetElementBase(ElementIndex);
1120 return TArrayView<AttributeType>(Element, Extent);
1121 }
1122 else
1123 {
1124 return static_cast<UnboundedArrayType*>(ArrayPtr)->GetArrayForChannel(0).Get(ElementIndex);
1125 }
1126 }
1127
1128 TArrayView<AttributeType> Get(int32 ElementIndex, const int32 Channel = 0) const
1129 {
1130 if (Extent > 0)
1131 {
1132 AttributeType* Element = static_cast<BoundedArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementIndex);
1133 return TArrayView<AttributeType>(Element, Extent);
1134 }
1135 else
1136 {
1137 return static_cast<UnboundedArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).Get(ElementIndex);
1138 }
1139 }
1140
1141 TArrayView<AttributeType> GetArrayView(int32 ElementIndex, const int32 Channel = 0) const
1142 {
1143 if (Extent > 0)
1144 {
1145 return TArrayView<AttributeType>(static_cast<BoundedArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).GetElementBase(ElementIndex), Extent);
1146 }
1147 else
1148 {
1149 return static_cast<UnboundedArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).Get(ElementIndex);
1150 }
1151 }
1152
1153 TArrayView<AttributeType> GetRawArray(const int32 ChannelIndex = 0) const
1154 {
1155 // Can't get the attribute set raw array for unbounded arrays because they are chunked
1156 check(Extent > 0);
1157
1158 if (ArrayPtr == nullptr || GetNumElements() == 0)
1159 {
1161 }
1162
1163 AttributeType* Element = static_cast<BoundedArrayType*>(ArrayPtr)->GetArrayForChannel(ChannelIndex).GetElementBase(0);
1164 return TArrayView<AttributeType>(Element, GetNumElements() * Extent);
1165 }
1166
1168 bool IsValid() const { return (ArrayPtr != nullptr); }
1169
1171 AttributeType GetDefaultValue() const { return static_cast<BoundedArrayType*>(ArrayPtr)->GetDefaultValue(); }
1172
1173 UE_DEPRECATED(5.0, "Please use GetNumChannels().")
1175 {
1176 return ArrayPtr->GetNumChannels();
1177 }
1178
1181 {
1182 return ArrayPtr->GetNumChannels();
1183 }
1184
1187 {
1188 return ArrayPtr->GetNumElements();
1189 }
1190
1192 EMeshAttributeFlags GetFlags() const { return ArrayPtr->GetFlags(); }
1193
1195 uint32 GetExtent() const { return Extent; }
1196
1200 {
1201 TArrayView<AttributeType> Elements = Get(ElementID);
1202 check(Value.Num() == Elements.Num());
1203 for (uint32 Index = 0; Index < Extent; Index++)
1204 {
1205 Elements[Index] = Value[Index];
1206 }
1207 }
1208
1211 void Set(const ElementIDType ElementID, const int32 Channel, TArrayView<const AttributeType> Value) const
1212 {
1213 TArrayView<AttributeType> Elements = Get(ElementID, Channel);
1214 check(Value.Num() == Elements.Num());
1215 for (uint32 Index = 0; Index < Extent; Index++)
1216 {
1217 Elements[Index] = Value[Index];
1218 }
1219 }
1220
1222 {
1223 TArrayView<AttributeType> Elements = Get(ElementIndex);
1224 check(Value.Num() == Elements.Num());
1225 for (uint32 Index = 0; Index < Extent; Index++)
1226 {
1227 Elements[Index] = Value[Index];
1228 }
1229 }
1230
1231 void Set(int32 ElementIndex, const int32 Channel, TArrayView<const AttributeType> Value) const
1232 {
1233 TArrayView<AttributeType> Elements = Get(ElementIndex, Channel);
1234 check(Value.Num() == Elements.Num());
1235 for (uint32 Index = 0; Index < Extent; Index++)
1236 {
1237 Elements[Index] = Value[Index];
1238 }
1239 }
1240
1242 {
1243 Set(ElementIndex, Value);
1244 }
1245
1246 void SetArrayView(int32 ElementIndex, const int32 Channel, TArrayView<const AttributeType> Value) const
1247 {
1248 Set(ElementIndex, Channel, Value);
1249 }
1250
1252 void Copy(TMeshAttributesConstRef<ElementIDType, TArrayView<AttributeType>> Src, const int32 DestChannel = 0, const int32 SrcChannel = 0);
1253
1254 UE_DEPRECATED(5.0, "Please use SetNumChannels().")
1255 void SetNumIndices(const int32 NumChannels) const
1256 {
1257 ArrayPtr->SetNumChannels(NumChannels);
1258 }
1259
1261 void SetNumChannels(const int32 NumChannels) const
1262 {
1263 ArrayPtr->SetNumChannels(NumChannels);
1264 }
1265
1266 UE_DEPRECATED(5.0, "Please use InsertChannel().")
1268 {
1269 ArrayPtr->InsertChannel(Index);
1270 }
1271
1273 void InsertChannel(const int32 Channel) const
1274 {
1275 ArrayPtr->InsertChannel(Channel);
1276 }
1277
1278 UE_DEPRECATED(5.0, "Please use RemoveChannel().")
1280 {
1281 ArrayPtr->RemoveChannel(Index);
1282 }
1283
1285 void RemoveChannel(const int32 Channel) const
1286 {
1287 ArrayPtr->RemoveChannel(Channel);
1288 }
1289
1290private:
1291 BaseArrayType* ArrayPtr;
1292 uint32 Extent;
1293};
1294
1295template <typename ElementIDType, typename AttributeType>
1297{
1298 check(Extent > 0);
1299 check(Src.IsValid());
1300 check(Src.Extent == Extent);
1301 const TMeshAttributeArrayBase<AttributeType>& SrcArray = static_cast<const BoundedArrayType*>(Src.ArrayPtr)->GetArrayForChannel(SrcChannel);
1302 TMeshAttributeArrayBase<AttributeType>& DestArray = static_cast<BoundedArrayType*>(ArrayPtr)->GetArrayForChannel(DestChannel);
1303 const int32 Num = FMath::Min(SrcArray.Num(), DestArray.Num());
1304 for (int32 Index = 0; Index < Num; Index++)
1305 {
1306 for (uint32 Count = 0; Count < Extent; Count++)
1307 {
1308 DestArray.GetElementBase(Index)[Count] = SrcArray.GetElementBase(Index)[Count];
1309 }
1310 }
1311}
1312
1313
1314template <typename ElementIDType, typename AttributeType>
1316{
1317 template <typename T, typename U> friend class TMeshAttributesRef;
1318
1319public:
1322
1325 : ArrayPtr(InArrayPtr)
1326 {}
1327
1329 template <typename SrcAttributeType,
1330 typename DestAttributeType = AttributeType,
1331 typename TEnableIf<std::is_const_v<DestAttributeType>, int>::Type = 0,
1332 typename TEnableIf<!std::is_const_v<SrcAttributeType>, int>::Type = 0>
1336
1338 template <typename IDType = ElementIDType,
1339 typename TEnableIf<!std::is_same_v<IDType, int32>, int>::Type = 0>
1343
1345 template <typename SrcAttributeType,
1346 typename DestAttributeType = AttributeType,
1347 typename IDType = ElementIDType,
1348 typename TEnableIf<!std::is_same_v<IDType, int32>, int>::Type = 0,
1349 typename TEnableIf<std::is_const_v<DestAttributeType>, int>::Type = 0,
1350 typename TEnableIf<!std::is_const_v<SrcAttributeType>, int>::Type = 0>
1354
1355
1359 {
1360 return TArrayAttribute<AttributeType>(static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0), ElementID.GetValue());
1361 }
1362
1365 TArrayAttribute<AttributeType> Get(const ElementIDType ElementID, const int32 Channel = 0) const
1366 {
1367 return TArrayAttribute<AttributeType>(static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel), ElementID.GetValue());
1368 }
1369
1371 {
1372 return TArrayAttribute<AttributeType>(static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0), ElementIndex);
1373 }
1374
1375 TArrayAttribute<AttributeType> Get(int32 ElementIndex, const int32 Channel = 0) const
1376 {
1377 return TArrayAttribute<AttributeType>(static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel), ElementIndex);
1378 }
1379
1380 TArrayView<AttributeType> GetArrayView(int32 ElementIndex, const int32 Channel = 0) const
1381 {
1382 return Get(ElementIndex, Channel).ToArrayView();
1383 }
1384
1387 {
1388 if (ArrayPtr == nullptr || GetNumElements() == 0)
1389 {
1390 return nullptr;
1391 }
1392
1393 return &static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(AttributeChannel);
1394 }
1395
1397 bool IsValid() const { return (ArrayPtr != nullptr); }
1398
1400 AttributeType GetDefaultValue() const { return static_cast<ArrayType*>(ArrayPtr)->GetDefaultValue(); }
1401
1404 {
1405 return static_cast<ArrayType*>(ArrayPtr)->ArrayType::GetNumChannels(); // note: override virtual dispatch
1406 }
1407
1410 {
1411 return ArrayPtr->GetNumElements();
1412 }
1413
1415 EMeshAttributeFlags GetFlags() const { return ArrayPtr->GetFlags(); }
1416
1420 {
1421 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).Set(ElementID.GetValue(), Value.ToArrayView());
1422 }
1423
1426 void Set(const ElementIDType ElementID, const int32 Channel, TArrayAttribute<const AttributeType> Value) const
1427 {
1428 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).Set(ElementID.GetValue(), Value.ToArrayView());
1429 }
1430
1432 {
1433 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).Set(ElementIndex, Value.ToArrayView());
1434 }
1435
1436 void Set(int32 ElementIndex, const int32 Channel, TArrayAttribute<const AttributeType> Value) const
1437 {
1438 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).Set(ElementIndex, Value.ToArrayView());
1439 }
1440
1442 {
1443 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(0).Set(ElementIndex, Value);
1444 }
1445
1446 void SetArrayView(int32 ElementIndex, const int32 Channel, TArrayView<const AttributeType> Value) const
1447 {
1448 static_cast<ArrayType*>(ArrayPtr)->GetArrayForChannel(Channel).Set(ElementIndex, Value);
1449 }
1450
1453
1455 void SetNumChannels(const int32 NumChannels) const
1456 {
1457 static_cast<ArrayType*>(ArrayPtr)->ArrayType::SetNumChannels(NumChannels); // note: override virtual dispatch
1458 }
1459
1461 void InsertChannel(const int32 Index) const
1462 {
1463 static_cast<ArrayType*>(ArrayPtr)->ArrayType::InsertChannel(Index); // note: override virtual dispatch
1464 }
1465
1467 void RemoveChannel(const int32 Index) const
1468 {
1469 static_cast<ArrayType*>(ArrayPtr)->ArrayType::RemoveChannel(Index); // note: override virtual dispatch
1470 }
1471
1472private:
1473 BaseArrayType* ArrayPtr;
1474};
1475
1476
1483{
1484public:
1490
1494 template <typename AttributeType>
1495 FAttributesSetEntry(const int32 NumberOfChannels, const AttributeType& Default, const EMeshAttributeFlags Flags, const int32 NumElements, const int32 Extent)
1496 {
1497 if (Extent > 0)
1498 {
1500 }
1501 else
1502 {
1504 }
1505 }
1506
1509
1512 : Ptr(Other.Ptr ? Other.Ptr->Clone() : nullptr)
1513 {}
1514
1517
1520 {
1522 Swap(*this, Temp);
1523 return *this;
1524 }
1525
1528
1530 inline const FMeshAttributeArraySetBase* Get() const { return Ptr.Get(); }
1531 inline const FMeshAttributeArraySetBase* operator->() const { return Ptr.Get(); }
1532 inline const FMeshAttributeArraySetBase& operator*() const { return *Ptr; }
1533 inline FMeshAttributeArraySetBase* Get() { return Ptr.Get(); }
1534 inline FMeshAttributeArraySetBase* operator->() { return Ptr.Get(); }
1535 inline FMeshAttributeArraySetBase& operator*() { return *Ptr; }
1536
1538 inline explicit operator bool() const { return Ptr.IsValid(); }
1539 inline bool operator!() const { return !Ptr.IsValid(); }
1540
1542 void CreateArrayOfType(const uint32 Type, const uint32 Extent);
1543
1545 friend FArchive& operator<<(FArchive& Ar, FAttributesSetEntry& Entry);
1546
1547private:
1549};
1550
1551
1557{
1558public:
1561 : NumElements(0)
1562 {}
1563
1576 template <typename T>
1578 const FName AttributeName,
1579 const int32 NumberOfChannels = 1,
1582 {
1583 using AttributeType = typename TMeshAttributesRegisterType<T>::AttributeType;
1584 using RealAttributeType = typename TMeshAttributesRegisterType<T>::RealAttributeType;
1585 using RefType = typename TMeshAttributesRegisterType<T>::RefType;
1587
1588 if (FAttributesSetEntry* ArraySetPtr = Map.Find(AttributeName))
1589 {
1590 if ((*ArraySetPtr)->HasType<RealAttributeType>() && (*ArraySetPtr)->GetExtent() == Extent)
1591 {
1592 (*ArraySetPtr)->SetNumChannels(NumberOfChannels);
1593 (*ArraySetPtr)->SetFlags(Flags);
1594 return TMeshAttributesArray<RefType>(ArraySetPtr->Get(), Extent);
1595 }
1596 else
1597 {
1598 Map.Remove(AttributeName);
1599 }
1600 }
1601
1602 FAttributesSetEntry& Entry = Map.Emplace(AttributeName, FAttributesSetEntry(NumberOfChannels, Default, Flags, NumElements, Extent));
1603 return TMeshAttributesArray<RefType>(Entry.Get(), Extent);
1604 }
1605
1612 template <typename T,
1613 typename TEnableIf<!TIsArray<T>::Value, int>::Type = 0>
1622
1629 template <typename T,
1630 typename TEnableIf<TIsArray<T>::Value, int>::Type = 0>
1639
1646 template <typename T,
1655
1659 void UnregisterAttribute(const FName AttributeName)
1660 {
1661 Map.Remove(AttributeName);
1662 }
1663
1665 bool HasAttribute(const FName AttributeName) const
1666 {
1667 return Map.Contains(AttributeName);
1668 }
1669
1673 template <typename T>
1674 bool HasAttributeOfType(const FName AttributeName) const
1675 {
1676 using RealAttributeType = typename TMeshAttributesRefType<T>::RealAttributeType;
1677
1678 if (const FAttributesSetEntry* ArraySetPtr = Map.Find(AttributeName))
1679 {
1680 return (*ArraySetPtr)->HasType<RealAttributeType>() &&
1681 (*ArraySetPtr)->GetExtent() >= TMeshAttributesRefType<T>::MinExpectedExtent &&
1682 (*ArraySetPtr)->GetExtent() <= TMeshAttributesRefType<T>::MaxExpectedExtent;
1683 }
1684
1685 return false;
1686 }
1687
1690 {
1692 for (auto& MapEntry : Map)
1693 {
1694 MapEntry.Value->Initialize(Count);
1695 }
1696 }
1697
1700 {
1702 for (auto& MapEntry : Map)
1703 {
1704 MapEntry.Value->SetNumElements(Count);
1705 }
1706 }
1707
1710 {
1711 return NumElements;
1712 }
1713
1715 void Remap(const TSparseArray<int32>& IndexRemap);
1716
1718 template <typename Allocator>
1723
1726 {
1727 if (const FAttributesSetEntry* ArraySetPtr = Map.Find(AttributeName))
1728 {
1729 return EnumHasAnyFlags((*ArraySetPtr)->GetFlags(), AttributeFlags);
1730 }
1731
1732 return false;
1733 }
1734
1737 {
1738 if (const FAttributesSetEntry* ArraySetPtr = Map.Find(AttributeName))
1739 {
1740 return EnumHasAllFlags((*ArraySetPtr)->GetFlags(), AttributeFlags);
1741 }
1742
1743 return false;
1744 }
1745
1746 uint32 GetHash(const FName AttributeName) const
1747 {
1748 if (const FAttributesSetEntry* ArraySetPtr = Map.Find(AttributeName))
1749 {
1750 return (*ArraySetPtr)->GetHash();
1751 }
1752 return 0;
1753 }
1754
1759 void Insert(const int32 Index)
1760 {
1761 NumElements = FMath::Max(NumElements, Index + 1);
1762
1763 for (auto& MapEntry : Map)
1764 {
1765 MapEntry.Value->Insert(Index);
1766
1767#if DO_CHECK
1768 // Log out some more debug info when this fails, as it's failing in public builds with no known repro
1769 if (MapEntry.Value->GetNumElements() != NumElements)
1770 {
1771 UE_LOGFMT(LogMeshDescription, Error, "NumElements mismatch in FAttributesSetBase::Insert");
1772 UE_LOGFMT(LogMeshDescription, Error, "NumElements: {NumElements}", NumElements);
1773 UE_LOGFMT(LogMeshDescription, Error, "Index: {Index}", Index);
1774 UE_LOGFMT(LogMeshDescription, Error, "Mismatched attribute: {Attribute}\n", MapEntry.Key.ToString());
1775
1776 for (const TPair<FName, FAttributesSetEntry>& Pair : Map)
1777 {
1778 UE_LOGFMT(LogMeshDescription, Error, "Attribute {Attribute} NumElements: {NumElements}\n", Pair.Key.ToString(), Pair.Value->GetNumElements());
1779 }
1780
1781 // Add some info to the assert message anyway, in case the logs are suppressed
1782 checkf(false, TEXT("NumElements mismatch in FAttributesSetBase::Insert: %s: %i != %i"), *MapEntry.Key.ToString(), MapEntry.Value->GetNumElements(), NumElements);
1783 }
1784#endif
1785 }
1786 }
1787
1792 void Remove(const int32 Index)
1793 {
1794 for (auto& MapEntry : Map)
1795 {
1796 MapEntry.Value->Remove(Index);
1797 }
1798 }
1799
1804 template <typename T>
1806 {
1807 using RefType = typename TMeshAttributesRefType<T>::ConstRefType;
1808
1809 if (const FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1810 {
1811 using AttributeType = typename TMeshAttributesRefType<T>::AttributeType;
1812 using RealAttributeType = typename TMeshAttributesRefType<T>::RealAttributeType;
1813
1814 if ((*ArraySetPtr)->HasType<RealAttributeType>())
1815 {
1816 uint32 ActualExtent = (*ArraySetPtr)->GetExtent();
1818 {
1820 }
1821 }
1822 }
1823
1825 }
1826
1827 template <typename T>
1829 {
1830 using RefType = typename TMeshAttributesRefType<T>::RefType;
1831
1832 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1833 {
1834 using AttributeType = typename TMeshAttributesRefType<T>::AttributeType;
1835 using RealAttributeType = typename TMeshAttributesRefType<T>::RealAttributeType;
1836
1837 if ((*ArraySetPtr)->HasType<RealAttributeType>())
1838 {
1839 uint32 ActualExtent = (*ArraySetPtr)->GetExtent();
1841 {
1843 }
1844 }
1845 }
1846
1848 }
1849
1851
1852protected:
1855
1856 template <typename T>
1858
1861
1864};
1865
1866
1871template <typename ElementIDType>
1873{
1876
1877public:
1894 template <typename T>
1896 {
1897 using RefType = typename TMeshAttributesRefType<T>::ConstRefType;
1898
1899 if (const FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1900 {
1901 using AttributeType = typename TMeshAttributesRefType<T>::AttributeType;
1902 using RealAttributeType = typename TMeshAttributesRefType<T>::RealAttributeType;
1903
1904 if ((*ArraySetPtr)->HasType<RealAttributeType>())
1905 {
1906 uint32 ActualExtent = (*ArraySetPtr)->GetExtent();
1908 {
1910 }
1911 }
1912 }
1913
1915 }
1916
1917 // Non-const version
1918 template <typename T>
1920 {
1921 using RefType = typename TMeshAttributesRefType<T>::RefType;
1922
1923 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1924 {
1925 using AttributeType = typename TMeshAttributesRefType<T>::AttributeType;
1926 using RealAttributeType = typename TMeshAttributesRefType<T>::RealAttributeType;
1927
1928 if ((*ArraySetPtr)->HasType<RealAttributeType>())
1929 {
1930 uint32 ActualExtent = (*ArraySetPtr)->GetExtent();
1932 {
1934 }
1935 }
1936 }
1937
1939 }
1940
1941
1942 UE_DEPRECATED(5.0, "Please use GetAttributeChannelCount() instead.")
1943 int32 GetAttributeIndexCount(const FName AttributeName) const
1944 {
1945 return GetAttributeChannelCount(AttributeName);
1946 }
1947
1949 int32 GetAttributeChannelCount(const FName AttributeName) const
1950 {
1951 if (const FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1952 {
1953 return (*ArraySetPtr)->GetNumChannels();
1954 }
1955
1956 return 0;
1957 }
1958
1959 template <typename AttributeType>
1960 UE_DEPRECATED(5.0, "Please use GetAttributeChannelCount() instead.")
1961 int32 GetAttributeIndexCount(const FName AttributeName) const
1962 {
1963 if (const FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1964 {
1965 if ((*ArraySetPtr)->HasType<AttributeType>())
1966 {
1967 using ArrayType = TMeshAttributeArraySet<AttributeType>;
1968 return static_cast<const ArrayType*>( ArraySetPtr->Get() )->ArrayType::GetNumChannels(); // note: override virtual dispatch
1969 }
1970 }
1971
1972 return 0;
1973 }
1974
1975 UE_DEPRECATED(5.0, "Please use SetAttributeChannelCount() instead.")
1976 void SetAttributeIndexCount(const FName AttributeName, const int32 NumChannels)
1977 {
1978 SetAttributeChannelCount(AttributeName, NumChannels);
1979 }
1980
1982 void SetAttributeChannelCount(const FName AttributeName, const int32 NumChannels)
1983 {
1984 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1985 {
1986 (*ArraySetPtr)->SetNumChannels(NumChannels);
1987 }
1988 }
1989
1990 template <typename AttributeType>
1991 UE_DEPRECATED(5.0, "Please use untemplated SetAttributeChannelCount() instead.")
1992 void SetAttributeIndexCount(const FName AttributeName, const int32 NumIndices)
1993 {
1994 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
1995 {
1996 if ((*ArraySetPtr)->HasType<AttributeType>())
1997 {
1998 using ArrayType = TMeshAttributeArraySet<AttributeType>;
1999 static_cast<ArrayType*>(ArraySetPtr->Get())->ArrayType::SetNumChannels(NumIndices); // note: override virtual dispatch
2000 }
2001 }
2002 }
2003
2004 UE_DEPRECATED(5.0, "Please use InsertAttributeChannel() instead.")
2005 void InsertAttributeIndex(const FName AttributeName, const int32 Index)
2006 {
2007 InsertAttributeChannel(AttributeName, Index);
2008 }
2009
2011 void InsertAttributeChannel(const FName AttributeName, const int32 Index)
2012 {
2013 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
2014 {
2015 (*ArraySetPtr)->InsertChannel(Index);
2016 }
2017 }
2018
2019 template <typename AttributeType>
2020 UE_DEPRECATED(5.0, "Please use untemplated InsertAttributeIndexCount() instead.")
2021 void InsertAttributeIndex(const FName AttributeName, const int32 Index)
2022 {
2023 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
2024 {
2025 if ((*ArraySetPtr)->HasType<AttributeType>())
2026 {
2027 using ArrayType = TMeshAttributeArraySet<AttributeType>;
2028 static_cast<ArrayType*>(ArraySetPtr->Get())->ArrayType::InsertChannel(Index); // note: override virtual dispatch
2029 }
2030 }
2031 }
2032
2033 UE_DEPRECATED(5.0, "Please use RemoveAttributeChannel() instead.")
2034 void RemoveAttributeIndex(const FName AttributeName, const int32 Index)
2035 {
2036 RemoveAttributeChannel(AttributeName, Index);
2037 }
2038
2040 void RemoveAttributeChannel(const FName AttributeName, const int32 Index)
2041 {
2042 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
2043 {
2044 (*ArraySetPtr)->RemoveChannel(Index);
2045 }
2046 }
2047
2048 template <typename AttributeType>
2049 UE_DEPRECATED(5.0, "Please use untemplated RemoveAttributeIndexCount() instead.")
2050 void RemoveAttributeIndex(const FName AttributeName, const int32 Index)
2051 {
2052 if (FAttributesSetEntry* ArraySetPtr = this->Map.Find(AttributeName))
2053 {
2054 if ((*ArraySetPtr)->HasType<AttributeType>())
2055 {
2056 using ArrayType = TMeshAttributeArraySet<AttributeType>;
2057 static_cast<ArrayType*>(ArraySetPtr->Get())->ArrayType::RemoveChannel(Index); // note: override virtual dispatch
2058 }
2059 }
2060 }
2061
2066 template <typename T>
2067 T GetAttribute(const ElementIDType ElementID, const FName AttributeName, const int32 AttributeChannel = 0) const
2068 {
2069 using RefType = typename TMeshAttributesRefType<T>::ConstRefType;
2070 using AttributeType = typename TMeshAttributesRefType<T>::AttributeType;
2071 using RealAttributeType = typename TMeshAttributesRefType<T>::RealAttributeType;
2072
2073 const FMeshAttributeArraySetBase* ArraySetPtr = this->Map.FindChecked(AttributeName).Get();
2074 uint32 ActualExtent = ArraySetPtr->GetExtent();
2075 check(ArraySetPtr->HasType<RealAttributeType>());
2077
2079 return Ref.Get(ElementID, AttributeChannel);
2080 }
2081
2082
2087 template <typename T>
2088 void SetAttribute(const ElementIDType ElementID, const FName AttributeName, const int32 AttributeChannel, const T& AttributeValue)
2089 {
2090 using NonConstRefType = typename TMeshAttributesRefType<T>::NonConstRefType;
2091 using AttributeType = typename TMeshAttributesRefType<T>::AttributeType;
2092 using RealAttributeType = typename TMeshAttributesRefType<T>::RealAttributeType;
2093
2094 FMeshAttributeArraySetBase* ArraySetPtr = this->Map.FindChecked(AttributeName).Get();
2095 uint32 ActualExtent = ArraySetPtr->GetExtent();
2096 check(ArraySetPtr->HasType<std::remove_cv_t<RealAttributeType>>());
2098
2100 return Ref.Set(ElementID, AttributeChannel, AttributeValue);
2101 }
2102
2103
2104
2106 inline void Insert(const ElementIDType ElementID)
2107 {
2108 this->Insert(ElementID.GetValue());
2109 }
2110
2112 inline void Remove(const ElementIDType ElementID)
2113 {
2114 this->Remove(ElementID.GetValue());
2115 }
2116
2121 template <typename ForEachFunc> void ForEach(ForEachFunc Func);
2122
2127 template <typename ForEachFunc> void ForEach(ForEachFunc Func) const;
2128
2134 template <typename AttributeType, typename ForEachFunc> void ForEachByType(ForEachFunc Func);
2135
2141 template <typename AttributeType, typename ForEachFunc> void ForEachByType(ForEachFunc Func) const;
2142};
2143
2144
2183template <typename FnType, uint32 Size>
2185{
2186 template <typename... T>
2187 explicit constexpr TJumpTable( T... Ts ) : Fns{ Ts... } {}
2188
2190};
2191
2192
2193
2195{
2196 // Declare type of jump table used to dispatch functions
2197 template <typename ElementIDType, typename ForEachFunc>
2199
2200 // Define dispatch function
2201 template <typename ElementIDType, typename ForEachFunc, uint32 I>
2202 static void Dispatch(FName Name, ForEachFunc Fn, FMeshAttributeArraySetBase* Attributes)
2203 {
2204 using AttributeType = typename TTupleElement<I, AttributeTypes>::Type;
2205 if (Attributes->GetExtent() == 0)
2206 {
2208 }
2209 else if (Attributes->GetExtent() == 1)
2210 {
2212 }
2213 else
2214 {
2216 }
2217 }
2218
2219 // Build ForEach jump table at compile time, a separate instantiation of Dispatch for each attribute type
2220 template <typename ElementIDType, typename ForEachFunc, uint32... Is>
2222 {
2224 }
2225}
2226
2227template <typename ElementIDType>
2228template <typename ForEachFunc>
2230{
2231 // Construct compile-time jump table for dispatching ForEachImpl::Dispatch() by the attribute type at runtime
2233 JumpTable = ForEachImpl::MakeJumpTable<ElementIDType, ForEachFunc>(TMakeIntegerSequence<uint32, TTupleArity<AttributeTypes>::Value>());
2234
2235 for (auto& MapEntry : this->Map)
2236 {
2237 const uint32 Type = MapEntry.Value->GetType();
2238 JumpTable.Fns[Type](MapEntry.Key, Func, MapEntry.Value.Get());
2239 }
2240}
2241
2242
2244{
2245 // Declare type of jump table used to dispatch functions
2246 template <typename ElementIDType, typename ForEachFunc>
2248
2249 // Define dispatch function
2250 template <typename ElementIDType, typename ForEachFunc, uint32 I>
2251 static void Dispatch(FName Name, ForEachFunc Fn, const FMeshAttributeArraySetBase* Attributes)
2252 {
2253 using AttributeType = typename TTupleElement<I, AttributeTypes>::Type;
2254 if (Attributes->GetExtent() == 0)
2255 {
2257 }
2258 else if (Attributes->GetExtent() == 1)
2259 {
2261 }
2262 else
2263 {
2265 }
2266 }
2267
2268 // Build ForEach jump table at compile time, a separate instantiation of Dispatch for each attribute type
2269 template <typename ElementIDType, typename ForEachFunc, uint32... Is>
2271 {
2273 }
2274}
2275
2276template <typename ElementIDType>
2277template <typename ForEachFunc>
2279{
2280 // Construct compile-time jump table for dispatching ForEachImpl::Dispatch() by the attribute type at runtime
2282 JumpTable = ForEachConstImpl::MakeJumpTable<ElementIDType, ForEachFunc>(TMakeIntegerSequence<uint32, TTupleArity<AttributeTypes>::Value>());
2283
2284 for (const auto& MapEntry : this->Map)
2285 {
2286 const uint32 Type = MapEntry.Value->GetType();
2287 JumpTable.Fns[Type](MapEntry.Key, Func, MapEntry.Value.Get());
2288 }
2289}
2290
2291
2293{
2294 template<typename ElementIDType, typename AttributeType, typename ForEachFunc>
2296 {
2298 {
2299 if (TTupleIndex<AttributeType, AttributeTypes>::Value == Attributes->GetType() && Attributes->GetExtent() == 1)
2300 {
2302 }
2303 }
2304 };
2305
2306 template<typename ElementIDType, typename AttributeType, typename ForEachFunc>
2308 {
2310 {
2311 if (TTupleIndex<AttributeType, AttributeTypes>::Value == Attributes->GetType() && Attributes->GetExtent() >= 1)
2312 {
2314 }
2315 }
2316 };
2317
2318 template<typename ElementIDType, typename AttributeType, typename ForEachFunc>
2329
2330 template<typename ElementIDType, typename AttributeType, typename ForEachFunc>
2332 {
2334 {
2335 if (TTupleIndex<AttributeType, AttributeTypes>::Value == Attributes->GetType() && Attributes->GetExtent() == 1)
2336 {
2338 }
2339 }
2340 };
2341
2342 template<typename ElementIDType, typename AttributeType, typename ForEachFunc>
2344 {
2346 {
2347 if (TTupleIndex<AttributeType, AttributeTypes>::Value == Attributes->GetType() && Attributes->GetExtent() >= 1)
2348 {
2350 }
2351 }
2352 };
2353
2354 template<typename ElementIDType, typename AttributeType, typename ForEachFunc>
2365
2366template <typename ElementIDType>
2367template < typename AttributeType, typename ForEachFunc>
2375
2376template <typename ElementIDType>
2377template < typename AttributeType, typename ForEachFunc>
2385
2386
2394{
2395 // Declare type of jump table used to dispatch functions
2397
2398 // Define dispatch function
2399 template <uint32 I>
2400 static TUniquePtr<FMeshAttributeArraySetBase> Dispatch(uint32 Extent)
2401 {
2402 using AttributeType = typename TTupleElement<I, AttributeTypes>::Type;
2403 if (Extent > 0)
2404 {
2406 }
2407 else
2408 {
2410 }
2411 }
2412
2413 // Build RegisterAttributeOfType jump table at compile time, a separate instantiation of Dispatch for each attribute type
2414 template <uint32... Is>
2415 static constexpr JumpTableType MakeJumpTable(TIntegerSequence< uint32, Is...>)
2416 {
2417 return JumpTableType(Dispatch<Is>...);
2418 }
2419}
2420
2421inline void FAttributesSetEntry::CreateArrayOfType(const uint32 Type, const uint32 Extent)
2422{
2423 static constexpr CreateTypeImpl::JumpTableType JumpTable = CreateTypeImpl::MakeJumpTable(TMakeIntegerSequence<uint32, TTupleArity<AttributeTypes>::Value>());
2424 Ptr = JumpTable.Fns[Type](Extent);
2425}
2426
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
typename TCopyQualifiersFromTo< From, To >::Type TCopyQualifiersFromTo_T
Definition CopyQualifiersFromTo.h:17
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
constexpr bool EnumHasAnyFlags(Enum Flags, Enum Contains)
Definition EnumClassFlags.h:35
constexpr bool EnumHasAllFlags(Enum Flags, Enum Contains)
Definition EnumClassFlags.h:28
#define ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:6
typename UE4IntegerSequence_Private::TMakeIntegerSequenceImpl< T, N >::Type TMakeIntegerSequence
Definition IntegerSequence.h:31
UE::Math::TVector2< float > FVector2f
Definition MathFwd.h:74
UE::Math::TVector< float > FVector3f
Definition MathFwd.h:73
UE::Math::TVector4< float > FVector4f
Definition MathFwd.h:75
TEnableIf<!TIsBulkSerializable< T >::Value, FArchive >::Type & operator<<(FArchive &Ar, TMeshAttributeArrayBase< T > &Array)
Definition MeshAttributeArray.h:222
EMeshAttributeFlags
Definition MeshAttributeArray.h:292
@ Num
Definition MetalRHIPrivate.h:234
const bool
Definition NetworkReplayStreaming.h:178
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
#define UE_LOGFMT(CategoryName, Verbosity, Format,...)
Definition StructuredLog.h:46
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint32 Size
Definition VulkanMemory.cpp:4034
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
CORE_API int32 CustomVer(const struct FGuid &Key) const
Definition Archive.cpp:602
virtual CORE_API const FCustomVersionContainer & GetCustomVersions() const
Definition Archive.cpp:546
Definition MeshAttributeArray.h:1557
void Insert(const int32 Index)
Definition MeshAttributeArray.h:1759
FAttributesSetBase()
Definition MeshAttributeArray.h:1560
TMeshAttributesArray< typename TMeshAttributesRegisterType< T >::RefType > RegisterAttribute(const FName AttributeName, const int32 NumberOfChannels=1, const T &Default=T(), const EMeshAttributeFlags Flags=EMeshAttributeFlags::None)
Definition MeshAttributeArray.h:1614
bool DoesAttributeHaveAnyFlags(const FName AttributeName, EMeshAttributeFlags AttributeFlags) const
Definition MeshAttributeArray.h:1725
TMap< FName, FAttributesSetEntry > Map
Definition MeshAttributeArray.h:1860
TMeshAttributesRef< int32, typename TMeshAttributesRefType< T >::RefType > GetAttributesRef(const FName AttributeName)
Definition MeshAttributeArray.h:1828
void Initialize(const int32 Count)
Definition MeshAttributeArray.h:1689
int32 GetNumElements() const
Definition MeshAttributeArray.h:1709
uint32 GetHash(const FName AttributeName) const
Definition MeshAttributeArray.h:1746
TMeshAttributesConstRef< int32, typename TMeshAttributesRefType< T >::ConstRefType > GetAttributesRef(const FName AttributeName) const
Definition MeshAttributeArray.h:1805
void Remap(const TSparseArray< int32 > &IndexRemap)
Definition MeshAttributeArray.cpp:112
void AppendAttributesFrom(const FAttributesSetBase &OtherAttributesSet)
Definition MeshAttributeArray.cpp:132
bool DoesAttributeHaveAllFlags(const FName AttributeName, EMeshAttributeFlags AttributeFlags) const
Definition MeshAttributeArray.h:1736
TMeshAttributesArray< typename TMeshAttributesRegisterType< T >::RefType > RegisterAttributeInternal(const FName AttributeName, const int32 NumberOfChannels=1, const typename TMeshAttributesRegisterType< T >::RealAttributeType &Default=typename TMeshAttributesRegisterType< T >::RealAttributeType(), const EMeshAttributeFlags Flags=EMeshAttributeFlags::None)
Definition MeshAttributeArray.h:1577
friend MESHDESCRIPTION_API FArchive & operator<<(FArchive &Ar, FAttributesSetBase &AttributesSet)
Definition MeshAttributeArray.cpp:56
TMeshAttributesArray< typename TMeshAttributesRegisterType< T >::RefType > RegisterIndexAttribute(const FName AttributeName, const int32 NumberOfChannels=1, const EMeshAttributeFlags Flags=EMeshAttributeFlags::None)
Definition MeshAttributeArray.h:1648
TMeshAttributesArray< typename TMeshAttributesRegisterType< T >::RefType > RegisterAttribute(const FName AttributeName, const int32 NumberOfChannels=1, const typename TMeshAttributesRegisterType< T >::RealAttributeType &Default=typename TMeshAttributesRegisterType< T >::RealAttributeType(), const EMeshAttributeFlags Flags=EMeshAttributeFlags::None)
Definition MeshAttributeArray.h:1631
int32 NumElements
Definition MeshAttributeArray.h:1863
friend void SerializeLegacy(FArchive &Ar, FAttributesSetBase &AttributesSet)
Definition MeshAttributeArray.cpp:41
void Remove(const int32 Index)
Definition MeshAttributeArray.h:1792
void GetAttributeNames(TArray< FName, Allocator > &OutAttributeNames) const
Definition MeshAttributeArray.h:1719
bool HasAttribute(const FName AttributeName) const
Definition MeshAttributeArray.h:1665
bool HasAttributeOfType(const FName AttributeName) const
Definition MeshAttributeArray.h:1674
void UnregisterAttribute(const FName AttributeName)
Definition MeshAttributeArray.h:1659
void SetNumElements(const int32 Count)
Definition MeshAttributeArray.h:1699
Definition MeshAttributeArray.h:1483
FAttributesSetEntry(FAttributesSetEntry &&)=default
friend FArchive & operator<<(FArchive &Ar, FAttributesSetEntry &Entry)
Definition MeshAttributeArray.cpp:9
FAttributesSetEntry & operator=(const FAttributesSetEntry &Other)
Definition MeshAttributeArray.h:1519
const FMeshAttributeArraySetBase * Get() const
Definition MeshAttributeArray.h:1530
FAttributesSetEntry()=default
const FMeshAttributeArraySetBase * operator->() const
Definition MeshAttributeArray.h:1531
void CreateArrayOfType(const uint32 Type, const uint32 Extent)
Definition MeshAttributeArray.h:2421
FAttributesSetEntry(const int32 NumberOfChannels, const AttributeType &Default, const EMeshAttributeFlags Flags, const int32 NumElements, const int32 Extent)
Definition MeshAttributeArray.h:1495
FAttributesSetEntry(const FAttributesSetEntry &Other)
Definition MeshAttributeArray.h:1511
FAttributesSetEntry & operator=(FAttributesSetEntry &&)=default
FMeshAttributeArraySetBase * Get()
Definition MeshAttributeArray.h:1533
FMeshAttributeArraySetBase & operator*()
Definition MeshAttributeArray.h:1535
~FAttributesSetEntry()=default
FMeshAttributeArraySetBase * operator->()
Definition MeshAttributeArray.h:1534
const FMeshAttributeArraySetBase & operator*() const
Definition MeshAttributeArray.h:1532
bool operator!() const
Definition MeshAttributeArray.h:1539
CORE_API const FCustomVersion * GetVersion(FGuid CustomKey) const
Definition CustomVersion.cpp:365
Definition MeshAttributeArray.h:318
virtual void Serialize(FArchive &Ar)=0
virtual void Remap(const TSparseArray< int32 > &IndexRemap)=0
uint32 GetExtent() const
Definition MeshAttributeArray.h:364
uint32 GetType() const
Definition MeshAttributeArray.h:361
virtual ~FMeshAttributeArraySetBase()=default
virtual void SetNumIndices(const int32 NumIndices)=0
int32 GetNumElements() const
Definition MeshAttributeArray.h:373
void SetFlags(const EMeshAttributeFlags InFlags)
Definition MeshAttributeArray.h:370
virtual void Insert(const int32 Index)=0
virtual int32 GetNumChannels() const =0
EMeshAttributeFlags Flags
Definition MeshAttributeArray.h:386
FMeshAttributeArraySetBase(const uint32 InType, const EMeshAttributeFlags InFlags, const int32 InNumberOfElements, const uint32 InExtent)
Definition MeshAttributeArray.h:321
virtual int32 GetNumIndices() const =0
virtual void InsertIndex(const int32 Index)=0
virtual void Initialize(const int32 Count)=0
virtual void InsertChannel(const int32 Index)=0
virtual void SetNumChannels(const int32 NumChannels)=0
virtual void SetNumElements(const int32 Count)=0
virtual TUniquePtr< FMeshAttributeArraySetBase > Clone() const =0
virtual void RemoveChannel(const int32 Index)=0
int32 NumElements
Definition MeshAttributeArray.h:383
virtual uint32 GetHash() const =0
uint32 Type
Definition MeshAttributeArray.h:377
EMeshAttributeFlags GetFlags() const
Definition MeshAttributeArray.h:367
virtual void Remove(const int32 Index)=0
uint32 Extent
Definition MeshAttributeArray.h:380
virtual void RemoveIndex(const int32 Index)=0
bool HasType() const
Definition MeshAttributeArray.h:355
Definition NameTypes.h:617
Definition AttributeArrayContainer.h:393
Definition ArrayView.h:139
UE_FORCEINLINE_HINT constexpr SizeType Num() const
Definition ArrayView.h:380
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Reset(SizeType NewSize=0)
Definition Array.h:2246
UE_NODEBUG UE_FORCEINLINE_HINT ElementType * GetData() UE_LIFETIMEBOUND
Definition Array.h:1027
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
Definition AttributeArrayContainer.h:12
void Initialize(const int32 ElementCount, const AttributeType &Default)
Definition AttributeArrayContainer.h:24
Definition MeshAttributeArray.h:1873
void ForEach(ForEachFunc Func)
Definition MeshAttributeArray.h:2229
void ForEachByType(ForEachFunc Func)
Definition MeshAttributeArray.h:2368
void SetAttributeChannelCount(const FName AttributeName, const int32 NumChannels)
Definition MeshAttributeArray.h:1982
void InsertAttributeChannel(const FName AttributeName, const int32 Index)
Definition MeshAttributeArray.h:2011
TMeshAttributesRef< ElementIDType, typename TMeshAttributesRefType< T >::RefType > GetAttributesRef(const FName AttributeName)
Definition MeshAttributeArray.h:1919
TMeshAttributesConstRef< ElementIDType, typename TMeshAttributesRefType< T >::ConstRefType > GetAttributesRef(const FName AttributeName) const
Definition MeshAttributeArray.h:1895
void SetAttribute(const ElementIDType ElementID, const FName AttributeName, const int32 AttributeChannel, const T &AttributeValue)
Definition MeshAttributeArray.h:2088
void RemoveAttributeIndex(const FName AttributeName, const int32 Index)
Definition MeshAttributeArray.h:2034
void RemoveAttributeChannel(const FName AttributeName, const int32 Index)
Definition MeshAttributeArray.h:2040
void Remove(const ElementIDType ElementID)
Definition MeshAttributeArray.h:2112
void InsertAttributeIndex(const FName AttributeName, const int32 Index)
Definition MeshAttributeArray.h:2005
int32 GetAttributeIndexCount(const FName AttributeName) const
Definition MeshAttributeArray.h:1943
int32 GetAttributeChannelCount(const FName AttributeName) const
Definition MeshAttributeArray.h:1949
T GetAttribute(const ElementIDType ElementID, const FName AttributeName, const int32 AttributeChannel=0) const
Definition MeshAttributeArray.h:2067
void Insert(const ElementIDType ElementID)
Definition MeshAttributeArray.h:2106
void SetAttributeIndexCount(const FName AttributeName, const int32 NumChannels)
Definition MeshAttributeArray.h:1976
Definition EnableIf.h:20
Definition UnrealString.h.inl:34
Definition MeshAttributeArray.h:84
uint32 Extent
Definition MeshAttributeArray.h:162
const AttributeType * GetElementBase(const int32 Index) const
Definition MeshAttributeArray.h:152
void Remap(const TSparseArray< int32 > &IndexRemap, const AttributeType &Default)
Definition MeshAttributeArray.h:200
void Initialize(const int32 ElementCount, const AttributeType &Default)
Definition MeshAttributeArray.h:102
uint32 GetHash(uint32 Crc=0) const
Definition MeshAttributeArray.h:125
uint32 GetExtent() const
Definition MeshAttributeArray.h:155
const AttributeType * GetData() const
Definition MeshAttributeArray.h:99
void Insert(const int32 Index, const AttributeType &Default)
Definition MeshAttributeArray.h:179
TMeshAttributeArrayBase(uint32 InExtent=1)
Definition MeshAttributeArray.h:86
AttributeType * GetElementBase(const int32 Index)
Definition MeshAttributeArray.h:153
int32 Num() const
Definition MeshAttributeArray.h:95
void SetNum(const int32 ElementCount, const AttributeType &Default)
Definition MeshAttributeArray.h:111
TArray< AttributeType > Container
Definition MeshAttributeArray.h:159
void SetToDefault(const int32 Index, const AttributeType &Default)
Definition MeshAttributeArray.h:134
friend TEnableIf<!TIsBulkSerializable< T >::Value, FArchive >::Type & operator<<(FArchive &Ar, TMeshAttributeArrayBase< T > &Array)
Definition MeshAttributeArray.h:222
Definition MeshAttributeArray.h:395
virtual void SetNumChannels(const int32 NumChannels) override
Definition MeshAttributeArray.h:495
virtual void SetNumIndices(const int32 NumIndices) override
Definition MeshAttributeArray.h:492
virtual void SetNumElements(const int32 Count) override
Definition MeshAttributeArray.h:450
const TMeshAttributeArrayBase< AttributeType > & GetArrayForIndex(const int32 Index) const
Definition MeshAttributeArray.h:537
const TMeshAttributeArrayBase< AttributeType > & GetArrayForChannel(const int32 Index) const
Definition MeshAttributeArray.h:542
virtual void Remove(const int32 Index) override
Definition MeshAttributeArray.h:431
virtual void InsertIndex(const int32 Index) override
Definition MeshAttributeArray.h:511
AttributeType DefaultValue
Definition MeshAttributeArray.h:564
virtual int32 GetNumIndices() const override
Definition MeshAttributeArray.h:486
TMeshAttributeArraySet(const int32 NumberOfChannels, const AttributeType &InDefaultValue, const EMeshAttributeFlags InFlags, const int32 InNumberOfElements, const uint32 Extent)
Definition MeshAttributeArray.h:406
virtual void RemoveIndex(const int32 Index) override
Definition MeshAttributeArray.h:524
virtual void Remap(const TSparseArray< int32 > &IndexRemap) override
Definition MeshAttributeArray.h:476
virtual uint32 GetHash() const override
Definition MeshAttributeArray.h:459
virtual int32 GetNumChannels() const override
Definition MeshAttributeArray.h:489
virtual void RemoveChannel(const int32 Index) override
Definition MeshAttributeArray.h:530
virtual void Serialize(FArchive &Ar) override
Definition MeshAttributeArray.h:470
virtual void Initialize(const int32 Count) override
Definition MeshAttributeArray.h:440
TArray< TMeshAttributeArrayBase< AttributeType >, TInlineAllocator< 1 > > ArrayForChannels
Definition MeshAttributeArray.h:561
TMeshAttributeArrayBase< AttributeType > & GetArrayForChannel(const int32 Index)
Definition MeshAttributeArray.h:543
virtual void InsertChannel(const int32 Index) override
Definition MeshAttributeArray.h:517
friend FArchive & operator<<(FArchive &Ar, TMeshAttributeArraySet &AttributeArraySet)
Definition MeshAttributeArray.h:549
virtual void Insert(const int32 Index) override
Definition MeshAttributeArray.h:420
AttributeType GetDefaultValue() const
Definition MeshAttributeArray.h:546
virtual TUniquePtr< FMeshAttributeArraySetBase > Clone() const override
Definition MeshAttributeArray.h:414
TMeshAttributeArraySet(const int32 Extent=1)
Definition MeshAttributeArray.h:402
void Set(const ElementIDType ElementID, const int32 Channel, TArrayAttribute< const AttributeType > Value) const
Definition MeshAttributeArray.h:1426
void RemoveChannel(const int32 Index) const
Definition MeshAttributeArray.h:1467
int32 GetNumElements() const
Definition MeshAttributeArray.h:1409
TArrayAttribute< AttributeType > Get(const ElementIDType ElementID, const int32 Channel=0) const
Definition MeshAttributeArray.h:1365
TMeshAttributesRef(const TMeshAttributesRef< int32, TArrayAttribute< SrcAttributeType > > &InRef)
Definition MeshAttributeArray.h:1351
TArrayAttribute< AttributeType > operator[](int32 ElementIndex) const
Definition MeshAttributeArray.h:1370
TCopyQualifiersFromTo_T< AttributeType, FMeshAttributeArraySetBase > BaseArrayType
Definition MeshAttributeArray.h:1320
void SetArrayView(int32 ElementIndex, const int32 Channel, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1446
bool IsValid() const
Definition MeshAttributeArray.h:1397
TCopyQualifiersFromTo_T< AttributeType, TMeshUnboundedAttributeArraySet< std::remove_cv_t< AttributeType > > > ArrayType
Definition MeshAttributeArray.h:1321
void Set(int32 ElementIndex, const int32 Channel, TArrayAttribute< const AttributeType > Value) const
Definition MeshAttributeArray.h:1436
void SetNumChannels(const int32 NumChannels) const
Definition MeshAttributeArray.h:1455
void Set(int32 ElementIndex, TArrayAttribute< const AttributeType > Value) const
Definition MeshAttributeArray.h:1431
TMeshAttributesRef(const TMeshAttributesRef< ElementIDType, TArrayAttribute< SrcAttributeType > > &InRef)
Definition MeshAttributeArray.h:1333
void InsertChannel(const int32 Index) const
Definition MeshAttributeArray.h:1461
void Set(const ElementIDType ElementID, TArrayAttribute< const AttributeType > Value) const
Definition MeshAttributeArray.h:1419
AttributeType GetDefaultValue() const
Definition MeshAttributeArray.h:1400
TArrayAttribute< AttributeType > Get(int32 ElementIndex, const int32 Channel=0) const
Definition MeshAttributeArray.h:1375
TMeshAttributesRef(const TMeshAttributesRef< int32, TArrayAttribute< AttributeType > > &InRef)
Definition MeshAttributeArray.h:1340
void Copy(TMeshAttributesConstRef< ElementIDType, TArrayAttribute< AttributeType > > Src, const int32 DestChannel=0, const int32 SrcChannel=0)
void SetArrayView(int32 ElementIndex, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1441
TMeshAttributesRef(BaseArrayType *InArrayPtr=nullptr, uint32 InExtent=0)
Definition MeshAttributeArray.h:1324
EMeshAttributeFlags GetFlags() const
Definition MeshAttributeArray.h:1415
TArrayView< AttributeType > GetArrayView(int32 ElementIndex, const int32 Channel=0) const
Definition MeshAttributeArray.h:1380
int32 GetNumChannels() const
Definition MeshAttributeArray.h:1403
const TAttributeArrayContainer< AttributeType > * GetRawArray(const int32 AttributeChannel=0) const
Definition MeshAttributeArray.h:1386
TArrayAttribute< AttributeType > operator[](const ElementIDType ElementID) const
Definition MeshAttributeArray.h:1358
TArrayView< AttributeType > GetArrayView(int32 ElementIndex, const int32 Channel=0) const
Definition MeshAttributeArray.h:1141
TArrayView< AttributeType > GetRawArray(const int32 ChannelIndex=0) const
Definition MeshAttributeArray.h:1153
TCopyQualifiersFromTo_T< AttributeType, TMeshUnboundedAttributeArraySet< std::remove_cv_t< AttributeType > > > UnboundedArrayType
Definition MeshAttributeArray.h:1046
void Set(const ElementIDType ElementID, const int32 Channel, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1211
TMeshAttributesRef(const TMeshAttributesRef< ElementIDType, TArrayView< SrcAttributeType > > &InRef)
Definition MeshAttributeArray.h:1059
TMeshAttributesRef(const TMeshAttributesRef< int32, TArrayView< SrcAttributeType > > &InRef)
Definition MeshAttributeArray.h:1079
void SetArrayView(int32 ElementIndex, const int32 Channel, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1246
TArrayView< AttributeType > Get(int32 ElementIndex, const int32 Channel=0) const
Definition MeshAttributeArray.h:1128
void RemoveChannel(const int32 Channel) const
Definition MeshAttributeArray.h:1285
int32 GetNumElements() const
Definition MeshAttributeArray.h:1186
void Set(const ElementIDType ElementID, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1199
TArrayView< AttributeType > Get(const ElementIDType ElementID, const int32 Channel=0) const
Definition MeshAttributeArray.h:1102
void Set(int32 ElementIndex, const int32 Channel, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1231
uint32 GetExtent() const
Definition MeshAttributeArray.h:1195
int32 GetNumChannels() const
Definition MeshAttributeArray.h:1180
void SetArrayView(int32 ElementIndex, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1241
EMeshAttributeFlags GetFlags() const
Definition MeshAttributeArray.h:1192
TCopyQualifiersFromTo_T< AttributeType, TMeshAttributeArraySet< std::remove_cv_t< AttributeType > > > BoundedArrayType
Definition MeshAttributeArray.h:1045
TMeshAttributesRef(BaseArrayType *InArrayPtr=nullptr, uint32 InExtent=1)
Definition MeshAttributeArray.h:1049
AttributeType GetDefaultValue() const
Definition MeshAttributeArray.h:1171
TCopyQualifiersFromTo_T< AttributeType, FMeshAttributeArraySetBase > BaseArrayType
Definition MeshAttributeArray.h:1044
bool IsValid() const
Definition MeshAttributeArray.h:1168
void SetNumChannels(const int32 NumChannels) const
Definition MeshAttributeArray.h:1261
TMeshAttributesRef(const TMeshAttributesRef< int32, TArrayView< AttributeType > > &InRef)
Definition MeshAttributeArray.h:1067
void InsertChannel(const int32 Channel) const
Definition MeshAttributeArray.h:1273
TArrayView< AttributeType > operator[](int32 ElementIndex) const
Definition MeshAttributeArray.h:1115
TArrayView< AttributeType > operator[](const ElementIDType ElementID) const
Definition MeshAttributeArray.h:1087
void Set(int32 ElementIndex, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:1221
Definition MeshAttributeArray.h:836
TCopyQualifiersFromTo_T< AttributeType, TMeshAttributeArraySet< std::remove_cv_t< AttributeType > > > ArrayType
Definition MeshAttributeArray.h:841
void SetArrayView(int32 ElementIndex, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:969
void SetArrayView(int32 ElementIndex, const int32 Channel, TArrayView< const AttributeType > Value) const
Definition MeshAttributeArray.h:975
AttributeType & operator[](const ElementIDType ElementID) const
Definition MeshAttributeArray.h:877
AttributeType Get(int32 ElementIndex, const int32 Channel=0) const
Definition MeshAttributeArray.h:894
void SetNumIndices(const int32 NumChannels) const
Definition MeshAttributeArray.h:985
TArrayView< AttributeType > GetRawArray(const int32 AttributeChannel=0) const
Definition MeshAttributeArray.h:904
TCopyQualifiersFromTo_T< AttributeType, FMeshAttributeArraySetBase > BaseArrayType
Definition MeshAttributeArray.h:840
EMeshAttributeFlags GetFlags() const
Definition MeshAttributeArray.h:940
AttributeType & operator[](int32 ElementIndex) const
Definition MeshAttributeArray.h:889
int32 GetNumChannels() const
Definition MeshAttributeArray.h:928
void Set(int32 ElementIndex, const int32 Channel, const AttributeType &Value) const
Definition MeshAttributeArray.h:964
TMeshAttributesRef(const TMeshAttributesRef< int32, AttributeType > &InRef)
Definition MeshAttributeArray.h:860
TArrayView< AttributeType > GetArrayView(int32 ElementIndex, const int32 Channel=0) const
Definition MeshAttributeArray.h:899
void SetNumChannels(const int32 NumChannels) const
Definition MeshAttributeArray.h:991
void InsertIndex(const int32 Index) const
Definition MeshAttributeArray.h:997
int32 GetNumElements() const
Definition MeshAttributeArray.h:934
TMeshAttributesRef(const TMeshAttributesRef< ElementIDType, SrcAttributeType > &InRef)
Definition MeshAttributeArray.h:853
AttributeType Get(const ElementIDType ElementID, const int32 Channel=0) const
Definition MeshAttributeArray.h:884
TMeshAttributesRef(BaseArrayType *InArrayPtr=nullptr, uint32 InExtent=1)
Definition MeshAttributeArray.h:844
void InsertChannel(const int32 Channel) const
Definition MeshAttributeArray.h:1003
TMeshAttributesRef(const TMeshAttributesRef< int32, SrcAttributeType > &InRef)
Definition MeshAttributeArray.h:871
uint32 GetExtent() const
Definition MeshAttributeArray.h:943
AttributeType GetDefaultValue() const
Definition MeshAttributeArray.h:919
void Copy(TMeshAttributesRef< ElementIDType, const AttributeType > Src, const int32 DestChannel=0, const int32 SrcChannel=0)
Definition MeshAttributeArray.h:1025
void Set(const ElementIDType ElementID, const AttributeType &Value) const
Definition MeshAttributeArray.h:947
void RemoveChannel(const int32 Channel) const
Definition MeshAttributeArray.h:1015
bool IsValid() const
Definition MeshAttributeArray.h:916
void RemoveIndex(const int32 Index) const
Definition MeshAttributeArray.h:1009
void Set(int32 ElementIndex, const AttributeType &Value) const
Definition MeshAttributeArray.h:959
int32 GetNumIndices() const
Definition MeshAttributeArray.h:922
void Set(const ElementIDType ElementID, const int32 Channel, const AttributeType &Value) const
Definition MeshAttributeArray.h:954
Definition MeshAttributeArray.h:573
virtual uint32 GetHash() const override
Definition MeshAttributeArray.h:635
virtual void SetNumIndices(const int32 NumIndices) override
Definition MeshAttributeArray.h:668
virtual void Remap(const TSparseArray< int32 > &IndexRemap) override
Definition MeshAttributeArray.h:652
TMeshUnboundedAttributeArraySet(const int32 NumberOfChannels, const AttributeType &InDefaultValue, const EMeshAttributeFlags InFlags, const int32 InNumberOfElements)
Definition MeshAttributeArray.h:582
virtual void SetNumElements(const int32 Count) override
Definition MeshAttributeArray.h:626
virtual void InsertIndex(const int32 Index) override
Definition MeshAttributeArray.h:687
friend FArchive & operator<<(FArchive &Ar, TMeshUnboundedAttributeArraySet &AttributeArraySet)
Definition MeshAttributeArray.h:719
virtual void Serialize(FArchive &Ar) override
Definition MeshAttributeArray.h:646
const TAttributeArrayContainer< AttributeType > & GetArrayForChannel(const int32 Index) const
Definition MeshAttributeArray.h:712
TArray< TAttributeArrayContainer< AttributeType >, TInlineAllocator< 1 > > ArrayForChannels
Definition MeshAttributeArray.h:731
TMeshUnboundedAttributeArraySet()
Definition MeshAttributeArray.h:578
virtual void Insert(const int32 Index) override
Definition MeshAttributeArray.h:596
AttributeType GetDefaultValue() const
Definition MeshAttributeArray.h:716
virtual int32 GetNumChannels() const override
Definition MeshAttributeArray.h:665
virtual void Remove(const int32 Index) override
Definition MeshAttributeArray.h:607
AttributeType DefaultValue
Definition MeshAttributeArray.h:734
virtual int32 GetNumIndices() const override
Definition MeshAttributeArray.h:662
TAttributeArrayContainer< AttributeType > & GetArrayForChannel(const int32 Index)
Definition MeshAttributeArray.h:713
virtual void Initialize(const int32 Count) override
Definition MeshAttributeArray.h:616
virtual TUniquePtr< FMeshAttributeArraySetBase > Clone() const override
Definition MeshAttributeArray.h:590
virtual void SetNumChannels(const int32 NumChannels) override
Definition MeshAttributeArray.h:671
virtual void RemoveChannel(const int32 Index) override
Definition MeshAttributeArray.h:706
virtual void RemoveIndex(const int32 Index) override
Definition MeshAttributeArray.h:700
virtual void InsertChannel(const int32 Index) override
Definition MeshAttributeArray.h:693
Definition ContainerAllocationPolicies.h:894
Definition SparseArray.h:1137
Definition SparseArray.h:524
void Insert(int32 Index, typename TTypeTraits< ElementType >::ConstInitType Element)
Definition SparseArray.h:644
Definition UniquePtr.h:107
bool IsValid() const
Definition UniquePtr.h:280
UE_FORCEINLINE_HINT T * Get() const
Definition UniquePtr.h:324
Definition TVariant.h:48
Definition MeshAttributeArray.h:2394
TJumpTable< TUniquePtr< FMeshAttributeArraySetBase >(uint32), TTupleArity< AttributeTypes >::Value > JumpTableType
Definition MeshAttributeArray.h:2396
Definition MeshAttributeArray.h:2293
Definition MeshAttributeArray.h:2244
Definition MeshAttributeArray.h:2195
U16 Index
Definition radfft.cpp:71
static UE_FORCEINLINE_HINT uint32 MemCrc32(const void *Data, int32 Length, uint32 CRC=0)
Definition Crc.h:31
Definition CustomVersion.h:40
Definition MeshTypes.h:22
Definition TVariant.h:29
CORE_API static const FGuid GUID
Definition FortniteMainBranchObjectVersion.h:21
CORE_API static const FGuid GUID
Definition ReleaseObjectVersion.h:154
@ MeshDescriptionNewSerialization
Definition ReleaseObjectVersion.h:66
@ MeshDescriptionNewFormat
Definition ReleaseObjectVersion.h:107
CORE_API static const FGuid GUID
Definition UE5MainStreamObjectVersion.h:22
void operator()(FName Name, ForEachFunc Fn, const FMeshAttributeArraySetBase *Attributes)
Definition MeshAttributeArray.h:2357
void operator()(FName Name, ForEachFunc Fn, const FMeshAttributeArraySetBase *Attributes)
Definition MeshAttributeArray.h:2345
Definition MeshAttributeArray.h:2332
void operator()(FName Name, ForEachFunc Fn, const FMeshAttributeArraySetBase *Attributes)
Definition MeshAttributeArray.h:2333
void operator()(FName Name, ForEachFunc Fn, FMeshAttributeArraySetBase *Attributes)
Definition MeshAttributeArray.h:2321
void operator()(FName Name, ForEachFunc Fn, FMeshAttributeArraySetBase *Attributes)
Definition MeshAttributeArray.h:2309
Definition MeshAttributeArray.h:2296
void operator()(FName Name, ForEachFunc Fn, FMeshAttributeArraySetBase *Attributes)
Definition MeshAttributeArray.h:2297
Definition IntegerSequence.h:9
Definition IsArray.h:10
Definition MeshAttributeArray.h:70
static const bool Value
Definition MeshAttributeArray.h:70
Definition MeshAttributeArray.h:2185
FnType * Fns[Size]
Definition MeshAttributeArray.h:2189
constexpr TJumpTable(T... Ts)
Definition MeshAttributeArray.h:2187
Definition MeshAttributeArray.h:750
std::conditional_t< TIsDerivedFrom< AttributeType, FElementID >::Value, int32, AttributeType > RealAttributeType
Definition MeshAttributeArray.h:752
T AttributeType
Definition MeshAttributeArray.h:751
Definition MeshAttributeArray.h:757
const T ConstRefType
Definition MeshAttributeArray.h:761
std::remove_cv_t< T > NonConstRefType
Definition MeshAttributeArray.h:762
static const uint32 MinExpectedExtent
Definition MeshAttributeArray.h:758
T RefType
Definition MeshAttributeArray.h:760
static const uint32 MaxExpectedExtent
Definition MeshAttributeArray.h:759
Definition MeshAttributeArray.h:796
static const uint32 Extent
Definition MeshAttributeArray.h:797
Definition Tuple.h:752
Definition Tuple.h:652
Definition MeshAttributeArray.h:62