UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
FrameRate.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "HAL/Platform.h"
8#include "Math/Range.h"
9#include "Math/RangeBound.h"
11#include "Misc/FrameNumber.h"
12#include "Misc/FrameTime.h"
14
15struct FExpressionError;
16
21{
26 : Numerator(60000), Denominator(1)
27 {}
28
32
39
44
48 bool IsValid() const
49 {
50 return Denominator > 0;
51 }
52
58 double AsInterval() const;
59
65 double AsDecimal() const;
66
73 double AsSeconds(FFrameTime FrameNumber) const;
74
82
90
94 bool IsMultipleOf(FFrameRate Other) const;
95
99 bool IsFactorOf(FFrameRate Other) const;
100
109 static FFrameTime TransformTime(FFrameTime SourceTime, FFrameRate SourceRate, FFrameRate DestinationRate);
110
119 static FFrameTime Snap(FFrameTime SourceTime, FFrameRate SourceRate, FFrameRate SnapToRate);
120
126
137 CORE_API bool ComputeGridSpacing(const float PixelsPerSecond, double& OutMajorInterval, int32& OutMinorDivisions, float MinTickPx = 30.f, float DesiredMajorTickPx = 120.f) const;
138
142 CORE_API double MaxSeconds() const;
143
148 {
150 }
151
152 friend inline bool operator==(const FFrameRate& A, const FFrameRate& B)
153 {
154 return A.Numerator == B.Numerator && A.Denominator == B.Denominator;
155 }
156
157 friend inline bool operator!=(const FFrameRate& A, const FFrameRate& B)
158 {
159 return A.Numerator != B.Numerator || A.Denominator != B.Denominator;
160 }
161
163 {
164 return FFrameRate(A.Numerator * B.Numerator, A.Denominator * B.Denominator);
165 }
166
168 {
169 return FFrameRate(A.Numerator * B.Denominator, A.Denominator * B.Numerator);
170 }
171
172 friend inline double operator/(FFrameNumber Frame, FFrameRate Rate)
173 {
174 return Rate.AsSeconds(FFrameTime(Frame));
175 }
176
178 {
179 TRangeBound<FFrameNumber> LowerBound = FrameRange.GetLowerBound();
180 TRangeBound<FFrameNumber> UpperBound = FrameRange.GetUpperBound();
181
182 return TRange<double>(
183 LowerBound.IsOpen()
185 : LowerBound.IsInclusive()
186 ? TRangeBound<double>::Inclusive(Rate.AsSeconds(LowerBound.GetValue()))
187 : TRangeBound<double>::Inclusive(Rate.AsSeconds(LowerBound.GetValue()+1)),
188
189 UpperBound.IsOpen()
191 : UpperBound.IsInclusive()
192 ? TRangeBound<double>::Exclusive(Rate.AsSeconds(UpperBound.GetValue()+1))
193 : TRangeBound<double>::Exclusive(Rate.AsSeconds(UpperBound.GetValue()))
194 );
195 }
196
197 friend inline double operator/(FFrameTime FrameTime, FFrameRate Rate)
198 {
199 return Rate.AsSeconds(FrameTime);
200 }
201
202 friend inline FFrameTime operator*(double TimeInSeconds, FFrameRate Rate)
203 {
204 return Rate.AsFrameTime(TimeInSeconds);
205 }
206
207 friend inline FFrameTime operator*(float TimeInSeconds, FFrameRate Rate)
208 {
209 return Rate.AsFrameTime(TimeInSeconds);
210 }
211
212 friend inline uint32 GetTypeHash(const FFrameRate& Rate)
213 {
215 }
216
218
219 CORE_API bool Serialize(FArchive& Ar);
220};
221
222inline double FFrameRate::AsInterval() const
223{
225}
226
227inline double FFrameRate::AsDecimal() const
228{
230}
231
232inline double FFrameRate::AsSeconds(FFrameTime FrameTime) const
233{
234 const int64 IntegerPart = FrameTime.GetFrame().Value * int64(Denominator);
235 const double FloatPart = FrameTime.GetSubFrame() * double(Denominator);
236
237 return (double(IntegerPart) + FloatPart) / Numerator;
238}
239
240inline FFrameTime FFrameRate::AsFrameTime(double TimeInSeconds) const
241{
242 // @todo: sequencer-timecode: proper large number integer multiplication/division before coercion to float ?
243 const double TimeAsFrame = (TimeInSeconds * Numerator) / Denominator;
244 FFrameNumber FrameNumber = static_cast<int32>(FMath::Clamp(FMath::FloorToDouble(TimeAsFrame), static_cast<double>(TNumericLimits<int32>::Min()), static_cast<double>(TNumericLimits<int32>::Max())));
245
246 float SubFrame = static_cast<float>(TimeAsFrame - FMath::FloorToDouble(TimeAsFrame));
247 const int32 TruncatedSubFrame = FMath::TruncToInt(SubFrame);
248 SubFrame -= static_cast<float>(TruncatedSubFrame);
249 FrameNumber.Value += TruncatedSubFrame;
250 if (SubFrame > 0.f)
251 {
252 SubFrame = FMath::Min(SubFrame, FFrameTime::MaxSubframe);
253 }
254
255 return FFrameTime(FrameNumber, SubFrame);
256}
257
258inline FFrameNumber FFrameRate::AsFrameNumber(double TimeInSeconds) const
259{
260 // @todo: sequencer-timecode: proper large number integer multiplication/division before coercion to float ?
261 const double TimeAsFrame = (static_cast<double>(TimeInSeconds) * Numerator) / Denominator;
262 return static_cast<int32>(FMath::Clamp(FMath::FloorToDouble(TimeAsFrame + static_cast<double>(FMath::TruncToInt(static_cast<float>(TimeAsFrame - FMath::FloorToDouble(TimeAsFrame))))), static_cast<double>(TNumericLimits<int32>::Min()), static_cast<double>(TNumericLimits<int32>::Max())));
263}
264
265inline FFrameTime ConvertFrameTime(FFrameTime SourceTime, FFrameRate SourceRate, FFrameRate DestinationRate)
266{
267 if (SourceRate == DestinationRate)
268 {
269 return SourceTime;
270 }
271 //We want NewTime =SourceTime * (DestinationRate/SourceRate);
272 //And want to limit conversions and keep int precision as much as possible
273
274 // If SourceRate.Numerator is 0 then NewDenominator will be 0 and will cause a divide by 0 error.
275 check(SourceRate.Numerator != 0);
276
277 //@todo: These integers should not need the volatile keyword here, but adding it works around
278 // a compiler bug that results in an uninitialized vector register being used
279 volatile int64 NewNumerator = static_cast<int64>(DestinationRate.Numerator) * SourceRate.Denominator;
280 volatile int64 NewDenominator = static_cast<int64>(DestinationRate.Denominator) * SourceRate.Numerator;
281
284 //Now the IntegerPart may have a Float Part, and then the FloatPart may have an IntegerPart,
285 //So we add the extra Float from the IntegerPart to the FloatPart and then add back any extra Integer to IntegerPart
287 const double IntegerFloatPart = ((double(SourceTime.GetFrame().Value) * double(NewNumerator)) / double(NewDenominator)) - double(IntegerPart);
288 const double FloatPart = ((SourceTime.GetSubFrame() * NewNumerator_d) / NewDenominator_d) + IntegerFloatPart;
289 const double FloatPartFloored = FMath::FloorToDouble(FloatPart);
292 float SubFrame = static_cast<float>(FloatPart - FloatPartFloored);
293 if (SubFrame > 0.f)
294 {
295 SubFrame = FMath::Min(SubFrame, FFrameTime::MaxSubframe);
296 }
297
299 return FFrameTime(static_cast<int32>(IntegerPart), SubFrame);
300}
301
302inline FFrameTime FFrameRate::TransformTime(FFrameTime SourceTime, FFrameRate SourceRate, FFrameRate DestinationRate)
303{
304 return ConvertFrameTime(SourceTime, SourceRate, DestinationRate);
305}
306
308{
309 return ConvertFrameTime(ConvertFrameTime(SourceTime, SourceRate, SnapToRate).RoundToFrame(), SnapToRate, SourceRate);
310}
311
313{
314 int64 CommonValueA = int64(Numerator) * Other.Denominator;
316
318}
319
321{
322 return Other.IsMultipleOf(*this);
323}
324
330
335
336#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_6
337# include "ExpressionParserTypes.h"
338#endif
#define check(expr)
Definition AssertionMacros.h:314
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
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
CORE_API bool TryParseString(FFrameRate &OutFrameRate, const TCHAR *InString)
Definition FrameRate.cpp:343
FFrameTime ConvertFrameTime(FFrameTime SourceTime, FFrameRate SourceRate, FFrameRate DestinationRate)
Definition FrameRate.h:265
CORE_API TValueOrError< FFrameRate, FExpressionError > ParseFrameRate(const TCHAR *FrameRateString)
Definition FrameRate.cpp:337
constexpr uint32 HashCombine(uint32 A, uint32 C)
Definition TypeHash.h:36
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition Text.h:385
Definition RangeBound.h:36
static TRangeBound Inclusive(ElementValueOrConstRef Value)
Definition RangeBound.h:209
static TRangeBound Open()
Definition RangeBound.h:224
static TRangeBound Exclusive(ElementValueOrConstRef Value)
Definition RangeBound.h:193
Definition Range.h:50
Definition ValueOrError.h:58
Definition ExpressionParserTypes.h:27
Definition FrameNumber.h:18
int32 Value
Definition FrameNumber.h:77
Definition FrameRate.h:21
friend FFrameTime operator*(float TimeInSeconds, FFrameRate Rate)
Definition FrameRate.h:207
double AsDecimal() const
Definition FrameRate.h:227
FFrameNumber AsFrameNumber(double InTimeSeconds) const
Definition FrameRate.h:258
static FFrameTime Snap(FFrameTime SourceTime, FFrameRate SourceRate, FFrameRate SnapToRate)
Definition FrameRate.h:307
int32 Denominator
Definition FrameRate.h:43
friend double operator/(FFrameNumber Frame, FFrameRate Rate)
Definition FrameRate.h:172
CORE_API bool ComputeGridSpacing(const float PixelsPerSecond, double &OutMajorInterval, int32 &OutMinorDivisions, float MinTickPx=30.f, float DesiredMajorTickPx=120.f) const
Definition FrameRate.cpp:232
static FFrameTime TransformTime(FFrameTime SourceTime, FFrameRate SourceRate, FFrameRate DestinationRate)
Definition FrameRate.h:302
double AsSeconds(FFrameTime FrameNumber) const
Definition FrameRate.h:232
friend FFrameRate operator/(FFrameRate A, FFrameRate B)
Definition FrameRate.h:167
friend bool operator!=(const FFrameRate &A, const FFrameRate &B)
Definition FrameRate.h:157
CORE_API FText ToPrettyText() const
Definition FrameRate.cpp:215
CORE_API double MaxSeconds() const
Definition FrameRate.cpp:210
friend bool operator==(const FFrameRate &A, const FFrameRate &B)
Definition FrameRate.h:152
friend double operator/(FFrameTime FrameTime, FFrameRate Rate)
Definition FrameRate.h:197
bool IsValid() const
Definition FrameRate.h:48
int32 Numerator
Definition FrameRate.h:38
FFrameRate()
Definition FrameRate.h:25
friend FFrameTime operator*(double TimeInSeconds, FFrameRate Rate)
Definition FrameRate.h:202
double AsInterval() const
Definition FrameRate.h:222
friend FFrameRate operator*(FFrameRate A, FFrameRate B)
Definition FrameRate.h:162
friend TRange< double > operator/(const TRange< FFrameNumber > &FrameRange, FFrameRate Rate)
Definition FrameRate.h:177
FFrameRate(uint32 InNumerator, uint32 InDenominator)
Definition FrameRate.h:29
friend uint32 GetTypeHash(const FFrameRate &Rate)
Definition FrameRate.h:212
bool IsMultipleOf(FFrameRate Other) const
Definition FrameRate.h:312
FFrameTime AsFrameTime(double InTimeSeconds) const
Definition FrameRate.h:240
bool IsFactorOf(FFrameRate Other) const
Definition FrameRate.h:320
FFrameRate Reciprocal() const
Definition FrameRate.h:147
friend CORE_API FArchive & operator<<(FArchive &Ar, FFrameRate &FrameRate)
Definition FrameRate.cpp:356
Definition FrameTime.h:16
UE_FORCEINLINE_HINT float GetSubFrame() const
Definition FrameTime.h:64
static CORE_API const float MaxSubframe
Definition FrameTime.h:18
UE_FORCEINLINE_HINT FFrameNumber GetFrame() const
Definition FrameTime.h:56
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592
Definition NumericLimits.h:41