当前位置: 首页>>代码示例>>C++>>正文


C++ unfbx::FFbxImporter类代码示例

本文整理汇总了C++中unfbx::FFbxImporter的典型用法代码示例。如果您正苦于以下问题:C++ FFbxImporter类的具体用法?C++ FFbxImporter怎么用?C++ FFbxImporter使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了FFbxImporter类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: SkeletonsAreCompatible

/** Check that root bone is the same, and that any bones that are common have the correct parent. */
bool SkeletonsAreCompatible( const FReferenceSkeleton& NewSkel, const FReferenceSkeleton& ExistSkel )
{
	if(NewSkel.GetBoneName(0) != ExistSkel.GetBoneName(0))
	{
		UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();	
		FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("MeshHasDifferentRoot", "Root Bone is '{0}' instead of '{1}'.\nDiscarding existing LODs."),
			FText::FromName(NewSkel.GetBoneName(0)), FText::FromName(ExistSkel.GetBoneName(0)))));
		return false;
	}

	for(int32 i=1; i<NewSkel.GetNum(); i++)
	{
		// See if bone is in both skeletons.
		int32 NewBoneIndex = i;
		FName NewBoneName = NewSkel.GetBoneName(NewBoneIndex);
		int32 BBoneIndex = ExistSkel.FindBoneIndex(NewBoneName);

		// If it is, check parents are the same.
		if(BBoneIndex != INDEX_NONE)
		{
			FName NewParentName = NewSkel.GetBoneName( NewSkel.GetParentIndex(NewBoneIndex) );
			FName ExistParentName = ExistSkel.GetBoneName( ExistSkel.GetParentIndex(BBoneIndex) );

			if(NewParentName != ExistParentName)
			{
				UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();			
				FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("MeshHasDifferentRoot", "Root Bone is '{0}' instead of '{1}'.\nDiscarding existing LODs."),
					FText::FromName(NewBoneName), FText::FromName(NewParentName))));
				return false;
			}
		}
	}

	return true;
}
开发者ID:Tigrouzen,项目名称:UnrealEngine-4,代码行数:36,代码来源:SkeletalMeshImport.cpp

示例2: ImportANode

UObject* UFbxFactory::ImportANode(void* VoidFbxImporter, void* VoidNode, UObject* InParent, FName InName, EObjectFlags Flags, int32& NodeIndex, int32 Total, UObject* InMesh, int LODIndex)
{
	UnFbx::FFbxImporter* FFbxImporter = (UnFbx::FFbxImporter*)VoidFbxImporter;
	FbxNode* Node = (FbxNode*)VoidNode;

	UObject* NewObject = NULL;
	FName OutputName = FFbxImporter->MakeNameForMesh(InName.ToString(), Node);
	
	{
		// skip collision models
		FbxString NodeName(Node->GetName());
		if ( NodeName.Find("UCX") != -1 || NodeName.Find("MCDCX") != -1 ||
			 NodeName.Find("UBX") != -1 || NodeName.Find("USP") != -1 )
		{
			return NULL;
		}

		NewObject = FFbxImporter->ImportStaticMesh( InParent, Node, OutputName, Flags, ImportUI->StaticMeshImportData, Cast<UStaticMesh>(InMesh), LODIndex );
	}

	if (NewObject)
	{
		NodeIndex++;
		FFormatNamedArguments Args;
		Args.Add( TEXT("NodeIndex"), NodeIndex );
		Args.Add( TEXT("ArrayLength"), Total );
		GWarn->StatusUpdate( NodeIndex, Total, FText::Format( NSLOCTEXT("UnrealEd", "Importingf", "Importing ({NodeIndex} of {ArrayLength})"), Args ) );
	}

	return NewObject;
}
开发者ID:RandomDeveloperM,项目名称:UE4_Hairworks,代码行数:31,代码来源:FbxFactory.cpp

示例3: OutputAnimationTransformDebugData

	void OutputAnimationTransformDebugData(TArray<AnimationTransformDebug::FAnimationTransformDebugData> &TransformDebugData, int32 TotalNumKeys, const FReferenceSkeleton& RefSkeleton)
	{
		bool bShouldOutputToMessageLog = true;

		for(int32 Key=0; Key<TotalNumKeys; ++Key)
		{
			// go through all bones and find 
			for(int32 BoneIndex=0; BoneIndex<TransformDebugData.Num(); ++BoneIndex)
			{
				FAnimationTransformDebugData& Data = TransformDebugData[BoneIndex];
				int32 ParentIndex = RefSkeleton.GetParentIndex(Data.BoneIndex);
				int32 ParentTransformDebugDataIndex = 0;

				check(Data.RecalculatedLocalTransform.Num() == TotalNumKeys);
				check(Data.SourceGlobalTransform.Num() == TotalNumKeys);
				check(Data.SourceParentGlobalTransform.Num() == TotalNumKeys);

				for(; ParentTransformDebugDataIndex<BoneIndex; ++ParentTransformDebugDataIndex)
				{
					if(ParentIndex == TransformDebugData[ParentTransformDebugDataIndex].BoneIndex)
					{
						FTransform ParentTransform = TransformDebugData[ParentTransformDebugDataIndex].RecalculatedLocalTransform[Key] * TransformDebugData[ParentTransformDebugDataIndex].RecalculatedParentTransform[Key];
						Data.RecalculatedParentTransform.Add(ParentTransform);
						break;
					}
				}

				// did not find Parent
				if(ParentTransformDebugDataIndex == BoneIndex)
				{
					Data.RecalculatedParentTransform.Add(FTransform::Identity);
				}

				check(Data.RecalculatedParentTransform.Num() == Key+1);

				FTransform GlobalTransform = Data.RecalculatedLocalTransform[Key] * Data.RecalculatedParentTransform[Key];
				// makes more generous on the threshold. 
				if(GlobalTransform.Equals(Data.SourceGlobalTransform[Key], 0.1f) == false)
				{
					// so that we don't spawm with this message
					if(bShouldOutputToMessageLog)
					{
						UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
						// now print information - it doesn't match well, find out what it is
						FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, FText::Format(LOCTEXT("FBXImport_TransformError", "Imported bone transform is different from original. Please check Output Log to see detail of error. "),
							FText::FromName(Data.BoneName), FText::AsNumber(Data.BoneIndex), FText::FromString(Data.SourceGlobalTransform[Key].ToString()), FText::FromString(GlobalTransform.ToString()))), FFbxErrors::Animation_TransformError);

						bShouldOutputToMessageLog = false;
					}
					
					// now print information - it doesn't match well, find out what it is
					UE_LOG(LogFbx, Warning, TEXT("IMPORT TRANSFORM ERROR : Bone (%s:%d) \r\nSource Global Transform (%s), \r\nConverted Global Transform (%s)"),
						*Data.BoneName.ToString(), Data.BoneIndex, *Data.SourceGlobalTransform[Key].ToString(), *GlobalTransform.ToString());
				}
			}
		}
	}
开发者ID:colwalder,项目名称:unrealengine,代码行数:57,代码来源:SkeletalMeshEdit.cpp

示例4: ImportStaticMesh

EReimportResult::Type UReimportFbxSceneFactory::ImportStaticMesh(void* VoidFbxImporter, TSharedPtr<FFbxMeshInfo> MeshInfo, TSharedPtr<FFbxSceneInfo> SceneInfoPtr)
{
	UnFbx::FFbxImporter* FbxImporter = (UnFbx::FFbxImporter*)VoidFbxImporter;
	//FEditorDelegates::OnAssetPreImport.Broadcast(this, UStaticMesh::StaticClass(), GWorld, FName(""), TEXT("fbx"));
	FbxNode *GeometryParentNode = nullptr;
	//Get the first parent geometry node
	for (int idx = 0; idx < FbxImporter->Scene->GetGeometryCount(); ++idx)
	{
		FbxGeometry *Geometry = FbxImporter->Scene->GetGeometry(idx);
		if (Geometry->GetUniqueID() == MeshInfo->UniqueId)
		{
			GeometryParentNode = Geometry->GetNode();
			break;
		}
	}
	if (GeometryParentNode == nullptr)
	{
		FbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(FText::FromString("Reimport Mesh {0} fail, the mesh dont have any parent node inside the fbx."), FText::FromString(MeshInfo->GetImportPath()))), FName(TEXT("Reimport Fbx Scene")));
		return EReimportResult::Failed;
	}

	FString PackageName = MeshInfo->GetImportPath();
	FString StaticMeshName;
	UPackage* Pkg = CreatePackageForNode(PackageName, StaticMeshName);
	if (Pkg == nullptr)
	{
		return EReimportResult::Failed;
	}

	//Copy default options to StaticMeshImportData
	SFbxSceneOptionWindow::CopyFbxOptionsToStaticMeshOptions(GlobalImportSettingsReference, SceneImportOptionsStaticMesh);
	SceneImportOptionsStaticMesh->FillStaticMeshInmportData(StaticMeshImportData, SceneImportOptions);

	UnFbx::FBXImportOptions* OverrideImportSettings = GetOptionsFromName(MeshInfo->OptionName);
	if (OverrideImportSettings != nullptr)
	{
		SFbxSceneOptionWindow::CopyFbxOptionsToFbxOptions(OverrideImportSettings, GlobalImportSettings);
		SFbxSceneOptionWindow::CopyFbxOptionsToStaticMeshOptions(OverrideImportSettings, SceneImportOptionsStaticMesh);
	}
	else
	{
		SFbxSceneOptionWindow::CopyFbxOptionsToFbxOptions(GlobalImportSettingsReference, GlobalImportSettings);
		SFbxSceneOptionWindow::CopyFbxOptionsToStaticMeshOptions(GlobalImportSettingsReference, SceneImportOptionsStaticMesh);
	}
	SceneImportOptionsStaticMesh->FillStaticMeshInmportData(StaticMeshImportData, SceneImportOptions);

	FName StaticMeshFName = FName(*(MeshInfo->Name));
	UStaticMesh *NewObject = FbxImporter->ImportStaticMesh(Pkg, GeometryParentNode, StaticMeshFName, EObjectFlags::RF_Standalone, StaticMeshImportData );
	if (NewObject == nullptr)
	{
		return EReimportResult::Failed;
	}
	AllNewAssets.Add(MeshInfo, NewObject);
	AssetToSyncContentBrowser.Add(NewObject);
	return EReimportResult::Succeeded;
}
开发者ID:RandomDeveloperM,项目名称:UE4_Hairworks,代码行数:56,代码来源:ReimportFbxSceneFactory.cpp

示例5: ProcessImportMeshSkeleton

/**
* Process and fill in the mesh ref skeleton bone hierarchy using the raw binary import data
* 
* @param RefSkeleton - [out] reference skeleton hierarchy to update
* @param SkeletalDepth - [out] depth of the reference skeleton hierarchy
* @param ImportData - raw binary import data to process
* @return true if the operation completed successfully
*/
bool ProcessImportMeshSkeleton(FReferenceSkeleton& RefSkeleton, int32& SkeletalDepth, FSkeletalMeshImportData& ImportData)
{
	TArray <VBone>&	RefBonesBinary = ImportData.RefBonesBinary;

	// Setup skeletal hierarchy + names structure.
	RefSkeleton.Empty();

	// Digest bones to the serializable format.
	for( int32 b=0; b<RefBonesBinary.Num(); b++ )
	{
		const VBone & BinaryBone = RefBonesBinary[ b ];
		const FString BoneName = FSkeletalMeshImportData::FixupBoneName( BinaryBone.Name );
		const FMeshBoneInfo BoneInfo(FName(*BoneName, FNAME_Add, true), BinaryBone.ParentIndex);
		const FTransform BoneTransform(BinaryBone.BonePos.Orientation, BinaryBone.BonePos.Position, FVector(1.f));

		if(RefSkeleton.FindBoneIndex(BoneInfo.Name) != INDEX_NONE)
		{
			UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
			FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("SkeletonHasDuplicateBones", "Skeleton has non-unique bone names.\nBone named '{0}' encountered more than once."), FText::FromName(BoneInfo.Name))));
			return false;
		}

		RefSkeleton.Add(BoneInfo, BoneTransform);
	}

	// Add hierarchy index to each bone and detect max depth.
	SkeletalDepth = 0;

	TArray<int32> SkeletalDepths;
	SkeletalDepths.Empty( RefBonesBinary.Num() );
	SkeletalDepths.AddZeroed( RefBonesBinary.Num() );
	for( int32 b=0; b < RefSkeleton.GetNum(); b++ )
	{
		int32 Parent	= RefSkeleton.GetParentIndex(b);
		int32 Depth	= 1.0f;

		SkeletalDepths[b]	= 1.0f;
		if( Parent != INDEX_NONE )
		{
			Depth += SkeletalDepths[Parent];
		}
		if( SkeletalDepth < Depth )
		{
			SkeletalDepth = Depth;
		}
		SkeletalDepths[b] = Depth;
	}

	return true;
}
开发者ID:Tigrouzen,项目名称:UnrealEngine-4,代码行数:58,代码来源:SkeletalMeshImport.cpp

示例6: CleanUp

void UFbxFactory::CleanUp() 
{
	UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
	bDetectImportTypeOnImport = true;
	bShowOption = true;
	// load options
	if (FFbxImporter)
	{
		struct UnFbx::FBXImportOptions* ImportOptions = FFbxImporter->GetImportOptions();
		if ( ImportOptions )
		{
			ImportOptions->SkeletonForAnimation = NULL;
			ImportOptions->PhysicsAsset = NULL;
		}
	}
}
开发者ID:RandomDeveloperM,项目名称:UE4_Hairworks,代码行数:16,代码来源:FbxFactory.cpp

示例7: Restore

void FSavedCustomSortInfo::Restore(USkeletalMesh* NewSkeletalMesh, int32 LODModelIndex)
{
	FStaticLODModel& LODModel = NewSkeletalMesh->GetImportedResource()->LODModels[LODModelIndex];
	FSkeletalMeshLODInfo& LODInfo = NewSkeletalMesh->LODInfo[LODModelIndex];

	// List of sections in the new model yet to be matched to the sorted sections
	TArray<int32> UnmatchedSections;
	for( int32 SectionIdx=0;SectionIdx<LODModel.Sections.Num();SectionIdx++ )
	{
		UnmatchedSections.Add(SectionIdx);
	}

	for( int32 Idx=0;Idx<SortSectionInfos.Num();Idx++ )
	{
		FSavedCustomSortSectionInfo& SortSectionInfo = SortSectionInfos[Idx];

		if( SortSectionInfo.SavedSortOption == TRISORT_Custom || SortSectionInfo.SavedSortOption == TRISORT_CustomLeftRight )
		{
			// Restore saved custom sort order
			SortSectionInfo.Restore(NewSkeletalMesh, LODModelIndex, UnmatchedSections);
		}
		else
		{
			if( !LODModel.Sections.IsValidIndex(SortSectionInfo.SavedSectionIdx) ||
				!LODInfo.TriangleSortSettings.IsValidIndex(SortSectionInfo.SavedSectionIdx) )
			{
				UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
				FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("FailedRestoreSortingForSectionNumber", "Unable to restore triangle sort setting \"{0}\" for section {1} as the new mesh does not contain that many sections. Please find the matching section and apply manually."),
					FText::FromString(TriangleSortOptionToString((ETriangleSortOption)SortSectionInfo.SavedSortOption)),
					FText::AsNumber(SortSectionInfo.SavedSectionIdx))), 
					FFbxErrors::SkeletalMesh_RestoreSortingForSectionNumber);
				continue;
			}

			// Update the UI version of the data.
			FTriangleSortSettings& TriangleSortSettings = LODInfo.TriangleSortSettings[SortSectionInfo.SavedSectionIdx];
			TriangleSortSettings.TriangleSorting = SortSectionInfo.SavedSortOption;
			TriangleSortSettings.CustomLeftRightAxis = SortSectionInfo.SavedCustomLeftRightAxis;
			TriangleSortSettings.CustomLeftRightBoneName = SortSectionInfo.SavedCustomLeftRightBoneName;

			// Just reapply the same sorting method to the section again.
			FVector SortCenter;
			bool bHaveSortCenter = NewSkeletalMesh->GetSortCenterPoint(SortCenter);
			LODModel.SortTriangles(SortCenter, bHaveSortCenter, SortSectionInfo.SavedSectionIdx, (ETriangleSortOption)SortSectionInfo.SavedSortOption);
		}
	}		
}
开发者ID:johndpope,项目名称:UE4,代码行数:47,代码来源:SkeletalMeshImport.cpp

示例8: DetectImportType

bool UFbxFactory::DetectImportType(const FString& InFilename)
{
	UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
	UnFbx::FFbxLoggerSetter Logger(FFbxImporter);
	int32 ImportType = FFbxImporter->GetImportType(InFilename);
	if ( ImportType == -1)
	{
		return false;
	}
	else
	{
		ImportUI->MeshTypeToImport = EFBXImportType(ImportType);
		ImportUI->OriginalImportType = ImportUI->MeshTypeToImport;
	}
	
	return true;
}
开发者ID:RandomDeveloperM,项目名称:UE4_Hairworks,代码行数:17,代码来源:FbxFactory.cpp

示例9: Restore


//.........这里部分代码省略.........
						bool FoundMatch = false;
						for( int32 NewTriIdx=0;NewTriIdx<NewStripIndices.Num();NewTriIdx+=3 )
						{
							if( (SavedVertices[OldStripIndices[OldTriIdx+0]] - NewVertices[NewStripIndices[NewTriIdx+0]].Position).SizeSquared() < KINDA_SMALL_NUMBER &&
								(SavedVertices[OldStripIndices[OldTriIdx+1]] - NewVertices[NewStripIndices[NewTriIdx+1]].Position).SizeSquared() < KINDA_SMALL_NUMBER &&
								(SavedVertices[OldStripIndices[OldTriIdx+2]] - NewVertices[NewStripIndices[NewTriIdx+2]].Position).SizeSquared() < KINDA_SMALL_NUMBER )
							{
								// Found a triangle match. Remove the triangle from the new list and try to match the next old triangle.
								NewStripIndices.RemoveAt(NewTriIdx,3);
								FoundMatch = true;
								break;
							}
						}

						// If we didn't find a match for this old triangle, the whole strip doesn't match.
						if( !FoundMatch )
						{
							break;
						}
					}

					if( NewStripIndices.Num() == 0 )
					{
						// strip completely matched
						MatchingNewStrip = NsIdx;
					}
				}

				if( MatchingNewStrip != INDEX_NONE )
				{
					NewSortedStrips.Add( NewStrips[MatchingNewStrip] );
					NewStrips.RemoveAt(MatchingNewStrip);
				}
				else
				{
					NumMismatchedStrips++;
				}
			}

			if( IndexCopy == 0 )
			{
				if( 100 * NumMismatchedStrips / OldStrips[0].Num() > 50 )
				{
					// If less than 50% of this section's strips match, we assume this is not the correct section.
					break;
				}

				// This section matches!
				bFoundMatchingSection = true;

				// Warn the user if we couldn't match things up.
				if( NumMismatchedStrips )
				{
					UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
					FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, FText::Format(LOCTEXT("RestoreSortingMismatchedStripsForSection", "While restoring \"{0}\" sort order for section {1}, {2} of {3} strips could not be matched to the new data."),
						FText::FromString(TriangleSortOptionToString((ETriangleSortOption)SavedSortOption)),
						FText::AsNumber(SavedSectionIdx),
						FText::AsNumber(NumMismatchedStrips),
						FText::AsNumber(OldStrips[0].Num()))));
				}

				// Restore the settings saved in the LODInfo (used for the UI)
				FTriangleSortSettings& TriangleSortSettings = LODInfo.TriangleSortSettings[SectionIndex];
				TriangleSortSettings.TriangleSorting = SavedSortOption;
				TriangleSortSettings.CustomLeftRightAxis = SavedCustomLeftRightAxis;
				TriangleSortSettings.CustomLeftRightBoneName = SavedCustomLeftRightBoneName;

				// Restore the sorting mode. For TRISORT_CustomLeftRight, this will also make the second copy of the index data.
				FVector SortCenter;
				bool bHaveSortCenter = NewSkelMesh->GetSortCenterPoint(SortCenter);
				LODModel.SortTriangles(SortCenter, bHaveSortCenter, SectionIndex, (ETriangleSortOption)SavedSortOption);
			}

			// Append any strips we couldn't match to the end
			NewSortedStrips += NewStrips;

			// Export the strips out to the index buffer in order
			TArray<uint32> Indexes;
			LODModel.MultiSizeIndexContainer.GetIndexBuffer( Indexes );
			uint32* NewIndices = Indexes.GetData() + (Section.BaseIndex + Section.NumTriangles*3*IndexCopy);
			for( int32 StripIdx=0;StripIdx<NewSortedStrips.Num();StripIdx++ )
			{
				FMemory::Memcpy( NewIndices, &NewSortedStrips[StripIdx][0], NewSortedStrips[StripIdx].Num() * sizeof(uint32) );

				// Cache-optimize the triangle order inside the final strip
				CacheOptimizeSortStrip( NewIndices, NewSortedStrips[StripIdx].Num() );

				NewIndices += NewSortedStrips[StripIdx].Num();
			}
			LODModel.MultiSizeIndexContainer.CopyIndexBuffer( Indexes );
		}
	}

	if( !bFoundMatchingSection )
	{
		UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
		FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, FText::Format(LOCTEXT("FailedRestoreSortingNoSectionMatch", "Unable to restore triangle sort setting \"{0}\" for section number {1} in the old mesh, as a matching section could not be found in the new mesh. The custom sorting information has been lost."),
			FText::FromString(TriangleSortOptionToString((ETriangleSortOption)SavedSortOption)), FText::AsNumber(SavedSectionIdx))));
	}
}
开发者ID:Tigrouzen,项目名称:UnrealEngine-4,代码行数:101,代码来源:SkeletalMeshImport.cpp

示例10: SaveExistingSkelMeshData


//.........这里部分代码省略.........
					{
						bMissingBone = true;
						MissingBoneName = MeshData->ExistingRefSkeleton.GetBoneName( LODModel.ActiveBoneIndices[j] );
					}
					else
					{
						LODModel.ActiveBoneIndices[j] = NewBoneIndex;
					}
				}

				// Fix RequiredBones array.
				for(int32 j=0; j<LODModel.RequiredBones.Num() && !bMissingBone; j++)
				{
					int32 NewBoneIndex = OldToNewMap[ LODModel.RequiredBones[j] ];
					if(NewBoneIndex == INDEX_NONE)
					{
						bMissingBone = true;
						MissingBoneName = MeshData->ExistingRefSkeleton.GetBoneName( LODModel.RequiredBones[j] );
					}
					else
					{
						LODModel.RequiredBones[j] = NewBoneIndex;
					}
				}

				// Sort ascending for parent child relationship
				LODModel.RequiredBones.Sort();

				// Fix the chunks' BoneMaps.
				for(int32 ChunkIndex = 0;ChunkIndex < LODModel.Chunks.Num();ChunkIndex++)
				{
					FSkelMeshChunk& Chunk = LODModel.Chunks[ChunkIndex];
					for(int32 BoneIndex = 0;BoneIndex < Chunk.BoneMap.Num();BoneIndex++)
					{
						int32 NewBoneIndex = OldToNewMap[ Chunk.BoneMap[BoneIndex] ];
						if(NewBoneIndex == INDEX_NONE)
						{
							bMissingBone = true;
							MissingBoneName = MeshData->ExistingRefSkeleton.GetBoneName(Chunk.BoneMap[BoneIndex]);
							break;
						}
						else
						{
							Chunk.BoneMap[BoneIndex] = NewBoneIndex;
						}
					}
					if(bMissingBone)
					{
						break;
					}
				}

				if(bMissingBone)
				{
					UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
					FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, FText::Format(LOCTEXT("NewMeshMissingBoneFromLOD", "New mesh is missing bone '{0}' required by an LOD. LOD will be removed."), FText::FromName(MissingBoneName))));
				}
				else
				{
					FStaticLODModel* NewLODModel = new(SkeletalMesh->GetImportedResource()->LODModels) FStaticLODModel( LODModel );
			
					NewLODModel->MultiSizeIndexContainer.RebuildIndexBuffer( MeshData->ExistingIndexBufferData[i] );

					SkeletalMesh->LODInfo.Add( LODInfo );
				}
			}
		}

		for (int32 AssetIndex = 0; AssetIndex < MeshData->ExistingPhysicsAssets.Num(); ++AssetIndex)
		{
			UPhysicsAsset* PhysicsAsset = MeshData->ExistingPhysicsAssets[AssetIndex];
			if ( AssetIndex == 0 )
			{
				// First asset is the one that the skeletal mesh should point too
				SkeletalMesh->PhysicsAsset = PhysicsAsset;
			}
			// No need to mark as modified here, because the asset hasn't actually changed
			if (PhysicsAsset)
			{
				PhysicsAsset->PreviewSkeletalMesh = SkeletalMesh;
			}
		}

		SkeletalMesh->Skeleton = MeshData->ExistingSkeleton;

		// Copy mirror table.
		SkeletalMesh->ImportMirrorTable(MeshData->ExistingMirrorTable);

		SkeletalMesh->MorphTargets.Empty(MeshData->ExistingMorphTargets.Num());
		SkeletalMesh->MorphTargets.Append(MeshData->ExistingMorphTargets);
		SkeletalMesh->InitMorphTargets();

		SkeletalMesh->bUseFullPrecisionUVs = MeshData->bExistingUseFullPrecisionUVs; 

		MeshData->ExistingSortInfo.Restore(SkeletalMesh, 0);

		SkeletalMesh->AssetImportData = MeshData->ExistingAssetImportData.Get();
		SkeletalMesh->ThumbnailInfo = MeshData->ExistingThumbnailInfo.Get();
	}
}
开发者ID:Tigrouzen,项目名称:UnrealEngine-4,代码行数:101,代码来源:SkeletalMeshImport.cpp

示例11: ReimportStaticMesh

EReimportResult::Type UReimportFbxSceneFactory::ReimportStaticMesh(void* VoidFbxImporter, TSharedPtr<FFbxMeshInfo> MeshInfo)
{
	UnFbx::FFbxImporter* FbxImporter = (UnFbx::FFbxImporter*)VoidFbxImporter;
	//Find the UObject associate with this MeshInfo
	UPackage* PkgExist = LoadPackage(nullptr, *(MeshInfo->GetImportPath()), LOAD_Verify | LOAD_NoWarn);
	if (PkgExist != nullptr)
	{
		PkgExist->FullyLoad();
	}

	FString AssetName = MeshInfo->GetFullImportName();
	UStaticMesh* Mesh = FindObjectSafe<UStaticMesh>(ANY_PACKAGE, *AssetName);
	if (Mesh == nullptr)
	{
		//We reimport only static mesh here
		FbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(FText::FromString("Reimport Mesh {0} fail, the original staicmesh in the content browser cannot be load."), FText::FromString(MeshInfo->GetImportPath()))), FName(TEXT("Reimport Fbx Scene")));
		return EReimportResult::Failed;
	}
	
	//Copy default options to StaticMeshImportData
	SFbxSceneOptionWindow::CopyFbxOptionsToStaticMeshOptions(GlobalImportSettingsReference, SceneImportOptionsStaticMesh);
	SceneImportOptionsStaticMesh->FillStaticMeshInmportData(StaticMeshImportData, SceneImportOptions);

	UnFbx::FBXImportOptions* OverrideImportSettings = GetOptionsFromName(MeshInfo->OptionName);
	if (OverrideImportSettings != nullptr)
	{
		SFbxSceneOptionWindow::CopyFbxOptionsToFbxOptions(OverrideImportSettings, GlobalImportSettings);
		SFbxSceneOptionWindow::CopyFbxOptionsToStaticMeshOptions(OverrideImportSettings, SceneImportOptionsStaticMesh);
	}
	else
	{
		SFbxSceneOptionWindow::CopyFbxOptionsToFbxOptions(GlobalImportSettingsReference, GlobalImportSettings);
		SFbxSceneOptionWindow::CopyFbxOptionsToStaticMeshOptions(GlobalImportSettingsReference, SceneImportOptionsStaticMesh);
	}
	SceneImportOptionsStaticMesh->FillStaticMeshInmportData(StaticMeshImportData, SceneImportOptions);

	FbxImporter->ApplyTransformSettingsToFbxNode(FbxImporter->Scene->GetRootNode(), StaticMeshImportData);
	const TArray<UAssetUserData*>* UserData = Mesh->GetAssetUserDataArray();
	TArray<UAssetUserData*> UserDataCopy;
	if (UserData)
	{
		for (int32 Idx = 0; Idx < UserData->Num(); Idx++)
		{
			UserDataCopy.Add((UAssetUserData*)StaticDuplicateObject((*UserData)[Idx], GetTransientPackage()));
		}
	}

	// preserve settings in navcollision subobject
	UNavCollision* NavCollision = Mesh->NavCollision ?
		(UNavCollision*)StaticDuplicateObject(Mesh->NavCollision, GetTransientPackage()) :
		nullptr;

	// preserve extended bound settings
	const FVector PositiveBoundsExtension = Mesh->PositiveBoundsExtension;
	const FVector NegativeBoundsExtension = Mesh->NegativeBoundsExtension;
	Mesh = FbxImporter->ReimportSceneStaticMesh(MeshInfo->UniqueId, Mesh, StaticMeshImportData);
	if (Mesh != nullptr)
	{
		//Put back the new mesh data since the reimport is putting back the original import data
		SceneImportOptionsStaticMesh->FillStaticMeshInmportData(StaticMeshImportData, SceneImportOptions);
		Mesh->AssetImportData = StaticMeshImportData;

		// Copy user data to newly created mesh
		for (int32 Idx = 0; Idx < UserDataCopy.Num(); Idx++)
		{
			UserDataCopy[Idx]->Rename(nullptr, Mesh, REN_DontCreateRedirectors | REN_DoNotDirty);
			Mesh->AddAssetUserData(UserDataCopy[Idx]);
		}

		if (NavCollision)
		{
			Mesh->NavCollision = NavCollision;
			NavCollision->Rename(nullptr, Mesh, REN_DontCreateRedirectors | REN_DoNotDirty);
		}

		// Restore bounds extension settings
		Mesh->PositiveBoundsExtension = PositiveBoundsExtension;
		Mesh->NegativeBoundsExtension = NegativeBoundsExtension;

		Mesh->AssetImportData->Update(FbxImportFileName);

		// Try to find the outer package so we can dirty it up
		if (Mesh->GetOutermost())
		{
			Mesh->GetOutermost()->MarkPackageDirty();
		}
		else
		{
			Mesh->MarkPackageDirty();
		}
		AllNewAssets.Add(MeshInfo, Mesh);
		AssetToSyncContentBrowser.Add(Mesh);
	}
	else
	{
		return EReimportResult::Failed;
	}
	return EReimportResult::Succeeded;
}
开发者ID:RandomDeveloperM,项目名称:UE4_Hairworks,代码行数:99,代码来源:ReimportFbxSceneFactory.cpp

示例12: ProcessImportMeshInfluences

/**
* Process and update the vertex Influences using the raw binary import data
* 
* @param ImportData - raw binary import data to process
*/
void ProcessImportMeshInfluences(FSkeletalMeshImportData& ImportData)
{
	TArray <FVector>& Points = ImportData.Points;
	TArray <VVertex>& Wedges = ImportData.Wedges;
	TArray <VRawBoneInfluence>& Influences = ImportData.Influences;

	// Sort influences by vertex index.
	struct FCompareVertexIndex
	{
		bool operator()( const VRawBoneInfluence& A, const VRawBoneInfluence& B ) const
		{
			if		( A.VertexIndex > B.VertexIndex	) return false;
			else if ( A.VertexIndex < B.VertexIndex	) return true;
			else if ( A.Weight      < B.Weight		) return false;
			else if ( A.Weight      > B.Weight		) return true;
			else if ( A.BoneIndex   > B.BoneIndex	) return false;
			else if ( A.BoneIndex   < B.BoneIndex	) return true;
			else									  return  false;	
		}
	};
	Influences.Sort( FCompareVertexIndex() );

	// Remove more than allowed number of weights by removing least important influences (setting them to 0). 
	// Relies on influences sorted by vertex index and weight and the code actually removing the influences below.
	int32 LastVertexIndex		= INDEX_NONE;
	int32 InfluenceCount		= 0;
	for(  int32 i=0; i<Influences.Num(); i++ )
	{		
		if( ( LastVertexIndex != Influences[i].VertexIndex ) )
		{
			InfluenceCount	= 0;
			LastVertexIndex	= Influences[i].VertexIndex;
		}

		InfluenceCount++;
		if( InfluenceCount > MAX_TOTAL_INFLUENCES || LastVertexIndex >= Points.Num() )
		{
			Influences[i].Weight = 0.f;
		}
	}

	// Remove influences below a certain threshold.
	int32 RemovedInfluences	= 0;
	const float MINWEIGHT	= 0.01f; // 1%
	for( int32 i=Influences.Num()-1; i>=0; i-- )
	{
		if( Influences[i].Weight < MINWEIGHT )
		{
			Influences.RemoveAt(i);
			RemovedInfluences++;
		}
	}

	// Renormalize influence weights.
	int32	LastInfluenceCount	= 0;
	InfluenceCount			= 0;
	LastVertexIndex			= INDEX_NONE;
	float TotalWeight		= 0.f;
	for( int32 i=0; i<Influences.Num(); i++ )
	{
		if( LastVertexIndex != Influences[i].VertexIndex )
		{
			LastInfluenceCount	= InfluenceCount;
			InfluenceCount		= 0;

			// Normalize the last set of influences.
			if( LastInfluenceCount && (TotalWeight != 1.0f) )
			{				
				float OneOverTotalWeight = 1.f / TotalWeight;
				for( int r=0; r<LastInfluenceCount; r++)
				{
					Influences[i-r-1].Weight *= OneOverTotalWeight;
				}
			}
			TotalWeight		= 0.f;				
			LastVertexIndex = Influences[i].VertexIndex;							
		}
		InfluenceCount++;
		TotalWeight	+= Influences[i].Weight;			
	}

	// Ensure that each vertex has at least one influence as e.g. CreateSkinningStream relies on it.
	// The below code relies on influences being sorted by vertex index.
	LastVertexIndex = -1;
	InfluenceCount	= 0;
	if( Influences.Num() == 0 )
	{
		UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
		// warn about no influences
		FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, LOCTEXT("WarningNoSkelInfluences", "Warning skeletal mesh is has no vertex influences")));
		// add one for each wedge entry
		Influences.AddUninitialized(Wedges.Num());
		for( int32 WedgeIdx=0; WedgeIdx<Wedges.Num(); WedgeIdx++ )
		{	
			Influences[WedgeIdx].VertexIndex = WedgeIdx;
//.........这里部分代码省略.........
开发者ID:Tigrouzen,项目名称:UnrealEngine-4,代码行数:101,代码来源:SkeletalMeshImport.cpp

示例13: AddedTransform

bool UnFbx::FFbxImporter::ImportAnimation(USkeleton* Skeleton, UAnimSequence * DestSeq, const FString& FileName, TArray<FbxNode*>& SortedLinks, TArray<FbxNode*>& NodeArray, FbxAnimStack* CurAnimStack, const int32 ResampleRate, const FbxTimeSpan AnimTimeSpan)
{
	// @todo : the length might need to change w.r.t. sampling keys
	FbxTime SequenceLength = AnimTimeSpan.GetDuration();
	float PreviousSequenceLength = DestSeq->SequenceLength;

	// if you have one pose(thus 0.f duration), it still contains animation, so we'll need to consider that as MINIMUM_ANIMATION_LENGTH time length
	DestSeq->SequenceLength = FGenericPlatformMath::Max<float>(SequenceLength.GetSecondDouble(), MINIMUM_ANIMATION_LENGTH);

	if(PreviousSequenceLength > MINIMUM_ANIMATION_LENGTH && DestSeq->RawCurveData.FloatCurves.Num() > 0)
	{
		// The sequence already existed when we began the import. We need to scale the key times for all curves to match the new 
		// duration before importing over them. This is to catch any user-added curves
		float ScaleFactor = DestSeq->SequenceLength / PreviousSequenceLength;
		for(FFloatCurve& Curve : DestSeq->RawCurveData.FloatCurves)
		{
			Curve.FloatCurve.ScaleCurve(0.0f, ScaleFactor);
		}
	}

	if (ImportOptions->bDeleteExistingMorphTargetCurves)
	{
		for (int32 CurveIdx=0; CurveIdx<DestSeq->RawCurveData.FloatCurves.Num(); ++CurveIdx)
		{
			auto& Curve = DestSeq->RawCurveData.FloatCurves[CurveIdx];
			if (Curve.GetCurveTypeFlag(ACF_DrivesMorphTarget))
			{
				DestSeq->RawCurveData.FloatCurves.RemoveAt(CurveIdx, 1, false);
				--CurveIdx;
			}
		}

		DestSeq->RawCurveData.FloatCurves.Shrink();
	}

	//
	// import blend shape curves
	//
	{
		GWarn->BeginSlowTask( LOCTEXT("BeginImportMorphTargetCurves", "Importing Morph Target Curves"), true);
		for ( int32 NodeIndex = 0; NodeIndex < NodeArray.Num(); NodeIndex++ )
		{
			// consider blendshape animation curve
			FbxGeometry* Geometry = (FbxGeometry*)NodeArray[NodeIndex]->GetNodeAttribute();
			if (Geometry)
			{
				int32 BlendShapeDeformerCount = Geometry->GetDeformerCount(FbxDeformer::eBlendShape);
				for(int32 BlendShapeIndex = 0; BlendShapeIndex<BlendShapeDeformerCount; ++BlendShapeIndex)
				{
					FbxBlendShape* BlendShape = (FbxBlendShape*)Geometry->GetDeformer(BlendShapeIndex, FbxDeformer::eBlendShape);

					const int32 BlendShapeChannelCount = BlendShape->GetBlendShapeChannelCount();

					FString BlendShapeName = UTF8_TO_TCHAR(MakeName(BlendShape->GetName()));

					for(int32 ChannelIndex = 0; ChannelIndex<BlendShapeChannelCount; ++ChannelIndex)
					{
						FbxBlendShapeChannel* Channel = BlendShape->GetBlendShapeChannel(ChannelIndex);

						if(Channel)
						{
							FString ChannelName = UTF8_TO_TCHAR(MakeName(Channel->GetName()));

							// Maya adds the name of the blendshape and an underscore to the front of the channel name, so remove it
							if(ChannelName.StartsWith(BlendShapeName))
							{
								ChannelName = ChannelName.Right(ChannelName.Len() - (BlendShapeName.Len()+1));
							}

							FbxAnimCurve* Curve = Geometry->GetShapeChannel(BlendShapeIndex, ChannelIndex, (FbxAnimLayer*)CurAnimStack->GetMember(0));
							if (Curve && Curve->KeyGetCount() > 0)
							{
								FFormatNamedArguments Args;
								Args.Add(TEXT("BlendShape"), FText::FromString(ChannelName));
								const FText StatusUpate = FText::Format(LOCTEXT("ImportingMorphTargetCurvesDetail", "Importing Morph Target Curves [{BlendShape}]"), Args);
								GWarn->StatusUpdate(NodeIndex + 1, NodeArray.Num(), StatusUpate);
								// now see if we have one already exists. If so, just overwrite that. if not, add new one. 
								ImportCurveToAnimSequence(DestSeq, *ChannelName, Curve,  ACF_DrivesMorphTarget | ACF_TriggerEvent, AnimTimeSpan, 0.01f /** for some reason blend shape values are coming as 100 scaled **/);
							}
						}
					}
				}
			}
		}
		GWarn->EndSlowTask();
	}

	// 
	// importing custom attribute START
	//
	if (ImportOptions->bImportCustomAttribute)
	{
		GWarn->BeginSlowTask( LOCTEXT("BeginImportMorphTargetCurves", "Importing Custom Attirubte Curves"), true);
		const int32 TotalLinks = SortedLinks.Num();
		int32 CurLinkIndex=0;
		for(auto Node: SortedLinks)
		{
			FbxProperty Property = Node->GetFirstProperty();
			while (Property.IsValid())
			{
//.........这里部分代码省略.........
开发者ID:colwalder,项目名称:unrealengine,代码行数:101,代码来源:SkeletalMeshEdit.cpp

示例14: ProcessImportMeshInfluences

/**
* Process and update the vertex Influences using the raw binary import data
* 
* @param ImportData - raw binary import data to process
*/
void ProcessImportMeshInfluences(FSkeletalMeshImportData& ImportData)
{
	TArray <FVector>& Points = ImportData.Points;
	TArray <VVertex>& Wedges = ImportData.Wedges;
	TArray <VRawBoneInfluence>& Influences = ImportData.Influences;

	// Sort influences by vertex index.
	struct FCompareVertexIndex
	{
		bool operator()( const VRawBoneInfluence& A, const VRawBoneInfluence& B ) const
		{
			if		( A.VertexIndex > B.VertexIndex	) return false;
			else if ( A.VertexIndex < B.VertexIndex	) return true;
			else if ( A.Weight      < B.Weight		) return false;
			else if ( A.Weight      > B.Weight		) return true;
			else if ( A.BoneIndex   > B.BoneIndex	) return false;
			else if ( A.BoneIndex   < B.BoneIndex	) return true;
			else									  return  false;	
		}
	};
	Influences.Sort( FCompareVertexIndex() );

	TArray <VRawBoneInfluence> NewInfluences;
	int32	LastNewInfluenceIndex=0;
	int32	LastVertexIndex		= INDEX_NONE;
	int32	InfluenceCount			= 0;

	float TotalWeight		= 0.f;
	const float MINWEIGHT   = 0.01f;


	for( int32 i=0; i<Influences.Num(); i++ )
	{
		// we found next verts, normalize it now
		if (LastVertexIndex != Influences[i].VertexIndex )
		{
			// Normalize the last set of influences.
			if (InfluenceCount && (TotalWeight != 1.0f))
			{
				float OneOverTotalWeight = 1.f / TotalWeight;
				for (int r = 0; r < InfluenceCount; r++)
				{
					NewInfluences[LastNewInfluenceIndex - r].Weight *= OneOverTotalWeight;
				}
			}

			// now we insert missing verts
			if (LastVertexIndex != INDEX_NONE)
			{
				int32 CurrentVertexIndex = Influences[i].VertexIndex;
				for(int32 j=LastVertexIndex+1; j<CurrentVertexIndex; j++)
				{
					// Add a 0-bone weight if none other present (known to happen with certain MAX skeletal setups).
					LastNewInfluenceIndex = NewInfluences.AddUninitialized();
					NewInfluences[LastNewInfluenceIndex].VertexIndex	= j;
					NewInfluences[LastNewInfluenceIndex].BoneIndex		= 0;
					NewInfluences[LastNewInfluenceIndex].Weight		= 1.f;
				}
			}

			// clear to count next one
			InfluenceCount = 0;
			TotalWeight = 0.f;
			LastVertexIndex = Influences[i].VertexIndex;
		}
		
		// if less than min weight, or it's more than 8, then we clear it to use weight
		if (Influences[i].Weight > MINWEIGHT && InfluenceCount < MAX_TOTAL_INFLUENCES)
		{
			LastNewInfluenceIndex = NewInfluences.Add(Influences[i]);
			InfluenceCount++;
			TotalWeight	+= Influences[i].Weight;
		}
	}

	Influences = NewInfluences;

	// Ensure that each vertex has at least one influence as e.g. CreateSkinningStream relies on it.
	// The below code relies on influences being sorted by vertex index.
	if( Influences.Num() == 0 )
	{
		UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance();
		// warn about no influences
		FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, LOCTEXT("WarningNoSkelInfluences", "Warning skeletal mesh is has no vertex influences")), FFbxErrors::SkeletalMesh_NoInfluences);
		// add one for each wedge entry
		Influences.AddUninitialized(Wedges.Num());
		for( int32 WedgeIdx=0; WedgeIdx<Wedges.Num(); WedgeIdx++ )
		{	
			Influences[WedgeIdx].VertexIndex = WedgeIdx;
			Influences[WedgeIdx].BoneIndex = 0;
			Influences[WedgeIdx].Weight = 1.0f;
		}		
		for(int32 i=0; i<Influences.Num(); i++)
		{
			int32 CurrentVertexIndex = Influences[i].VertexIndex;
//.........这里部分代码省略.........
开发者ID:johndpope,项目名称:UE4,代码行数:101,代码来源:SkeletalMeshImport.cpp

示例15: ReimportFbxAnimation

bool UEditorEngine::ReimportFbxAnimation( USkeleton* Skeleton, UAnimSequence* AnimSequence, UFbxAnimSequenceImportData* ImportData, const TCHAR* InFilename)
{
	check(Skeleton);

	GWarn->BeginSlowTask( LOCTEXT("ImportingFbxAnimations", "Importing FBX animations"), true );

	UnFbx::FFbxImporter* FbxImporter = UnFbx::FFbxImporter::GetInstance();
	// logger for all error/warnings
	// this one prints all messages that are stored in FFbxImporter	
	UnFbx::FFbxLoggerSetter Logger(FbxImporter);	
	const bool bPrevImportMorph = (AnimSequence->RawCurveData.FloatCurves.Num() > 0) ;

	if ( ImportData )
	{
		// Prepare the import options
		UFbxImportUI* ReimportUI = NewObject<UFbxImportUI>();
		ReimportUI->MeshTypeToImport = FBXIT_Animation;
		ReimportUI->bOverrideFullName = false;
		ReimportUI->AnimSequenceImportData = ImportData;

		ApplyImportUIToImportOptions(ReimportUI, *FbxImporter->ImportOptions);
	}
	else
	{
		FbxImporter->ImportOptions->ResetForReimportAnimation();	
	}

	if ( !FbxImporter->ImportFromFile( InFilename, FPaths::GetExtension( InFilename ) ) )
	{
		// Log the error message and fail the import.
		FbxImporter->FlushToTokenizedErrorMessage(EMessageSeverity::Error);

	}
	else
	{
		// Log the import message and import the mesh.
		FbxImporter->FlushToTokenizedErrorMessage(EMessageSeverity::Warning);


		const FString Filename( InFilename );

		// Get Mesh nodes array that bind to the skeleton system, then morph animation is imported.
		TArray<FbxNode*> FBXMeshNodeArray;
		FbxNode* SkeletonRoot = FbxImporter->FindFBXMeshesByBone(Skeleton->GetReferenceSkeleton().GetBoneName(0), true, FBXMeshNodeArray);

		if (!SkeletonRoot)
		{
			FbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("Error_CouldNotFindFbxTrack", "Mesh contains {0} bone as root but animation doesn't contain the root track.\nImport failed."), FText::FromName(Skeleton->GetReferenceSkeleton().GetBoneName(0)))), FFbxErrors::Animation_CouldNotFindTrack);

			FbxImporter->ReleaseScene();
			GWarn->EndSlowTask();
			return false;
		}

		// for now import all the time?
		bool bImportMorphTracks = true;
		// Check for blend shape curves that are not skinned.  Unskinned geometry can still contain morph curves
		if( bImportMorphTracks )
		{
			TArray<FbxNode*> MeshNodes;
			FbxImporter->FillFbxMeshArray( FbxImporter->Scene->GetRootNode(), MeshNodes, FbxImporter );

			for( int32 NodeIndex = 0; NodeIndex < MeshNodes.Num(); ++NodeIndex )
			{
				// Its possible the nodes already exist so make sure they are only added once
				FBXMeshNodeArray.AddUnique( MeshNodes[NodeIndex] );
			}
		}

		TArray<FbxNode*> SortedLinks;
		FbxImporter->RecursiveBuildSkeleton(SkeletonRoot, SortedLinks);

		if(SortedLinks.Num() == 0)
		{
			FbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, LOCTEXT("Error_CouldNotBuildValidSkeleton", "Could not create a valid skeleton from the import data that matches the given Skeletal Mesh.  Check the bone names of both the Skeletal Mesh for this AnimSet and the animation data you are trying to import.")), FFbxErrors::Animation_CouldNotBuildSkeleton);
		}
		else
		{
			// find the correct animation based on import data
			FbxAnimStack* CurAnimStack = nullptr;
			
			//ignore the source animation name if there's only one animation in the file.
			//this is to make it easier for people who use content creation programs that only export one animation and/or ones that don't allow naming animations			
			if (FbxImporter->Scene->GetSrcObjectCount(FbxCriteria::ObjectType(FbxAnimStack::ClassId)) > 1 && !ImportData->SourceAnimationName.IsEmpty())
			{
				CurAnimStack = FbxCast<FbxAnimStack>(FbxImporter->Scene->FindSrcObject(FbxCriteria::ObjectType(FbxAnimStack::ClassId), TCHAR_TO_UTF8(*ImportData->SourceAnimationName), 0));
			}
			else
			{
				CurAnimStack = FbxCast<FbxAnimStack>(FbxImporter->Scene->GetSrcObject(FbxCriteria::ObjectType(FbxAnimStack::ClassId), 0));
			}
			
			if (CurAnimStack)
			{
				// set current anim stack
				int32 ResampleRate = DEFAULT_SAMPLERATE;
				if (FbxImporter->ImportOptions->bResample)
				{
					ResampleRate = FbxImporter->GetMaxSampleRate(SortedLinks, FBXMeshNodeArray);
				}
//.........这里部分代码省略.........
开发者ID:colwalder,项目名称:unrealengine,代码行数:101,代码来源:SkeletalMeshEdit.cpp


注:本文中的unfbx::FFbxImporter类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。