UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MovieSceneTimeHelpers.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "CoreTypes.h"
8#include "Math/Range.h"
9#include "Math/RangeBound.h"
12#include "Misc/FrameNumber.h"
13#include "Misc/FrameTime.h"
14
15class UMovieScene;
16struct FFrameRate;
17
18namespace UE
19{
20namespace MovieScene
21{
22
23struct IRetimingInterface;
24
26{
27public:
28
33 static MOVIESCENE_API void MigrateFrameTimes(FFrameRate SourceRate, FFrameRate DestinationRate, UMovieScene* MovieScene, bool bApplyRecursively = false);
34
35 static MOVIESCENE_API void MigrateFrameTimes(const IRetimingInterface& Retimer, UMovieScene* MovieScene, bool bApplyRecursively = false);
36
37};
38
43{
44 check(!InLowerBound.IsOpen());
45
46 // Add one for exclusive lower bounds since they start on the next subsequent frame
47 static const int32 Offsets[] = { 0, 1 };
48 const int32 OffsetIndex = (int32)InLowerBound.IsExclusive();
49
50 return InLowerBound.GetValue() + Offsets[OffsetIndex];
51}
52
53
61
62
67{
68 check(!InUpperBound.IsOpen());
69
70 // Add one for inclusive upper bounds since they finish on the next subsequent frame
71 static const int32 Offsets[] = { 0, 1 };
72 const int32 OffsetIndex = (int32)InUpperBound.IsInclusive();
73
74 return InUpperBound.GetValue() + Offsets[OffsetIndex];
75}
76
77
85
86
98
99
109
110
122
123
127inline bool IsEmptyOrZeroSize(const TRange<FFrameNumber>& InRange)
128{
129 return InRange.IsEmpty() || InRange.Size<FFrameNumber>() == 0;
130}
131
132
137{
138 check(!InLowerBound.IsOpen());
139
140 // Add one for exclusive lower bounds to ensure we end up with a range of the correct discrete size
141 static const int32 Offsets[] = { 0, 1 };
142 const int32 OffsetIndex = (int32)InLowerBound.IsExclusive();
143
146}
147
148
153{
154 check(!InUpperBound.IsOpen());
155
156 // Add one for inclusve upper bounds to ensure we end up with a range of the correct discrete size
157 static const int32 Offsets[] = { 0, 1 };
158 const int32 OffsetIndex = (int32)InUpperBound.IsInclusive();
159
162}
163
171{
173}
174
179{
180 if (InRange.GetLowerBound().IsOpen() || InRange.GetUpperBound().IsOpen())
181 {
182 return false;
183 }
184
185 // From here on we're handling ranges of the form [x,y], [x,y), (x,y] and (x,y)
186 const bool bLowerInclusive = InRange.GetLowerBound().IsInclusive();
187 const bool bUpperInclusive = InRange.GetUpperBound().IsInclusive();
188
189 if (bLowerInclusive)
190 {
191 // Lower is inclusive
192 return bUpperInclusive
193 ? InRange.GetLowerBoundValue() > InRange.GetUpperBoundValue() // [x, y] - empty if x > y
194 : InRange.GetLowerBoundValue() >= InRange.GetUpperBoundValue(); // [x, y) - empty if x >= y
195 }
196 else
197 {
198 // Lower is exclusive
199 return bUpperInclusive
200 ? InRange.GetLowerBoundValue() >= InRange.GetUpperBoundValue() // (x, y] - empty if x >= y
201 : InRange.GetLowerBoundValue() >= InRange.GetUpperBoundValue()-1; // (x, y) - empty if x >= y-1
202 }
203}
204
208template<typename T>
210{
211 TRangeBound<T> LowerBound = InRange.GetLowerBound();
212 TRangeBound<T> UpperBound = InRange.GetUpperBound();
213
214 return TRange<T>(
215 LowerBound.IsOpen()
217 : LowerBound.IsInclusive()
218 ? TRangeBound<T>::Inclusive(LowerBound.GetValue() + LowerAmount)
219 : TRangeBound<T>::Exclusive(LowerBound.GetValue() + LowerAmount),
220
221 UpperBound.IsOpen()
223 : UpperBound.IsInclusive()
224 ? TRangeBound<T>::Inclusive(UpperBound.GetValue() + UpperAmount)
225 : TRangeBound<T>::Exclusive(UpperBound.GetValue() + UpperAmount)
226 );
227}
228
229
233template<typename T>
234inline TRange<T> ExpandRange(const TRange<T>& InRange, T Amount)
235{
236 return DilateRange(InRange, -Amount, Amount);
237}
238
239
243template<typename T>
244inline TRange<T> TranslateRange(const TRange<T>& InRange, T Amount)
245{
246 return DilateRange(InRange, Amount, Amount);
247}
248
249
254{
256 FFrameTime MaxTime = FFrameTime(InRange.GetUpperBound().IsClosed() ? DiscreteExclusiveUpper(InRange)-1 : TNumericLimits<int32>::Max(), 0.99999994f);
257
258 return FMath::Clamp(InTime, MinTime, MaxTime);
259}
260
261
266{
267 TRange<FFrameTime> Result;
268 if (InRange.HasLowerBound())
269 {
270 if (InRange.GetLowerBound().IsInclusive())
271 {
272 Result.SetLowerBound(TRangeBound<FFrameTime>::Inclusive(InRange.GetLowerBoundValue()));
273 }
274 else
275 {
276 Result.SetLowerBound(TRangeBound<FFrameTime>::Exclusive(InRange.GetLowerBoundValue()));
277 }
278 }
279 if (InRange.HasUpperBound())
280 {
281 if (InRange.GetUpperBound().IsInclusive())
282 {
283 Result.SetUpperBound(TRangeBound<FFrameTime>::Inclusive(InRange.GetUpperBoundValue()));
284 }
285 else
286 {
287 Result.SetUpperBound(TRangeBound<FFrameTime>::Exclusive(InRange.GetUpperBoundValue()));
288 }
289 }
290 return Result;
291}
292
294{
295 TRange<FFrameTime> Result;
296 if (InRange.HasLowerBound())
297 {
298 if (InRange.GetLowerBound().IsInclusive())
299 {
301 }
302 else
303 {
305 }
306 }
307 if (InRange.HasUpperBound())
308 {
309 if (InRange.GetUpperBound().IsInclusive())
310 {
312 }
313 else
314 {
316 }
317 }
318 return Result;
319}
320
322{
324 if (InRange.HasLowerBound())
325 {
326 // A frame time of (10.5 does not include _all_ of frame 10, so we can't include that frame
327 FFrameTime LowerBound = InRange.GetLowerBoundValue();
328 if (InRange.GetLowerBound().IsInclusive() && LowerBound.GetSubFrame() == 0.f)
329 {
330 Result.SetLowerBound(TRangeBound<FFrameNumber>::Inclusive(LowerBound.GetFrame()));
331 }
332 else
333 {
334 Result.SetLowerBound(TRangeBound<FFrameNumber>::Inclusive(LowerBound.GetFrame()+1));
335 }
336 }
337 if (InRange.HasUpperBound())
338 {
339 FFrameTime UpperBound = InRange.GetUpperBoundValue();
340 Result.SetUpperBound(TRangeBound<FFrameNumber>::Exclusive(UpperBound.GetFrame()));
341 }
342 return Result;
343}
344
345
350template<typename InBoundType, typename OutBoundType>
369
370// Specialization of ConvertRange for round down FFrameTime to FFrameNumber.
371template<>
373{
374 const TRangeBound<FFrameTime> SourceLower = Range.GetLowerBound();
377 SourceLower.IsInclusive() ?
378 TRangeBound<FFrameNumber>::Inclusive(SourceLower.GetValue().FloorToFrame()) :
379 TRangeBound<FFrameNumber>::Exclusive(SourceLower.GetValue().FloorToFrame());
380
381 const TRangeBound<FFrameTime> SourceUpper = Range.GetUpperBound();
384 SourceUpper.IsInclusive() ?
385 TRangeBound<FFrameNumber>::Inclusive(SourceUpper.GetValue().FloorToFrame()) :
386 TRangeBound<FFrameNumber>::Exclusive(SourceUpper.GetValue().FloorToFrame());
387
389}
390
391} // namespace MovieScene
392} // namespace UE
393
394inline FString LexToString(const TRange<FFrameNumber>& InRange)
395{
398
399 return *FString::Printf(TEXT("%s,%s"),
400 SourceLower.IsOpen() ?
401 TEXT("[-inf") :
402 SourceLower.IsInclusive() ?
403 *FString::Printf(TEXT("[%i"), SourceLower.GetValue().Value) :
404 *FString::Printf(TEXT("(%i"), SourceLower.GetValue().Value),
405
406 SourceUpper.IsOpen() ?
407 TEXT("+inf]") :
408 SourceUpper.IsInclusive() ?
409 *FString::Printf(TEXT("%i]"), SourceUpper.GetValue().Value) :
410 *FString::Printf(TEXT("%i)"), SourceUpper.GetValue().Value)
411 );
412}
413
414inline FString LexToString(const TRange<FFrameTime>& InRange)
415{
418
419 return *FString::Printf(TEXT("%s,%s"),
420 SourceLower.IsOpen() ?
421 TEXT("[-inf") :
422 SourceLower.IsInclusive() ?
423 *FString::Printf(TEXT("[%s"), *LexToShortString(SourceLower.GetValue())) :
424 *FString::Printf(TEXT("(%s"), *LexToShortString(SourceLower.GetValue())),
425
426 SourceUpper.IsOpen() ?
427 TEXT("+inf]") :
428 SourceUpper.IsInclusive() ?
429 *FString::Printf(TEXT("%s]"), *LexToShortString(SourceUpper.GetValue())) :
430 *FString::Printf(TEXT("%s)"), *LexToShortString(SourceUpper.GetValue()))
431 );
432}
433
#define check(expr)
Definition AssertionMacros.h:314
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
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
FString LexToShortString(const FFrameTime InTime)
Definition FrameTime.h:329
FString LexToString(const TRange< FFrameNumber > &InRange)
Definition MovieSceneTimeHelpers.h:394
Definition MovieScene.Build.cs:6
Definition RangeBound.h:36
UE_FORCEINLINE_HINT bool IsClosed() const
Definition RangeBound.h:125
static TRangeBound Inclusive(ElementValueOrConstRef Value)
Definition RangeBound.h:209
UE_FORCEINLINE_HINT bool IsInclusive() const
Definition RangeBound.h:145
UE_FORCEINLINE_HINT bool IsOpen() const
Definition RangeBound.h:155
static TRangeBound Open()
Definition RangeBound.h:224
static TRangeBound Exclusive(ElementValueOrConstRef Value)
Definition RangeBound.h:193
Definition Range.h:50
bool HasLowerBound() const
Definition Range.h:320
bool IsEmpty() const
Definition Range.h:361
DifferenceType Size() const
Definition Range.h:427
bool HasUpperBound() const
Definition Range.h:331
BoundsType GetUpperBound() const
Definition Range.h:274
ElementValueOrConstRef GetLowerBoundValue() const
Definition Range.h:263
ElementValueOrConstRef GetUpperBoundValue() const
Definition Range.h:309
BoundsType GetLowerBound() const
Definition Range.h:228
Definition MovieSceneTimeHelpers.h:26
static MOVIESCENE_API void MigrateFrameTimes(FFrameRate SourceRate, FFrameRate DestinationRate, UMovieScene *MovieScene, bool bApplyRecursively=false)
Definition MovieSceneTimeHelpers.cpp:117
Definition MovieScene.h:358
int32 DiscreteSize(const TRange< FFrameNumber > &InRange)
Definition MovieSceneTimeHelpers.h:170
TRange< OutBoundType > ConvertRange(const TRange< InBoundType > &Range)
Definition MovieSceneTimeHelpers.h:351
TRange< FFrameNumber > MakeDiscreteRange(FFrameNumber MinInclusive, FFrameNumber MaxExclusive)
Definition MovieSceneTimeHelpers.h:94
TRange< FFrameNumber > MakeHullRange(const TRange< FFrameNumber > &InRange)
Definition MovieSceneTimeHelpers.h:103
TRange< T > DilateRange(const TRange< T > &InRange, T LowerAmount, T UpperAmount)
Definition MovieSceneTimeHelpers.h:209
TRange< FFrameNumber > MakeDiscreteRangeFromLower(const TRangeBound< FFrameNumber > &InLowerBound, int32 DiscreteSize)
Definition MovieSceneTimeHelpers.h:136
TRange< T > ExpandRange(const TRange< T > &InRange, T Amount)
Definition MovieSceneTimeHelpers.h:234
FFrameNumber DiscreteExclusiveUpper(const TRangeBound< FFrameNumber > &InUpperBound)
Definition MovieSceneTimeHelpers.h:66
FFrameTime ClampToDiscreteRange(FFrameTime InTime, const TRange< FFrameNumber > &InRange)
Definition MovieSceneTimeHelpers.h:253
TRange< FFrameTime > TranslateRange(const TRange< FFrameTime > &InRange, FFrameTime Offset)
Definition MovieSceneSequenceTransform.cpp:17
TRange< FFrameTime > ConvertToFrameTimeRange(const TRange< FFrameNumber > &InRange)
Definition MovieSceneTimeHelpers.h:265
bool DiscreteRangeIsEmpty(const TRange< FFrameNumber > &InRange)
Definition MovieSceneTimeHelpers.h:178
TRange< FFrameNumber > MakeDiscreteRangeFromUpper(const TRangeBound< FFrameNumber > &InUpperBound, int32 DiscreteSize)
Definition MovieSceneTimeHelpers.h:152
bool IsEmptyOrZeroSize(const TRange< FFrameNumber > &InRange)
Definition MovieSceneTimeHelpers.h:127
TRange< FFrameNumber > ConvertToDiscreteRange(const TRange< FFrameTime > &InRange)
Definition MovieSceneTimeHelpers.h:321
FFrameNumber DiscreteInclusiveLower(const TRangeBound< FFrameNumber > &InLowerBound)
Definition MovieSceneTimeHelpers.h:42
Definition AdvancedWidgetsModule.cpp:13
Definition FrameNumber.h:18
int32 Value
Definition FrameNumber.h:77
Definition FrameRate.h:21
Definition FrameTime.h:16
static FFrameTime FromDecimal(double InDecimalFrame)
Definition FrameTime.h:313
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592
Definition NumericLimits.h:41
Definition IMovieSceneRetimingInterface.h:18