VariableFrameStrippingSettings

VariableFrameStrippingSettings

#Overview

name: VariableFrameStrippingSettings

The value of this variable can be defined or overridden in .ini config files. 1 .ini config file referencing this setting variable.

It is referenced in 16 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of VariableFrameStrippingSettings is to control the variable frame stripping functionality for animation sequences in Unreal Engine 5. This feature is part of the animation compression system and is used to optimize animation data by selectively removing frames based on certain criteria.

The VariableFrameStrippingSettings is primarily used in the Animation subsystem of Unreal Engine. It is referenced in the AnimSequence and AnimStreamable classes, which are core components of the animation system.

The value of this variable is typically set through the Unreal Engine editor or programmatically using the SetVariableFrameStrippingSettings function in the AnimationBlueprintLibrary. It can also be created using the VariableFrameStrippingSettingsFactory.

This variable interacts closely with other animation-related variables, particularly those related to compression settings. It’s used in conjunction with BoneCompressionSettings and CurveCompressionSettings when generating DDC keys for animation data.

Developers must be aware that changing VariableFrameStrippingSettings can significantly impact animation quality and performance. It’s crucial to balance between file size reduction and maintaining animation fidelity.

Best practices when using this variable include:

  1. Carefully testing the impact of different settings on animation quality and performance.
  2. Considering platform-specific settings, as the variable supports per-platform configuration.
  3. Ensuring it’s properly set before compressing animation data.
  4. Using it in conjunction with other animation compression settings for optimal results.
  5. Being cautious when modifying it for existing animations, as it may require recompression of animation data.

Developers should also note that this setting contributes to the DDC key generation for animations, which means changing it will invalidate existing cached animation data and require recompression.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEngine.ini:3391, section: [Animation.DefaultObjectSettings]

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Editor/AnimationBlueprintLibrary/Private/AnimationBlueprintLibrary.cpp:275

Scope (from outer to inner):

file
function     void UAnimationBlueprintLibrary::GetVariableFrameStrippingSettings

Source code excerpt:

}

void UAnimationBlueprintLibrary::GetVariableFrameStrippingSettings(const UAnimSequence* AnimationSequence, UVariableFrameStrippingSettings*& VariableFrameStrippingSettings)
{
	if (AnimationSequence == nullptr)
	{
		UE_LOG(LogAnimationBlueprintLibrary, Warning, TEXT("Invalid VariableFrameStrippingSettings supplied for GetVariableFrameStrippingSettings"));
		return;
	}

	VariableFrameStrippingSettings = AnimationSequence->VariableFrameStrippingSettings;
}

void UAnimationBlueprintLibrary::SetVariableFrameStrippingSettings(UAnimSequence* AnimationSequence, UVariableFrameStrippingSettings* VariableFrameStrippingSettings)
{
	if (AnimationSequence == nullptr)
	{
		UE_LOG(LogAnimationBlueprintLibrary, Warning, TEXT("Invalid Animation Sequence supplied for SetVariableFrameStrippingSettings"));
		return;
	}

	if (VariableFrameStrippingSettings == nullptr)
	{
		UE_LOG(LogAnimationBlueprintLibrary, Warning, TEXT("Invalid VariableFrameStrippingSettings supplied for SetVariableFrameStrippingSettings"));
		return;
	}

	AnimationSequence->VariableFrameStrippingSettings = VariableFrameStrippingSettings;
}

void UAnimationBlueprintLibrary::GetAdditiveAnimationType(const UAnimSequence* AnimationSequence, TEnumAsByte<enum EAdditiveAnimationType>& AdditiveAnimationType)
{
	if (AnimationSequence)
	{

#Loc: <Workspace>/Engine/Source/Editor/AnimationBlueprintLibrary/Public/AnimationBlueprintLibrary.h:133

Scope (from outer to inner):

file
class        class UAnimationBlueprintLibrary : public UBlueprintFunctionLibrary

Source code excerpt:

	/** Retrieves the Variable Frame Stripping Settings for the given Animation Sequence */
	UFUNCTION(BlueprintPure, Category = "AnimationBlueprintLibrary|Compression")
	static void GetVariableFrameStrippingSettings(const UAnimSequence* AnimationSequence, UVariableFrameStrippingSettings*& VariableFrameStrippingSettings);

	/** Sets the Variable Frame Stripping Settings for the given Animation Sequence */
	UFUNCTION(BlueprintCallable, Category = "AnimationBlueprintLibrary|Compression")
	static void SetVariableFrameStrippingSettings(UAnimSequence* AnimationSequence, UVariableFrameStrippingSettings* VariableFrameStrippingSettings);

	// Additive 
	/** Retrieves the Additive Animation type for the given Animation Sequence */
	UFUNCTION(BlueprintPure, Category = "AnimationBlueprintLibrary|Additive")
	static void GetAdditiveAnimationType(const UAnimSequence* AnimationSequence, TEnumAsByte<enum EAdditiveAnimationType>& AdditiveAnimationType);

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Factories/VariableFrameStrippingSettingsFactory.cpp:20

Scope (from outer to inner):

file
function     UObject* UVariableFrameStrippingSettingsFactory::FactoryCreateNew

Source code excerpt:

UObject* UVariableFrameStrippingSettingsFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)
{
	// Create and return a new instance of VariableFrameStrippingSettings
	return NewObject<UVariableFrameStrippingSettings>(InParent, Class, Name, Flags);
}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Animation/AnimSequence.h:300

Scope (from outer to inner):

file
class        class UAnimSequence : public UAnimSequenceBase

Source code excerpt:


	UPROPERTY(Category = Compression, EditAnywhere, meta = (ForceShowEngineContent))
	TObjectPtr<class UVariableFrameStrippingSettings> VariableFrameStrippingSettings;

	/** Additive animation type. **/
	UPROPERTY(EditAnywhere, Category=AdditiveSettings, AssetRegistrySearchable)
	TEnumAsByte<enum EAdditiveAnimationType> AdditiveAnimType;

	/* Additive refrerence pose type. Refer above enum type */

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Animation/AnimStreamable.h:189

Scope (from outer to inner):

file
class        class UAnimStreamable : public UAnimSequenceBase

Source code excerpt:

	/** The settings used to control whether or not to use variable frame stripping and its amount*/
	UPROPERTY(Category = Compression, EditAnywhere)
	TObjectPtr<class UVariableFrameStrippingSettings> VariableFrameStrippingSettings;

	/** If this is on, it will allow extracting of root motion **/
	UPROPERTY(EditAnywhere, AssetRegistrySearchable, Category = RootMotion, meta = (DisplayName = "EnableRootMotion"))
	bool bEnableRootMotion;

	/** Root Bone will be locked to that position when extracting root motion.**/

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimCompressionTypes.cpp:938

Scope (from outer to inner):

file
function     void FCompressibleAnimData::FetchData

Source code excerpt:


		const FName TargetPlatformName = InPlatform->GetPlatformInfo().IniPlatformName;
		const TObjectPtr<class UVariableFrameStrippingSettings> VarFrameStrippingSettings = AnimSequence->VariableFrameStrippingSettings;
		const FPerPlatformBool PlatformBool = VarFrameStrippingSettings->UseVariableFrameStripping;
		const bool bUseMultiplier = PlatformBool.GetValueForPlatform(TargetPlatformName);

		const int32 NumTracks = RawAnimationData.Num();

		if (bUseMultiplier) 
		{
			int32 Rate = AnimSequence->VariableFrameStrippingSettings->FrameStrippingRate.GetValueForPlatform(TargetPlatformName);
			for (FRawAnimSequenceTrack& Track : RawAnimationData)
			{
				StripFramesMultipler(Track.PosKeys, NumberOfKeys, Rate);
				StripFramesMultipler(Track.RotKeys, NumberOfKeys, Rate);
				StripFramesMultipler(Track.ScaleKeys, NumberOfKeys, Rate);
			}

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimSequence.cpp:273

Scope (from outer to inner):

file
function     FString GetAnimSequenceSpecificCacheKeySuffix

Source code excerpt:

	Seq.BoneCompressionSettings->PopulateDDCKey(UE::Anim::Compression::FAnimDDCKeyArgs(Seq, TargetPlatform), ArcToHexString.Ar);
	Seq.CurveCompressionSettings->PopulateDDCKey(ArcToHexString.Ar);
	Seq.VariableFrameStrippingSettings->PopulateDDCKey(UE::Anim::Compression::FAnimDDCKeyArgs(Seq, TargetPlatform), ArcToHexString.Ar);

	FString Ret = FString::Printf(TEXT("%i_%s%s%s_%c%c%i_%s_%s_%i"),
		Seq.CompressCommandletVersion,
		PRAGMA_DISABLE_DEPRECATION_WARNINGS
		*Seq.GetDataModel()->GenerateGuid().ToString(),
		PRAGMA_ENABLE_DEPRECATION_WARNINGS

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimSequence.cpp:902

Scope (from outer to inner):

file
function     void UAnimSequence::GetPreloadDependencies

Source code excerpt:

		OutDeps.Add(BoneCompressionSettings);
	}
	if (VariableFrameStrippingSettings != nullptr)
	{
		OutDeps.Add(VariableFrameStrippingSettings);
	}
}

void UAnimSequence::PreSave(const class ITargetPlatform* TargetPlatform)
{
	PRAGMA_DISABLE_DEPRECATION_WARNINGS;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimSequence.cpp:1137

Scope (from outer to inner):

file
function     void UAnimSequence::PostEditChangeProperty

Source code excerpt:

											  || PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UAnimSequence, BoneCompressionSettings)
											  || PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UAnimSequence, CurveCompressionSettings)
											  || PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UAnimSequence, VariableFrameStrippingSettings);

		bShouldResample = PropertyChangedEvent.GetMemberPropertyName() == GET_MEMBER_NAME_CHECKED(UAnimSequence, PlatformTargetFrameRate) || bChangedRefFrameIndex;
	}

	if (bShouldResample)
	{

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimSequence.cpp:4549

Scope (from outer to inner):

file
function     FIoHash UAnimSequence::CreateDerivedDataKeyHash

Source code excerpt:

	BoneCompressionSettings->PopulateDDCKey(UE::Anim::Compression::FAnimDDCKeyArgs(*this, TargetPlatform), ArcToHexString.Ar);
	CurveCompressionSettings->PopulateDDCKey(ArcToHexString.Ar);
	VariableFrameStrippingSettings->PopulateDDCKey(UE::Anim::Compression::FAnimDDCKeyArgs(*this, TargetPlatform), ArcToHexString.Ar);
	
	const FFrameRate FrameRate = PlatformTargetFrameRate.GetValueForPlatform(TargetPlatform->GetPlatformInfo().IniPlatformName);

	FString Ret = FString::Printf(TEXT("%i_%s%s%s_%c%c%i_%s_%s_%i_%i_%s"),
		CompressCommandletVersion,
		PRAGMA_DISABLE_DEPRECATION_WARNINGS

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimSequence.cpp:4607

Scope (from outer to inner):

file
function     FIoHash UAnimSequence::BeginCacheDerivedData

Source code excerpt:

		CurveCompressionSettings = FAnimationUtils::GetDefaultAnimationCurveCompressionSettings();
	}
	if (VariableFrameStrippingSettings == nullptr)
	{
		VariableFrameStrippingSettings = FAnimationUtils::GetDefaultVariableFrameStrippingSettings();
	}

	// Make sure all our required dependencies are loaded, we need them to compute the KeyHash
	FAnimationUtils::EnsureAnimSequenceLoaded(*this);
		
	const FIoHash KeyHash = CreateDerivedDataKeyHash(TargetPlatform);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimStreamable.cpp:487

Scope (from outer to inner):

file
function     void UAnimStreamable::InitFrom

Source code excerpt:

	
	DataModelInterface = StaticDuplicateObject(InSourceSequence->GetDataModelInterface().GetObject(), this);
	VariableFrameStrippingSettings = InSourceSequence->VariableFrameStrippingSettings;

	// Far from ideal (retrieving controller to ensure it matches the DataModelInterface type)
	Controller = DataModelInterface->GetController();
	Controller->SetModel(DataModelInterface);

	Notifies = InSourceSequence->Notifies;

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimStreamable.cpp:571

Scope (from outer to inner):

file
function     void UAnimStreamable::RequestCompressedData

Source code excerpt:

	}

	if (VariableFrameStrippingSettings == nullptr)
	{
		VariableFrameStrippingSettings = FAnimationUtils::GetDefaultVariableFrameStrippingSettings();
	}

	checkf(Platform, TEXT("Failed to specify platform for streamable animation compression"));

	FStreamableAnimPlatformData& PlatformData = GetStreamingAnimPlatformData(Platform);

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimStreamable.cpp:803

Scope (from outer to inner):

file
function     FString UAnimStreamable::GetBaseDDCKey

Source code excerpt:

	BoneCompressionSettings->PopulateDDCKey(UE::Anim::Compression::FAnimDDCKeyArgs(*this, TargetPlatform), ArcToHexString.Ar);
	CurveCompressionSettings->PopulateDDCKey(ArcToHexString.Ar);
	VariableFrameStrippingSettings->PopulateDDCKey(UE::Anim::Compression::FAnimDDCKeyArgs(*this, TargetPlatform), ArcToHexString.Ar);

	FString Ret = FString::Printf(TEXT("%s%s%s%s_%s"),
		StreamingAnimChunkVersion,
		*RawDataGuid.ToString(),
		*GetSkeleton()->GetGuid().ToString(),
		*GetSkeleton()->GetVirtualBoneGuid().ToString(),

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimationUtils.cpp:984

Scope (from outer to inner):

file
function     UVariableFrameStrippingSettings* FAnimationUtils::GetDefaultVariableFrameStrippingSettings

Source code excerpt:

	if (DefaultVariableFrameStrippingSettings == nullptr)
	{
		DefaultVariableFrameStrippingSettings = Cast<UVariableFrameStrippingSettings>(GetDefaultAnimationCompressionSettings(TEXT("VariableFrameStrippingSettings"), true));
	}

	return DefaultVariableFrameStrippingSettings;
}

void FAnimationUtils::EnsureAnimSequenceLoaded(UAnimSequence& AnimSeq)

#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/Animation/AnimationUtils.cpp:997

Scope (from outer to inner):

file
function     void FAnimationUtils::EnsureAnimSequenceLoaded

Source code excerpt:

	EnsureDependenciesAreLoaded(AnimSeq.CurveCompressionSettings);
	EnsureDependenciesAreLoaded(AnimSeq.RefPoseSeq);
	EnsureDependenciesAreLoaded(AnimSeq.VariableFrameStrippingSettings);
}

void FAnimationUtils::ExtractTransformForFrameFromTrackSafe(const FRawAnimSequenceTrack& RawTrack, int32 Frame, FTransform& OutAtom)
{
	// Bail out (with rather wacky data) if data is empty for some reason.
	if (RawTrack.PosKeys.Num() == 0 || RawTrack.RotKeys.Num() == 0)