UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
AnimEncoding.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4 AnimEncoding.h: Skeletal mesh animation compression.
5=============================================================================*/
6
7#pragma once
8
9#include "CoreMinimal.h"
10#include "Misc/MemStack.h"
11#include "Animation/AnimTypes.h"
15
16// switches to toggle subsets of the new animation codec system
17#define USE_ANIMATION_CODEC_BATCH_SOLVER 1
18
19// all past encoding package version numbers should be listed here
20#define ANIMATION_ENCODING_PACKAGE_ORIGINAL 0
21
22// the current animation encoding package version
23#define CURRENT_ANIMATION_ENCODING_PACKAGE_VERSION ANIMATION_ENCODING_PACKAGE_ORIGINAL
24
25class FMemoryWriter;
26
28//
29// Interfaces For Working With Encoded Animations
30//
32
45
50#define MAX_BONES 65536 // DesiredBones is passed to the decompression routines as a TArray<FBoneIndexType>, so we know this max is appropriate
52
53
56
57
79 float& TranslationKeySize,
80 float& RotationKeySize,
81 float& ScaleKeySize,
86
92template<typename CompressedDataType>
94
95#if WITH_EDITORONLY_DATA
96#define AC_UnalignedSwap( MemoryArchive, Data, Len ) \
97 MemoryArchive.ByteOrderSerialize( (Data), (Len) ); \
98 (Data) += (Len);
99#else
100 // No need to swap on consoles, as the cooker will have ordered bytes for the target platform.
101#define AC_UnalignedSwap( MemoryArchive, Data, Len ) \
102 MemoryArchive.Serialize( (Data), (Len) ); \
103 (Data) += (Len);
104#endif // !WITH_EDITORONLY_DATA
105
113
114class FMemoryWriter;
115class FMemoryReader;
116
117void PadMemoryWriter(FMemoryWriter* MemoryWriter, uint8*& TrackData, const int32 Alignment);
118void PadMemoryReader(FMemoryReader* MemoryReader, uint8*& TrackData, const int32 Alignment);
119
120
122{
123public:
131 virtual void ByteSwapIn(
132 FUECompressedAnimData& CompressedData,
133 FMemoryReader& MemoryReader) PURE_VIRTUAL(AnimEncoding::ByteSwapIn,);
134
142 virtual void ByteSwapOut(
143 FUECompressedAnimData& CompressedData,
144 FMemoryWriter& MemoryWriter) PURE_VIRTUAL(AnimEncoding::ByteSwapOut, );
145
146#if USE_ANIMATION_CODEC_BATCH_SOLVER
147
155 virtual void GetPoseRotations(
158 FAnimSequenceDecompressionContext& DecompContext) PURE_VIRTUAL(AnimEncoding::GetPoseRotations,);
159
167 virtual void GetPoseTranslations(
170 FAnimSequenceDecompressionContext& DecompContext) PURE_VIRTUAL(AnimEncoding::GetPoseTranslations,);
171
179 virtual void GetPoseScales(
182 FAnimSequenceDecompressionContext& DecompContext) PURE_VIRTUAL(AnimEncoding::GetPoseScales,);
183#endif
184
185protected:
186
198 static float TimeToIndex(
199 float SequenceLength,
200 float RelativePos,
201 int32 NumKeys,
202 EAnimInterpolationType Interpolation,
205
218 static float TimeToIndex(
219 EAnimInterpolationType Interpolation,
220 int32 NumberOfFrames,
221 const uint8* FrameTable,
222 float RelativePos,
223 int32 NumKeys,
226};
227
228
235{
236public:
244 virtual void GetBoneAtomRotation(
247 int32 TrackIndex) PURE_VIRTUAL(AnimEncoding::GetBoneAtomRotation,);
248
256 virtual void GetBoneAtomTranslation(
259 int32 TrackIndex) PURE_VIRTUAL(AnimEncoding::GetBoneAtomTranslation,);
260
268 virtual void GetBoneAtomScale(
271 int32 TrackIndex) PURE_VIRTUAL(AnimEncoding::GetBoneAtomScale,);
272
279 virtual void ByteSwapIn(
280 FUECompressedAnimData& CompressedData,
281 FMemoryReader& MemoryReader) override;
282
290 virtual void ByteSwapOut(
291 FUECompressedAnimData& CompressedData,
292 FMemoryWriter& MemoryWriter) override;
293
304 virtual void ByteSwapRotationIn(
305 FUECompressedAnimData& CompressedData,
306 FMemoryReader& MemoryReader,
307 uint8*& Stream,
308 int32 NumKeys) PURE_VIRTUAL(AnimEncoding::ByteSwapRotationIn,);
309
320 virtual void ByteSwapTranslationIn(
321 FUECompressedAnimData& CompressedData,
322 FMemoryReader& MemoryReader,
323 uint8*& Stream,
324 int32 NumKeys) PURE_VIRTUAL(AnimEncoding::ByteSwapTranslationIn,);
325
336 virtual void ByteSwapScaleIn(
337 FUECompressedAnimData& CompressedData,
338 FMemoryReader& MemoryReader,
339 uint8*& Stream,
340 int32 NumKeys) PURE_VIRTUAL(AnimEncoding::ByteSwapScaleIn,);
341
351 virtual void ByteSwapRotationOut(
352 FUECompressedAnimData& CompressedData,
353 FMemoryWriter& MemoryWriter,
354 uint8*& Stream,
355 int32 NumKeys) PURE_VIRTUAL(AnimEncoding::ByteSwapRotationOut,);
356
366 virtual void ByteSwapTranslationOut(
367 FUECompressedAnimData& CompressedData,
368 FMemoryWriter& MemoryWriter,
369 uint8*& Stream,
370 int32 NumKeys) PURE_VIRTUAL(AnimEncoding::ByteSwapTranslationOut,);
371
381 virtual void ByteSwapScaleOut(
382 FUECompressedAnimData& CompressedData,
383 FMemoryWriter& MemoryWriter,
384 uint8*& Stream,
385 int32 NumKeys) PURE_VIRTUAL(AnimEncoding::ByteSwapScaleOut,);
386};
387
388
400 float SequenceLength,
401 float RelativePos,
402 int32 NumKeys,
403 EAnimInterpolationType Interpolation,
406{
407 float Alpha;
408
409 if (NumKeys < 2)
410 {
411 checkSlow(NumKeys == 1); // check if data is empty for some reason.
412 PosIndex0Out = 0;
413 PosIndex1Out = 0;
414 return 0.0f;
415 }
416 // Check for before-first-frame case.
417 if( RelativePos <= 0.f )
418 {
419 PosIndex0Out = 0;
420 PosIndex1Out = 0;
421 Alpha = 0.0f;
422 }
423 else
424 {
425 NumKeys -= 1; // never used without the minus one in this case
426 // Check for after-last-frame case.
427 if( RelativePos >= 1.0f )
428 {
429 // If we're not looping, key n-1 is the final key.
430 PosIndex0Out = NumKeys;
431 PosIndex1Out = NumKeys;
432 Alpha = 0.0f;
433 }
434 else
435 {
436 // For non-looping animation, the last frame is the ending frame, and has no duration.
437 const float KeyPos = RelativePos * float(NumKeys);
438 checkSlow(KeyPos >= 0.0f);
439 const float KeyPosFloor = floorf(KeyPos);
440 PosIndex0Out = FMath::Min( FMath::TruncToInt(KeyPosFloor), NumKeys );
441 Alpha = (Interpolation == EAnimInterpolationType::Step) ? 0.0f : KeyPos - KeyPosFloor;
442 PosIndex1Out = FMath::Min( PosIndex0Out + 1, NumKeys );
443 }
444 }
445 return Alpha;
446}
447
457template <typename TABLE_TYPE>
459 const TABLE_TYPE* FrameTable,
460 int32 NumKeys,
463{
464 const int32 LastKeyIndex = NumKeys-1;
466
468 {
469 // unless we find something better, we'll default to the last key
471
472 // search forward from the estimate for the first value greater than our search parameter
473 // if found, this is the high key and we want the one just prior to it
474 for (int32 i = KeyEstimate+1; i <= LastKeyIndex; ++i)
475 {
476 if (FrameTable[i] > SearchFrame)
477 {
478 LowKeyIndex= i-1;
479 break;
480 }
481 }
482 }
483 else
484 {
485 // unless we find something better, we'll default to the first key
486 LowKeyIndex = 0;
487
488 // search backward from the estimate for the first value less than or equal to the search parameter
489 // if found, this is the low key we are searching for
490 for (int32 i = KeyEstimate-1; i > 0; --i)
491 {
492 if (FrameTable[i] <= SearchFrame)
493 {
494 LowKeyIndex= i;
495 break;
496 }
497 }
498 }
499
500 return LowKeyIndex;
501}
502
515 EAnimInterpolationType Interpolation,
516 int32 NumberOfFrames,
517 const uint8* FrameTable,
518 float RelativePos,
519 int32 NumKeys,
522{
523 float Alpha = 0.0f;
524
525 check(NumKeys != 0);
526
527 const int32 LastKey= NumKeys-1;
528
529 int32 TotalFrames = NumberOfFrames -1;
530 int32 EndingKey = LastKey;
531
532 if (NumKeys < 2 || RelativePos <= 0.f)
533 {
534 // return the first key
535 PosIndex0Out = 0;
536 PosIndex1Out = 0;
537 Alpha = 0.0f;
538 }
539 else if( RelativePos >= 1.0f )
540 {
541 // return the ending key
544 Alpha = 0.0f;
545 }
546 else
547 {
548 // find the proper key range to return
549 const int32 LastFrame= TotalFrames-1;
550 const float KeyPos = RelativePos * (float)LastKey;
551 const float FramePos = RelativePos * (float)TotalFrames;
552 const int32 FramePosFloor = FMath::Clamp(FMath::TruncToInt(FramePos), 0, LastFrame);
553 const int32 KeyEstimate = FMath::Clamp(FMath::TruncToInt(KeyPos), 0, LastKey);
554
555 int32 LowFrame = 0;
556 int32 HighFrame = 0;
557
558 // find the pair of keys which surround our target frame index
559 if (NumberOfFrames > 0xFF)
560 {
561 const uint16* Frames= (uint16*)FrameTable;
564
566 if (PosIndex1Out > LastKey)
567 {
569 }
571 }
572 else
573 {
574 const uint8* Frames= (uint8*)FrameTable;
577
579 if (PosIndex1Out > LastKey)
580 {
582 }
584 }
585
586 // compute the blend parameters for the keys we have found
587 int32 Delta= FMath::Max(HighFrame - LowFrame, 1);
588 const float Remainder = (FramePos - (float)LowFrame);
589 Alpha = Interpolation == EAnimInterpolationType::Step ? 0.f : (Remainder / (float)Delta);
590 }
591
592 return Alpha;
593}
ENGINE_API const int32 CompressedTranslationNum[ACF_MAX]
Definition AnimEncoding.cpp:26
ENGINE_API const uint8 PerTrackNumComponentTable[ACF_MAX *8]
Definition AnimEncoding.cpp:65
ENGINE_API void AnimationFormat_GetStats(const FUECompressedAnimData &CompressedData, int32 &NumTransTracks, int32 &NumRotTracks, int32 &NumScaleTracks, int32 &TotalNumTransKeys, int32 &TotalNumRotKeys, int32 &TotalNumScaleKeys, float &TranslationKeySize, float &RotationKeySize, float &ScaleKeySize, int32 &OverheadSize, int32 &NumTransTracksWithOneKey, int32 &NumRotTracksWithOneKey, int32 &NumScaleTracksWithOneKey)
Definition AnimEncoding.cpp:335
ENGINE_API const int32 CompressedScaleStrides[ACF_MAX]
Definition AnimEncoding.cpp:77
void PadMemoryWriter(FMemoryWriter *MemoryWriter, uint8 *&TrackData, const int32 Alignment)
Definition AnimEncoding.cpp:153
ENGINE_API const int32 CompressedRotationNum[ACF_MAX]
Definition AnimEncoding.cpp:50
ENGINE_API const int32 CompressedScaleNum[ACF_MAX]
Definition AnimEncoding.cpp:89
void AnimationFormat_SetInterfaceLinks(CompressedDataType &CompressedData)
Definition AnimEncoding.cpp:581
ENGINE_API const int32 CompressedTranslationStrides[ACF_MAX]
Definition AnimEncoding.cpp:14
int32 FindLowKeyIndex(const TABLE_TYPE *FrameTable, int32 NumKeys, int32 SearchFrame, int32 KeyEstimate)
Definition AnimEncoding.h:458
void PadMemoryReader(FMemoryReader *MemoryReader, uint8 *&TrackData, const int32 Alignment)
Definition AnimEncoding.cpp:169
TArray< BoneTrackPair > BoneTrackArray
Definition AnimEncoding.h:51
TArray< FTransform, TMemStackAllocator<> > FTransformArray
Definition AnimEncoding.h:55
ENGINE_API const int32 CompressedRotationStrides[ACF_MAX]
Definition AnimEncoding.cpp:38
EAnimInterpolationType
Definition AnimTypes.h:689
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define PURE_VIRTUAL(func,...)
Definition CoreMiscDefines.h:103
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
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
Definition AnimEncoding.h:235
virtual void virtual GetBoneAtomRotation(FTransform &OutAtom, const FAnimSequenceDecompressionContext &DecompContext, int32 TrackIndex) PURE_VIRTUAL(AnimEncoding void virtual GetBoneAtomTranslation(FTransform &OutAtom, const FAnimSequenceDecompressionContext &DecompContext, int32 TrackIndex) PURE_VIRTUAL(AnimEncoding void virtual GetBoneAtomScale(FTransform &OutAtom, const FAnimSequenceDecompressionContext &DecompContext, int32 TrackIndex) PURE_VIRTUAL(AnimEncoding void ByteSwapIn(FUECompressedAnimData &CompressedData, FMemoryReader &MemoryReader) override
Definition AnimEncoding.h:279
virtual void ByteSwapOut(FUECompressedAnimData &CompressedData, FMemoryWriter &MemoryWriter) override
Definition AnimEncoding.cpp:250
Definition AnimEncoding.h:122
static float TimeToIndex(float SequenceLength, float RelativePos, int32 NumKeys, EAnimInterpolationType Interpolation, int32 &PosIndex0Out, int32 &PosIndex1Out)
Definition AnimEncoding.h:399
Definition MemoryReader.h:17
Definition MemoryWriter.h:101
Definition ArrayView.h:139
Definition Array.h:670
Definition AnimEncoding.h:38
BoneTrackPair()
Definition AnimEncoding.h:42
int32 TrackIndex
Definition AnimEncoding.h:40
int32 AtomIndex
Definition AnimEncoding.h:39
BoneTrackPair(int32 Atom, int32 Track)
Definition AnimEncoding.h:43
Definition AnimSequenceDecompressionContext.h:14
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592
Definition AnimCompressionTypes.h:505