FbxQuaternionTest.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // ***********************************************************************
  2. // Copyright (c) 2017 Unity Technologies. All rights reserved.
  3. //
  4. // Licensed under the ##LICENSENAME##.
  5. // See LICENSE.md file in the project root for full license information.
  6. // ***********************************************************************
  7. using NUnit.Framework;
  8. using Autodesk.Fbx;
  9. namespace Autodesk.Fbx.UnitTests
  10. {
  11. public class FbxQuaternionTest
  12. {
  13. #if ENABLE_COVERAGE_TEST
  14. [Test]
  15. public void TestCoverage() { CoverageTester.TestCoverage(typeof(FbxQuaternion), this.GetType()); }
  16. #endif
  17. /// <summary>
  18. /// Check that two quaternions represent a similar rotation.
  19. ///
  20. /// Either they're equal (within tolerance) or they're exactly opposite.
  21. /// Note that a slerp will go opposite directions if they're opposite.
  22. ///
  23. /// If you want to use the boolean result, pass in 'nothrow' as true.
  24. /// Otherwise a failed comparision will throw an exception.
  25. /// </summary>
  26. public static bool AssertSimilar(FbxQuaternion expected, FbxQuaternion actual,
  27. double tolerance = 1e-10, bool nothrow = false)
  28. {
  29. // Are they bitwise equal?
  30. if (expected == actual) {
  31. return true;
  32. }
  33. // Compute the dot product. It'll be +1 or -1 if they're the same rotation.
  34. if (System.Math.Abs(expected.DotProduct(actual)) >= 1 - tolerance) {
  35. return true;
  36. }
  37. // Fail. Print it out nicely.
  38. if (!nothrow) { Assert.AreEqual(expected, actual); }
  39. return false;
  40. }
  41. public static bool AssertSimilar(FbxVector4 euler, FbxQuaternion actual,
  42. double tolerance = 1e-10, bool nothrow = false)
  43. {
  44. var expected = new FbxQuaternion();
  45. expected.ComposeSphericalXYZ(euler);
  46. return AssertSimilar(expected, actual, tolerance, nothrow);
  47. }
  48. [Test]
  49. public void TestEquality()
  50. {
  51. EqualityTester<FbxQuaternion>.TestEquality(
  52. new FbxQuaternion(0.0, 0.1, 0.2, 0.3),
  53. new FbxQuaternion(0.3, 0.2, 0.1, 0.0),
  54. new FbxQuaternion(0.0, 0.1, 0.2, 0.3));
  55. }
  56. [Test]
  57. public void BasicTests ()
  58. {
  59. FbxQuaternion u, v;
  60. // make sure the no-arg constructor doesn't crash
  61. new FbxQuaternion();
  62. // test dispose
  63. using (new FbxQuaternion()) { }
  64. DisposeTester.TestDispose(new FbxQuaternion());
  65. // Test other constructors
  66. v = new FbxQuaternion(0.1, 0.2, 0.3, 0.4);
  67. u = new FbxQuaternion(v);
  68. Assert.AreEqual(v, u);
  69. u[0] = 0.5;
  70. Assert.AreEqual(0.5, u[0]);
  71. Assert.AreEqual(0.1, v[0]); // check that setting u doesn't set v
  72. // axis-angle constructor and setter
  73. v = new FbxQuaternion(new FbxVector4(1,2,3), 90);
  74. u = new FbxQuaternion();
  75. u.SetAxisAngle(new FbxVector4(1,2,3), 90);
  76. Assert.AreEqual(u, v);
  77. // euler
  78. v = new FbxQuaternion();
  79. v.ComposeSphericalXYZ(new FbxVector4(20, 30, 40));
  80. var euler = v.DecomposeSphericalXYZ();
  81. Assert.That(euler.X, Is.InRange(19.99, 20.01));
  82. Assert.That(euler.Y, Is.InRange(29.99, 30.01));
  83. Assert.That(euler.Z, Is.InRange(39.99, 40.01));
  84. Assert.AreEqual(0, euler.W);
  85. v = new FbxQuaternion(0.1, 0.2, 0.3);
  86. Assert.AreEqual(0.1, v[0]);
  87. Assert.AreEqual(0.2, v[1]);
  88. Assert.AreEqual(0.3, v[2]);
  89. Assert.AreEqual(1, v[3]); // w is assumed to be a homogenous coordinate
  90. v.Set(0.9, 0.8, 0.7, 0.6);
  91. Assert.AreEqual(0.9, v[0]);
  92. Assert.AreEqual(0.8, v[1]);
  93. Assert.AreEqual(0.7, v[2]);
  94. Assert.AreEqual(0.6, v[3]);
  95. v.Set(0.9, 0.8, 0.7);
  96. Assert.AreEqual(0.9, v[0]);
  97. Assert.AreEqual(0.8, v[1]);
  98. Assert.AreEqual(0.7, v[2]);
  99. v.SetAt(1, 2);
  100. Assert.AreEqual(2, v.GetAt(1));
  101. // Test operator[]
  102. v = new FbxQuaternion();
  103. v[0] = 0.1;
  104. Assert.AreEqual(0.1, v[0]);
  105. v[1] = 0.2;
  106. Assert.AreEqual(0.2, v[1]);
  107. v[2] = 0.3;
  108. Assert.AreEqual(0.3, v[2]);
  109. v[3] = 0.4;
  110. Assert.AreEqual(0.4, v[3]);
  111. v.SetAt(3, 0.5);
  112. Assert.AreEqual(0.5, v.GetAt(3));
  113. Assert.That(() => v[-1], Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  114. Assert.That(() => v[ 4], Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  115. Assert.That(() => v.GetAt(-1), Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  116. Assert.That(() => v.GetAt( 4), Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  117. Assert.That(() => v[-1] = 0.5, Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  118. Assert.That(() => v[ 4] = 0.5, Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  119. Assert.That(() => v.SetAt(-1, 0.5), Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  120. Assert.That(() => v.SetAt( 4, 0.5), Throws.Exception.TypeOf<System.ArgumentOutOfRangeException>());
  121. // Test W/X/Y/Z
  122. v.X = 0.1;
  123. Assert.AreEqual(0.1, v.X);
  124. v.Y = 0.2;
  125. Assert.AreEqual(0.2, v.Y);
  126. v.Z = 0.3;
  127. Assert.AreEqual(0.3, v.Z);
  128. v.W = 0.4;
  129. Assert.AreEqual(0.4, v.W);
  130. // call the multiply/divide/add/sub operators, make sure they're vaguely sane
  131. u = new FbxQuaternion(v);
  132. v = v * v;
  133. Assert.AreNotEqual(0, u.Compare(v, 1e-15)); // test compare can return false
  134. v = v * 9;
  135. v = 9 * v;
  136. v = v + 5;
  137. v = v - 5; // undo v + 5
  138. v = v + u;
  139. v = v - u; // undo v + u
  140. v = v / 81; // undo 9 * (v * 9)
  141. v = v / u; // undo v*v
  142. Assert.AreEqual(0, u.Compare(v)); // u and v are the same up to rounding
  143. Assert.AreEqual(u * u, u.Product(u));
  144. // unary negate and dot product
  145. Assert.AreEqual(0, (-u).Compare(-v));
  146. Assert.AreEqual(-0.3, v.DotProduct(-v), 1e-6);
  147. Assert.AreEqual(System.Math.Sqrt(0.3), v.Length(), 1e-6);
  148. v.Normalize();
  149. Assert.AreEqual(1, v.DotProduct(v), 1e-6);
  150. // various others where we assume that FBX works, just test that they don't crash
  151. v.Conjugate();
  152. v.Inverse();
  153. v.Slerp(u, 0.5);
  154. }
  155. }
  156. }