UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
AnimCurveUtils.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "AnimBulkCurves.h"
6#include "AnimCurveTypes.h"
7#include "AnimCurveFilter.h"
8
9
10namespace UE::Anim
11{
12
14{
15private:
17 static bool ElementPassesFilter(ECurveFilterMode InFilterMode, ECurveFilterFlags InFilterFlags)
18 {
20 {
21 return false;
22 }
23
24 switch(InFilterMode)
25 {
27 return true;
29 return false;
34 }
35
36 return false;
37 };
38
39 // Helper function for building curves, applying any filtering
40 // Assumes (and enforces in debug builds) elements being built are in FName sorted order
41 template<typename NamePredicateType, typename ValuePredicateType, typename CurveAllocatorType, typename CurveElementType>
43 {
44 // Early out if we are filtering all curves
45 if(InFilter.FilterMode == ECurveFilterMode::DisallowAll)
46 {
47 OutCurve.Empty();
48 return;
49 }
50
51 InFilter.SortElementsIfRequired();
52
53 OutCurve.Empty();
54 OutCurve.Reserve(InNumElements);
55
57 const int32 NumElements1 = InFilter.Elements.Num();
58
61
62#if DO_ANIM_NAMED_VALUE_SORTING_CHECKS
64#endif
65
66 // Perform dual-iteration on the two sorted arrays
68 {
70 {
71 // Reached end of user data with remaining in filter, we can just early out
72 break;
73 }
75 {
76 // Reached end of filter with remaining in user data, we can just run straight through the user data
77 OutCurve.Elements.Reserve(OutCurve.Elements.Num() + (NumElements0 - ElementIndex0));
79 {
80 if(ElementPassesFilter(InFilter.FilterMode, ECurveFilterFlags::None))
81 {
83 }
84 }
85 break;
86 }
87
88 const FName CurveName = InNamePredicate(ElementIndex0);
90
91#if DO_ANIM_NAMED_VALUE_SORTING_CHECKS
92 // Check sorting invariants
93 if(ElementIndex0 > 0)
94 {
95 check(LastCurveName == CurveName || LastCurveName.FastLess(CurveName))
96 }
97 LastCurveName = CurveName;
98#endif
99
100 if(CurveName == Element1->Name)
101 {
102 // Elements match, check filter & write to curve
103 if(ElementPassesFilter(InFilter.FilterMode, Element1->Flags))
104 {
105 OutCurve.Elements.Emplace(CurveName, InValuePredicate(ElementIndex0));
106 }
107
110 }
111 else if(CurveName.FastLess(Element1->Name))
112 {
113 // Element exists only in user data
114 if(ElementPassesFilter(InFilter.FilterMode, ECurveFilterFlags::None))
115 {
116 OutCurve.Elements.Emplace(CurveName, InValuePredicate(ElementIndex0));
117 }
118
120 }
121 else
122 {
123 // Element exists only in filter, skip
125 }
126 }
127
128 OutCurve.CheckDuplicates();
129 }
130
131 // Helper function for building curves
132 template<typename NamePredicateType, typename ValuePredicateType, typename CurveAllocatorType, typename CurveElementType>
134 {
135 OutCurve.Empty();
136 OutCurve.Reserve(InNumElements);
137
138 for(int32 ElementIndex = 0; ElementIndex < InNumElements; ++ElementIndex)
139 {
140 OutCurve.Elements.Emplace(InNamePredicate(ElementIndex), InValuePredicate(ElementIndex));
141 }
142
143 OutCurve.CheckDuplicates();
144 }
145
146 // Helper function for building curves
147 template<typename NamePredicateType, typename ValuePredicateType, typename ValidityPredicateType, typename CurveAllocatorType, typename CurveElementType>
149 {
150 OutCurve.Empty();
151 OutCurve.Reserve(InNumElements);
152
153 for(int32 ElementIndex = 0; ElementIndex < InNumElements; ++ElementIndex)
154 {
155 if (InValidityPredicate(ElementIndex))
156 {
157 OutCurve.Elements.Emplace(InNamePredicate(ElementIndex), InValuePredicate(ElementIndex));
158 }
159 }
160
161 OutCurve.CheckDuplicates();
162 }
163
164public:
165 // Helper function for building curves, applying any filtering
166 // Assumes (and enforces in debug builds) elements being built are in FName sorted order
167 template<typename NamePredicateType, typename ValuePredicateType, typename CurveAllocatorType, typename CurveElementType>
169 {
171
172 OutCurve.bSorted = true;
173
174 if(InFilter != nullptr && !InFilter->IsEmpty())
175 {
176 BuildSortedFiltered(OutCurve, InNumElements, InNamePredicate, InValuePredicate, *InFilter);
177 OutCurve.CheckSorted();
178 }
179 else
180 {
181 BuildLinearUnfiltered(OutCurve, InNumElements, InNamePredicate, InValuePredicate);
182 OutCurve.CheckSorted();
183 }
184 }
185
186 // Helper function for building curves
187 template<typename NamePredicateType, typename ValuePredicateType, typename CurveAllocatorType, typename CurveElementType>
194
195 // Helper function for building curves from a map
196 template<typename CurveAllocatorType, typename CurveElementType>
198 {
200
201 OutCurve.Empty();
202 OutCurve.Reserve(InMap.Num());
203
205 {
206 OutCurve.Elements.Emplace(NameValuePair.Key, NameValuePair.Value);
207 }
208 }
209
210 // Helper function for building curves from an array view of name/value pairs
211 template<typename CurveAllocatorType, typename CurveElementType>
226
227 // Helper function for building curves from an initializer list of name/value pairs
228 template<typename CurveAllocatorType, typename CurveElementType>
230 {
232
233 OutCurve.Empty();
234 OutCurve.Reserve(InInputArgs.size());
235
237 {
238 OutCurve.Elements.Emplace(NameValueTuple.Get<0>(), NameValueTuple.Get<1>());
239 }
240
241 OutCurve.CheckDuplicates();
242 }
243
244 // Helper function for building curves from an initializer list of name/flag pairs
245 template<typename CurveAllocatorType, typename CurveElementType>
260
261 // Helper function for building curves from an initializer list of name/value/flag tuples
262 template<typename CurveAllocatorType, typename CurveElementType>
277
278 // Helper function for building curves, applying any filtering
279 // Note: uses TMemStackAllocator internally when filtering, so requires a FMemMark to be set somewhere in the callstack
280 template<typename NamePredicateType, typename ValuePredicateType, typename CurveAllocatorType, typename CurveElementType>
282 {
284
285 if(InFilter != nullptr && !InFilter->IsEmpty())
286 {
287 // To use the filter, we need to pre-sort so we can effectively merge
288 // Build a set of indices
290 SortedIndices.SetNumUninitialized(InNumElements);
292 {
293 SortedIndices[NameIndex] = NameIndex;
294 }
295
296 // Sort indices by name
297 SortedIndices.Sort([&InNamePredicate](int32 InLHS, int32 InRHS)
298 {
299 return InNamePredicate(InLHS).FastLess(InNamePredicate(InRHS));
300 });
301
302 auto GetSortedName = [&SortedIndices, &InNamePredicate](int32 InIndex)
303 {
304 return InNamePredicate(SortedIndices[InIndex]);
305 };
306
307 auto GetSortedValue = [&SortedIndices, &InValuePredicate](int32 InIndex)
308 {
309 return InValuePredicate(SortedIndices[InIndex]);
310 };
311
312 OutCurve.bSorted = true;
313 BuildSortedFiltered(OutCurve, InNumElements, GetSortedName, GetSortedValue, *InFilter);
314 OutCurve.CheckSorted();
315 }
316 else
317 {
318 BuildLinearUnfiltered(OutCurve, InNumElements, InNamePredicate, InValuePredicate);
319 }
320 }
321
322 // Helper function for building curves, applying filtering through InValidityPredicate
323 template<typename NamePredicateType, typename ValuePredicateType, typename ValidityPredicateType, typename CurveAllocatorType, typename CurveElementType>
329
333 template<typename CurveAllocatorType, typename CurveElementType>
335 {
337
338 switch(InFilter.FilterMode)
339 {
341 // No filtering, early out
342 return;
344 // Filtering all curves, so just clear curve
345 InOutCurve.Elements.Reset();
346 return;
348 if(InFilter.Num() == 0)
349 {
350 // Allow only filtered, and no filtered, so just clear curve
351 InOutCurve.Elements.Reset();
352 return;
353 }
354 break;
355 default:
356 break;
357 }
358
359 // Sort both inputs if required
360 InOutCurve.SortElementsIfRequired();
361 InFilter.SortElementsIfRequired();
362
364 const int32 NumElements1 = InFilter.Num();
365
366 // Perform dual-iteration on the two sorted arrays
369
370 while(true)
371 {
373 {
374 // Reached end of curve with remaining in filter, we can just early out
375 break;
376 }
378 {
379 // Reached end of filter with remaining in curve, we can just run straight through the curve
381 {
382 if(!ElementPassesFilter(InFilter.FilterMode, ECurveFilterFlags::None))
383 {
384 InOutCurve.Elements.RemoveAt(ElementIndex0, EAllowShrinking::No);
385 NumElements0 = InOutCurve.Num();
386 }
387 else
388 {
390 }
391 }
392 break;
393 }
395 {
396 // All elements exhausted, exit
397 break;
398 }
399
402
403 if(Element0->Name == Element1->Name)
404 {
405 // Elements match so check filter flags to see if it should be removed from curve
406 if(!ElementPassesFilter(InFilter.FilterMode, Element1->Flags))
407 {
409 NumElements0 = InOutCurve.Num();
411 }
412 else
413 {
416 }
417 }
418 else if(Element0->Name.FastLess(Element1->Name))
419 {
420 // Element exists only in curve, check filter
421 if(!ElementPassesFilter(InFilter.FilterMode, ECurveFilterFlags::None))
422 {
423 InOutCurve.Elements.RemoveAt(ElementIndex0, EAllowShrinking::No);
424 NumElements0 = InOutCurve.Num();
425 }
426 else
427 {
429 }
430 }
431 else
432 {
433 // Element exists only in filter, skip
435 }
436 }
437
438 InOutCurve.CheckSorted();
439 }
440
448 template<typename CurveType0, typename CurveType1, typename ValuePredicateType>
450 {
452
454 [&InValuePredicate](const typename CurveType0::ElementType& InElement0, const typename CurveType1::ElementType& InElement1)
455 {
457 });
458 }
459
467 template<typename CurveType0, typename CurveType1, typename ValuePredicateType>
481};
482
483}
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define RESTRICT
Definition Platform.h:706
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 CURVE_PROFILE_CYCLE_COUNTER(Stat)
Definition NamedValueArray.h:17
Definition NameTypes.h:617
FORCEINLINE bool FastLess(const FName &Other) const
Definition NameTypes.h:815
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void RemoveAt(SizeType Index, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2083
UE_FORCEINLINE_HINT SizeType Emplace(ArgsType &&... Args)
Definition Array.h:2561
void SetNumUninitialized(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2369
UE_NODEBUG void Sort()
Definition Array.h:3418
UE_FORCEINLINE_HINT void Reserve(SizeType Number)
Definition Array.h:3016
Definition UnrealString.h.inl:34
Definition AnimationAsset.h:42
ENamedValueUnionFlags
Definition NamedValueArray.h:237
ECurveFilterMode
Definition AnimCurveFilter.h:35
ECurveFilterFlags
Definition AnimCurveFilter.h:18
Definition AnimCurveTypes.h:487
void Reserve(int32 InNumElements)
Definition AnimCurveTypes.h:1010
Definition Tuple.h:652
Definition AnimCurveFilter.h:50
Definition AnimCurveFilter.h:68
bool IsEmpty() const
Definition AnimCurveFilter.h:79
Definition AnimCurveUtils.h:14
static void BuildUnsorted(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, TConstArrayView< TTuple< FName, float > > InInputArrayView)
Definition AnimCurveUtils.h:212
static void BuildUnsorted(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, int32 InNumElements, NamePredicateType InNamePredicate, ValuePredicateType InValuePredicate, const FCurveFilter *InFilter=nullptr)
Definition AnimCurveUtils.h:281
static void BuildUnsortedValidated(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, int32 InNumElements, NamePredicateType InNamePredicate, ValuePredicateType InValuePredicate, ValidityPredicateType InValidityPredicate)
Definition AnimCurveUtils.h:324
static void BulkSet(CurveType0 &InCurve, const CurveType1 &InBulkCurves, ValuePredicateType InValuePredicate)
Definition AnimCurveUtils.h:468
static void BuildUnsorted(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, std::initializer_list< TTuple< FName, float > > InInputArgs)
Definition AnimCurveUtils.h:229
static void BuildUnsorted(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, const TMap< FName, float > &InMap)
Definition AnimCurveUtils.h:197
static void Filter(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &InOutCurve, const FCurveFilter &InFilter)
Definition AnimCurveUtils.h:334
static void BuildUnsorted(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, std::initializer_list< TTuple< FName, UE::Anim::ECurveElementFlags > > InInputArgs)
Definition AnimCurveUtils.h:246
static void BuildUnsortedUnfiltered(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, int32 InNumElements, NamePredicateType InNamePredicate, ValuePredicateType InValuePredicate)
Definition AnimCurveUtils.h:188
static void BuildUnsorted(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, std::initializer_list< TTuple< FName, float, UE::Anim::ECurveElementFlags > > InInputArgs)
Definition AnimCurveUtils.h:263
static void BuildSorted(TBaseBlendedCurve< CurveAllocatorType, CurveElementType > &OutCurve, int32 InNumElements, NamePredicateType InNamePredicate, ValuePredicateType InValuePredicate, const FCurveFilter *InFilter=nullptr)
Definition AnimCurveUtils.h:168
static void BulkGet(const CurveType0 &InCurve, const CurveType1 &InBulkCurves, ValuePredicateType InValuePredicate)
Definition AnimCurveUtils.h:449
static void Union(TNamedValueArray< AllocatorTypeResult, ElementTypeResult > &InOutValueArray0, const TNamedValueArray< AllocatorTypeParam, ElementTypeParam > &InValueArray1, PredicateType InPredicate)
Definition NamedValueArray.h:261
static void Intersection(const TNamedValueArray< AllocatorType0, ElementType0 > &InNamedValues0, const TNamedValueArray< AllocatorType1, ElementType1 > &InNamedValues1, ValuePredicateType InValuePredicate)
Definition NamedValueArray.h:642
bool bSorted
Definition NamedValueArray.h:232
int32 Num() const
Definition NamedValueArray.h:130
void SortElementsIfRequired() const
Definition NamedValueArray.h:158
void CheckSorted() const
Definition NamedValueArray.h:170
TArray< ElementType, AllocatorType > Elements
Definition NamedValueArray.h:229
void CheckDuplicates() const
Definition NamedValueArray.h:181
void Empty()
Definition NamedValueArray.h:93