예제 #1
0
        // 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));
            }
        }
예제 #2
0
        [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);
                }
            }
        }
예제 #3
0
        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");
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        // 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);
        }
예제 #5
0
        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));
        }
예제 #6
0
        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));
            }
        }