diff --git a/03-UnrealEngine/Editor/FBXAnimation导入逻辑.md b/03-UnrealEngine/Editor/FBXAnimation导入&导出逻辑.md similarity index 61% rename from 03-UnrealEngine/Editor/FBXAnimation导入逻辑.md rename to 03-UnrealEngine/Editor/FBXAnimation导入&导出逻辑.md index 9040e4e..52fe5a6 100644 --- a/03-UnrealEngine/Editor/FBXAnimation导入逻辑.md +++ b/03-UnrealEngine/Editor/FBXAnimation导入&导出逻辑.md @@ -111,4 +111,61 @@ UE5中FBXSDK相关函数调用方式: # 参考 1. Interchange\\Runtime\\Source\\Parsers 1. InterchangeFbxParser.Build.cs - 2. FbxInclude.h:FBXSDK头文件包含问题。 \ No newline at end of file + 2. FbxInclude.h:FBXSDK头文件包含问题。 + +# UE5中使用FBXSDK导出动画逻辑 +1. FFbxExporter::ExportSkeletalMeshToFbx => FFbxExporter::ExportAnimSequence => FFbxExporter::ExportAnimSequenceToFbx +2. FFbxExporter::CorrectAnimTrackInterpolation + +直接导出会有问题,所以UE在这里做了一步Correct: +```c++ +// The curve code doesn't differentiate between angles and other data, so an interpolation from 179 to -179 +// will cause the bone to rotate all the way around through 0 degrees. So here we make a second pass over the +// rotation tracks to convert the angles into a more interpolation-friendly format. +FFbxExporter::CorrectAnimTrackInterpolation() +{ +void FFbxExporter::CorrectAnimTrackInterpolation( TArray& BoneNodes, FbxAnimLayer* InAnimLayer ) +{ + // Add the animation data to the bone nodes + for(int32 BoneIndex = 0; BoneIndex < BoneNodes.Num(); ++BoneIndex) + { + FbxNode* CurrentBoneNode = BoneNodes[BoneIndex]; + + // Fetch the AnimCurves + FbxAnimCurve* Curves[3]; + Curves[0] = CurrentBoneNode->LclRotation.GetCurve(InAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true); + Curves[1] = CurrentBoneNode->LclRotation.GetCurve(InAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true); + Curves[2] = CurrentBoneNode->LclRotation.GetCurve(InAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true); + + for(int32 CurveIndex = 0; CurveIndex < 3; ++CurveIndex) + { + FbxAnimCurve* CurrentCurve = Curves[CurveIndex]; + CurrentCurve->KeyModifyBegin(); + + float CurrentAngleOffset = 0.f; + for(int32 KeyIndex = 1; KeyIndex < CurrentCurve->KeyGetCount(); ++KeyIndex) + { + float PreviousOutVal = CurrentCurve->KeyGetValue( KeyIndex-1 ); + float CurrentOutVal = CurrentCurve->KeyGetValue( KeyIndex ); + + float DeltaAngle = (CurrentOutVal + CurrentAngleOffset) - PreviousOutVal; + + if(DeltaAngle >= 180) + { + CurrentAngleOffset -= 360; + } + else if(DeltaAngle <= -180) + { + CurrentAngleOffset += 360; + } + + CurrentOutVal += CurrentAngleOffset; + + CurrentCurve->KeySetValue(KeyIndex, CurrentOutVal); + } + + CurrentCurve->KeyModifyEnd(); + } + } +} +```