public void TestLayoutAssignmentAndReset() { var pool = new GeometryPool { Layout = new VertexLayout { texcoord0 = new TexcoordInfo { size = 2 }, texcoord1 = new TexcoordInfo { size = 3 }, texcoord2 = new TexcoordInfo { size = 4 }, } }; Assert.IsNotNull(pool.m_Texcoord0.v2); Assert.IsNotNull(pool.m_Texcoord1.v3); Assert.IsNotNull(pool.m_Texcoord2.v4); int N = 30; pool.m_Texcoord0.v2.AddRange(MathTestUtils.RandomVector2List(N)); pool.m_Texcoord1.v3.AddRange(MathTestUtils.RandomVector3List(N)); pool.m_Texcoord2.v4.AddRange(MathTestUtils.RandomVector4List(N)); pool.Reset(); Assert.AreEqual(0, pool.m_Texcoord0.v2.Count); Assert.AreEqual(0, pool.m_Texcoord1.v3.Count); Assert.AreEqual(0, pool.m_Texcoord2.v4.Count); }
// Checks invariants for the return value of Plane.ToTrTransform() void CheckToTrTransformInvariants(Plane plane) { var reflect = plane.ToTrTransform(); // Basis vectors should map properly. Actually, we could use any 3 independent vectors. foreach (var basis in kBasisVectors) { Mtu.AssertAlmostEqual(plane.ReflectVector(basis), reflect.MultiplyVector(basis)); } // Det should be -1 Assert.AreEqual(-1, reflect.scale); // Points on plane should not move. We need to check at least 3 distinct points on the plane. // Any non-degenerate tetrahedron will project to at least 3 distinct points. foreach (var basis in kTetrahedron) { Vector3 v = plane.ClosestPointOnPlane(basis); Mtu.AssertAlmostEqual(v, reflect.MultiplyPoint(v)); } // Points not on the plane should move. // Specifically, they should be reflected. { Vector3 notOnPlane = plane.ClosestPointOnPlane(Vector3.zero) + plane.normal; Assert.IsTrue(!Mtu.AlmostEqual( notOnPlane, reflect.MultiplyPoint(notOnPlane), Mtu.ABSEPS, Mtu.RELEPS)); Mtu.AssertAlmostEqual(plane.ReflectPoint(notOnPlane), reflect.MultiplyPoint(notOnPlane)); } }
[TestCase(8, -8, -8, 3, -4, -5, 0, 0, 0)] // +x-y-z vert public void TestClosestPointOnBox( float px, float py, float pz, float spx, float spy, float spz, float nx, float ny, float nz) { var pos = new Vector3(px, py, pz); var halfWidth = new Vector3(3, 4, 5); var expectedSurfacePos = new Vector3(spx, spy, spz); var expectedSurfaceNorm = new Vector3(nx, ny, nz); Vector3 surfacePos, surfaceNorm; CubeStencil.FindClosestPointOnBoxSurface(pos, halfWidth, out surfacePos, out surfaceNorm); MathTestUtils.AssertAlmostEqual(expectedSurfacePos, surfacePos); if (expectedSurfaceNorm != Vector3.zero) { MathTestUtils.AssertAlmostEqual(expectedSurfaceNorm, surfaceNorm); } else { // Test case wants us to calculate it from scratch Vector3 diff = pos - expectedSurfacePos; if (diff != Vector3.zero) { MathTestUtils.AssertAlmostEqual(diff.normalized, surfaceNorm); } } }
public void TestToTrTransform() { for (int i = 0; i < 10; ++i) { Plane plane = Mtu.RandomPlane(); CheckToTrTransformInvariants(plane); } }
public void TestReflectRandom() { for (int i = 0; i < 10; ++i) { Plane p = Mtu.RandomPlane(); Vector3 v = Random.onUnitSphere * Random.Range(-10, 10); TestReflectHelper(p, v); } }
public void TestReflectPoseKeepHandedness() { for (int i = 0; i < 30; ++i) { Plane plane = Mtu.RandomPlane(); TrTransform pose = Mtu.RandomTr(); CheckReflectPoseInvariants(plane, pose); } }
public void TestClosestPointOnBoxEdgeCases() { var halfWidth = new Vector3(3, 4, 5); // Try all permutations of points directly on verts, faces, edges for (int xsign = -1; xsign <= 1; ++xsign) { for (int ysign = -1; ysign <= 1; ++ysign) { for (int zsign = -1; zsign <= 1; ++zsign) { int numFaces = Mathf.Abs(xsign) + Mathf.Abs(ysign) + Mathf.Abs(zsign); // Only care about running tests where the point is on 2 or 3 faces (ie edge, or vert) if (numFaces <= 1) { continue; } var pos = new Vector3(xsign * halfWidth.x, ysign * halfWidth.y, zsign * halfWidth.z); Vector3 surfacePos, surfaceNorm; CubeStencil.FindClosestPointOnBoxSurface(pos, halfWidth, out surfacePos, out surfaceNorm); MathTestUtils.AssertAlmostEqual(pos, surfacePos); MathTestUtils.AssertAlmostEqual(1, surfaceNorm.magnitude); for (int axis = 0; axis < 3; ++axis) { float p = pos[axis]; float h = halfWidth[axis]; float n = surfaceNorm[axis]; // The normal is not well defined, but it should at least point away from the box if (p == h) { Assert.GreaterOrEqual(n, 0, "Axis {0}", axis); } else if (p == -h) { Assert.LessOrEqual(n, 0, "Axis {0}", axis); } else if (-h < p & p < h) { // Should have no component parallel to the edge we're on Assert.AreEqual(n, 0, "Axis {0}", axis); } else { Assert.Fail("Bad test"); } } } } } }
public void TestTransformRandomPlane() { for (int i = 0; i < 10; ++i) { TrTransform tr = MathTestUtils.RandomTr(); Plane p = MathTestUtils.RandomPlane(); Vector3 v = Random.onUnitSphere * Random.Range(.1f, 10); HelperCheckOrientationInvariant(p, v, tr); HelperCheckMirrorInvariant(p, v, tr); } }
// Checks invariants for the return value of Plane.ReflectPose(). void CheckReflectPoseInvariants(Plane plane, TrTransform pose0) { // Object -> world var pose1 = plane.ReflectPoseKeepHandedness(pose0); // Object x axis should be preserved. // Object y and z axes should be reflected. This can actually be checked for any 2 vectors // that are orthogonal to the preserved axis. Mtu.AssertAlmostEqual(-plane.ReflectVector(pose0.right), pose1.right); Mtu.AssertAlmostEqual(plane.ReflectVector(pose0.forward), pose1.forward); Mtu.AssertAlmostEqual(plane.ReflectVector(pose0.up), pose1.up); // pose.translation should be reflected. Mtu.AssertAlmostEqual(plane.ReflectPoint(pose0.translation), pose1.translation); // Handedness should not change (sign should be the same). // Magnitude should stay the same too. Assert.AreEqual(pose0.scale, pose1.scale); }
public void TestFbxQuaternion() { var uq = new Quaternion(1, 2, 3, 4); var fq = uq.ToFbxQuaternion(); // Basic round-tripping var uq2 = fq.ToUQuaternion(); MathTestUtils.AssertAlmostEqual(uq, uq2); // Check that [3] is w, the real part (docs don't say anything about this) var fqc = new FbxQuaternion(fq); fqc.Conjugate(); // [3] is the real part MathTestUtils.AssertAlmostEqual((float)fq.GetAt(3), (float)fqc.GetAt(3)); // and 0-2 are the imaginary part MathTestUtils.AssertAlmostEqual((float)fq.GetAt(1), -(float)fqc.GetAt(1)); }
public void TestListRoundTrip() { // Test a list going into and out of the stream. List <Vector3> lst = MathTestUtils.RandomVector3List(20); MemoryStream stream = new MemoryStream(); using (var writer = new SketchBinaryWriter(stream)) { writer.WriteLengthPrefixed(lst); writer.BaseStream = null; } stream.Position = 0; List <Vector3> lst2 = new List <Vector3>(); using (var reader = new SketchBinaryReader(stream)) { Assert.IsTrue(reader.ReadIntoExact(lst2, lst.Count)); } Assert.AreEqual(lst, lst2); }
static void TestReflectHelper(Plane plane, Vector3 v) { // There are 2 invariants for a point and its mirror: // - They have the same closest point on plane // - They have opposite signed distance to plane { Vector3 p2 = plane.ReflectPoint(v); Mtu.AssertAlmostEqual(plane.ClosestPointOnPlane(v), plane.ClosestPointOnPlane(p2)); Mtu.AssertAlmostEqual(plane.GetDistanceToPoint(v), -plane.GetDistanceToPoint(p2)); } // The invariants for reflecting a vector are similar; but they apply // to the plane with distance=0. { Vector3 v2 = plane.ReflectVector(v); Plane pO = plane; pO.distance = 0; Mtu.AssertAlmostEqual(pO.ClosestPointOnPlane(v), pO.ClosestPointOnPlane(v2)); Mtu.AssertAlmostEqual(pO.GetDistanceToPoint(v), -pO.GetDistanceToPoint(v2)); } }
private static GeometryPool RandomGeometryPool() { int vertexCount = 20; int indexCount = 60; var pool = new GeometryPool(); pool.Layout = new VertexLayout { texcoord0 = new TexcoordInfo { size = 2, semantic = Semantic.XyIsUv }, bUseNormals = true, bUseColors = true, bUseTangents = true }; pool.m_Vertices = MathTestUtils.RandomVector3List(vertexCount); pool.m_Tris = MathTestUtils.RandomIntList(indexCount, 0, vertexCount); pool.m_Normals = MathTestUtils.RandomVector3List(vertexCount); pool.m_Colors = MathTestUtils.RandomColor32List(vertexCount); pool.m_Tangents = MathTestUtils.RandomVector4List(vertexCount); pool.m_Texcoord0.v2 = MathTestUtils.RandomVector2List(vertexCount); return(pool); }