bUseT0AsRefPose

bUseT0AsRefPose

#Overview

name: bUseT0AsRefPose

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

#Summary

#Usage in the C++ source code

The purpose of bUseT0AsRefPose is to control whether frame 0 (T0) of an imported animation should be used as the reference pose for skeletal meshes.

This setting variable is primarily used in the skeletal mesh and animation import system of Unreal Engine. It affects how the reference pose of a skeletal mesh is determined during the import process.

The value of this variable is typically set through import options in the Unreal Editor’s UI or programmatically during the import process. It’s often part of the FBXImportOptions struct or UFbxSkeletalMeshImportData class.

This variable interacts closely with other import settings, particularly those related to skeletal mesh and animation import. For example, it works in conjunction with bUpdateSkeletonReferencePose to determine how the reference pose is handled.

Developers should be aware that:

  1. Using T0 as the reference pose can affect how animations are applied to the skeletal mesh.
  2. This setting can impact the visual appearance of the skeletal mesh in its default pose.
  3. It may affect how the skeletal mesh interacts with animations and physics simulations.

Best practices when using this variable include:

  1. Ensure that the T0 frame of your animation contains a suitable reference pose if you enable this option.
  2. Consider the impact on existing animations if changing this setting during a re-import.
  3. Test the imported skeletal mesh with various animations to ensure the reference pose works as expected.
  4. Coordinate with animators and other team members to establish a consistent approach to reference poses in your project.

#Setting Variables

#References In INI files

Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:671, section: [/Script/UnrealEd.FbxSkeletalMeshImportData]

#References in C++ code

#Callsites

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

#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:193

Scope (from outer to inner):

file
namespace    UE::Interchange::Private
function     void FillInterchangeGenericAssetsPipelineFromFbxSkeletalMeshImportData

Source code excerpt:

		GenericAssetPipeline->MeshPipeline->bImportVertexAttributes = SkeletalMeshImportData->bImportVertexAttributes;
		GenericAssetPipeline->MeshPipeline->bUpdateSkeletonReferencePose = SkeletalMeshImportData->bUpdateSkeletonReferencePose;
		GenericAssetPipeline->CommonSkeletalMeshesAndAnimationsProperties->bUseT0AsRefPose = SkeletalMeshImportData->bUseT0AsRefPose;
		if (SkeletalMeshImportData->ImportContentType == EFBXImportContentType::FBXICT_All)
		{
			GenericAssetPipeline->MeshPipeline->SkeletalMeshImportContentType = EInterchangeSkeletalMeshContentType::All;
		}
		else if (SkeletalMeshImportData->ImportContentType == EFBXImportContentType::FBXICT_Geometry)
		{

#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:382

Scope (from outer to inner):

file
namespace    UE::Interchange::Private
function     UAssetImportData* ConvertToLegacyFbx

Source code excerpt:

				DestinationSkeletalMeshImportData->bPreserveSmoothingGroups = true;
				DestinationSkeletalMeshImportData->bUpdateSkeletonReferencePose = GenericAssetPipeline->MeshPipeline->bUpdateSkeletonReferencePose;
				DestinationSkeletalMeshImportData->bUseT0AsRefPose = GenericAssetPipeline->CommonSkeletalMeshesAndAnimationsProperties->bUseT0AsRefPose;
				if (GenericAssetPipeline->MeshPipeline->SkeletalMeshImportContentType == EInterchangeSkeletalMeshContentType::All)
				{
					DestinationSkeletalMeshImportData->ImportContentType = EFBXImportContentType::FBXICT_All;
				}
				else if (GenericAssetPipeline->MeshPipeline->SkeletalMeshImportContentType == EInterchangeSkeletalMeshContentType::Geometry)
				{

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Private/InterchangeGenericCommonSkeletalMeshesAndAnimationsProperties.cpp:51

Scope (from outer to inner):

file
function     UInterchangeSkeletonFactoryNode* UInterchangeGenericCommonSkeletalMeshesAndAnimationsProperties::CreateSkeletonFactoryNode

Source code excerpt:

		SkeletonFactoryNode->InitializeSkeletonNode(SkeletonUid, DisplayLabel, USkeleton::StaticClass()->GetName());
		SkeletonFactoryNode->SetCustomRootJointUid(RootJointNode->GetUniqueID());
		SkeletonFactoryNode->SetCustomUseTimeZeroForBindPose(bUseT0AsRefPose);
		BaseNodeContainer->AddNode(SkeletonFactoryNode);
	}

	//If we have a specified skeleton
	if (Skeleton.IsValid())
	{

#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Public/InterchangeGenericAssetsPipelineSharedSettings.h:157

Scope (from outer to inner):

file
class        class UInterchangeGenericCommonSkeletalMeshesAndAnimationsProperties : public UInterchangePipelineBase

Source code excerpt:

	/** If enabled, frame 0 is used as the reference pose for skeletal meshes. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Common Skeletal Meshes and Animations")
	bool bUseT0AsRefPose = false;

	/** If enabled, all static meshes that have morph targets will be imported as skeletal meshes instead. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Static Meshes")
	bool bConvertStaticsWithMorphTargetsToSkeletals = false;
#if WITH_EDITOR
	virtual bool IsPropertyChangeNeedRefresh(const FPropertyChangedEvent& PropertyChangedEvent) override

#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/FbxAutomationTests.cpp:429

Scope (from outer to inner):

file
function     BEGIN_FUNCTION_BUILD_OPTIMIZATION bool F

Source code excerpt:

					ImportData->bKeepSectionsSeparate = TestPlan->ImportUI->SkeletalMeshImportData->bKeepSectionsSeparate;
					ImportData->bUpdateSkeletonReferencePose = TestPlan->ImportUI->SkeletalMeshImportData->bUpdateSkeletonReferencePose;
					ImportData->bUseT0AsRefPose = TestPlan->ImportUI->SkeletalMeshImportData->bUseT0AsRefPose;
					//Copy UFbxMeshImportData
					ImportData->bTransformVertexToAbsolute = TestPlan->ImportUI->SkeletalMeshImportData->bTransformVertexToAbsolute;
					ImportData->bBakePivotInVertex = TestPlan->ImportUI->SkeletalMeshImportData->bBakePivotInVertex;
					ImportData->bImportMeshLODs = TestPlan->ImportUI->SkeletalMeshImportData->bImportMeshLODs;
					ImportData->NormalImportMethod = TestPlan->ImportUI->SkeletalMeshImportData->NormalImportMethod;
					ImportData->NormalGenerationMethod = TestPlan->ImportUI->SkeletalMeshImportData->NormalGenerationMethod;

#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/FbxAutomationTests.cpp:527

Scope (from outer to inner):

file
function     BEGIN_FUNCTION_BUILD_OPTIMIZATION bool F

Source code excerpt:

					ImportData->bKeepSectionsSeparate = TestPlan->ImportUI->SkeletalMeshImportData->bKeepSectionsSeparate;
					ImportData->bUpdateSkeletonReferencePose = TestPlan->ImportUI->SkeletalMeshImportData->bUpdateSkeletonReferencePose;
					ImportData->bUseT0AsRefPose = TestPlan->ImportUI->SkeletalMeshImportData->bUseT0AsRefPose;
					//Copy UFbxMeshImportData
					ImportData->bTransformVertexToAbsolute = TestPlan->ImportUI->SkeletalMeshImportData->bTransformVertexToAbsolute;
					ImportData->bBakePivotInVertex = TestPlan->ImportUI->SkeletalMeshImportData->bBakePivotInVertex;
					ImportData->bImportMeshLODs = TestPlan->ImportUI->SkeletalMeshImportData->bImportMeshLODs;
					ImportData->NormalImportMethod = TestPlan->ImportUI->SkeletalMeshImportData->NormalImportMethod;
					ImportData->NormalGenerationMethod = TestPlan->ImportUI->SkeletalMeshImportData->NormalGenerationMethod;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSceneImportOptionsSkeletalMesh.h:28

Scope (from outer to inner):

file
class        class UFbxSceneImportOptionsSkeletalMesh : public UObject

Source code excerpt:

	/** TODO support T0AsRefPose Enable this option to use frame 0 as reference pose */
	UPROPERTY()
	uint32 bUseT0AsRefPose : 1;

	/** If checked, triangles with non-matching smoothing groups will be physically split. */
	UPROPERTY(EditAnywhere, config, Category = SkeletalMesh)
	uint32 bPreserveSmoothingGroups : 1;

	/** If checked, sections with matching materials are kept separate and will not get combined. */

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSkeletalMeshImportData.h:70

Scope (from outer to inner):

file
class        class UFbxSkeletalMeshImportData : public UFbxMeshImportData

Source code excerpt:

	/** Enable this option to use frame 0 as reference pose */
	UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category= Mesh, meta=(ImportType="SkeletalMesh|RigAndGeo", DisplayName="Use T0 As Ref Pose"))
	uint32 bUseT0AsRefPose:1;

	/** If checked, triangles with non-matching smoothing groups will be physically split. */
	UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category=Mesh, meta=(ImportType="SkeletalMesh|GeoOnly"))
	uint32 bPreserveSmoothingGroups:1;

	/** If checked, sections with matching materials are kept separate and will not get combined. */

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:475

Scope (from outer to inner):

file
namespace    UnFbx
function     void ApplyImportUIToImportOptions

Source code excerpt:

		InOutImportOptions.bUpdateSkeletonReferencePose = ImportUI->SkeletalMeshImportData->bUpdateSkeletonReferencePose;
		InOutImportOptions.bImportRigidMesh				= ImportUI->OriginalImportType == FBXIT_StaticMesh && ImportUI->MeshTypeToImport == FBXIT_SkeletalMesh;
		InOutImportOptions.bUseT0AsRefPose				= ImportUI->SkeletalMeshImportData->bUseT0AsRefPose;
		InOutImportOptions.bPreserveSmoothingGroups		= ImportUI->SkeletalMeshImportData->bPreserveSmoothingGroups;
		InOutImportOptions.bKeepSectionsSeparate		= ImportUI->SkeletalMeshImportData->bKeepSectionsSeparate;
		InOutImportOptions.OverlappingThresholds.ThresholdPosition = ImportUI->SkeletalMeshImportData->ThresholdPosition;
		InOutImportOptions.OverlappingThresholds.ThresholdTangentNormal = ImportUI->SkeletalMeshImportData->ThresholdTangentNormal;
		InOutImportOptions.OverlappingThresholds.ThresholdUV = ImportUI->SkeletalMeshImportData->ThresholdUV;
		InOutImportOptions.OverlappingThresholds.MorphThresholdPosition = ImportUI->SkeletalMeshImportData->MorphThresholdPosition;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:1763

Scope (from outer to inner):

file
lambda-function

Source code excerpt:

							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt KeepSectionsSeparate"), CaptureImportOptions->bKeepSectionsSeparate));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt UpdateSkeletonReferencePose"), CaptureImportOptions->bUpdateSkeletonReferencePose));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt UseT0AsRefPose"), CaptureImportOptions->bUseT0AsRefPose));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.ThresholdPosition"), CaptureImportOptions->OverlappingThresholds.ThresholdPosition));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.ThresholdTangentNormal"), CaptureImportOptions->OverlappingThresholds.ThresholdTangentNormal));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.ThresholdUV"), CaptureImportOptions->OverlappingThresholds.ThresholdUV));
							Attribs.Add(FAnalyticsEventAttribute(TEXT("SkeletalMeshOpt OverlappingThresholds.MorphThresholdPosition"), CaptureImportOptions->OverlappingThresholds.MorphThresholdPosition));
						};

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportData.cpp:116

Scope (from outer to inner):

file
function     UnFbx::FBXImportOptions *JSONToFbxOption

Source code excerpt:

	OptionObj->TryGetBoolField(TEXT("bUpdateSkeletonReferencePose"), Option->bUpdateSkeletonReferencePose);
	//TODO support T0AsRefPose
	//OptionObj->TryGetBoolField(TEXT("bUseT0AsRefPose"), Option->bUseT0AsRefPose);
	Option->bUseT0AsRefPose = false;
	OptionObj->TryGetBoolField(TEXT("bPreserveSmoothingGroups"), Option->bPreserveSmoothingGroups);
	OptionObj->TryGetBoolField(TEXT("bKeepSectionsSeparate"), Option->bKeepSectionsSeparate);
	OptionObj->TryGetBoolField(TEXT("bImportMeshesInBoneHierarchy"), Option->bImportMeshesInBoneHierarchy);
	OptionObj->TryGetBoolField(TEXT("bImportMorphTargets"), Option->bImportMorph);
	OptionObj->TryGetBoolField(TEXT("bImportVertexAttributes"), Option->bImportVertexAttributes);
	

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportData.cpp:207

Scope (from outer to inner):

file
function     FString FbxOptionToJSON

Source code excerpt:

	JsonString += FString::Printf(TEXT("\"bUpdateSkeletonReferencePose\" : \"%d\", \"bUseT0AsRefPose\" : \"%d\", \"bPreserveSmoothingGroups\" : \"%d\", \"bKeepSectionsSeparate\" : \"%d\", \"bImportMeshesInBoneHierarchy\" : \"%d\", \"bImportMorphTargets\" : \"%d\", , \"bImportVertexAttributes\" : \"%d\", \"OverlappingThresholds\" : {\"ThresholdPosition\" : \"%f\", \"ThresholdTangentNormal\" : \"%f\", \"ThresholdUV\" : \"%f\", \"MorphThresholdPosition\" : \"%f\"},"),
		Option->bUpdateSkeletonReferencePose ? 1 : 0,
		Option->bUseT0AsRefPose ? 1 : 0,
		Option->bPreserveSmoothingGroups ? 1 : 0,
		Option->bKeepSectionsSeparate ? 1 : 0,
		Option->bImportMeshesInBoneHierarchy ? 1 : 0,
		Option->bImportMorph ? 1 : 0,
		Option->bImportVertexAttributes ? 1 : 0,
		Option->OverlappingThresholds.ThresholdPosition,

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportFactory.cpp:126

Scope (from outer to inner):

file
function     bool GetFbxSceneImportOptions

Source code excerpt:

	GlobalImportSettings->bKeepSectionsSeparate = false;
	//TODO support T0AsRefPose
	GlobalImportSettings->bUseT0AsRefPose = false;

	GlobalImportSettings->ImportTranslation = FVector(0);
	GlobalImportSettings->ImportRotation = FRotator(0);
	GlobalImportSettings->ImportUniformScale = 1.0f;
	GlobalImportSettings->DistanceFieldResolutionScale = 1.0f;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:14

Scope (from outer to inner):

file
function     UFbxSceneImportOptionsSkeletalMesh::UFbxSceneImportOptionsSkeletalMesh

Source code excerpt:

	, bUpdateSkeletonReferencePose(false)
	, bCreatePhysicsAsset(false)
	, bUseT0AsRefPose(false)
	, bPreserveSmoothingGroups(false)
	, bKeepSectionsSeparate(false)
	, bImportMeshesInBoneHierarchy(true)
	, bImportMorphTargets(false)
	, bImportVertexAttributes(false)
	, ThresholdPosition(THRESH_POINTS_ARE_SAME)

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:51

Scope (from outer to inner):

file
function     void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData

Source code excerpt:

	SkeletalMeshImportData->bKeepSectionsSeparate = bKeepSectionsSeparate;
	SkeletalMeshImportData->bUpdateSkeletonReferencePose = bUpdateSkeletonReferencePose;
	SkeletalMeshImportData->bUseT0AsRefPose = bUseT0AsRefPose;

	SkeletalMeshImportData->bImportMeshLODs = SceneImportOptions->bImportSkeletalMeshLODs;
	SkeletalMeshImportData->ImportTranslation = SceneImportOptions->ImportTranslation;
	SkeletalMeshImportData->ImportRotation = SceneImportOptions->ImportRotation;
	SkeletalMeshImportData->ImportUniformScale = SceneImportOptions->ImportUniformScale;
	SkeletalMeshImportData->bTransformVertexToAbsolute = SceneImportOptions->bTransformVertexToAbsolute;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSkeletalMeshImport.cpp:1353

Scope (from outer to inner):

file
function     bool UnFbx::FFbxImporter::FillSkeletalMeshImportData

Source code excerpt:


	bool bDiffPose = false;
	bool bUseT0AsRefPose = ImportOptions->bUseT0AsRefPose;

	// Note: importing morph data causes additional passes through this function, so disable the warning dialogs
	// from popping up again on each additional pass.
	if (!ImportBones(NodeArray, *SkelMeshImportDataPtr, TemplateImportData, SortedLinkArray, bDiffPose, (FbxShapeArray != nullptr), bUseT0AsRefPose, Node, bIsReimport))
	{
		if (!(bIsReimport && ImportOptions->bImportAsSkeletalGeometry)) //Do not import bone if we import only the geometry and we are reimporting
		{
			return false;
		}
	}
	
	bMapMorphTargetToTimeZero = bUseT0AsRefPose & bDiffPose;

 	FbxNode* SceneRootNode = Scene->GetRootNode();
 	if(SceneRootNode && TemplateImportData)
 	{
 		ApplyTransformSettingsToFbxNode(SceneRootNode, TemplateImportData);
 	}

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/ReimportFbxSceneFactory.cpp:238

Scope (from outer to inner):

file
function     bool GetFbxSceneReImportOptions

Source code excerpt:

	GlobalImportSettings->bImportMaterials = true;
	//TODO support T0AsRefPose
	GlobalImportSettings->bUseT0AsRefPose = false;
	//Make sure skeletal mesh sections with the same material are combined (and not kept separate)
	GlobalImportSettings->bKeepSectionsSeparate = false;
	//Make sure we do not mess with AutoComputeLodDistances when re-importing
	GlobalImportSettings->bAutoComputeLodDistances = true;
	GlobalImportSettings->LodNumber = 0;
	GlobalImportSettings->MinimumLodNumber = 0;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1504

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopySkeletalMeshOptionsToFbxOptions

Source code excerpt:

	ImportSettings->bKeepSectionsSeparate = SkeletalMeshOptions->bKeepSectionsSeparate;
	ImportSettings->bUpdateSkeletonReferencePose = SkeletalMeshOptions->bUpdateSkeletonReferencePose;
	ImportSettings->bUseT0AsRefPose = SkeletalMeshOptions->bUseT0AsRefPose;

	ImportSettings->bImportAnimations = SkeletalMeshOptions->bImportAnimations;
	ImportSettings->AnimationLengthImportType = SkeletalMeshOptions->AnimationLength;
	ImportSettings->bDeleteExistingMorphTargetCurves = SkeletalMeshOptions->bDeleteExistingMorphTargetCurves;
	ImportSettings->bImportCustomAttribute = SkeletalMeshOptions->bImportCustomAttribute;
	ImportSettings->bDeleteExistingCustomAttributeCurves = SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1533

Scope (from outer to inner):

file
function     void SFbxSceneOptionWindow::CopyFbxOptionsToSkeletalMeshOptions

Source code excerpt:

	SkeletalMeshOptions->bKeepSectionsSeparate = ImportSettings->bKeepSectionsSeparate;
	SkeletalMeshOptions->bUpdateSkeletonReferencePose = ImportSettings->bUpdateSkeletonReferencePose;
	SkeletalMeshOptions->bUseT0AsRefPose = ImportSettings->bUseT0AsRefPose;

	SkeletalMeshOptions->bImportAnimations = ImportSettings->bImportAnimations;
	SkeletalMeshOptions->AnimationLength = ImportSettings->AnimationLengthImportType;
	SkeletalMeshOptions->bDeleteExistingMorphTargetCurves = ImportSettings->bDeleteExistingMorphTargetCurves;
	SkeletalMeshOptions->bImportCustomAttribute = ImportSettings->bImportCustomAttribute;
	SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves = ImportSettings->bDeleteExistingCustomAttributeCurves;

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Public/FbxImporter.h:182

Scope (from outer to inner):

file
namespace    UnFbx

Source code excerpt:

	bool bSnapToClosestFrameBoundary;
	bool bImportRigidMesh;
	bool bUseT0AsRefPose;
	bool bPreserveSmoothingGroups;
	bool bKeepSectionsSeparate;
	FOverlappingThresholds OverlappingThresholds;
	bool bImportMeshesInBoneHierarchy;
	bool bCreatePhysicsAsset;
	UPhysicsAsset *PhysicsAsset;