ThresholdTangentNormal
ThresholdTangentNormal
#Overview
name: ThresholdTangentNormal
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 35
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of ThresholdTangentNormal is to serve as a threshold value used to determine whether two normals, tangents, or bi-normals are considered equal during mesh building and processing operations in Unreal Engine 5.
This setting variable is primarily used in the mesh building and import subsystems of Unreal Engine, particularly for skeletal meshes and FBX imports. It’s referenced in various parts of the engine, including:
- The Customizable Object system
- Interchange Editor and Runtime modules
- FBX import and scene import functionalities
- Skeletal mesh building and processing
- Mesh utilities and skin weights utilities
The value of this variable is typically set during the import process or when configuring mesh build settings. It can be set through various means:
- In FBX import options
- In skeletal mesh build settings
- In customizable object instances
- Through the Interchange pipeline
ThresholdTangentNormal often interacts with other threshold variables like ThresholdPosition, ThresholdUV, and MorphThresholdPosition. These variables work together to determine how vertices, normals, tangents, UVs, and other mesh attributes are processed and optimized.
Developers should be aware that this threshold affects the precision of normal and tangent comparisons during mesh processing. A lower threshold will result in more precise comparisons but may lead to more unique vertices, while a higher threshold may reduce vertex count at the cost of some precision.
Best practices when using this variable include:
- Adjusting it based on the specific needs of your project and the characteristics of your meshes.
- Considering the balance between mesh precision and performance implications.
- Testing different threshold values to find the optimal balance for your specific use case.
- Keeping it consistent across related assets to ensure uniform processing.
- Documenting any custom values used in your project to maintain consistency across the development team.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEditorPerProjectUserSettings.ini:677, section: [/Script/UnrealEd.FbxSkeletalMeshImportData]
- INI Section:
/Script/UnrealEd.FbxSkeletalMeshImportData
- Raw value:
0.00002
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Plugins/Experimental/Mutable/Source/CustomizableObject/Private/MuCO/CustomizableObjectInstance.cpp:3265
Scope (from outer to inner):
file
function void UCustomizableInstancePrivate::InitSkeletalMeshData
Source code excerpt:
LODInfo.BuildSettings.bUseBackwardsCompatibleF16TruncUVs = false;
LODInfo.BuildSettings.ThresholdPosition = TNumericLimits<float>::Min();
LODInfo.BuildSettings.ThresholdTangentNormal = TNumericLimits<float>::Min();
LODInfo.BuildSettings.ThresholdUV = TNumericLimits<float>::Min();
LODInfo.BuildSettings.MorphThresholdPosition = TNumericLimits<float>::Min();
LODInfo.BuildSettings.BoneInfluenceLimit = 0;
#endif
LODInfo.LODMaterialMap.SetNumZeroed(1);
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:222
Scope (from outer to inner):
file
namespace UE::Interchange::Private
function void FillInterchangeGenericAssetsPipelineFromFbxSkeletalMeshImportData
Source code excerpt:
GenericAssetPipeline->MeshPipeline->MorphThresholdPosition = SkeletalMeshImportData->MorphThresholdPosition;
GenericAssetPipeline->MeshPipeline->ThresholdPosition = SkeletalMeshImportData->ThresholdPosition;
GenericAssetPipeline->MeshPipeline->ThresholdTangentNormal = SkeletalMeshImportData->ThresholdTangentNormal;
GenericAssetPipeline->MeshPipeline->ThresholdUV = SkeletalMeshImportData->ThresholdUV;
if (SkeletalMeshImportData->VertexColorImportOption == EVertexColorImportOption::Ignore)
{
GenericAssetPipeline->CommonMeshesProperties->VertexColorImportOption = EInterchangeVertexColorImportOption::IVCIO_Ignore;
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Editor/Source/InterchangeEditor/Private/InterchangeFbxAssetImportDataConverter.cpp:411
Scope (from outer to inner):
file
namespace UE::Interchange::Private
function UAssetImportData* ConvertToLegacyFbx
Source code excerpt:
DestinationSkeletalMeshImportData->MorphThresholdPosition = GenericAssetPipeline->MeshPipeline->MorphThresholdPosition;
DestinationSkeletalMeshImportData->ThresholdPosition = GenericAssetPipeline->MeshPipeline->ThresholdPosition;
DestinationSkeletalMeshImportData->ThresholdTangentNormal = GenericAssetPipeline->MeshPipeline->ThresholdTangentNormal;
DestinationSkeletalMeshImportData->ThresholdUV = GenericAssetPipeline->MeshPipeline->ThresholdUV;
if (GenericAssetPipeline->CommonMeshesProperties->VertexColorImportOption == EInterchangeVertexColorImportOption::IVCIO_Ignore)
{
DestinationSkeletalMeshImportData->VertexColorImportOption = EVertexColorImportOption::Ignore;
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/FactoryNodes/Private/InterchangeSkeletalMeshFactoryNode.cpp:170
Scope (from outer to inner):
file
function bool UInterchangeSkeletalMeshFactoryNode::FillCustomThresholdTangentNormalFromAsset
Source code excerpt:
bool UInterchangeSkeletalMeshFactoryNode::FillCustomThresholdTangentNormalFromAsset(UObject* Asset)
{
IMPLEMENT_SKELETALMESH_BUILD_ASSET_TO_VALUE(ThresholdTangentNormal, ThresholdTangentNormal);
}
bool UInterchangeSkeletalMeshFactoryNode::GetCustomThresholdUV(float& AttributeValue) const
{
IMPLEMENT_NODE_ATTRIBUTE_GETTER(ThresholdUV, float)
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Private/InterchangeGenericAssetsPipeline.cpp:262
Scope (from outer to inner):
file
function void UInterchangeGenericAssetsPipeline::FilterPropertiesFromTranslatedData
Source code excerpt:
LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, bImportMorphTargets));
LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, ThresholdPosition));
LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, ThresholdTangentNormal));
LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, ThresholdUV));
LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, MorphThresholdPosition));
}
else if (MeshPipeline->SkeletalMeshImportContentType == EInterchangeSkeletalMeshContentType::Geometry)
{
LocalHideProperty(MeshPipeline, GET_MEMBER_NAME_CHECKED(UInterchangeGenericMeshPipeline, bUpdateSkeletonReferencePose));
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Private/InterchangeGenericSkeletalMeshPipeline.cpp:494
Scope (from outer to inner):
file
function UInterchangeSkeletalMeshFactoryNode* UInterchangeGenericMeshPipeline::CreateSkeletalMeshFactoryNode
Source code excerpt:
SkeletalMeshFactoryNode->SetCustomUseHighPrecisionSkinWeights(bUseHighPrecisionSkinWeights);
SkeletalMeshFactoryNode->SetCustomThresholdPosition(ThresholdPosition);
SkeletalMeshFactoryNode->SetCustomThresholdTangentNormal(ThresholdTangentNormal);
SkeletalMeshFactoryNode->SetCustomThresholdUV(ThresholdUV);
SkeletalMeshFactoryNode->SetCustomMorphThresholdPosition(MorphThresholdPosition);
SkeletalMeshFactoryNode->SetCustomBoneInfluenceLimit(BoneInfluenceLimit);
return SkeletalMeshFactoryNode;
}
#Loc: <Workspace>/Engine/Plugins/Interchange/Runtime/Source/Pipelines/Public/InterchangeGenericMeshPipeline.h:186
Scope (from outer to inner):
file
class class UInterchangeGenericMeshPipeline : public UInterchangePipelineBase
Source code excerpt:
/** Threshold value that is used to decide whether two normals, tangents, or bi-normals are equal. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skeletal Meshes", meta = (SubCategory = "Build"))
float ThresholdTangentNormal = 0.00002f;
/** Threshold value that is used to decide whether two UVs are equal. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Skeletal Meshes", meta = (SubCategory = "Build"))
float ThresholdUV = 0.0009765625f;
/** Threshold to compare vertex position equality when computing morph target deltas. */
#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/FbxAutomationTests.cpp:423
Scope (from outer to inner):
file
function BEGIN_FUNCTION_BUILD_OPTIMIZATION bool F
Source code excerpt:
ImportData->bImportVertexAttributes = TestPlan->ImportUI->SkeletalMeshImportData->bImportVertexAttributes;
ImportData->ThresholdPosition = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdPosition;
ImportData->ThresholdTangentNormal = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdTangentNormal;
ImportData->MorphThresholdPosition = TestPlan->ImportUI->SkeletalMeshImportData->MorphThresholdPosition;
ImportData->ThresholdUV = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdUV;
ImportData->bPreserveSmoothingGroups = TestPlan->ImportUI->SkeletalMeshImportData->bPreserveSmoothingGroups;
ImportData->bKeepSectionsSeparate = TestPlan->ImportUI->SkeletalMeshImportData->bKeepSectionsSeparate;
ImportData->bUpdateSkeletonReferencePose = TestPlan->ImportUI->SkeletalMeshImportData->bUpdateSkeletonReferencePose;
ImportData->bUseT0AsRefPose = TestPlan->ImportUI->SkeletalMeshImportData->bUseT0AsRefPose;
#Loc: <Workspace>/Engine/Plugins/Tests/EditorTests/Source/EditorTests/Private/UnrealEd/FbxAutomationTests.cpp:521
Scope (from outer to inner):
file
function BEGIN_FUNCTION_BUILD_OPTIMIZATION bool F
Source code excerpt:
ImportData->bImportVertexAttributes = TestPlan->ImportUI->SkeletalMeshImportData->bImportVertexAttributes;
ImportData->ThresholdPosition = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdPosition;
ImportData->ThresholdTangentNormal = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdTangentNormal;
ImportData->ThresholdUV = TestPlan->ImportUI->SkeletalMeshImportData->ThresholdUV;
ImportData->MorphThresholdPosition = TestPlan->ImportUI->SkeletalMeshImportData->MorphThresholdPosition;
ImportData->bPreserveSmoothingGroups = TestPlan->ImportUI->SkeletalMeshImportData->bPreserveSmoothingGroups;
ImportData->bKeepSectionsSeparate = TestPlan->ImportUI->SkeletalMeshImportData->bKeepSectionsSeparate;
ImportData->bUpdateSkeletonReferencePose = TestPlan->ImportUI->SkeletalMeshImportData->bUpdateSkeletonReferencePose;
ImportData->bUseT0AsRefPose = TestPlan->ImportUI->SkeletalMeshImportData->bUseT0AsRefPose;
#Loc: <Workspace>/Engine/Source/Developer/MeshUtilities/Public/MeshUtilities.h:173
Scope (from outer to inner):
file
class class IMeshUtilities : public IModuleInterface
function void FillOptions
Source code excerpt:
{
OverlappingThresholds.ThresholdPosition = SkeletalMeshBuildSettings.ThresholdPosition;
OverlappingThresholds.ThresholdTangentNormal = SkeletalMeshBuildSettings.ThresholdTangentNormal;
OverlappingThresholds.ThresholdUV = SkeletalMeshBuildSettings.ThresholdUV;
OverlappingThresholds.MorphThresholdPosition = SkeletalMeshBuildSettings.MorphThresholdPosition;
BoneInfluenceLimit = SkeletalMeshBuildSettings.BoneInfluenceLimit;
bComputeNormals = SkeletalMeshBuildSettings.bRecomputeNormals;
bComputeTangents = SkeletalMeshBuildSettings.bRecomputeTangents;
bUseMikkTSpace = SkeletalMeshBuildSettings.bUseMikkTSpace;
#Loc: <Workspace>/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp:1913
Scope (from outer to inner):
file
function float FSkeletalMeshBuildSettingsLayout::GetThresholdTangentNormal
Source code excerpt:
float FSkeletalMeshBuildSettingsLayout::GetThresholdTangentNormal() const
{
return BuildSettings.ThresholdTangentNormal;
}
void FSkeletalMeshBuildSettingsLayout::SetThresholdTangentNormal(float Value)
{
if (BuildSettings.ThresholdTangentNormal != Value)
{
FText TransactionText = FText::Format(LOCTEXT("PersonaSetThresholdTangentNormalLOD", "LOD{0} build settings: threshold for tangent and normal changed"), LODIndex);
FScopedTransaction Transaction(TransactionText);
ModifyMeshLODSettingsDelegate.ExecuteIfBound(LODIndex);
BuildSettings.ThresholdTangentNormal = Value;
}
}
float FSkeletalMeshBuildSettingsLayout::GetThresholdUV() const
{
return BuildSettings.ThresholdUV;
#Loc: <Workspace>/Engine/Source/Editor/Persona/Private/PersonaMeshDetails.cpp:4054
Scope (from outer to inner):
file
function FReply FPersonaMeshDetails::ApplyLODChanges
Source code excerpt:
SKImportData->bComputeWeightedNormals = LODInfo->BuildSettings.bComputeWeightedNormals;
SKImportData->ThresholdPosition = LODInfo->BuildSettings.ThresholdPosition;
SKImportData->ThresholdTangentNormal = LODInfo->BuildSettings.ThresholdTangentNormal;
SKImportData->ThresholdUV = LODInfo->BuildSettings.ThresholdUV;
SKImportData->MorphThresholdPosition = LODInfo->BuildSettings.MorphThresholdPosition;
}
}
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSceneImportOptionsSkeletalMesh.h:56
Scope (from outer to inner):
file
class class UFbxSceneImportOptionsSkeletalMesh : public UObject
Source code excerpt:
/** Threshold to compare normal, tangent or bi-normal equality. */
UPROPERTY(EditAnywhere, config, Category = "SkeletalMesh|Thresholds", meta = (NoSpinbox = "true", ClampMin = "0.0", ClampMax = "1.0"))
float ThresholdTangentNormal;
/** Threshold to compare UV equality. */
UPROPERTY(EditAnywhere, config, Category = "SkeletalMesh|Thresholds", meta = (NoSpinbox = "true", ClampMin = "0.0", ClampMax = "1.0"))
float ThresholdUV;
/** Threshold to compare vertex position equality when computing morph target deltas. */
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/Factories/FbxSkeletalMeshImportData.h:98
Scope (from outer to inner):
file
class class UFbxSkeletalMeshImportData : public UFbxMeshImportData
Source code excerpt:
/** Threshold to compare normal, tangent or bi-normal equality. */
UPROPERTY(EditAnywhere, config, Category="Mesh", meta = (ImportType = "SkeletalMesh|GeoOnly", SubCategory = "Thresholds", NoSpinbox = "true", ClampMin = "0.0", ClampMax = "1.0"))
float ThresholdTangentNormal;
/** Threshold to compare UV equality. */
UPROPERTY(EditAnywhere, config, Category="Mesh", meta = (ImportType = "SkeletalMesh|GeoOnly", SubCategory = "Thresholds", NoSpinbox = "true", ClampMin = "0.0", ClampMax = "1.0"))
float ThresholdUV;
/** Threshold to compare vertex position equality when computing morph target deltas. */
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Factories/EditorFactories.cpp:6708
Scope (from outer to inner):
file
function EReimportResult::Type UReimportFbxSkeletalMeshFactory::Reimport
Source code excerpt:
LODInfo->BuildSettings.bUseMikkTSpace = SKImportData->NormalGenerationMethod == EFBXNormalGenerationMethod::MikkTSpace;
LODInfo->BuildSettings.ThresholdPosition = SKImportData->ThresholdPosition;
LODInfo->BuildSettings.ThresholdTangentNormal = SKImportData->ThresholdTangentNormal;
LODInfo->BuildSettings.ThresholdUV = SKImportData->ThresholdUV;
LODInfo->BuildSettings.MorphThresholdPosition = SKImportData->MorphThresholdPosition;
}
}
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:479
Scope (from outer to inner):
file
namespace UnFbx
function void ApplyImportUIToImportOptions
Source code excerpt:
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;
InOutImportOptions.bImportMeshesInBoneHierarchy = ImportUI->SkeletalMeshImportData->bImportMeshesInBoneHierarchy;
}
//Static mesh unshared options
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:1667
Scope (from outer to inner):
file
namespace UnFbx
function bool FFbxImporter::ImportFromFile
Source code excerpt:
* @EventParam UseT0AsRefPose boolean Returns whether the importer should use the the animation 0 time has the reference pose
* @EventParam ThresholdPosition float Returns the threshold delta to weld vertices
* @EventParam ThresholdTangentNormal float Returns the threshold delta to weld tangents and normals
* @EventParam ThresholdUV float Returns the threshold delta to weld UVs
* @EventParam MorphThresholdPosition float Returns the morph target threshold delta to compute deltas
* @EventParam AutoComputeLodDistances boolean Returns whether the importer should set the auto compute LOD distance
* @EventParam LodNumber integer Returns the LOD number we should have after the import
* @EventParam BuildReversedIndexBuffer boolean Returns whether the importer should fill the reverse index buffer when building the static mesh
* @EventParam GenerateLightmapUVs boolean Returns whether the importer should generate light map UVs
* @EventParam ImportStaticMeshLODs boolean Returns whether the importer should import the LODs
* @EventParam RemoveDegenerates boolean Returns whether the importer should remove the degenerated triangles when building the static mesh
* @EventParam MinimumLodNumber integer Returns the minimum LOD use by the rendering
* @EventParam StaticMeshLODGroup string Returns the LOD Group settings we use to build this imported static mesh
* @EventParam VertexColorImportOption string Returns how the importer should import the vertex color
* @EventParam VertexOverrideColor string Returns the color use if we need to override the vertex color
* @EventParam AnimationLengthImportType string Returns how we choose the animation time span
* @EventParam DeleteExistingMorphTargetCurves boolean Returns whether the importer should delete the existing morph target curves
* @EventParam AnimationRange string Returns the range of animation the importer should sample if the time span is custom
* @EventParam DoNotImportCurveWithZero boolean Returns whether the importer should import curves containing only zero value
* @EventParam ImportBoneTracks boolean Returns whether the importer should import the bone tracks
* @EventParam ImportCustomAttribute boolean Returns whether the importer should import the custom attribute curves
* @EventParam PreserveLocalTransform boolean Returns whether the importer should preserve the local transform when importing the animation
* @EventParam RemoveRedundantKeys boolean Returns whether the importer should remove all redundant key in an animation
* @EventParam Resample boolean Returns whether the importer should re-sample the animation
* @EventParam SetMaterialDriveParameterOnCustomAttribute boolean Returns whether the importer should hook all custom attribute curve to unreal material attribute
* @EventParam SetMaterialDriveParameterOnCustomAttribute boolean Returns whether the importer should hook some custom attribute (having the suffix) curve to unreal material attribute
* @EventParam ResampleRate float Returns the rate the exporter is suppose to re-sample any imported animations
*
* @Owner Alexis.Matte
*/
FbxDocumentInfo* DocInfo = Scene->GetSceneInfo();
if (DocInfo)
{
if( FEngineAnalytics::IsAvailable() )
{
const static UEnum* FBXImportTypeEnum = StaticEnum<EFBXImportType>();
const static UEnum* FBXAnimationLengthImportTypeEnum = StaticEnum<EFBXAnimationLengthImportType>();
const static UEnum* MaterialSearchLocationEnum = StaticEnum<EMaterialSearchLocation>();
const static UEnum* FBXNormalGenerationMethodEnum = StaticEnum<EFBXNormalGenerationMethod::Type>();
const static UEnum* FBXNormalImportMethodEnum = StaticEnum<EFBXNormalImportMethod>();
const static UEnum* VertexColorImportOptionEnum = StaticEnum<EVertexColorImportOption::Type>();
TArray<FAnalyticsEventAttribute> Attribs;
FString LastSavedVendor(UTF8_TO_TCHAR(DocInfo->LastSaved_ApplicationVendor.Get().Buffer()));
FString LastSavedAppName(UTF8_TO_TCHAR(DocInfo->LastSaved_ApplicationName.Get().Buffer()));
FString LastSavedAppVersion(UTF8_TO_TCHAR(DocInfo->LastSaved_ApplicationVersion.Get().Buffer()));
Attribs.Add(FAnalyticsEventAttribute(TEXT("LastSaved Application Vendor"), LastSavedVendor));
Attribs.Add(FAnalyticsEventAttribute(TEXT("LastSaved Application Name"), LastSavedAppName));
Attribs.Add(FAnalyticsEventAttribute(TEXT("LastSaved Application Version"), LastSavedAppVersion));
Attribs.Add(FAnalyticsEventAttribute(TEXT("FBX Version"), FbxFileVersion));
//////////////////////////////////////////////////////////////////////////
//FBX import options
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportType"), FBXImportTypeEnum->GetNameStringByValue(ImportOptions->ImportType)));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ConvertScene"), ImportOptions->bConvertScene));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ConvertSceneUnit"), ImportOptions->bConvertSceneUnit));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ForceFrontXAxis"), ImportOptions->bForceFrontXAxis));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportMaterials"), ImportOptions->bImportMaterials));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportTextures"), ImportOptions->bImportTextures));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt InvertNormalMap"), ImportOptions->bInvertNormalMap));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt RemoveNameSpace"), ImportOptions->bRemoveNameSpace));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt UsedAsFullName"), ImportOptions->bUsedAsFullName));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportTranslation"), ImportOptions->ImportTranslation.ToString()));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportRotation"), ImportOptions->ImportRotation.ToString()));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ImportUniformScale"), ImportOptions->ImportUniformScale));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt MaterialBasePath"), ImportOptions->MaterialBasePath));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt MaterialSearchLocation"), MaterialSearchLocationEnum->GetNameStringByValue((uint64)(ImportOptions->MaterialSearchLocation))));
Attribs.Add(FAnalyticsEventAttribute(TEXT("GenOpt ReorderMaterialToFbxOrder"), ImportOptions->bReorderMaterialToFbxOrder));
//We cant capture a this member, so just assign the pointer here
FBXImportOptions* CaptureImportOptions = ImportOptions;
auto AddMeshAnalytic = [&Attribs, &CaptureImportOptions]()
{
Attribs.Add(FAnalyticsEventAttribute(TEXT("MeshOpt AutoGenerateCollision"), CaptureImportOptions->bAutoGenerateCollision));
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxMainImport.cpp:1765
Scope (from outer to inner):
file
lambda-function
Source code excerpt:
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));
};
auto AddSMAnalytic = [&Attribs, &CaptureImportOptions]()
{
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportData.cpp:133
Scope (from outer to inner):
file
function UnFbx::FBXImportOptions *JSONToFbxOption
Source code excerpt:
if ((*DataObj)->TryGetNumberField(TEXT("ThresholdTangentNormal"), NTB))
{
Option->OverlappingThresholds.ThresholdTangentNormal = (float)NTB;
}
if ((*DataObj)->TryGetNumberField(TEXT("ThresholdUV"), UV))
{
Option->OverlappingThresholds.ThresholdUV = (float)UV;
}
if ((*DataObj)->TryGetNumberField(TEXT("MorphThresholdPosition"), MorphPos))
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportData.cpp:214
Scope (from outer to inner):
file
function FString FbxOptionToJSON
Source code excerpt:
Option->bImportVertexAttributes ? 1 : 0,
Option->OverlappingThresholds.ThresholdPosition,
Option->OverlappingThresholds.ThresholdTangentNormal,
Option->OverlappingThresholds.ThresholdUV,
Option->OverlappingThresholds.MorphThresholdPosition
);
JsonString += FString::Printf(TEXT("\"MaterialBasePath\" : \"%s\"}"), *(Option->MaterialBasePath.ToString()));
return JsonString;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:21
Scope (from outer to inner):
file
function UFbxSceneImportOptionsSkeletalMesh::UFbxSceneImportOptionsSkeletalMesh
Source code excerpt:
, bImportVertexAttributes(false)
, ThresholdPosition(THRESH_POINTS_ARE_SAME)
, ThresholdTangentNormal(THRESH_NORMALS_ARE_SAME)
, ThresholdUV(THRESH_UVS_ARE_SAME)
, MorphThresholdPosition(THRESH_POINTS_ARE_NEAR)
, bImportAnimations(true)
, AnimationLength(EFBXAnimationLengthImportType::FBXALIT_AnimatedKey)
, FrameImportRange(0, 0)
, bUseDefaultSampleRate(false)
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSceneImportOptionsSkeletalMesh.cpp:45
Scope (from outer to inner):
file
function void UFbxSceneImportOptionsSkeletalMesh::FillSkeletalMeshInmportData
Source code excerpt:
SkeletalMeshImportData->ThresholdPosition = ThresholdPosition;
SkeletalMeshImportData->ThresholdTangentNormal = ThresholdTangentNormal;
SkeletalMeshImportData->ThresholdUV = ThresholdUV;
SkeletalMeshImportData->MorphThresholdPosition = MorphThresholdPosition;
SkeletalMeshImportData->bPreserveSmoothingGroups = bPreserveSmoothingGroups;
SkeletalMeshImportData->bKeepSectionsSeparate = bKeepSectionsSeparate;
SkeletalMeshImportData->bUpdateSkeletonReferencePose = bUpdateSkeletonReferencePose;
SkeletalMeshImportData->bUseT0AsRefPose = bUseT0AsRefPose;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSkeletalMeshImport.cpp:1825
Scope (from outer to inner):
file
function USkeletalMesh* UnFbx::FFbxImporter::ImportSkeletalMesh
Source code excerpt:
BuildOptions.bRemoveDegenerates = ImportOptions->bRemoveDegenerates;
BuildOptions.ThresholdPosition = ImportOptions->OverlappingThresholds.ThresholdPosition;
BuildOptions.ThresholdTangentNormal = ImportOptions->OverlappingThresholds.ThresholdTangentNormal;
BuildOptions.ThresholdUV = ImportOptions->OverlappingThresholds.ThresholdUV;
BuildOptions.MorphThresholdPosition = ImportOptions->OverlappingThresholds.MorphThresholdPosition;
TSharedPtr<FExistingSkelMeshData> ExistSkelMeshDataPtr;
if (ExistingSkelMesh)
{
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/FbxSkeletalMeshImport.cpp:2454
Scope (from outer to inner):
file
function USkeletalMesh* UnFbx::FFbxImporter::ReimportSkeletalMesh
Source code excerpt:
LODInfo->BuildSettings.bUseMikkTSpace = SKImportData->NormalGenerationMethod == EFBXNormalGenerationMethod::MikkTSpace;
LODInfo->BuildSettings.ThresholdPosition = SKImportData->ThresholdPosition;
LODInfo->BuildSettings.ThresholdTangentNormal = SKImportData->ThresholdTangentNormal;
LODInfo->BuildSettings.ThresholdUV = SKImportData->ThresholdUV;
LODInfo->BuildSettings.MorphThresholdPosition = SKImportData->MorphThresholdPosition;
}
}
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1498
Scope (from outer to inner):
file
function void SFbxSceneOptionWindow::CopySkeletalMeshOptionsToFbxOptions
Source code excerpt:
ImportSettings->bImportVertexAttributes = SkeletalMeshOptions->bImportVertexAttributes;
ImportSettings->OverlappingThresholds.ThresholdPosition = SkeletalMeshOptions->ThresholdPosition;
ImportSettings->OverlappingThresholds.ThresholdTangentNormal = SkeletalMeshOptions->ThresholdTangentNormal;
ImportSettings->OverlappingThresholds.ThresholdUV = SkeletalMeshOptions->ThresholdUV;
ImportSettings->OverlappingThresholds.MorphThresholdPosition = SkeletalMeshOptions->MorphThresholdPosition;
ImportSettings->bPreserveSmoothingGroups = SkeletalMeshOptions->bPreserveSmoothingGroups;
ImportSettings->bKeepSectionsSeparate = SkeletalMeshOptions->bKeepSectionsSeparate;
ImportSettings->bUpdateSkeletonReferencePose = SkeletalMeshOptions->bUpdateSkeletonReferencePose;
ImportSettings->bUseT0AsRefPose = SkeletalMeshOptions->bUseT0AsRefPose;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Fbx/SFbxSceneOptionWindow.cpp:1527
Scope (from outer to inner):
file
function void SFbxSceneOptionWindow::CopyFbxOptionsToSkeletalMeshOptions
Source code excerpt:
SkeletalMeshOptions->bImportVertexAttributes = ImportSettings->bImportVertexAttributes;
SkeletalMeshOptions->ThresholdPosition = ImportSettings->OverlappingThresholds.ThresholdPosition;
SkeletalMeshOptions->ThresholdTangentNormal = ImportSettings->OverlappingThresholds.ThresholdTangentNormal;
SkeletalMeshOptions->ThresholdUV = ImportSettings->OverlappingThresholds.ThresholdUV;
SkeletalMeshOptions->MorphThresholdPosition = ImportSettings->OverlappingThresholds.MorphThresholdPosition;
SkeletalMeshOptions->bPreserveSmoothingGroups = ImportSettings->bPreserveSmoothingGroups;
SkeletalMeshOptions->bKeepSectionsSeparate = ImportSettings->bKeepSectionsSeparate;
SkeletalMeshOptions->bUpdateSkeletonReferencePose = ImportSettings->bUpdateSkeletonReferencePose;
SkeletalMeshOptions->bUseT0AsRefPose = ImportSettings->bUseT0AsRefPose;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/FbxMeshUtils.cpp:656
Scope (from outer to inner):
file
namespace FbxMeshUtils
function bool ImportSkeletalMeshLOD
Source code excerpt:
LODInfo->BuildSettings.bRemoveDegenerates = ImportOptions->bRemoveDegenerates;
LODInfo->BuildSettings.ThresholdPosition = ImportOptions->OverlappingThresholds.ThresholdPosition;
LODInfo->BuildSettings.ThresholdTangentNormal = ImportOptions->OverlappingThresholds.ThresholdTangentNormal;
LODInfo->BuildSettings.ThresholdUV = ImportOptions->OverlappingThresholds.ThresholdUV;
LODInfo->BuildSettings.MorphThresholdPosition = ImportOptions->OverlappingThresholds.MorphThresholdPosition;
}
}
// Populate the mesh array
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkinWeightsUtilities.cpp:285
Scope (from outer to inner):
file
function bool FSkinWeightsUtilities::ImportAlternateSkinWeight
Source code excerpt:
//Use the Lod info build settings
BuildOptions.OverlappingThresholds.ThresholdPosition = LODInfo->BuildSettings.ThresholdPosition;
BuildOptions.OverlappingThresholds.ThresholdTangentNormal = LODInfo->BuildSettings.ThresholdTangentNormal;
BuildOptions.OverlappingThresholds.ThresholdUV = LODInfo->BuildSettings.ThresholdUV;
BuildOptions.OverlappingThresholds.MorphThresholdPosition = LODInfo->BuildSettings.MorphThresholdPosition;
BuildOptions.bComputeNormals = LODInfo->BuildSettings.bRecomputeNormals;
BuildOptions.bComputeTangents = LODInfo->BuildSettings.bRecomputeTangents;
BuildOptions.bUseMikkTSpace = LODInfo->BuildSettings.bUseMikkTSpace;
BuildOptions.bComputeWeightedNormals = LODInfo->BuildSettings.bComputeWeightedNormals;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/SkinWeightsUtilities.cpp:399
Scope (from outer to inner):
file
function bool FSkinWeightsUtilities::RemoveSkinnedWeightProfileData
Source code excerpt:
{
BuildOptions.OverlappingThresholds.ThresholdPosition = LODInfo->BuildSettings.ThresholdPosition;
BuildOptions.OverlappingThresholds.ThresholdTangentNormal = LODInfo->BuildSettings.ThresholdTangentNormal;
BuildOptions.OverlappingThresholds.ThresholdUV = LODInfo->BuildSettings.ThresholdUV;
BuildOptions.OverlappingThresholds.MorphThresholdPosition = LODInfo->BuildSettings.MorphThresholdPosition;
BuildOptions.bComputeNormals = LODInfo->BuildSettings.bRecomputeNormals;
BuildOptions.bComputeTangents = LODInfo->BuildSettings.bRecomputeTangents;
BuildOptions.bUseMikkTSpace = LODInfo->BuildSettings.bUseMikkTSpace;
BuildOptions.bComputeWeightedNormals = LODInfo->BuildSettings.bComputeWeightedNormals;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h:2788
Scope: file
Source code excerpt:
/** Threshold use to decide if two normal, tangents or bi-normals are equal. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = BuildSettings)
float ThresholdTangentNormal;
/** Threshold use to decide if two UVs are equal. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = BuildSettings)
float ThresholdUV;
/** Threshold to compare vertex position equality when computing morph target deltas. */
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h:2820
Scope (from outer to inner):
file
function FSkeletalMeshBuildSettings
Source code excerpt:
, bUseBackwardsCompatibleF16TruncUVs(false)
, ThresholdPosition(0.00002f)
, ThresholdTangentNormal(0.00002f)
, ThresholdUV(0.0009765625f)
, MorphThresholdPosition(0.015f)
, BoneInfluenceLimit(0)
{}
/** Equality operator. */
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Classes/Engine/EngineTypes.h:2839
Scope (from outer to inner):
file
function bool operator==
Source code excerpt:
&& bUseBackwardsCompatibleF16TruncUVs == Other.bUseBackwardsCompatibleF16TruncUVs
&& ThresholdPosition == Other.ThresholdPosition
&& ThresholdTangentNormal == Other.ThresholdTangentNormal
&& ThresholdUV == Other.ThresholdUV
&& MorphThresholdPosition == Other.MorphThresholdPosition
&& BoneInfluenceLimit == Other.BoneInfluenceLimit;
}
/** Inequality. */
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Private/SkinnedAssetCommon.cpp:73
Scope (from outer to inner):
file
function static void SerializeBuildSettingsForDDC
Source code excerpt:
FArchive_Serialize_BitfieldBool(Ar, BuildSettings.bUseHighPrecisionSkinWeights);
Ar << BuildSettings.ThresholdPosition;
Ar << BuildSettings.ThresholdTangentNormal;
Ar << BuildSettings.ThresholdUV;
Ar << BuildSettings.MorphThresholdPosition;
Ar << BuildSettings.BoneInfluenceLimit;
}
FGuid FSkeletalMeshLODInfo::ComputeDeriveDataCacheKey(const FSkeletalMeshLODGroupSettings* SkeletalMeshLODGroupSettings)
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/MeshBuild.h:15
Scope (from outer to inner):
file
function FOverlappingThresholds
Source code excerpt:
FOverlappingThresholds()
: ThresholdPosition(UE_THRESH_POINTS_ARE_SAME)
, ThresholdTangentNormal(UE_THRESH_NORMALS_ARE_SAME)
, ThresholdUV(UE_THRESH_UVS_ARE_SAME)
, MorphThresholdPosition(UE_THRESH_POINTS_ARE_NEAR)
{}
/** Threshold use to decide if two vertex position are equal. */
float ThresholdPosition;
/** Threshold use to decide if two normal, tangents or bi-normals are equal. */
float ThresholdTangentNormal;
/** Threshold use to decide if two UVs are equal. */
float ThresholdUV;
/** Threshold use to decide if two vertex position are equal. */
float MorphThresholdPosition;
#Loc: <Workspace>/Engine/Source/Runtime/Engine/Public/MeshBuild.h:66
Scope (from outer to inner):
file
function inline bool NormalsEqual
Source code excerpt:
inline bool NormalsEqual(const FVector3f& V1,const FVector3f& V2, const FOverlappingThresholds& OverlappingThreshold)
{
const float Epsilon = OverlappingThreshold.ThresholdTangentNormal;
return FMath::Abs(V1.X - V2.X) <= Epsilon && FMath::Abs(V1.Y - V2.Y) <= Epsilon && FMath::Abs(V1.Z - V2.Z) <= Epsilon;
}
inline bool UVsEqual(const FVector2f& V1, const FVector2f& V2, const FOverlappingThresholds& OverlappingThreshold)
{
const float Epsilon = OverlappingThreshold.ThresholdUV;