UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
MovieSceneMultiChannelBlending.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
8#include "EulerTransform.h"
9
58namespace UE
59{
60namespace MovieScene
61{
67 template<typename T, uint8 N>
69 {
70 static_assert(N > 0 && N <= 32, "Cannot store more than 32 channels in this type.");
71
74 : Mask(0)
75 {}
76
78 template<typename OtherType>
79 TMultiChannelValue(std::initializer_list<OtherType> InitList)
80 : Mask((1 << N) - 1)
81 {
82 check(InitList.size() == N);
83 T* CurrChannel = &Channels[0];
84 for (auto Val : InitList)
85 {
86 (*CurrChannel++) = Val;
87 }
88 }
89
92 {
93 checkf(Index < N && IsSet(Index), TEXT("Attempting to access an invalid channel."));
94 return Channels[Index];
95 }
96
98 T Get(uint8 Index, T Default) const
99 {
100 return IsSet(Index) ? Channels[Index] : Default;
101 }
102
104 bool IsEmpty() const
105 {
106 return Mask == 0;
107 }
108
110 bool IsFull() const
111 {
112 static const uint32 FullChannelMask = N == 32 ? 0xFFFFFFFF : (1 << N) - 1;
113 return Mask == FullChannelMask;
114 }
115
117 bool IsSet(uint8 Index) const
118 {
119 check(Index < N);
120 return (Mask & (1 << Index)) != 0;
121 }
122
125 {
126 check(Index < N);
127
128 Channels[Index] = Value;
129 Mask |= (1 << Index);
130 }
131
134 {
135 check(Index < N);
136
137 Channels[Index] = IsSet(Index) ? Channels[Index] + Value : Value;
138 Mask |= (1 << Index);
139 }
140
143 {
144 check(Index < N);
145
146 Channels[Index] = IsSet(Index) ? ((1.0 - Weight)*Channels[Index]) + (Value * Weight) : Value;
147 Mask |= (1 << Index);
148 }
149
150 private:
151
153 T Channels[N];
154
156 uint32 Mask;
157 };
158
160 template<typename T, typename SourceData, uint8 N>
162 {
163 static_assert(std::is_same_v<T, void>, "MultiChannelFromData must be implemented to blend SourceData with multi-channel data.");
164 }
165
170 template<typename T, typename SourceData, uint8 N>
172 {
173 static_assert(std::is_same_v<T, void>, "ResolveChannelsToData must be implemented to blend SourceData with multi-channel data.");
174 }
175
177 template<typename DataType, uint8 N>
179 {
181 {
182 // All weights start at 0
184 }
185
190
193
196
199
201 template<typename ActualDataType>
203 {
205
207
208 // Iterate through each channel
209 for (uint8 Channel = 0; Channel < N; ++Channel)
210 {
211 // Any animated channels with a weight of 0 should match the object's *initial* position. Exclusively additive channels are based implicitly off the initial value
212 if (Override.IsSet(Channel)) //if override then we override
213 {
214 Result.Set(Channel, Override[Channel]);
215 }
216 else
217 {
218 const bool bUseInitialValue = (Absolute.IsSet(Channel) && AbsoluteWeights[Channel] == 0.f) || (!Absolute.IsSet(Channel) && Additive.IsSet(Channel));
220 {
221 if (!InitialValue.IsSet())
222 {
223 InitialValue.Emplace();
224 MultiChannelFromData(InitialValueStore.GetInitialValue(), InitialValue.GetValue());
225 }
226
227 Result.Set(Channel, InitialValue.GetValue()[Channel]);
228 }
229 else if (Absolute.IsSet(Channel))
230 {
231 // If it has a non-zero weight, divide by it, and apply the absolute total to the result
232 Result.Set(Channel, Absolute[Channel] / AbsoluteWeights[Channel]);
233 }
234
235 // If it has any additive values in the channel, add those on
236 if (Additive.IsSet(Channel))
237 {
238 Result.Increment(Channel, Additive[Channel]);
239 }
240 }
241
242 // If the channel has not been animated at all, set it to the *current* value
243 if (!Result.IsSet(Channel))
244 {
245 if (!CurrentValue.IsSet())
246 {
247 CurrentValue.Emplace();
248 MultiChannelFromData(InitialValueStore.RetrieveCurrentValue(), CurrentValue.GetValue());
249 }
250 Result.Set(Channel, CurrentValue.GetValue()[Channel]);
251 }
252 }
253
254 ensureMsgf(Result.IsFull(), TEXT("Attempting to apply a compound data type with some channels uninitialized."));
255
256 // Resolve the final channel data into the correct data type for the actuator
259 return FinalResult;
260 }
261 };
262
263 template<typename OutputType, typename InputType, typename ActualValueType, uint8 ChannelSize>
265 {
266 if (BlendType == EMovieSceneBlendType::Absolute || BlendType == EMovieSceneBlendType::Relative)
267 {
268 if (BlendType == EMovieSceneBlendType::Relative)
269 {
270 // If it's relative, we need to add our value onto the channel's initial value
271 if (!OutBlend.InitialValue.IsSet())
272 {
273 OutBlend.InitialValue.Emplace();
274 MultiChannelFromData(InitialValueStore.GetInitialValue(), OutBlend.InitialValue.GetValue());
275 }
276 OutBlend.Absolute.Increment(ChannelIndex, (OutBlend.InitialValue.GetValue()[ChannelIndex] + InValue) * Weight);
277 }
278 else
279 {
280 // Coerce to the output type before applying a weight to ensure that we're operating with the working data type throughout.
281 // This allows us to blend integers as doubles without losing precision at extreme numeric ranges
282 OutBlend.Absolute.Increment(ChannelIndex, OutputType(InValue) * Weight);
283 }
284
285 // Accumulate total weights
286 OutBlend.AbsoluteWeights[ChannelIndex] += Weight;
287 }
288 else if (BlendingOrder != INDEX_NONE)
289 {
290 //If there is a blending order set we use the additive to contain
291 //the full blended value consiting of absolute + overrides + additives
292 //This will already be sorted so we just need to accumulate the values
293 if (OutBlend.Override.IsSet(ChannelIndex) == false)
294 {
295 if (OutBlend.Absolute.IsSet(ChannelIndex))
296 {
297 // If it has a non-zero weight, divide by it, and apply the absolute total to the result
298 OutputType AbsoluteWeight = (OutBlend.AbsoluteWeights[ChannelIndex] != 0.f) ? OutBlend.AbsoluteWeights[ChannelIndex] : 1.0;
299 OutBlend.Override.Set(ChannelIndex, OutBlend.Absolute[ChannelIndex] / AbsoluteWeight);
300 }
301 }
302 if (BlendType == EMovieSceneBlendType::Additive)
303 {
304 OutBlend.Override.Increment(ChannelIndex, OutputType(InValue) * Weight);
305 }
306 else if (BlendType == EMovieSceneBlendType::Override)
307 {
308 OutBlend.Override.WeightedBlend(ChannelIndex, OutputType(InValue), Weight);
309 }
310 }
311 else if (BlendType == EMovieSceneBlendType::Additive)
312 {
313 // Additive animation just increments the additive channel
314 // Coerce to the output type before applying a weight to ensure that we're operating with the working data type throughout.
315 // This allows us to blend integers as doubles without losing precision at extreme numeric ranges
316 OutBlend.Additive.Increment(ChannelIndex, OutputType(InValue) * Weight);
317 }
318 }
319
320 template<typename OutputType, typename InputType, typename ActualValueType>
325
326 template<typename OutputType, typename ActualValueType, uint8 ChannelSize>
337
338 inline void MultiChannelFromData(int32 In, TMultiChannelValue<double, 1>& Out) { Out = { In }; }
339 inline void MultiChannelFromData(float In, TMultiChannelValue<float, 1>& Out) { Out = { In }; }
340 inline void MultiChannelFromData(FVector2D In, TMultiChannelValue<float, 2>& Out) { Out = { In.X, In.Y }; }
341 inline void MultiChannelFromData(FVector In, TMultiChannelValue<float, 3>& Out) { Out = { In.X, In.Y, In.Z }; }
342 inline void MultiChannelFromData(const FVector4& In, TMultiChannelValue<float, 4>& Out) { Out = { In.X, In.Y, In.Z, In.W }; }
358 {
359 Out = { In.R, In.G, In.B, In.A };
360 }
361
362 inline void ResolveChannelsToData(const TMultiChannelValue<double, 1>& In, int32& Out) { Out = In[0]; }
363 inline void ResolveChannelsToData(const TMultiChannelValue<float, 1>& In, float& Out) { Out = In[0]; }
364 inline void ResolveChannelsToData(const TMultiChannelValue<float, 2>& In, FVector2D& Out) { Out = FVector2D(In[0], In[1]); }
365 inline void ResolveChannelsToData(const TMultiChannelValue<float, 3>& In, FVector& Out) { Out = FVector(In[0], In[1], In[2]); }
366 inline void ResolveChannelsToData(const TMultiChannelValue<float, 4>& In, FVector4& Out) { Out = FVector4(In[0], In[1], In[2], In[3]); }
368 {
369 Out = FTransform(
370 FRotator::MakeFromEuler(FVector(In[3], In[4], In[5])),
371 FVector(In[0], In[1], In[2]),
372 FVector(In[6], In[7], In[8])
373 );
374 }
376 {
377 Out = FEulerTransform(
378 FVector(In[0], In[1], In[2]),
379 FRotator::MakeFromEuler(FVector(In[3], In[4], In[5])),
380 FVector(In[6], In[7], In[8])
381 );
382 }
384 {
385 Out = FLinearColor(In[0], In[1], In[2], In[3]);
386 }
387} // namespace MovieScene
388} // namespace UE
389
399
#define check(expr)
Definition AssertionMacros.h:314
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
@ INDEX_NONE
Definition CoreMiscDefines.h:150
#define TEXT(x)
Definition Platform.h:1272
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
#define FVector
Definition IOSSystemIncludes.h:8
UE::Math::TTransform< double > FTransform
Definition MathFwd.h:53
UE::Math::TVector4< double > FVector4
Definition MathFwd.h:49
UE::Math::TRotator< double > FRotator3d
Definition MathFwd.h:70
UE::Math::TVector2< double > FVector2D
Definition MathFwd.h:48
EMovieSceneBlendType
Definition MovieSceneBlendType.h:19
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< FVector2D >()
Definition MovieSceneMultiChannelBlending.cpp:7
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< FLinearColor >()
Definition MovieSceneMultiChannelBlending.cpp:12
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< float >()
Definition MovieSceneMultiChannelBlending.cpp:6
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< FVector4 >()
Definition MovieSceneMultiChannelBlending.cpp:9
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< FTransform >()
Definition MovieSceneMultiChannelBlending.cpp:10
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< FVector >()
Definition MovieSceneMultiChannelBlending.cpp:8
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< int32 >()
Definition MovieSceneMultiChannelBlending.cpp:5
MOVIESCENE_API FMovieSceneAnimTypeID GetBlendingDataType< FEulerTransform >()
Definition MovieSceneMultiChannelBlending.cpp:11
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
float Val(const FString &Value)
Definition UnrealMath.cpp:3163
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MovieScene.Build.cs:6
void ResolveChannelsToData(const TMultiChannelValue< T, N > &OutChannelData, SourceData &OutData)
Definition MovieSceneMultiChannelBlending.h:171
void BlendValue(WorkingDataType &OutBlend, InType InValue, float Weight, EMovieSceneBlendType BlendType, TMovieSceneInitialValueStore< SourceDataType > &InitialValueStore)
Definition BlendableToken.h:80
void MultiChannelFromData(SourceData InSourceData, TMultiChannelValue< T, N > &OutChannelData)
Definition MovieSceneMultiChannelBlending.h:161
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71
Definition EulerTransform.h:32
FVector Location
Definition EulerTransform.h:73
FRotator Rotation
Definition EulerTransform.h:77
FVector Scale
Definition EulerTransform.h:81
Definition Color.h:48
float A
Definition Color.h:56
float G
Definition Color.h:54
float B
Definition Color.h:55
float R
Definition Color.h:53
static UE_FORCEINLINE_HINT void * Memzero(void *Dest, SIZE_T Count)
Definition UnrealMemory.h:131
Definition MovieSceneAnimTypeID.h:20
UE::MovieScene::TMaskedBlendable< float, 9 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:407
UE::MovieScene::TMaskedBlendable< float, 4 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:408
UE::MovieScene::TMaskedBlendable< float, 9 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:406
UE::MovieScene::TMaskedBlendable< float, 2 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:403
UE::MovieScene::TMaskedBlendable< float, 4 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:405
UE::MovieScene::TMaskedBlendable< float, 3 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:404
UE::MovieScene::TMaskedBlendable< float, 1 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:402
UE::MovieScene::TMaskedBlendable< double, 1 > WorkingDataType
Definition MovieSceneMultiChannelBlending.h:401
Definition BlendableToken.h:93
Definition MovieSceneInitialValueStore.h:49
Definition Optional.h:131
constexpr OptionalType & GetValue()
Definition Optional.h:443
constexpr bool IsSet() const
Definition Optional.h:69
OptionalType & Emplace(ArgsType &&... Args)
Definition Optional.h:323
CORE_API TRotator< T > Rotator() const
CORE_API TVector< T > Euler() const
Definition UnrealMath.cpp:553
static CORE_API TRotator MakeFromEuler(const TVector< double > &Euler)
Definition UnrealMath.cpp:559
TVector< T > GetTranslation() const
Definition TransformNonVectorized.h:1120
TQuat< T > GetRotation() const
Definition TransformNonVectorized.h:1109
TVector< T > GetScale3D() const
Definition TransformNonVectorized.h:1131
T Y
Definition Vector2D.h:52
T X
Definition Vector2D.h:49
T Y
Definition Vector4.h:46
T Z
Definition Vector4.h:49
T W
Definition Vector4.h:52
T X
Definition Vector4.h:43
T Z
Definition Vector.h:68
T Y
Definition Vector.h:65
T X
Definition Vector.h:62
Definition MovieSceneMultiChannelBlending.h:179
TMultiChannelValue< DataType, N > Additive
Definition MovieSceneMultiChannelBlending.h:192
ActualDataType Resolve(TMovieSceneInitialValueStore< ActualDataType > &InitialValueStore)
Definition MovieSceneMultiChannelBlending.h:202
TMultiChannelValue< DataType, N > Override
Definition MovieSceneMultiChannelBlending.h:195
TMaskedBlendable()
Definition MovieSceneMultiChannelBlending.h:180
TMultiChannelValue< DataType, N > Absolute
Definition MovieSceneMultiChannelBlending.h:187
float AbsoluteWeights[N]
Definition MovieSceneMultiChannelBlending.h:189
TOptional< TMultiChannelValue< DataType, N > > InitialValue
Definition MovieSceneMultiChannelBlending.h:198
Definition MovieSceneMultiChannelBlending.h:69
TMultiChannelValue()
Definition MovieSceneMultiChannelBlending.h:73
bool IsEmpty() const
Definition MovieSceneMultiChannelBlending.h:104
T Get(uint8 Index, T Default) const
Definition MovieSceneMultiChannelBlending.h:98
TMultiChannelValue(std::initializer_list< OtherType > InitList)
Definition MovieSceneMultiChannelBlending.h:79
bool IsSet(uint8 Index) const
Definition MovieSceneMultiChannelBlending.h:117
void Set(uint8 Index, T Value)
Definition MovieSceneMultiChannelBlending.h:124
void WeightedBlend(uint8 Index, T Value, float Weight)
Definition MovieSceneMultiChannelBlending.h:142
bool IsFull() const
Definition MovieSceneMultiChannelBlending.h:110
void Increment(uint8 Index, T Value)
Definition MovieSceneMultiChannelBlending.h:133
T operator[](uint8 Index) const
Definition MovieSceneMultiChannelBlending.h:91