Skip to content

Commit fcb7d6c

Browse files
committed
unit test for continuous rotations
1 parent 8af38f5 commit fcb7d6c

File tree

1 file changed

+49
-14
lines changed

1 file changed

+49
-14
lines changed

Assets/FbxExporters/Editor/UnitTests/FbxAnimationTest.cs

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ public class AnimationTestDataClass
2626
Where (t => typeof (Component).IsAssignableFrom (t) &&
2727
ModelExporter.MapsToFbxObject.ContainsKey(t)).Except(m_exceptionTypes);
2828

29-
public static string [] m_localRotationNames = new string [4] { "m_LocalRotation.x", "m_LocalRotation.y", "m_LocalRotation.z", "m_LocalRotation.w" };
30-
public static string [] m_localTranslationNames = new string [3] { "m_LocalPosition.x", "m_LocalPosition.y", "m_LocalPosition.z"};
29+
public static string [] m_quaternionRotationNames = new string [4] { "m_LocalRotation.x", "m_LocalRotation.y", "m_LocalRotation.z", "m_LocalRotation.w" };
30+
public static string [] m_eulerRotationNames = new string [3] { "localEulerAnglesRaw.x", "localEulerAnglesRaw.y", "localEulerAnglesRaw.z" };
31+
public static string [] m_translationNames = new string [3] { "m_LocalPosition.x", "m_LocalPosition.y", "m_LocalPosition.z"};
3132

3233
public static float [] m_keytimes1 = new float [3] { 1f, 2f, 3f };
3334
public static float [] m_keyFloatValues1 = new float [3] { 0f, 100f, 0f };
@@ -51,13 +52,13 @@ public static IEnumerable TestCases1 {
5152
}
5253
public static IEnumerable TestCases2 {
5354
get {
54-
yield return new TestCaseData (m_keytimes1, m_keyEulerValues3, typeof (Transform), m_localRotationNames ).Returns (3);
55+
yield return new TestCaseData (m_keytimes1, m_keyEulerValues3, typeof (Transform), m_quaternionRotationNames ).Returns (3);
5556
}
5657
}
5758
// specify gimbal conditions for rotation
5859
public static IEnumerable TestCases3 {
5960
get {
60-
yield return new TestCaseData (m_keytimes1, m_keyEulerValues4, typeof (Transform), m_localRotationNames ).Returns (3);
61+
yield return new TestCaseData (m_keytimes1, m_keyEulerValues4, typeof (Transform), m_quaternionRotationNames ).Returns (3);
6162
}
6263
}
6364
// specify one of each component type
@@ -70,7 +71,7 @@ public static IEnumerable TestCases4 {
7071
// specify continuous rotations
7172
public static IEnumerable TestCases5 {
7273
get {
73-
yield return new TestCaseData (m_keytimes5, m_keyRotValues5.Concat(m_keyPosValues5).ToArray(), typeof (Transform), m_localRotationNames.Concat(m_localTranslationNames).ToArray() ).Returns (3);
74+
yield return new TestCaseData (m_keytimes5, m_keyRotValues5.Concat(m_keyPosValues5).ToArray(), typeof (Transform), m_eulerRotationNames.Concat(m_translationNames).ToArray() ).Returns (3);
7475
}
7576
}
7677
}
@@ -89,7 +90,7 @@ public class FbxAnimationTest : ExporterTestBase
8990
public override void Term ()
9091
{
9192
// NOTE: comment out the next line to leave temporary FBX files on disk
92-
base.Term ();
93+
//base.Term ();
9394
}
9495

9596
protected void AnimClipTest (AnimationClip animClipExpected, AnimationClip animClipActual)
@@ -116,8 +117,8 @@ protected void AnimCurveTest (float [] keyTimesExpected, float [] keyValuesExpec
116117
Assert.That (animCurveActual.length, Is.EqualTo(numKeysExpected), "animcurve number of keys doesn't match");
117118

118119
//check imported animation against original
119-
Assert.That(new ListMapper(animCurveActual.keys).Property ("time"), Is.EqualTo(keyTimesExpected), string.Format("{0} key time doesn't match",message));
120-
Assert.That(new ListMapper(animCurveActual.keys).Property ("value"), Is.EqualTo(keyValuesExpected), string.Format("{0} key value doesn't match", message));
120+
Assert.That(List.Map(animCurveActual.keys).Property ("time"), Is.EqualTo(keyTimesExpected), string.Format("{0} key time doesn't match",message));
121+
Assert.That(List.Map(animCurveActual.keys).Property ("value"), Is.EqualTo(keyValuesExpected).Within(0.000005f), string.Format("{0} key value doesn't match", message));
121122

122123
return ;
123124
}
@@ -186,32 +187,66 @@ public override int FindComponent (string name)
186187

187188
public class TransformKeyData : KeyData
188189
{
190+
public const int kNumQuatRotFields = 4;
191+
public const int kNumEulerRotFields = 3;
192+
public bool useQuaternion = false;
193+
194+
public int NumRotationFields { get { return ((useQuaternion) ? kNumQuatRotFields : kNumEulerRotFields); } }
195+
189196
public string[] propertyNames;
190-
public Vector3 [] keyValues; // NOTE: first half is Quaternions and second half is Translation
191-
public bool IsRotation(int id) { return id < 4 ; }
197+
public Vector3 [] keyValues; // NOTE: first half is Euler Rotation and second half is Translation
198+
private Quaternion [] keyQuatValues;
199+
200+
public bool IsRotation(int id) { return id < NumRotationFields; }
192201

193202
public override int NumKeys { get { return Mathf.Min (keyTimesInSeconds.Length, keyValues.Length / 2); } }
194203
public override int NumComponents { get { return propertyNames.Length; } }
195204
public override float [] GetKeyValues (int id)
196205
{
206+
if (!useQuaternion) return GetAltKeyValues(id);
207+
208+
// compute continous rotations
209+
if (keyQuatValues==null)
210+
{
211+
keyQuatValues = new Quaternion[NumKeys];
212+
Quaternion currQuat = new Quaternion();
213+
214+
for (int idx=0; idx < NumKeys; idx++)
215+
{
216+
if (idx==0)
217+
{
218+
keyQuatValues[idx] = Quaternion.Euler(keyValues[idx]);
219+
currQuat = keyQuatValues[idx];
220+
}
221+
else
222+
{
223+
Vector3 deltaRot = keyValues[idx] - keyValues[idx-1];
224+
currQuat *= Quaternion.Euler(deltaRot);
225+
keyQuatValues[idx] = currQuat;
226+
}
227+
Debug.Log(string.Format("{0} rot[{1},{2},{3}] quat[{4},{5},{6},{7}]", idx,
228+
keyValues[idx][0], keyValues[idx][1], keyValues[idx][2],
229+
keyQuatValues[idx][0], keyQuatValues[idx][1], keyQuatValues[idx][2], keyQuatValues[idx][3]
230+
));
231+
}
232+
}
233+
197234
float[] result = new float[NumKeys];
198-
bool isRot = IsRotation(id);
199235

200236
for (int idx=0; idx < NumKeys; idx++)
201237
{
202-
result[idx] = (isRot) ? Quaternion.Euler(keyValues[idx])[id] : keyValues[NumKeys+idx][id-4];
238+
result[idx] = IsRotation(id) ? keyQuatValues[idx][id] : keyValues[NumKeys+idx][id-NumRotationFields];
203239
}
204240

205241
return result;
206242
}
207243
public override float [] GetAltKeyValues (int id)
208244
{
209245
float[] result = new float[NumKeys];
210-
bool isRot = IsRotation(id);
211246

212247
for (int idx=0; idx < NumKeys; idx++)
213248
{
214-
result[idx] = (isRot) ? keyValues[idx][id] : keyValues[NumKeys+idx][id-4];
249+
result[idx] = IsRotation(id) ? keyValues[idx][id] : keyValues[NumKeys+idx][id-NumRotationFields];
215250
}
216251

217252
return result;

0 commit comments

Comments
 (0)