bPreserveLocalTransform
bPreserveLocalTransform
#Overview
name: bPreserveLocalTransform
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 13
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of bPreserveLocalTransform is to control whether local transforms of bones should be preserved during animation import in Unreal Engine 5. This setting is primarily used in the animation and skeletal mesh import systems.
Based on the provided code references, this variable is utilized in the following Unreal Engine subsystems and modules:
- Interchange Editor Plugin
- UnrealEd module
- FBX import system
The value of this variable is typically set during the import process, either through user interface options or programmatically. It can be found in various import data classes such as UFbxAnimSequenceImportData and UFbxSceneImportOptionsSkeletalMesh.
This variable interacts with other import settings, particularly those related to animation and skeletal mesh import. It is often used in conjunction with other variables like bImportCustomAttribute, bRemoveRedundantKeys, and bSnapToClosestFrameBoundary.
Developers should be aware of the following when using this variable:
- Setting bPreserveLocalTransform to true will maintain the local transforms of bones as they are in the source file.
- Setting it to false (default) will recalculate the local transforms based on the global transforms and parent-child relationships.
Best practices when using this variable include:
- Consider the source of your animations and whether preserving local transforms is necessary for your specific use case.
- Be consistent in your usage across related assets to ensure proper animation behavior.
- Test the results with both true and false settings to determine which provides the best outcome for your specific animations and skeletal meshes.
- Document your choice and reasoning for future reference, especially if it deviates from the default setting.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:694, section: [/Script/UnrealEd.FbxAnimSequenceImportData]
- INI Section:
/Script/UnrealEd.FbxAnimSequenceImportData
- Raw value:
False
- Is Array:
False
#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:494
Scope (from outer to inner):
file
namespace UE::Interchange::Private
function UAssetImportData* ConvertToLegacyFbx
Source code excerpt:
DestinationAnimSequenceImportData->bImportCustomAttribute = GenericAssetPipeline->AnimationPipeline->bImportCustomAttribute;
DestinationAnimSequenceImportData->bImportMeshesInBoneHierarchy = GenericAssetPipeline->CommonSkeletalMeshesAndAnimationsProperties->bImportMeshesInBoneHierarchy;
DestinationAnimSequenceImportData->bPreserveLocalTransform = false;
DestinationAnimSequenceImportData->bRemoveRedundantKeys = GenericAssetPipeline->AnimationPipeline->bRemoveCurveRedundantKeys;
DestinationAnimSequenceImportData->bSetMaterialDriveParameterOnCustomAttribute = GenericAssetPipeline->AnimationPipeline->bSetMaterialDriveParameterOnCustomAttribute;
DestinationAnimSequenceImportData->bSnapToClosestFrameBoundary = GenericAssetPipeline->AnimationPipeline->bSnapToClosestFrameBoundary;
DestinationAnimSequenceImportData->bUseDefaultSampleRate = GenericAssetPipeline->AnimationPipeline->bUse30HzToBakeBoneAnimation;
DestinationAnimSequenceImportData->CustomSampleRate = GenericAssetPipeline->AnimationPipeline->CustomBoneAnimationSampleRate;
DestinationAnimSequenceImportData->FrameImportRange = GenericAssetPipeline->AnimationPipeline->FrameImportRange;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxAnimSequenceImportData.h:115
Scope (from outer to inner):
file
class class UFbxAnimSequenceImportData : public UFbxAssetImportData
Source code excerpt:
/** If enabled, this will import a curve within the animation */
UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = ImportSettings)
bool bPreserveLocalTransform;
/** Gets or creates fbx import data for the specified anim sequence */
static UNREALED_API UFbxAnimSequenceImportData* GetImportDataForAnimSequence(UAnimSequence* AnimSequence, UFbxAnimSequenceImportData* TemplateForCreation);
UNREALED_API virtual bool CanEditChange(const FProperty* InProperty) const override;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSceneImportOptionsSkeletalMesh.h:106
Scope (from outer to inner):
file
class class UFbxSceneImportOptionsSkeletalMesh : public UObject
Source code excerpt:
/** Type of asset to import from the FBX file */
UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = Animation)
bool bPreserveLocalTransform;
/** Type of asset to import from the FBX file */
UPROPERTY(EditAnywhere, AdvancedDisplay, config, Category = Animation)
bool bDeleteExistingMorphTargetCurves;
void FillSkeletalMeshInmportData(class UFbxSkeletalMeshImportData* SkeletalMeshImportData, class UFbxAnimSequenceImportData* AnimSequenceImportData, class UFbxSceneImportOptions* SceneImportOptions);
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxAnimSequenceImportData.cpp:91
Scope (from outer to inner):
file
function void UFbxAnimSequenceImportData::CopyAnimationValues
Source code excerpt:
bImportCustomAttribute = Other->bImportCustomAttribute;
bImportMeshesInBoneHierarchy = Other->bImportMeshesInBoneHierarchy;
bPreserveLocalTransform = Other->bPreserveLocalTransform;
bRemoveRedundantKeys = Other->bRemoveRedundantKeys;
bSetMaterialDriveParameterOnCustomAttribute = Other->bSetMaterialDriveParameterOnCustomAttribute;
bAddCurveMetadataToSkeleton = Other->bAddCurveMetadataToSkeleton;
bUseDefaultSampleRate = Other->bUseDefaultSampleRate;
CustomSampleRate = Other->CustomSampleRate;
FrameImportRange = Other->FrameImportRange;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:506
Scope (from outer to inner):
file
namespace UnFbx
function void ApplyImportUIToImportOptions
Source code excerpt:
InOutImportOptions.ResampleRate = ImportUI->AnimSequenceImportData->CustomSampleRate;
InOutImportOptions.bSnapToClosestFrameBoundary = ImportUI->AnimSequenceImportData->bSnapToClosestFrameBoundary;
InOutImportOptions.bPreserveLocalTransform = ImportUI->AnimSequenceImportData->bPreserveLocalTransform;
InOutImportOptions.bDeleteExistingMorphTargetCurves = ImportUI->AnimSequenceImportData->bDeleteExistingMorphTargetCurves;
InOutImportOptions.bRemoveRedundantKeys = ImportUI->AnimSequenceImportData->bRemoveRedundantKeys;
InOutImportOptions.bDoNotImportCurveWithZero = ImportUI->AnimSequenceImportData->bDoNotImportCurveWithZero;
InOutImportOptions.bImportCustomAttribute = ImportUI->AnimSequenceImportData->bImportCustomAttribute;
InOutImportOptions.bDeleteExistingCustomAttributeCurves = ImportUI->AnimSequenceImportData->bDeleteExistingCustomAttributeCurves;
InOutImportOptions.bDeleteExistingNonCurveCustomAttributes = ImportUI->AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:1794
Scope (from outer to inner):
file
lambda-function
Source code excerpt:
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DeleteExistingCustomAttributeCurves"), CaptureImportOptions->bDeleteExistingCustomAttributeCurves));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt DeleteExistingNonCurveCustomAttributes"), CaptureImportOptions->bDeleteExistingNonCurveCustomAttributes));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt PreserveLocalTransform"), CaptureImportOptions->bPreserveLocalTransform));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt RemoveRedundantKeys"), CaptureImportOptions->bRemoveRedundantKeys));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt Resample"), CaptureImportOptions->bResample));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt SetMaterialDriveParameterOnCustomAttribute"), CaptureImportOptions->bSetMaterialDriveParameterOnCustomAttribute));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt MaterialCurveSuffixes"), CaptureImportOptions->MaterialCurveSuffixes));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt ResampleRate"), CaptureImportOptions->ResampleRate));
Attribs.Add(FAnalyticsEventAttribute(TEXT("AnimOpt SnapToClosestFrameBoundary"), CaptureImportOptions->bSnapToClosestFrameBoundary));
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:32
Scope (from outer to inner):
file
function UFbxSceneImportOptionsSkeletalMesh::UFbxSceneImportOptionsSkeletalMesh
Source code excerpt:
, bDeleteExistingCustomAttributeCurves(false)
, bDeleteExistingNonCurveCustomAttributes(false)
, bPreserveLocalTransform(false)
, bDeleteExistingMorphTargetCurves(false)
{
}
void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData(UFbxSkeletalMeshImportData* SkeletalMeshImportData, UFbxAnimSequenceImportData* AnimSequenceImportData, UFbxSceneImportOptions* SceneImportOptions)
{
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:68
Scope (from outer to inner):
file
function void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData
Source code excerpt:
AnimSequenceImportData->bDeleteExistingCustomAttributeCurves = bDeleteExistingCustomAttributeCurves;
AnimSequenceImportData->bDeleteExistingNonCurveCustomAttributes = bDeleteExistingNonCurveCustomAttributes;
AnimSequenceImportData->bPreserveLocalTransform = bPreserveLocalTransform;
AnimSequenceImportData->bUseDefaultSampleRate = bUseDefaultSampleRate;
AnimSequenceImportData->CustomSampleRate = CustomSampleRate;
AnimSequenceImportData->FrameImportRange = FrameImportRange;
AnimSequenceImportData->bImportAsScene = true;
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1512
Scope (from outer to inner):
file
function void SFbxSceneOptionWindow::CopySkeletalMeshOptionsToFbxOptions
Source code excerpt:
ImportSettings->bDeleteExistingCustomAttributeCurves = SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves;
ImportSettings->bDeleteExistingNonCurveCustomAttributes = SkeletalMeshOptions->bDeleteExistingNonCurveCustomAttributes;
ImportSettings->bPreserveLocalTransform = SkeletalMeshOptions->bPreserveLocalTransform;
ImportSettings->bResample = !SkeletalMeshOptions->bUseDefaultSampleRate;
ImportSettings->ResampleRate = SkeletalMeshOptions->CustomSampleRate;
ImportSettings->bSnapToClosestFrameBoundary = SkeletalMeshOptions->bSnapToClosestFrameBoundary;
ImportSettings->AnimationRange.X = SkeletalMeshOptions->FrameImportRange.Min;
ImportSettings->AnimationRange.Y = SkeletalMeshOptions->FrameImportRange.Max;
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1541
Scope (from outer to inner):
file
function void SFbxSceneOptionWindow::CopyFbxOptionsToSkeletalMeshOptions
Source code excerpt:
SkeletalMeshOptions->bDeleteExistingCustomAttributeCurves = ImportSettings->bDeleteExistingCustomAttributeCurves;
SkeletalMeshOptions->bDeleteExistingNonCurveCustomAttributes = ImportSettings->bDeleteExistingNonCurveCustomAttributes;
SkeletalMeshOptions->bPreserveLocalTransform = ImportSettings->bPreserveLocalTransform;
SkeletalMeshOptions->bUseDefaultSampleRate = !ImportSettings->bResample;
SkeletalMeshOptions->CustomSampleRate = ImportSettings->ResampleRate;
SkeletalMeshOptions->FrameImportRange.Min = ImportSettings->AnimationRange.X;
SkeletalMeshOptions->FrameImportRange.Max = ImportSettings->AnimationRange.Y;
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkeletalMeshEdit.cpp:2142
Scope (from outer to inner):
file
function void UnFbx::FFbxImporter::ImportBoneTracks
Source code excerpt:
OutTotalNumKeys = 0;
UnFbx::FFbxImporter* FbxImporter = UnFbx::FFbxImporter::GetInstance();
const bool bPreserveLocalTransform = FbxImporter->GetImportOptions()->bPreserveLocalTransform;
UAnimSequence* DestSeq = AnimImportSettings.DestSeq;
const FbxTimeSpan& AnimTimeSpan = AnimImportSettings.AnimTimeSpan;
const bool bShouldTransact = bReimport;
// Build additional transform matrix
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkeletalMeshEdit.cpp:2240
Scope (from outer to inner):
file
function void UnFbx::FFbxImporter::ImportBoneTracks
Source code excerpt:
FTransform LocalTransform;
if (!bPreserveLocalTransform && LinkParent)
{
// I can't rely on LocalMatrix. I need to recalculate quaternion/scale based on global transform if Parent exists
FbxAMatrix ParentGlobalMatrix = Link->GetParent()->EvaluateGlobalTransform(CurTime);
if (BoneTreeIndex != 0)
{
ParentGlobalMatrix = ParentGlobalMatrix * FFbxDataConverter::GetJointPostConversionMatrix();
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Public/FbxImporter.h:195
Scope (from outer to inner):
file
namespace UnFbx
Source code excerpt:
FIntPoint AnimationRange;
FString AnimationName;
bool bPreserveLocalTransform;
bool bDeleteExistingMorphTargetCurves;
bool bImportCustomAttribute;
bool bDeleteExistingCustomAttributeCurves;
bool bDeleteExistingNonCurveCustomAttributes;
bool bImportBoneTracks;
bool bSetMaterialDriveParameterOnCustomAttribute;