Skip to content

Commit 716de3b

Browse files
committed
failed to create mixed (euler/quaternion) rotation clip
1 parent 10070e7 commit 716de3b

File tree

1 file changed

+95
-49
lines changed

1 file changed

+95
-49
lines changed

Assets/FbxExporters/Editor/UnitTests/FbxAnimationTest.cs

Lines changed: 95 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ namespace FbxExporters.UnitTests
1010
{
1111
using CustomExtensions;
1212

13+
public enum RotationInterpolation {
14+
kEuler=3,
15+
kMixed=(3+4),
16+
kQuaternion=4
17+
};
18+
1319
public class AnimationTestDataClass
1420
{
1521
// TODO: remove items that become supported by exporter
@@ -71,9 +77,11 @@ public static IEnumerable TestCases4 {
7177
// specify continuous rotations
7278
public static IEnumerable TestCases5 {
7379
get {
74-
yield return new TestCaseData (false /*use quaternion values*/, m_keytimes5, m_keyRotValues5.Concat(m_keyPosValues5).ToArray()).Returns (3);
75-
// Uni-35616 continuous rotations doesn't work with quaternions
76-
// yield return new TestCaseData (true /*use quaternion values*/, m_keytimes5, m_keyRotValues5.Concat(m_keyPosValues5).ToArray()).Returns (3);
80+
yield return new TestCaseData (RotationInterpolation.kEuler /*use quaternion values*/, m_keytimes5, m_keyPosValues5, m_keyRotValues5).Returns (3);
81+
// Uni-35616 can't programmatically define a Euler (Quaternion) mix.
82+
// yield return new TestCaseData (RotationInterpolation.kMixed /*use euler&quaternion values*/, m_keytimes5, m_keyPosValues5, m_keyRotValues5).Returns (3);
83+
// Uni-35616 doesn't work with quaternions; rotations don't exceed 180
84+
// yield return new TestCaseData (RotationInterpolation.kQuaternion /*use quaternion values*/, m_keytimes5, m_keyPosValues5, m_keyRotValues5).Returns (3);
7785
}
7886
}
7987
}
@@ -134,11 +142,11 @@ public class KeyData
134142
public GameObject targetObject;
135143

136144
public virtual int NumKeys { get { return 0; } }
137-
public virtual int NumComponents { get { return 0; } }
145+
public virtual int NumProperties { get { return 0; } }
138146
public virtual float[] GetKeyValues(int id) { return null; }
139147
public virtual float [] GetAltKeyValues (int id) { return GetKeyValues(id); }
140-
public virtual string GetComponentName (int id) { return null; }
141-
public virtual int FindComponent (string name) { return -1; }
148+
public virtual string GetPropertyName (int id) { return null; }
149+
public virtual int GetIndexOf (string name) { return -1; }
142150

143151
}
144152

@@ -148,10 +156,10 @@ public class ComponentKeyData : KeyData
148156
public float [] keyFloatValues;
149157

150158
public override int NumKeys { get { return Mathf.Min (keyTimesInSeconds.Length, keyFloatValues.Length); } }
151-
public override int NumComponents { get { return 1; } }
159+
public override int NumProperties { get { return 1; } }
152160
public override float[] GetKeyValues (int id) { return keyFloatValues; }
153-
public override string GetComponentName (int id) { return propertyName; }
154-
public override int FindComponent (string name) { return (name == propertyName) ? 0 : -1; }
161+
public override string GetPropertyName (int id) { return propertyName; }
162+
public override int GetIndexOf (string name) { return (name == propertyName) ? 0 : -1; }
155163
}
156164

157165
public class SingleKeyData : KeyData
@@ -160,10 +168,10 @@ public class SingleKeyData : KeyData
160168
public System.Single [] keyFloatValues;
161169

162170
public override int NumKeys { get { return Mathf.Min (keyTimesInSeconds.Length, keyFloatValues.Length); } }
163-
public override int NumComponents { get { return propertyNames.Length; } }
171+
public override int NumProperties { get { return propertyNames.Length; } }
164172
public override float [] GetKeyValues (int id) { return keyFloatValues; }
165-
public override string GetComponentName (int id) { return propertyNames[id]; }
166-
public override int FindComponent (string name) { return System.Array.IndexOf (propertyNames, name); }
173+
public override string GetPropertyName (int id) { return propertyNames[id]; }
174+
public override int GetIndexOf (string name) { return System.Array.IndexOf (propertyNames, name); }
167175
}
168176

169177
public class QuaternionKeyData : KeyData
@@ -172,7 +180,7 @@ public class QuaternionKeyData : KeyData
172180
public Vector3 [] keyEulerValues;
173181

174182
public override int NumKeys { get { return Mathf.Min (keyTimesInSeconds.Length, keyEulerValues.Length); } }
175-
public override int NumComponents { get { return propertyNames.Length; } }
183+
public override int NumProperties { get { return propertyNames.Length; } }
176184
public override float [] GetKeyValues (int id)
177185
{
178186
return (from e in keyEulerValues select Quaternion.Euler(e)[id]).ToArray ();
@@ -182,60 +190,69 @@ public override float [] GetAltKeyValues (int id)
182190
return (from e in keyEulerValues select e[id]).ToArray ();
183191
}
184192

185-
public override string GetComponentName (int id) { return propertyNames[id]; }
186-
public override int FindComponent (string name)
193+
public override string GetPropertyName (int id) { return propertyNames[id]; }
194+
public override int GetIndexOf (string name)
187195
{
188196
return System.Array.IndexOf (propertyNames, name);
189197
}
190198
}
191199

192200
public class TransformKeyData : KeyData
193201
{
194-
public const int kNumQuatRotFields = 4;
195-
public const int kNumEulerRotFields = 3;
196-
public bool useQuaternionValues = false;
197-
198-
public int NumRotationFields { get { return ((useQuaternionValues) ? kNumQuatRotFields : kNumEulerRotFields); } }
202+
public RotationInterpolation RotationType = RotationInterpolation.kEuler;
199203

200204
public string[] propertyNames;
201-
public Vector3 [] keyValues; // NOTE: first half is Euler Rotation and second half is Translation
205+
public Vector3 [] keyPosValues;
206+
public Vector3 [] keyEulerValues;
202207
private Quaternion [] keyQuatValues;
203208

204-
public bool IsRotation(int id) { return id < NumRotationFields; }
209+
public bool IsRotation(int id) { return id < (int)RotationType; }
205210

206-
public override int NumKeys { get { return Mathf.Min (keyTimesInSeconds.Length, keyValues.Length / 2); } }
207-
public override int NumComponents { get { return propertyNames.Length; } }
211+
public override int NumKeys { get { return keyTimesInSeconds.Length; } }
212+
public override int NumProperties { get { return propertyNames.Length; } }
208213
public override float [] GetKeyValues (int id)
209214
{
210-
if (!useQuaternionValues) return GetAltKeyValues(id);
215+
if (RotationType==RotationInterpolation.kEuler)
216+
return GetAltKeyValues(id);
211217

212218
// compute continous rotations
213219
if (keyQuatValues==null)
214220
{
215221
keyQuatValues = new Quaternion[NumKeys];
216-
Quaternion currQuat = new Quaternion();
217222

218223
for (int idx=0; idx < NumKeys; idx++)
219224
{
220-
if (idx==0)
221-
{
222-
keyQuatValues[idx] = Quaternion.Euler(keyValues[idx]);
223-
currQuat = keyQuatValues[idx];
224-
}
225-
else
226-
{
227-
Vector3 deltaRot = keyValues[idx] - keyValues[idx-1];
228-
currQuat *= Quaternion.Euler(deltaRot);
229-
keyQuatValues[idx] = currQuat;
230-
}
225+
keyQuatValues[idx] = Quaternion.Euler(keyEulerValues[idx]);
231226
}
232227
}
233228

234229
float[] result = new float[NumKeys];
235230

236231
for (int idx=0; idx < NumKeys; idx++)
237232
{
238-
result[idx] = IsRotation(id) ? keyQuatValues[idx][id] : keyValues[NumKeys+idx][id-NumRotationFields];
233+
if (IsRotation(id))
234+
{
235+
switch (RotationType)
236+
{
237+
case (RotationInterpolation.kEuler):
238+
result[idx] = keyEulerValues[idx][id];
239+
break;
240+
case (RotationInterpolation.kMixed):
241+
int NumEulerFields = (int)RotationInterpolation.kEuler;
242+
243+
result[idx] = (id<NumEulerFields)
244+
? keyEulerValues[idx][id] : keyQuatValues[idx][id-NumEulerFields];
245+
246+
break;
247+
case (RotationInterpolation.kQuaternion):
248+
result[idx] = keyQuatValues[idx][id];
249+
break;
250+
}
251+
}
252+
else
253+
{
254+
result[idx] = keyPosValues[idx][id-(int)RotationType];
255+
}
239256
}
240257

241258
return result;
@@ -246,14 +263,32 @@ public override float [] GetAltKeyValues (int id)
246263

247264
for (int idx=0; idx < NumKeys; idx++)
248265
{
249-
result[idx] = IsRotation(id) ? keyValues[idx][id] : keyValues[NumKeys+idx][id-NumRotationFields];
266+
// kMixed
267+
// 0..2 euler XYZ
268+
// 3..6 quaternion XYZ
269+
// 7..9 position XYZ
270+
// kQuaternion
271+
// 0..3 quarternion XYZW
272+
// 4..6 position XYZ
273+
// kEuler
274+
// 0..2 euler XYZ
275+
// 3..5 position XYZ
276+
277+
if (IsRotation(id))
278+
{
279+
result[idx] = keyEulerValues[idx][id];
280+
}
281+
else
282+
{
283+
result[idx] = keyPosValues[idx][id-(int)RotationType];
284+
}
250285
}
251286

252287
return result;
253288
}
254289

255-
public override string GetComponentName (int id) { return propertyNames[id]; }
256-
public override int FindComponent (string name)
290+
public override string GetPropertyName (int id) { return propertyNames[id]; }
291+
public override int GetIndexOf (string name)
257292
{
258293
return System.Array.IndexOf (propertyNames, name);
259294
}
@@ -286,7 +321,7 @@ public int AnimTest (KeyData keyData, string testName)
286321
animClipOriginal.legacy = true;
287322
animClipOriginal.name = "anim_" + testName;
288323

289-
for (int id = 0; id < keyData.NumComponents; id++) {
324+
for (int id = 0; id < keyData.NumProperties; id++) {
290325
// initialize keys
291326
Keyframe [] keys = new Keyframe [keyData.NumKeys];
292327

@@ -296,7 +331,7 @@ public int AnimTest (KeyData keyData, string testName)
296331
}
297332
AnimationCurve animCurveOriginal = new AnimationCurve (keys);
298333

299-
animClipOriginal.SetCurve ("", keyData.componentType, keyData.GetComponentName (id), animCurveOriginal);
334+
animClipOriginal.SetCurve ("", keyData.componentType, keyData.GetPropertyName (id), animCurveOriginal);
300335
}
301336

302337
animOrig.AddClip (animClipOriginal, animClipOriginal.name);
@@ -356,7 +391,7 @@ public int AnimTest (KeyData keyData, string testName)
356391
if (!hasAltPropertyName)
357392
altPropertyName = curveBinding.propertyName;
358393

359-
int id = keyData.FindComponent (altPropertyName);
394+
int id = keyData.GetIndexOf (altPropertyName);
360395

361396
if (id != -1) {
362397
AnimCurveTest (keyData.keyTimesInSeconds, hasAltPropertyName ? keyData.GetAltKeyValues (id) : keyData.GetKeyValues (id), animCurveImported, curveBinding.propertyName);
@@ -394,15 +429,26 @@ public int GimbalConditionsAnimTest (float [] keyTimesInSeconds, Vector3 [] keyV
394429

395430
[Description("Uni-35616 continuous rotations")]
396431
[Test, TestCaseSource (typeof (AnimationTestDataClass), "TestCases5")]
397-
public int ContinuousRotationAnimTest (bool useQuaternionValues, float [] keyTimesInSeconds, Vector3 [] keyValues)
432+
public int ContinuousRotationAnimTest (RotationInterpolation rotInterp, float [] keyTimesInSeconds, Vector3 [] keyPosValues, Vector3 [] keyEulerValues)
398433
{
399434
System.Type componentType = typeof(Transform);
400435

401-
string[] propertyNames = useQuaternionValues ?
402-
AnimationTestDataClass.m_quaternionRotationNames.Concat(AnimationTestDataClass.m_translationNames).ToArray() :
403-
AnimationTestDataClass.m_eulerRotationNames.Concat(AnimationTestDataClass.m_translationNames).ToArray();
436+
string[] propertyNames = null;
437+
438+
switch (rotInterp)
439+
{
440+
case RotationInterpolation.kEuler:
441+
propertyNames=AnimationTestDataClass.m_eulerRotationNames.Concat(AnimationTestDataClass.m_translationNames).ToArray();
442+
break;
443+
case RotationInterpolation.kQuaternion:
444+
propertyNames=AnimationTestDataClass.m_quaternionRotationNames.Concat(AnimationTestDataClass.m_translationNames).ToArray();
445+
break;
446+
case RotationInterpolation.kMixed:
447+
propertyNames=AnimationTestDataClass.m_eulerRotationNames.Concat(AnimationTestDataClass.m_quaternionRotationNames).Concat(AnimationTestDataClass.m_translationNames).ToArray();
448+
break;
449+
}
404450

405-
KeyData keyData = new TransformKeyData { useQuaternionValues = useQuaternionValues, propertyNames = propertyNames, componentType = componentType, keyTimesInSeconds = keyTimesInSeconds, keyValues = keyValues };
451+
KeyData keyData = new TransformKeyData { RotationType = rotInterp, propertyNames = propertyNames, componentType = componentType, keyTimesInSeconds = keyTimesInSeconds, keyPosValues = keyPosValues, keyEulerValues = keyEulerValues };
406452

407453
return AnimTest (keyData, componentType.ToString () + "_ContinuousRotations");
408454
}

0 commit comments

Comments
 (0)