Skip to content

Commit 2cecb18

Browse files
committed
export bones in original position instead of bindpose
When exporting bones of skinned meshes, their transform values are first set to the bindpose, so that the skin and bindpose are exported properly. However, afterwards we need to set the bones back to their original transform values so that if the character is not in the bindpose on export, the same pose is maintained in the FBX.
1 parent 6540444 commit 2cecb18

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

com.unity.formats.fbx/Editor/FbxExporter.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,29 @@ SkinnedMeshRenderer unitySkin
938938

939939
// add bind pose
940940
ExportBindPose (unitySkin, fbxNode, fbxScene, skinnedMeshToBonesMap);
941+
942+
// now that the skin and bindpose are set, make sure that each of the bones
943+
// is set to its original position
944+
var bones = unitySkin.bones;
945+
foreach (var bone in bones)
946+
{
947+
var fbxBone = MapUnityObjectToFbxNode[bone.gameObject];
948+
ExportTransform(bone, fbxBone, newCenter: Vector3.zero, TransformExportType.Local);
949+
950+
// cancel out the pre-rotation from the exported rotation
951+
var fbxPreRotationEuler = fbxBone.GetPreRotation(FbxNode.EPivotSet.eSourcePivot);
952+
// Get the inverse of the prerotation
953+
var fbxPreRotationInverse = ModelExporter.EulerToQuaternion(fbxPreRotationEuler);
954+
fbxPreRotationInverse.Inverse();
955+
956+
var fbxFinalQuat = fbxPreRotationInverse * EulerToQuaternion(new FbxVector4(fbxBone.LclRotation.Get()));
957+
958+
var finalUnityQuat = new FbxQuaternion((float)fbxFinalQuat.X, (float)fbxFinalQuat.Y, (float)fbxFinalQuat.Z, (float)fbxFinalQuat.W);
959+
960+
var quatToEulerMatrix = new FbxAMatrix();
961+
quatToEulerMatrix.SetQ(finalUnityQuat);
962+
fbxBone.LclRotation.Set(ToFbxDouble3(quatToEulerMatrix.GetR()));
963+
}
941964
}
942965

943966
return true;

0 commit comments

Comments
 (0)