251 lines
10 KiB
C#
251 lines
10 KiB
C#
// ***********************************************************************
|
|
// Copyright (c) 2017 Unity Technologies. All rights reserved.
|
|
//
|
|
// Licensed under the ##LICENSENAME##.
|
|
// See LICENSE.md file in the project root for full license information.
|
|
// ***********************************************************************
|
|
using NUnit.Framework;
|
|
using Autodesk.Fbx;
|
|
|
|
namespace Autodesk.Fbx.UnitTests
|
|
{
|
|
internal class FbxMatrixTest : FbxDouble4x4TestBase<FbxMatrix>
|
|
{
|
|
|
|
public static bool AssertIsIdentity(FbxMatrix mx,
|
|
double tolerance = 1e-10, bool nothrow = false)
|
|
{
|
|
using (var id = new FbxMatrix()) {
|
|
return AssertSimilar(id, mx, tolerance, nothrow);
|
|
}
|
|
}
|
|
|
|
public static bool AssertSimilar(FbxMatrix expected, FbxMatrix actual,
|
|
double tolerance = 1e-10, bool nothrow = false)
|
|
{
|
|
for(int y = 0; y < 4; ++y) {
|
|
for(int x = 0; x < 4; ++x) {
|
|
if (System.Math.Abs(expected.Get(x, y) - actual.Get(x, y)) >= tolerance) {
|
|
if (!nothrow) {
|
|
Assert.AreEqual(expected, actual, string.Format("Index {0} {1}", x, y));
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
[Test]
|
|
public void TestEquality()
|
|
{
|
|
var zero = new FbxVector4();
|
|
var one = new FbxVector4(1,1,1);
|
|
var mx1 = new FbxMatrix(zero, zero, one);
|
|
var mx2 = new FbxMatrix(one, zero, one);
|
|
// Check that equality is value equality, not reference equality.
|
|
var mx1copy = new FbxMatrix(zero, zero, one);
|
|
EqualityTester<FbxMatrix>.TestEquality(mx1, mx2, mx1copy);
|
|
|
|
// Check that we can compare with an affine matrix.
|
|
mx1 = new FbxMatrix(new FbxVector4(1, 2, 3), new FbxVector4(0, -90, 0), one);
|
|
var affine = new FbxAMatrix(new FbxVector4(1, 2, 3), new FbxVector4(0, -90, 0), one);
|
|
Assert.IsTrue(mx1 == affine);
|
|
}
|
|
|
|
[Test]
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|