Skip to content

Commit 86fd7a8

Browse files
authored
Merge pull request #490 from Unity-Technologies/UT-2995-export-anim-curve-tangents
Ut 2995 export anim curve tangents
2 parents 260508b + 8db2a2e commit 86fd7a8

File tree

5 files changed

+52
-68
lines changed

5 files changed

+52
-68
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ public bool HideSendToUnityMenuProperty
460460
}
461461

462462
[SerializeField]
463-
private bool BakeAnimation = true;
463+
private bool BakeAnimation = false;
464464
internal bool BakeAnimationProperty
465465
{
466466
get { return BakeAnimation; }
@@ -578,7 +578,7 @@ internal override void LoadDefaults()
578578
integrationSavePath = DefaultIntegrationSavePath;
579579
dccOptionPaths = null;
580580
dccOptionNames = null;
581-
BakeAnimationProperty = true;
581+
BakeAnimationProperty = false;
582582
ExportModelSettings = ScriptableObject.CreateInstance (typeof(ExportModelSettings)) as ExportModelSettings;
583583
exportModelSettingsSerialize = ExportModelSettings.info;
584584
ShowConvertToPrefabDialog = true;

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

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,13 @@ internal static HashSet<float> GetSampleTimes(AnimationCurve[] animCurves, doubl
17151715
lastTime = System.Math.Max(lastTime, ac[ac.length-1].time);
17161716
}
17171717

1718+
// if these values didn't get set there were no valid anim curves,
1719+
// so don't return any keys
1720+
if(firstTime == double.MaxValue || lastTime == double.MinValue)
1721+
{
1722+
return keyTimes;
1723+
}
1724+
17181725
int firstframe = (int)System.Math.Floor(firstTime * sampleRate);
17191726
int lastframe = (int)System.Math.Ceiling(lastTime * sampleRate);
17201727
for (int i = firstframe; i <= lastframe; i++) {
@@ -1745,23 +1752,9 @@ internal static HashSet<float> GetKeyTimes(AnimationCurve[] animCurves)
17451752
/// NOTE : This is a work in progress (WIP). We only export the key time and value on
17461753
/// a Cubic curve using the default tangents.
17471754
/// </summary>
1748-
internal void ExportAnimationKeys (AnimationCurve uniAnimCurve, FbxAnimCurve fbxAnimCurve,
1755+
internal static void ExportAnimationKeys (AnimationCurve uniAnimCurve, FbxAnimCurve fbxAnimCurve,
17491756
UnityToMayaConvertSceneHelper convertSceneHelper)
17501757
{
1751-
// TODO: complete the mapping between key tangents modes Unity and FBX
1752-
Dictionary<AnimationUtility.TangentMode, List<FbxAnimCurveDef.ETangentMode>> MapUnityKeyTangentModeToFBX =
1753-
new Dictionary<AnimationUtility.TangentMode, List<FbxAnimCurveDef.ETangentMode>>
1754-
{
1755-
//TangeantAuto|GenericTimeIndependent|GenericClampProgressive
1756-
{AnimationUtility.TangentMode.Free, new List<FbxAnimCurveDef.ETangentMode>{FbxAnimCurveDef.ETangentMode.eTangentAuto,FbxAnimCurveDef.ETangentMode.eTangentGenericClampProgressive}},
1757-
1758-
//TangeantAuto|GenericTimeIndependent
1759-
{AnimationUtility.TangentMode.Auto, new List<FbxAnimCurveDef.ETangentMode>{FbxAnimCurveDef.ETangentMode.eTangentAuto,FbxAnimCurveDef.ETangentMode.eTangentGenericTimeIndependent}},
1760-
1761-
//TangeantAuto|GenericTimeIndependent|GenericClampProgressive
1762-
{AnimationUtility.TangentMode.ClampedAuto, new List<FbxAnimCurveDef.ETangentMode>{FbxAnimCurveDef.ETangentMode.eTangentAuto,FbxAnimCurveDef.ETangentMode.eTangentGenericClampProgressive}},
1763-
};
1764-
17651758
// Copy Unity AnimCurve to FBX AnimCurve.
17661759
// NOTE: only cubic keys are supported by the FbxImporter
17671760
using (new FbxAnimCurveModifyHelper(new List<FbxAnimCurve>{fbxAnimCurve}))
@@ -1773,24 +1766,44 @@ internal void ExportAnimationKeys (AnimationCurve uniAnimCurve, FbxAnimCurve fbx
17731766

17741767
int fbxKeyIndex = fbxAnimCurve.KeyAdd (fbxTime);
17751768

1776-
fbxAnimCurve.KeySet (fbxKeyIndex,
1777-
fbxTime,
1778-
convertSceneHelper.Convert(uniKeyFrame.value)
1779-
);
17801769

17811770
// configure tangents
17821771
var lTangent = AnimationUtility.GetKeyLeftTangentMode(uniAnimCurve, keyIndex);
17831772
var rTangent = AnimationUtility.GetKeyRightTangentMode(uniAnimCurve, keyIndex);
17841773

1785-
if (!(MapUnityKeyTangentModeToFBX.ContainsKey(lTangent) && MapUnityKeyTangentModeToFBX.ContainsKey(rTangent)))
1774+
// Always set tangent mode to eTangentBreak, as other modes are not handled the same in FBX as in
1775+
// Unity, thus leading to discrepancies in animation curves.
1776+
FbxAnimCurveDef.ETangentMode tanMode = FbxAnimCurveDef.ETangentMode.eTangentBreak;
1777+
1778+
// Default to cubic interpolation, which is the default for KeySet
1779+
FbxAnimCurveDef.EInterpolationType interpMode = FbxAnimCurveDef.EInterpolationType.eInterpolationCubic;
1780+
switch (rTangent)
17861781
{
1787-
Debug.LogWarning(string.Format("key[{0}] missing tangent mapping ({1},{2})", keyIndex, lTangent.ToString(), rTangent.ToString()));
1788-
continue;
1782+
case AnimationUtility.TangentMode.Linear:
1783+
interpMode = FbxAnimCurveDef.EInterpolationType.eInterpolationLinear;
1784+
break;
1785+
case AnimationUtility.TangentMode.Constant:
1786+
interpMode = FbxAnimCurveDef.EInterpolationType.eInterpolationConstant;
1787+
break;
1788+
default:
1789+
break;
17891790
}
17901791

1791-
// TODO : handle broken tangents
1792-
1793-
// TODO : set key tangents
1792+
fbxAnimCurve.KeySet (fbxKeyIndex,
1793+
fbxTime,
1794+
convertSceneHelper.Convert(uniKeyFrame.value),
1795+
interpMode,
1796+
tanMode,
1797+
// value of right slope
1798+
convertSceneHelper.Convert(uniKeyFrame.outTangent),
1799+
// value of next left slope
1800+
keyIndex < uniAnimCurve.length -1 ? convertSceneHelper.Convert(uniAnimCurve[keyIndex+1].inTangent) : 0,
1801+
FbxAnimCurveDef.EWeightedMode.eWeightedAll,
1802+
// weight for right slope
1803+
uniKeyFrame.outWeight,
1804+
// weight for next left slope
1805+
keyIndex < uniAnimCurve.length - 1 ? uniAnimCurve[keyIndex + 1].inWeight : 0
1806+
);
17941807
}
17951808
}
17961809
}
@@ -1934,9 +1947,7 @@ private void ExportAnimationCurve (FbxNode fbxNode,
19341947
// AxisSystem (LeftHanded to RightHanded) and FBX's default units
19351948
// (Meters to Centimetres)
19361949
var convertSceneHelper = new UnityToMayaConvertSceneHelper (uniPropertyName);
1937-
1938-
// TODO: we'll resample the curve so we don't have to
1939-
// configure tangents
1950+
19401951
if (ModelExporter.ExportSettings.BakeAnimationProperty) {
19411952
ExportAnimationSamples (uniAnimCurve, fbxAnimCurve, frameRate, convertSceneHelper);
19421953
} else {
@@ -2117,8 +2128,15 @@ private void ExportAnimationClip (AnimationClip uniAnimClip, GameObject uniRoot,
21172128
continue;
21182129
}
21192130

2131+
// If this is an euler curve with a prerotation, then need to sample animations to remove the prerotation.
2132+
// Otherwise can export normally with tangents.
21202133
index = EulerCurve.GetEulerIndex (propertyName);
2121-
if (index >= 0) {
2134+
if (index >= 0 &&
2135+
// still need to sample euler curves if baking is specified
2136+
(ModelExporter.ExportSettings.BakeAnimationProperty ||
2137+
// also need to make sure to sample if there is a prerotation, as this is baked into the Unity curves
2138+
fbxNode.GetPreRotation(FbxNode.EPivotSet.eSourcePivot).Distance(new FbxVector4()) > 0)) {
2139+
21222140
RotationCurve rotCurve = GetRotationCurve<EulerCurve> (uniGO, uniAnimClip.frameRate, ref rotations);
21232141
rotCurve.SetCurve (index, uniAnimCurve);
21242142
continue;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ public PropertyChannelMap(Dictionary<string,string> propertyMap, Dictionary<stri
6161
{ "Motion T", "Lcl Translation" },
6262
{ "m_TranslationOffset", "Translation" },
6363
{ "m_ScaleOffset", "Scaling" },
64-
{ "m_RotationOffset", "Rotation" }
64+
{ "m_RotationOffset", "Rotation" },
65+
{ "localEulerAnglesRaw", "Lcl Rotation" }
6566
};
6667

6768
/// <summary>

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,7 @@ private Key [] ComputeKeys(UnityEngine.Quaternion restRotation, FbxNode node) {
5858
fbxPreRotationInverse.Inverse();
5959

6060
// Find when we have keys set.
61-
var keyTimes =
62-
(UnityEditor.Formats.Fbx.Exporter.ModelExporter.ExportSettings.BakeAnimationProperty)
63-
? ModelExporter.GetSampleTimes(GetCurves(), SampleRate)
64-
: ModelExporter.GetKeyTimes(GetCurves());
61+
var keyTimes = ModelExporter.GetSampleTimes(GetCurves(), SampleRate);
6562

6663
// Convert to the Key type.
6764
var keys = new Key[keyTimes.Count];
@@ -120,9 +117,6 @@ public void Animate(Transform unityTransform, FbxNode fbxNode, FbxAnimLayer fbxA
120117
}
121118
}
122119

123-
// Uni-35616 unroll curves to preserve continuous rotations
124-
var fbxCurveNode = fbxNode.LclRotation.GetCurveNode(fbxAnimLayer, false /*should already exist*/);
125-
126120
if (Verbose) {
127121
Debug.Log("Exported rotation animation for " + fbxNode.GetName());
128122
}

com.unity.formats.fbx/Tests/Models/Player/Player.controller

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,6 @@ AnimatorController:
2222
m_IKPass: 0
2323
m_SyncedLayerAffectsTiming: 0
2424
m_Controller: {fileID: 9100000}
25-
--- !u!1102 &380199431843810593
26-
AnimatorState:
27-
serializedVersion: 5
28-
m_ObjectHideFlags: 1
29-
m_CorrespondingSourceObject: {fileID: 0}
30-
m_PrefabInstance: {fileID: 0}
31-
m_PrefabAsset: {fileID: 0}
32-
m_Name: EulerAnimation 0
33-
m_Speed: 1
34-
m_CycleOffset: 0
35-
m_Transitions: []
36-
m_StateMachineBehaviours: []
37-
m_Position: {x: 50, y: 50, z: 0}
38-
m_IKOnFeet: 0
39-
m_WriteDefaultValues: 1
40-
m_Mirror: 0
41-
m_SpeedParameterActive: 0
42-
m_MirrorParameterActive: 0
43-
m_CycleOffsetParameterActive: 0
44-
m_TimeParameterActive: 0
45-
m_Motion: {fileID: 7400000, guid: dfbbf56ceff8a4b31b6f69b12073eefc, type: 2}
46-
m_Tag:
47-
m_SpeedParameter:
48-
m_MirrorParameter:
49-
m_CycleOffsetParameter:
50-
m_TimeParameter:
5125
--- !u!1102 &1102573189940394992
5226
AnimatorState:
5327
serializedVersion: 5
@@ -86,9 +60,6 @@ AnimatorStateMachine:
8660
- serializedVersion: 1
8761
m_State: {fileID: 1102573189940394992}
8862
m_Position: {x: 250, y: 170, z: 0}
89-
- serializedVersion: 1
90-
m_State: {fileID: 380199431843810593}
91-
m_Position: {x: 285, y: 235, z: 0}
9263
m_ChildStateMachines: []
9364
m_AnyStateTransitions: []
9465
m_EntryTransitions: []

0 commit comments

Comments
 (0)