FrameInterpolationProcessor

FrameInterpolationProcessor

#Overview

name: FrameInterpolationProcessor

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 12 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of FrameInterpolationProcessor is to handle frame interpolation for LiveLink subjects in Unreal Engine 5. It is primarily used in the animation system, specifically within the LiveLink plugin, which allows real-time streaming and recording of animation data from external sources.

FrameInterpolationProcessor is relied upon by the LiveLink plugin and its associated modules. It is used in the LiveLinkClient, LiveLinkSubject, and LiveLinkHubClient classes.

The value of this variable is typically set in the LiveLink settings. It can be configured per subject or as a default setting for all subjects.

This variable interacts with other LiveLink-related variables and objects, such as LiveLinkSubjectSettings, LiveLinkRole, and LiveLinkStaticData.

Developers must be aware that:

  1. The FrameInterpolationProcessor is optional. If not set, no interpolation will be performed.
  2. The processor class must be compatible with the subject’s role.
  3. It affects how frame data is retrieved and interpolated at specific world or scene times.

Best practices when using this variable include:

  1. Ensure the chosen FrameInterpolationProcessor is appropriate for the specific LiveLink subject role.
  2. Configure it properly in the LiveLink settings, either globally or per subject.
  3. Be mindful of performance implications when using complex interpolation processors.
  4. Test thoroughly to ensure the interpolation produces the desired results for your specific use case.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseGame.ini:218, section: [/Script/LiveLink.LiveLinkSettings]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkClient.cpp:629

Scope (from outer to inner):

file
function     void FLiveLinkClient::PushSubjectStaticData_Internal

Source code excerpt:

			SubjectSettings->Role = SubjectStaticData.Role;

			UClass* FrameInterpolationProcessorClass = DefaultSetting.FrameInterpolationProcessor.Get();
			if (FrameInterpolationProcessorClass != nullptr)
			{
				UClass* InterpolationRole = FrameInterpolationProcessorClass->GetDefaultObject<ULiveLinkFrameInterpolationProcessor>()->GetRole();
				if (SubjectStaticData.Role->IsChildOf(InterpolationRole))
				{
					SubjectSettings->InterpolationProcessor = NewObject<ULiveLinkFrameInterpolationProcessor>(SubjectSettings, FrameInterpolationProcessorClass);

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkClient.cpp:645

Scope (from outer to inner):

file
function     void FLiveLinkClient::PushSubjectStaticData_Internal

Source code excerpt:

			{
				// If no settings were found for a specific role, check if the default interpolator is compatible with the role
				UClass* FallbackInterpolationProcessorClass = LiveLinkSettings->FrameInterpolationProcessor.Get();
				if (FallbackInterpolationProcessorClass != nullptr)
				{
					UClass* InterpolationRole = FallbackInterpolationProcessorClass->GetDefaultObject<ULiveLinkFrameInterpolationProcessor>()->GetRole();
					if (SubjectStaticData.Role->IsChildOf(InterpolationRole))
					{
						SubjectSettings->InterpolationProcessor = NewObject<ULiveLinkFrameInterpolationProcessor>(SubjectSettings, FallbackInterpolationProcessorClass);

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkSubject.cpp:671

Scope (from outer to inner):

file
function     bool FLiveLinkSubject::GetFrameAtWorldTime

Source code excerpt:

	if (bResult)
	{
		if (FrameInterpolationProcessor.IsValid())
		{
			bResult = GetFrameAtWorldTime_Interpolated(InSeconds, OutFrame);
		}
		else
		{
			bResult = GetFrameAtWorldTime_Closest(InSeconds, OutFrame);

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkSubject.cpp:762

Scope (from outer to inner):

file
function     bool FLiveLinkSubject::GetFrameAtWorldTime_Interpolated

Source code excerpt:


	FLiveLinkInterpolationInfo InterpolationInfo;
	FrameInterpolationProcessor->Interpolate(InSeconds, StaticData, FrameData, OutFrame, InterpolationInfo);

	UE_LOG(LogLiveLink, Verbose, TEXT("Subject '%s' interpolating between frames %d and %d")
		, *SubjectKey.SubjectName.ToString()
		, InterpolationInfo.FrameIndexA
		, InterpolationInfo.FrameIndexB);

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkSubject.cpp:779

Scope (from outer to inner):

file
function     bool FLiveLinkSubject::GetFrameAtSceneTime

Source code excerpt:

	if (bResult)
	{
		if (FrameInterpolationProcessor.IsValid())
		{
			bResult = GetFrameAtSceneTime_Interpolated(InTimeInEngineFrameRate, OutFrame);
		}
		else
		{
			bResult = GetFrameAtSceneTime_Closest(InTimeInEngineFrameRate, OutFrame);

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkSubject.cpp:870

Scope (from outer to inner):

file
function     bool FLiveLinkSubject::GetFrameAtSceneTime_Interpolated

Source code excerpt:


	FLiveLinkInterpolationInfo InterpolationInfo;
	FrameInterpolationProcessor->Interpolate(InTimeInEngineFrameRate, StaticData, FrameData, OutFrame, InterpolationInfo);

	if (IsBufferStatsEnabled())
	{
		VerifyInterpolationInfo(InterpolationInfo);
	}

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Private/LiveLinkSubject.cpp:1080

Scope (from outer to inner):

file
function     void FLiveLinkSubject::CacheSettings

Source code excerpt:


		// Create a new or fetch the interpolation for this frame
		FrameInterpolationProcessor.Reset();
		if (SubjectSetting->InterpolationProcessor)
		{
			FrameInterpolationProcessor = SubjectSetting->InterpolationProcessor->FetchWorker();
		}

		// Create a new or fetch the translators for this frame
		FrameTranslators.Reset();
		for (ULiveLinkFrameTranslator* Translator : SubjectSetting->Translators)
		{

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkSettings.h:38

Scope: file

Source code excerpt:

	/** The interpolation to use for the subject. If null, no interpolation will be performed. */
	UPROPERTY(config, EditAnywhere, Category = "LiveLink")
	TSubclassOf<ULiveLinkFrameInterpolationProcessor> FrameInterpolationProcessor;

	/** The pre processors to use for the subject. */
	UPROPERTY(config, EditAnywhere, Category = "LiveLink")
	TArray<TSubclassOf<ULiveLinkFramePreProcessor>> FramePreProcessors;
};

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkSettings.h:81

Scope (from outer to inner):

file
class        class ULiveLinkSettings : public UObject

Source code excerpt:

	/** The interpolation class to use for new Subjects if no specific settings we set for the Subject's role. */
	UPROPERTY(config)
	TSubclassOf<ULiveLinkFrameInterpolationProcessor> FrameInterpolationProcessor;

	/** The default preset that should be applied */
	UPROPERTY(config, EditAnywhere, Category = "LiveLink")
	TSoftObjectPtr<ULiveLinkPreset> DefaultLiveLinkPreset;

#if WITH_EDITORONLY_DATA

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLink/Source/LiveLink/Public/LiveLinkSubject.h:153

Scope (from outer to inner):

file
class        class FLiveLinkSubject : public ILiveLinkSubject, public ITimedDataInputChannel

Source code excerpt:

	TArray<ULiveLinkFramePreProcessor::FWorkerSharedPtr> FramePreProcessors;

	ULiveLinkFrameInterpolationProcessor::FWorkerSharedPtr FrameInterpolationProcessor = nullptr;

	/** List of available translator the subject can use. */
	TArray<ULiveLinkFrameTranslator::FWorkerSharedPtr> FrameTranslators;

private:
	struct FLiveLinkCachedSettings

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLinkHub/Source/LiveLinkHub/Private/LiveLinkHubClient.cpp:318

Scope (from outer to inner):

file
function     void FLiveLinkHubClient::PushSubjectStaticData_AnyThread

Source code excerpt:

			SubjectSettings->Role = Role;

			UClass* FrameInterpolationProcessorClass = DefaultSetting.FrameInterpolationProcessor.Get();
			if (FrameInterpolationProcessorClass != nullptr)
			{
				UClass* InterpolationRole = FrameInterpolationProcessorClass->GetDefaultObject<ULiveLinkFrameInterpolationProcessor>()->GetRole();
				if (Role->IsChildOf(InterpolationRole))
				{
					SubjectSettings->InterpolationProcessor = NewObject<ULiveLinkFrameInterpolationProcessor>(SubjectSettings, FrameInterpolationProcessorClass);

#Loc: <Workspace>/Engine/Plugins/Animation/LiveLinkHub/Source/LiveLinkHub/Private/LiveLinkHubClient.cpp:334

Scope (from outer to inner):

file
function     void FLiveLinkHubClient::PushSubjectStaticData_AnyThread

Source code excerpt:

			{
				// If no settings were found for a specific role, check if the default interpolator is compatible with the role
				UClass* FallbackInterpolationProcessorClass = LiveLinkSettings->FrameInterpolationProcessor.Get();
				if (FallbackInterpolationProcessorClass != nullptr)
				{
					UClass* InterpolationRole = FallbackInterpolationProcessorClass->GetDefaultObject<ULiveLinkFrameInterpolationProcessor>()->GetRole();
					if (Role->IsChildOf(InterpolationRole))
					{
						SubjectSettings->InterpolationProcessor = NewObject<ULiveLinkFrameInterpolationProcessor>(SubjectSettings, FallbackInterpolationProcessorClass);