BlueRoseNote/03-UnrealEngine/Editor/FBXAnimation导入逻辑.md

3.8 KiB

title, date, excerpt, tags, rating
title date excerpt tags rating
FBXAnimation导入逻辑 2023-12-11 11:28:36

BVHImport插件中的案例

UObject* UBVHImportFactory::FactoryCreateFile(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, const FString& FileName, const TCHAR* Parms, FFeedbackContext* Warn, bool& bOutOperationCanceled)
{
	if (!shouldImport) {
		return nullptr;
	}
	bool fileSuccess = BVHFile.ImportData(TCHAR_TO_ANSI(*FileName));
	
	const bool bIsUnattended = (IsAutomatedImport()
		|| FApp::IsUnattended()
		|| IsRunningCommandlet()
		|| GIsRunningUnattendedScript);

	// Check if it's a re-import
	if (InParent != nullptr)
	{
		UObject* ExistingObject = StaticFindObject(UObject::StaticClass(), InParent, *InName.ToString());
		if (ExistingObject)
		{
			//reimport逻辑略
		}
	}
	
	if (fileSuccess)
	{	
		UAnimSequence* AnimSequence = NewObject<UAnimSequence>(InParent, InName, Flags & ~EObjectFlags::RF_Transactional);
		if (Skeleton == NULL) {
			//创建骨骼资产略
		}
		else {
			AnimSequence->SetSkeleton(Skeleton);//Skeleton bvhSkel
			AnimSequence->SetPreviewMesh(PreviewMesh);			
		}
		ExtractAnimDataFromBVHFile(AnimSequence);
		return AnimSequence;
		
	}
	return nullptr;
	
}
void UBVHImportFactory::ExtractAnimDataFromBVHFile(UAnimSequence* AnimSequence) {
	if (AnimSequence)
	{		
		// create animation		
		IAnimationDataController& Controller = AnimSequence->GetController();
		Controller.OpenBracket(LOCTEXT("ImportBVHAnimation", "Importing BVH Animation"));
		Controller.ResetModel();

		// Write animation data into animation sequence.
		// Extract transform of hip to create root motion.
		const FReferenceSkeleton& RefSkeleton = AnimSequence->GetSkeleton()->GetReferenceSkeleton();
		const FName RootName = RefSkeleton.GetBoneName(0);
		const int32 NumOfKeys = BVHFile.Root->FrameOffset.Num();

		AnimSequence->ImportFileFramerate = (float)BVHFile.Header.DataRate;
		AnimSequence->ImportResampleFramerate = BVHFile.Header.DataRate;

		Controller.SetPlayLength(float(NumOfKeys - 1) / (float)BVHFile.Header.DataRate);
		Controller.SetFrameRate(FFrameRate(BVHFile.Header.DataRate, 1));
		
		RecursiveReadKeysFromNode(Controller, BVHFile.Root.Get());

		Controller.NotifyPopulated();
		Controller.CloseBracket();

		AnimSequence->AdditiveAnimType = EAdditiveAnimationType::AAT_None;
		AnimSequence->PostEditChange();
		FAssetRegistryModule::AssetCreated(AnimSequence);
		AnimSequence->MarkPackageDirty();
	}
}
void UBVHImportFactory::RecursiveReadKeysFromNode(IAnimationDataController& Controller, FNode* Node)
{
	if (Node)
	{
		Controller.AddBoneTrack(Node->Name,false);
		Controller.SetBoneTrackKeys(Node->Name, Node->FrameOffset, Node->FrameQuat, Node->FrameScale,false);
		if (Node->Children.Num() > 0)
		{
			for (NodePtr Child : Node->Children)
			{
				RecursiveReadKeysFromNode(Controller, Child.Get());
			}
		}
	}
}

UAnimSequenceFactory

UObject* UAnimSequenceFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn)  
{  
    UAnimSequence* AnimSequence = NewObject<UAnimSequence>(InParent, Class, Name, Flags);  
    if (TargetSkeleton)  
    {       AnimSequence->SetSkeleton(TargetSkeleton);  
    }    if (PreviewSkeletalMesh)  
    {       AnimSequence->SetPreviewMesh(PreviewSkeletalMesh);  
    }  
    return AnimSequence;  
}

UFbxAnimSequenceImportData

class UNREALED_API UFbxAnimSequenceImportData : public UFbxAssetImportData

UAnimSequence * UnFbx::FFbxImporter::ImportAnimations(USkeleton* Skeleton, UObject* Outer, TArray<FbxNode*>& SortedLinks, const FString& Name, UFbxAnimSequenceImportData* TemplateImportData, TArray<FbxNode*>& NodeArray)
{

EReimportResult::Type UReimportFbxSceneFactory::ReimportSkeletalMesh(void* VoidFbxImporter, TSharedPtr MeshInfo)