Skip to content

Commit c4cc6d0

Browse files
author
DESKTOP-F8VO8FK\Austin
committed
Merge branch 'master' into Uni-35058-sprint42-release
2 parents 76677c2 + a69c98f commit c4cc6d0

File tree

6 files changed

+383
-23
lines changed

6 files changed

+383
-23
lines changed

Assets/FbxExporters/Editor/FbxExporter.cs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,30 @@ public static FbxVector4 ConvertQuaternionToXYZEuler (FbxQuaternion quat)
11371137
return new FbxVector4 (vector4.X, -vector4.Y, -vector4.Z, vector4.W);
11381138
}
11391139

1140+
/// <summary>
1141+
/// Euler to quaternion without axis conversion.
1142+
/// </summary>
1143+
/// <returns>a quaternion.</returns>
1144+
/// <param name="euler">Euler.</param>
1145+
public static FbxQuaternion EulerToQuaternion(FbxVector4 euler)
1146+
{
1147+
FbxAMatrix m = new FbxAMatrix ();
1148+
m.SetR (euler);
1149+
return m.GetQ ();
1150+
}
1151+
1152+
/// <summary>
1153+
/// Quaternion to euler without axis conversion.
1154+
/// </summary>
1155+
/// <returns>a euler.</returns>
1156+
/// <param name="quat">Quaternion.</param>
1157+
public static FbxVector4 QuaternionToEuler(FbxQuaternion quat)
1158+
{
1159+
FbxAMatrix m = new FbxAMatrix ();
1160+
m.SetQ (quat);
1161+
return m.GetR ();
1162+
}
1163+
11401164
// get a fbxNode's global default position.
11411165
protected bool ExportTransform (UnityEngine.Transform unityTransform, FbxNode fbxNode, Vector3 newCenter, TransformExportType exportType)
11421166
{
@@ -1602,8 +1626,9 @@ Key [] ComputeKeys(UnityEngine.Quaternion restRotation, FbxNode node) {
16021626
var fbxPreRotationEuler = node.GetRotationActive()
16031627
? node.GetPreRotation(FbxNode.EPivotSet.eSourcePivot)
16041628
: new FbxVector4();
1605-
var fbxPreRotationInverse = new FbxQuaternion();
1606-
fbxPreRotationInverse.ComposeSphericalXYZ(fbxPreRotationEuler);
1629+
1630+
// Get the inverse of the prerotation
1631+
var fbxPreRotationInverse = ModelExporter.EulerToQuaternion (fbxPreRotationEuler);
16071632
fbxPreRotationInverse.Inverse();
16081633

16091634
// If we're only animating along certain coords for some
@@ -1632,17 +1657,23 @@ Key [] ComputeKeys(UnityEngine.Quaternion restRotation, FbxNode node) {
16321657
(z == null) ? lclQuaternion[2] : z.Evaluate(seconds),
16331658
(w == null) ? lclQuaternion[3] : w.Evaluate(seconds));
16341659

1660+
// convert the final animation to righthanded coords
1661+
var finalEuler = ModelExporter.ConvertQuaternionToXYZEuler(fbxFinalAnimation);
1662+
1663+
// convert it back to a quaternion for multiplication
1664+
fbxFinalAnimation = ModelExporter.EulerToQuaternion (finalEuler);
1665+
16351666
// Cancel out the pre-rotation. Order matters. FBX reads left-to-right.
16361667
// When we run animation we will apply:
16371668
// pre-rotation
16381669
// then pre-rotation inverse
16391670
// then animation.
1640-
var fbxQuat = fbxPreRotationInverse * fbxFinalAnimation;
1671+
var fbxFinalQuat = fbxPreRotationInverse * fbxFinalAnimation;
16411672

16421673
// Store the key so we can sort them later.
16431674
Key key;
16441675
key.time = FbxTime.FromSecondDouble(seconds);
1645-
key.euler = ModelExporter.ConvertQuaternionToXYZEuler(fbxQuat);
1676+
key.euler = ModelExporter.QuaternionToEuler (fbxFinalQuat);;
16461677
keys[i++] = key;
16471678
}
16481679

Assets/FbxExporters/Editor/UnitTests/FbxAnimationTest.cs

Lines changed: 102 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using UnityEngine;
1+
using UnityEngine;
22
using UnityEditor;
33
using NUnit.Framework;
44
using System.Collections;
@@ -84,6 +84,12 @@ public static IEnumerable TestCases5 {
8484
// yield return new TestCaseData (RotationInterpolation.kQuaternion /*use quaternion values*/, m_keytimes5, m_keyPosValues5, m_keyRotValues5).Returns (3);
8585
}
8686
}
87+
88+
public static IEnumerable SkinnedMeshTestCases {
89+
get {
90+
yield return "Models/DefaultMale/Male_DyingHitFromBack_Blend_T3_Cut01_James.fbx";
91+
}
92+
}
8793
}
8894

8995
[TestFixture]
@@ -103,7 +109,7 @@ public override void Term ()
103109
base.Term ();
104110
}
105111

106-
protected void AnimClipTest (AnimationClip animClipExpected, AnimationClip animClipActual)
112+
protected void AnimClipPropertyTest (AnimationClip animClipExpected, AnimationClip animClipActual)
107113
{
108114
#if UNITY_EDITOR_WIN
109115
// TODO: figure out why we get __preview__ on Windows
@@ -135,6 +141,21 @@ protected void AnimCurveTest (float [] keyTimesExpected, float [] keyValuesExpec
135141
return ;
136142
}
137143

144+
private void AnimCurveTest(AnimationCurve animCurveImported, AnimationCurve animCurveActual, string message){
145+
// TODO : Uni-34492 number of keys don't match
146+
//Assert.That (animCurveActual.length, Is.EqualTo (animCurveImported.length), "animcurve number of keys doesn't match");
147+
148+
var actualTimeKeys = new ListMapper (animCurveActual.keys).Property ("time");
149+
var actualValueKeys = new ListMapper (animCurveActual.keys).Property ("value");
150+
151+
var importedTimeKeys = new ListMapper (animCurveImported.keys).Property ("time");
152+
var importedValueKeys = new ListMapper (animCurveImported.keys).Property ("value");
153+
154+
//check imported animation against original
155+
Assert.That(actualTimeKeys, Is.EqualTo(importedTimeKeys), string.Format("{0} key time doesn't match",message));
156+
Assert.That(actualValueKeys, Is.EqualTo(importedValueKeys), string.Format("{0} key value doesn't match", message));
157+
}
158+
138159
public class KeyData
139160
{
140161
public float [] keyTimesInSeconds;
@@ -357,23 +378,9 @@ public int AnimTest (KeyData keyData, string testName)
357378
}
358379

359380
//acquire imported object from exported file
360-
Object [] goAssetImported = AssetDatabase.LoadAllAssetsAtPath (path);
361-
Assert.That (goAssetImported, Is.Not.Null);
362-
363-
// TODO : configure object so that it imports w Legacy Animation
364-
365-
AnimationClip animClipImported = null;
366-
foreach (Object o in goAssetImported) {
367-
animClipImported = o as AnimationClip;
368-
if (animClipImported) break;
369-
}
370-
Assert.That (animClipImported, Is.Not.Null, "expected imported clip");
381+
AnimationClip animClipImported = GetClipFromFbx (path);
371382

372-
// TODO : configure import settings so we don't need to force legacy
373-
animClipImported.legacy = true;
374-
375-
// check clip properties match
376-
AnimClipTest (animClipOriginal, animClipImported);
383+
AnimClipPropertyTest (animClipOriginal, animClipImported);
377384

378385
// check animCurve & keys
379386
int result = 0;
@@ -402,6 +409,83 @@ public int AnimTest (KeyData keyData, string testName)
402409
return result;
403410
}
404411

412+
private AnimationClip GetClipFromFbx(string path){
413+
//acquire imported object from exported file
414+
Object [] goAssetImported = AssetDatabase.LoadAllAssetsAtPath (path);
415+
Assert.That (goAssetImported, Is.Not.Null);
416+
417+
// TODO : configure object so that it imports w Legacy Animation
418+
419+
AnimationClip animClipImported = null;
420+
foreach (Object o in goAssetImported) {
421+
animClipImported = o as AnimationClip;
422+
if (animClipImported) break;
423+
}
424+
Assert.That (animClipImported, Is.Not.Null, "expected imported clip");
425+
426+
// TODO : configure import settings so we don't need to force legacy
427+
animClipImported.legacy = true;
428+
429+
return animClipImported;
430+
}
431+
432+
[Ignore("Uni-34804 gimbal conditions, and Uni-34492 number of keys don't match")]
433+
[Test, TestCaseSource (typeof (AnimationTestDataClass), "SkinnedMeshTestCases")]
434+
public void LegacySkinnedMeshAnimTest (string fbxPath)
435+
{
436+
fbxPath = FindPathInUnitTests (fbxPath);
437+
Assert.That (fbxPath, Is.Not.Null);
438+
439+
// add fbx to scene
440+
GameObject originalFbxObj = AssetDatabase.LoadMainAssetAtPath("Assets/" + fbxPath) as GameObject;
441+
Assert.IsNotNull (originalFbxObj);
442+
GameObject originalGO = GameObject.Instantiate (originalFbxObj);
443+
Assert.IsTrue (originalGO);
444+
445+
// get clip
446+
AnimationClip animClipOriginal = originalGO.GetComponentInChildren<Animation>().clip;
447+
Assert.That (animClipOriginal, Is.Not.Null);
448+
449+
// export fbx
450+
// get GameObject
451+
string filename = GetRandomFbxFilePath();
452+
var exportedFilePath = ModelExporter.ExportObject (filename, originalGO);
453+
Assert.That (exportedFilePath, Is.EqualTo (filename));
454+
455+
// TODO: Uni-34492 change importer settings of (newly exported model)
456+
// so that it's not resampled and it is legacy animation
457+
{
458+
ModelImporter modelImporter = AssetImporter.GetAtPath (filename) as ModelImporter;
459+
modelImporter.resampleCurves = false;
460+
AssetDatabase.ImportAsset (filename);
461+
modelImporter.animationType = ModelImporterAnimationType.Legacy;
462+
AssetDatabase.ImportAsset (filename);
463+
}
464+
465+
var animClipImported = GetClipFromFbx (filename);
466+
467+
// check clip properties match
468+
AnimClipPropertyTest (animClipOriginal, animClipImported);
469+
470+
foreach (EditorCurveBinding curveBinding in AnimationUtility.GetCurveBindings (animClipOriginal)) {
471+
foreach(EditorCurveBinding impCurveBinding in AnimationUtility.GetCurveBindings (animClipImported)) {
472+
473+
// only compare if the path and property names match
474+
if (curveBinding.path != impCurveBinding.path || curveBinding.propertyName != impCurveBinding.propertyName) {
475+
continue;
476+
}
477+
478+
AnimationCurve animCurveOrig = AnimationUtility.GetEditorCurve (animClipOriginal, curveBinding);
479+
Assert.That (animCurveOrig, Is.Not.Null);
480+
481+
AnimationCurve animCurveImported = AnimationUtility.GetEditorCurve (animClipImported, impCurveBinding);
482+
Assert.That (animCurveImported, Is.Not.Null);
483+
484+
AnimCurveTest(animCurveImported, animCurveOrig, curveBinding.propertyName);
485+
}
486+
}
487+
}
488+
405489
[Test, TestCaseSource (typeof (AnimationTestDataClass), "TestCases1")]
406490
public int SimplePropertyAnimTest (float [] keyTimesInSeconds, float [] keyValues, System.Type componentType, string componentName)
407491
{

Assets/FbxExporters/Editor/UnitTests/FbxAnimationTest.cs.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/FbxExporters/Editor/UnitTests/Models/DefaultMale.meta

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)