public void BasicTests() { base.TestElementAccessAndDispose(new FbxMatrix()); FbxMatrix mx; // make sure the constructors compile and don't crash mx = new FbxMatrix(); mx = new FbxMatrix(new FbxMatrix()); mx = new FbxMatrix(new FbxAMatrix()); mx = new FbxMatrix(new FbxVector4(), new FbxVector4(), new FbxVector4(1, 1, 1)); mx = new FbxMatrix(new FbxVector4(), new FbxQuaternion(), new FbxVector4(1, 1, 1)); mx = new FbxMatrix(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); /* Check the values we typed in match up. */ for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(x + 4 * y, mx.Get(y, x)); } } Assert.AreEqual(new FbxVector4(4, 5, 6, 7), mx.GetRow(1)); Assert.AreEqual(new FbxVector4(1, 5, 9, 13), mx.GetColumn(1)); /* Check that set and get work (silly transpose operation). */ FbxMatrix mx2 = new FbxMatrix(); for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { mx2.Set(y, x, y + 4 * x); Assert.AreEqual(mx.Get(x, y), mx2.Get(y, x)); } } /* normal transpose operation */ Assert.AreEqual(mx, mx2.Transpose()); // Test SetIdentity Assert.IsFalse(AssertIsIdentity(mx, nothrow: true)); AssertIsIdentity(mx, 15); // squint very, very, very hard mx.SetIdentity(); AssertIsIdentity(mx); // Test getting the elements from a matrix built by TRS var translate = new FbxVector4(1, 2, 3); var rotate = new FbxVector4(0, 90, 0); var scale = new FbxVector4(1, 2, .5); mx = new FbxMatrix(translate, rotate, scale); FbxVector4 t, r, s, shear; double sign; mx.GetElements(out t, out r, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxVector4Test.AssertSimilarEuler(rotate, r); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); FbxQuaternion q = new FbxQuaternion(); mx.GetElements(out r, q, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxQuaternionTest.AssertSimilar(rotate, q); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); // Try SetTRS and SetTQS with the same arguments. using (var X = new FbxMatrix()) { X.SetTRS(translate, rotate, scale); X.GetElements(out r, q, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxQuaternionTest.AssertSimilar(rotate, q); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); } using (var X = new FbxMatrix()) { FbxQuaternion qRotate = new FbxQuaternion(); qRotate.ComposeSphericalXYZ(rotate); X.SetTQS(translate, q, scale); X.GetElements(out r, q, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxQuaternionTest.AssertSimilar(rotate, q); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); // While we're at it, transform a vertex. // Verify also that w turns out normalized. var v = new FbxVector4(1, 2, 3, 4); var v2 = X.MultNormalize(v); FbxVector4Test.AssertSimilarXYZW(new FbxVector4(2.5, 6, 2, 1), v2); // While we're at it, test that we can invert the matrix. // This matrix is invertible (since it's an affine transformation), // and the inversion turns out to be exact. AssertIsIdentity(X.Inverse() * X); using (var inv = new FbxMatrix( 0, 0, 2, 0, 0, 0.5, 0, 0, -1, 0, 0, 0, 3, -1, -2, 1)) { Assert.AreEqual(inv, X.Inverse()); } } // Test set column + set row mx = new FbxMatrix(); mx.SetColumn(1, new FbxVector4(1, 2, 3, 4)); mx.SetRow(2, new FbxVector4(5, 6, 7, 8)); //check that the column is what we expect Assert.AreEqual(1, mx.Get(0, 1)); Assert.AreEqual(2, mx.Get(1, 1)); Assert.AreEqual(6, mx.Get(2, 1)); // this value got changed by SetRow Assert.AreEqual(4, mx.Get(3, 1)); // check that the row is what we expect Assert.AreEqual(new FbxDouble4(5, 6, 7, 8), mx [2]); // Test operators on two matrices. using (var a = new FbxMatrix( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) { using (var b = new FbxMatrix( 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) { using (var sum = new FbxMatrix( 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15)) { Assert.AreEqual(sum, a + b); } using (var diff = new FbxMatrix( -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15)) { Assert.AreEqual(diff, a - b); } using (var prod = new FbxMatrix( 304, 358, 412, 466, 208, 246, 284, 322, 112, 134, 156, 178, 16, 22, 28, 34)) { Assert.AreEqual(prod, a * b); } using (var neg = new FbxMatrix( 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15)) { Assert.AreEqual(neg, -a); } } } var eyePosition = new FbxVector4(1, 2, 3); var eyeDirection = new FbxVector4(-1, -1, -1); var eyeUp = new FbxVector4(0, 1, 0); using (mx = new FbxMatrix()) { mx.SetLookToRH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( 0.707, -0.408, 0.577, 0, 0, 0.816, 0.577, 0, -0.707, -0.408, 0.577, 0, 1.414, 0, -3.464, 1), mx, 1e-2); mx.SetLookToLH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( -0.707, -0.408, -0.577, 0, 0, 0.816, -0.577, 0, 0.707, -0.408, -0.577, 0, -1.414, 0, 3.464, 1), mx, 1e-2); mx.SetLookAtRH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( 0.894, -0.249, 0.371, 0, 0, 0.834, 0.557, 0, -0.447, -0.498, 0.742, 0, 0.447, 0.083, -3.713, 1), mx, 1e-2); mx.SetLookAtLH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( -0.894, -0.249, -0.371, 0, 0, 0.834, -0.557, 0, 0.447, -0.498, -0.742, 0, -0.447, 0.083, 3.713, 1), mx, 1e-2); } }
public void BasicTests() { base.TestElementAccessAndDispose(new FbxAMatrix()); // make sure the constructors compile and don't crash new FbxAMatrix(); new FbxAMatrix(new FbxAMatrix()); var mx = new FbxAMatrix(new FbxVector4(), new FbxVector4(), new FbxVector4(1, 1, 1)); // check that the matrix is the id matrix Assert.IsTrue(mx.IsIdentity()); for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(x == y ? 1 : 0, mx.Get(y, x)); } } // Test that all the operations work. // In particular, test that they don't return the default element // when they aren't supposed to. var translate = new FbxVector4(5, 3, 1); var euler = new FbxVector4(-135, -90, 0); var scale = new FbxVector4(1, 2, .5); var quat = new FbxQuaternion(); quat.ComposeSphericalXYZ(euler); mx = new FbxAMatrix(translate, euler, scale); Assert.IsFalse(mx.IsIdentity()); Assert.IsTrue(mx.IsIdentity(10)); // squint very, very, very hard FbxVector4Test.AssertSimilarXYZ(translate, mx.GetT()); FbxVector4Test.AssertSimilarEuler(euler, mx.GetR()); FbxQuaternionTest.AssertSimilar(quat, mx.GetQ()); FbxVector4Test.AssertSimilarXYZ(scale, mx.GetS()); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(0.354, 0.354, 0), mx.GetRow(2), 1e-2); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(1, 0, 0), mx.GetColumn(2)); mx.SetT(translate * 2); FbxVector4Test.AssertSimilarXYZ(2 * translate, mx.GetT()); mx.SetR(euler * 2); FbxVector4Test.AssertSimilarEuler(2 * euler, mx.GetR()); mx.SetQ(quat * 2); FbxQuaternionTest.AssertSimilar(2 * quat, mx.GetQ()); mx.SetS(scale * 2); FbxVector4Test.AssertSimilarXYZ(2 * scale, mx.GetS()); mx.SetTRS(translate, euler, scale); FbxVector4Test.AssertSimilarXYZ(translate, mx.GetT()); mx.SetTQS(2 * translate, 2 * quat, 2 * scale); FbxVector4Test.AssertSimilarXYZ(2 * translate, mx.GetT()); // Test Inverse. var mxInv = mx.Inverse(); Assert.AreNotEqual(mx.GetT(), mxInv.GetT()); Assert.IsTrue((mx * mxInv).IsIdentity()); // Test multiplying by a translation. Really we just want to make sure we got a result // different than doing nothing. FbxVector4Test.AssertSimilarXYZ(new FbxVector4(17.778175, 2.464466, 4), mx.MultT(new FbxVector4(1, 2, 3)), 1e-5); // Test multiplying by a rotation. FbxVector4Test.AssertSimilarEuler(new FbxVector4(-180, 0, 45), mx.MultR(new FbxVector4(0, -90, 0))); quat.ComposeSphericalXYZ(new FbxVector4(0, -90, 0)); quat = mx.MultQ(quat); var quatExpected = new FbxQuaternion(); quatExpected.ComposeSphericalXYZ(new FbxVector4(-180, 0, 45)); FbxQuaternionTest.AssertSimilar(quatExpected, quat); // Test multiplying a scale. FbxVector4Test.AssertSimilarXYZ(new FbxVector4(4, 6, .5), mx.MultS(new FbxVector4(2, 1.5, .5))); // Test scaling. Multiply/divide by powers of two so there's no roundoff. // The scale/rotate is scaled, the translation is cleared to (0,0,0,1). AssertScaled(mx, mx * 2, 2); AssertScaled(mx, 2 * mx, 2); AssertScaled(mx, mx / 2, 0.5); // Test negating. This is different from scaling by -1. using (var mxNegated = -mx) { for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(-mx.Get(x, y), mxNegated.Get(x, y), string.Format("Index {0} {1}", x, y)); } } } // Test transpose. using (var mxTranspose = mx.Transpose()) { for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(mx.Get(y, x), mxTranspose.Get(x, y), string.Format("Index {0} {1}", x, y)); } } } // Test setting to identity. mx.SetIdentity(); Assert.IsTrue(mx.IsIdentity()); // Slerp between two rotation matrices. var q1 = new FbxQuaternion(); q1.ComposeSphericalXYZ(new FbxVector4(0, -90, 0)); var q2 = new FbxQuaternion(); q2.ComposeSphericalXYZ(new FbxVector4(0, 90, 0)); var m1 = new FbxAMatrix(); m1.SetQ(q1); var m2 = new FbxAMatrix(); m2.SetQ(q2); var m12 = m1.Slerp(m2, 0.25); var q12 = new FbxQuaternion(); q12.ComposeSphericalXYZ(new FbxVector4(0, -45, 0)); FbxQuaternionTest.AssertSimilar(q12, m12.GetQ()); }