Exemplo n.º 1
0
        public void ComputeCollision()
        {
            Gjk algo = new Gjk(new CollisionDetection());

              CollisionObject a = new CollisionObject
              {
            GeometricObject = new GeometricObject(new TriangleShape(new Vector3F(0, 0, 0), new Vector3F(0, 1, 0), new Vector3F(0, 0, 1)), Pose.Identity),
              };

              CollisionObject b = new CollisionObject
              {
            GeometricObject = new GeometricObject(new SphereShape(1), Pose.Identity),
              };

              ContactSet set;

              set = algo.GetClosestPoints(a, b);
              Assert.AreEqual(true, algo.HaveContact(a, b));
              Assert.AreEqual(0, set[0].PenetrationDepth);

              ((GeometricObject)b.GeometricObject).Pose = new Pose(new Vector3F(2, 0.1f, 0.2f));
              algo.UpdateClosestPoints(set, 0);
              Assert.AreEqual(false, algo.HaveContact(a, b));
              Assert.IsTrue(Numeric.AreEqual(-1, set[0].PenetrationDepth, 0.001f));
              Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(0, 0.1f, 0.2f), set[0].PositionAWorld, 0.01f));
              Assert.IsTrue(Vector3F.AreNumericallyEqual(new Vector3F(1, 0.1f, 0.2f), set[0].PositionBWorld, 0.01f));
        }
Exemplo n.º 2
0
        public void ComputeCollision()
        {
            Gjk algo = new Gjk(new CollisionDetection());

            CollisionObject a = new CollisionObject
            {
                GeometricObject = new GeometricObject(new TriangleShape(new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1)), Pose.Identity),
            };

            CollisionObject b = new CollisionObject
            {
                GeometricObject = new GeometricObject(new SphereShape(1), Pose.Identity),
            };

            ContactSet set;

            set = algo.GetClosestPoints(a, b);
            Assert.AreEqual(true, algo.HaveContact(a, b));
            Assert.AreEqual(0, set[0].PenetrationDepth);

            ((GeometricObject)b.GeometricObject).Pose = new Pose(new Vector3(2, 0.1f, 0.2f));
            algo.UpdateClosestPoints(set, 0);
            Assert.AreEqual(false, algo.HaveContact(a, b));
            Assert.IsTrue(Numeric.AreEqual(-1, set[0].PenetrationDepth, 0.001f));
            Assert.IsTrue(Vector3.AreNumericallyEqual(new Vector3(0, 0.1f, 0.2f), set[0].PositionAWorld, 0.01f));
            Assert.IsTrue(Vector3.AreNumericallyEqual(new Vector3(1, 0.1f, 0.2f), set[0].PositionBWorld, 0.01f));
        }
Exemplo n.º 3
0
        private void UpdateDeterminant(int xmIdx)
        {
            int index1 = 1 << xmIdx;

            this.det[index1][xmIdx] = 1f;
            int bitsToIndex = Gjk.bitsToIndices[this.simplexBits];
            int num1        = bitsToIndex;
            int num2        = 0;

            while (num1 != 0)
            {
                int index2 = (num1 & 7) - 1;
                int num3   = 1 << index2;
                int index3 = num3 | index1;
                this.det[index3][index2] = Gjk.Dot(ref this.edges[xmIdx][index2], ref this.y[xmIdx]);
                this.det[index3][xmIdx]  = Gjk.Dot(ref this.edges[index2][xmIdx], ref this.y[index2]);
                int num4 = bitsToIndex;
                for (int index4 = 0; index4 < num2; ++index4)
                {
                    int index5 = (num4 & 7) - 1;
                    int num5   = 1 << index5;
                    int index6 = index3 | num5;
                    int index7 = (double)this.edgeLengthSq[index2][index5] < (double)this.edgeLengthSq[xmIdx][index5] ? index2 : xmIdx;
                    this.det[index6][index5] = (float)((double)this.det[index3][index2] * (double)Gjk.Dot(ref this.edges[index7][index5], ref this.y[index2]) + (double)this.det[index3][xmIdx] * (double)Gjk.Dot(ref this.edges[index7][index5], ref this.y[xmIdx]));
                    int index8 = (double)this.edgeLengthSq[index5][index2] < (double)this.edgeLengthSq[xmIdx][index2] ? index5 : xmIdx;
                    this.det[index6][index2] = (float)((double)this.det[num5 | index1][index5] * (double)Gjk.Dot(ref this.edges[index8][index2], ref this.y[index5]) + (double)this.det[num5 | index1][xmIdx] * (double)Gjk.Dot(ref this.edges[index8][index2], ref this.y[xmIdx]));
                    int index9 = (double)this.edgeLengthSq[index2][xmIdx] < (double)this.edgeLengthSq[index5][xmIdx] ? index2 : index5;
                    this.det[index6][xmIdx] = (float)((double)this.det[num3 | num5][index5] * (double)Gjk.Dot(ref this.edges[index9][xmIdx], ref this.y[index5]) + (double)this.det[num3 | num5][index2] * (double)Gjk.Dot(ref this.edges[index9][xmIdx], ref this.y[index2]));
                    num4 >>= 3;
                }
                num1 >>= 3;
                ++num2;
            }
            if ((this.simplexBits | index1) != 15)
            {
                return;
            }
            int index10 = (double)this.edgeLengthSq[1][0] < (double)this.edgeLengthSq[2][0] ? ((double)this.edgeLengthSq[1][0] < (double)this.edgeLengthSq[3][0] ? 1 : 3) : ((double)this.edgeLengthSq[2][0] < (double)this.edgeLengthSq[3][0] ? 2 : 3);

            this.det[15][0] = (float)((double)this.det[14][1] * (double)Gjk.Dot(ref this.edges[index10][0], ref this.y[1]) + (double)this.det[14][2] * (double)Gjk.Dot(ref this.edges[index10][0], ref this.y[2]) + (double)this.det[14][3] * (double)Gjk.Dot(ref this.edges[index10][0], ref this.y[3]));
            int index11 = (double)this.edgeLengthSq[0][1] < (double)this.edgeLengthSq[2][1] ? ((double)this.edgeLengthSq[0][1] < (double)this.edgeLengthSq[3][1] ? 0 : 3) : ((double)this.edgeLengthSq[2][1] < (double)this.edgeLengthSq[3][1] ? 2 : 3);

            this.det[15][1] = (float)((double)this.det[13][0] * (double)Gjk.Dot(ref this.edges[index11][1], ref this.y[0]) + (double)this.det[13][2] * (double)Gjk.Dot(ref this.edges[index11][1], ref this.y[2]) + (double)this.det[13][3] * (double)Gjk.Dot(ref this.edges[index11][1], ref this.y[3]));
            int index12 = (double)this.edgeLengthSq[0][2] < (double)this.edgeLengthSq[1][2] ? ((double)this.edgeLengthSq[0][2] < (double)this.edgeLengthSq[3][2] ? 0 : 3) : ((double)this.edgeLengthSq[1][2] < (double)this.edgeLengthSq[3][2] ? 1 : 3);

            this.det[15][2] = (float)((double)this.det[11][0] * (double)Gjk.Dot(ref this.edges[index12][2], ref this.y[0]) + (double)this.det[11][1] * (double)Gjk.Dot(ref this.edges[index12][2], ref this.y[1]) + (double)this.det[11][3] * (double)Gjk.Dot(ref this.edges[index12][2], ref this.y[3]));
            int index13 = (double)this.edgeLengthSq[0][3] < (double)this.edgeLengthSq[1][3] ? ((double)this.edgeLengthSq[0][3] < (double)this.edgeLengthSq[2][3] ? 0 : 2) : ((double)this.edgeLengthSq[1][3] < (double)this.edgeLengthSq[2][3] ? 1 : 2);

            this.det[15][3] = (float)((double)this.det[7][0] * (double)Gjk.Dot(ref this.edges[index13][3], ref this.y[0]) + (double)this.det[7][1] * (double)Gjk.Dot(ref this.edges[index13][3], ref this.y[1]) + (double)this.det[7][2] * (double)Gjk.Dot(ref this.edges[index13][3], ref this.y[2]));
        }
        public void TestCoplanar()
        {
            var tta = new TriangleTriangleAlgorithm(new CollisionDetection());
            var gjk = new Gjk(new CollisionDetection());

            int numberOfContacts = 0;
            int numberOfTests    = 1000;

            RandomHelper.Random = new Random(1234567);
            for (int i = 0; i < numberOfTests; i++)
            {
                // Create two triangles.
                var tA = new Triangle();
                tA.Vertex0 = new Vector3(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tA.Vertex1 = new Vector3(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tA.Vertex2 = new Vector3(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

                var tB = new Triangle();
                tB.Vertex0 = new Vector3(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tB.Vertex1 = new Vector3(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tB.Vertex2 = new Vector3(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

                var ttTest = GeometryHelper.HaveContact(tA, tB);

                if (ttTest)
                {
                    numberOfContacts++;
                }

                var coA = new CollisionObject(new GeometricObject(new TriangleShape(tA)));
                var coB = new CollisionObject(new GeometricObject(new TriangleShape(tB)));

                var csTta = tta.GetContacts(coA, coB);
                var csGjk = gjk.GetClosestPoints(coA, coB);

                if (csTta.HaveContact != csGjk.HaveContact)
                {
                    Trace.WriteLine("Test failed: " + i + " GJK: " + csGjk.HaveContact + " TTA: " + csTta);
                }

                Assert.AreEqual(ttTest, csGjk.HaveContact);
                Assert.AreEqual(ttTest, csTta.HaveContact);
            }

            //Trace.WriteLine("% hits:" + 100f * numberOfContacts / numberOfTests);
        }
Exemplo n.º 5
0
        public void TestTriangles()
        {
            var mpr = new MinkowskiPortalRefinement(new CollisionDetection());
            var gjk = new Gjk(new CollisionDetection());

            RandomHelper.Random = new Random(1234567);

            for (int i = 0; i < 100000; i++)
            {
                // Create two triangles in a plane.
                var tA = new Triangle();
                tA.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
                tA.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
                tA.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));

                var tB = new Triangle();
                tB.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
                tB.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
                tB.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));

                var coA = new CollisionObject(new GeometricObject(new TriangleShape(tA)));
                var coB = new CollisionObject(new GeometricObject(new TriangleShape(tB)));

                var csMpr = mpr.GetContacts(coA, coB);
                var csGjk = gjk.GetClosestPoints(coA, coB);

                // Test again using boolean query.
                bool haveMprContact = mpr.HaveContact(coA, coB);

                // The exceptions are tested cases - all extreme shallow surface contacts.
                if (i != 28487 && i != 47846 && i != 97305)
                {
                    Assert.AreEqual(csGjk.HaveContact, haveMprContact);
                    Assert.AreEqual(csGjk.HaveContact, csMpr.HaveContact);
                }
            }
        }
Exemplo n.º 6
0
        public void GjkRealTest()
        {
            Gjk gjk = new Gjk();

            BoundingSphere shape1 = new BoundingSphere(new Vector3(30, 52, 119), 91);
            BoundingSphere shape2 = new BoundingSphere(new Vector3(139, 13, 35), 49);

            float expected = Collision.DistanceSphereSphere(ref shape1, ref shape2);

            //BoundingSphere shape1 = new BoundingSphere(new Vector3(-10.01f, 99f, 2.7f), 0.0001f);
            //BoundingSphere shape2 = new BoundingSphere(new Vector3(12.7f, 2f, -120.07f), 0.0001f);

            //BoundingSphere shape1 = new BoundingSphere(new Vector3(0, 15, 0), 1);
            //BoundingBox shape1 = new BoundingBox(new Vector3(0, 0, 0), new Vector3(1, 1, 1));
            //BoundingBox shape2 = new BoundingBox(new Vector3(0, 2, 0), new Vector3(3, 3, 3));

            float distance = gjk.GetMinimumDistance(v =>
            {
                Vector3 a = shape1.SupportMapping(v);
                Vector3 b = shape2.SupportMapping(-v);

                return(a - b);
            }, maxIterations: 50);
        }
Exemplo n.º 7
0
        public CollisionAlgorithmMatrix(CollisionDetection collisionDetection)
        {
            // Initialize with dummy collision algorithms.
            var noAlgo       = new NoCollisionAlgorithm(collisionDetection);   // Definitely no collision wanted.
            var infiniteAlgo = new InfiniteShapeAlgorithm(collisionDetection); // Returns always a collision.

            // Build default configuration:
            var gjk                = new Gjk(collisionDetection);
            var gjkBoxAlgorithm    = new CombinedCollisionAlgorithm(collisionDetection, gjk, new BoxBoxAlgorithm(collisionDetection));
            var gjkMprAlgorithm    = new CombinedCollisionAlgorithm(collisionDetection, gjk, new MinkowskiPortalRefinement(collisionDetection));
            var gjkTriTriAlgorithm = new CombinedCollisionAlgorithm(collisionDetection, gjk, new TriangleTriangleAlgorithm(collisionDetection));

            BoxSphereAlgorithm        boxSphereAlgorithm        = new BoxSphereAlgorithm(collisionDetection);
            CompositeShapeAlgorithm   compositeAlgorithm        = new CompositeShapeAlgorithm(collisionDetection);
            HeightFieldAlgorithm      heightFieldAlgorithm      = new HeightFieldAlgorithm(collisionDetection);
            LineAlgorithm             lineAlgorithm             = new LineAlgorithm(collisionDetection);
            PlaneBoxAlgorithm         planeBoxAlgorithm         = new PlaneBoxAlgorithm(collisionDetection);
            PlaneConvexAlgorithm      planeConvexAlgorithm      = new PlaneConvexAlgorithm(collisionDetection);
            PlaneRayAlgorithm         planeRayAlgorithm         = new PlaneRayAlgorithm(collisionDetection);
            PlaneSphereAlgorithm      planeSphereAlgorithm      = new PlaneSphereAlgorithm(collisionDetection);
            RayBoxAlgorithm           rayBoxAlgorithm           = new RayBoxAlgorithm(collisionDetection);
            RayConvexAlgorithm        rayConvexAlgorithm        = new RayConvexAlgorithm(collisionDetection);
            RaySphereAlgorithm        raySphereAlgorithm        = new RaySphereAlgorithm(collisionDetection);
            RayTriangleAlgorithm      rayTriangleAlgorithm      = new RayTriangleAlgorithm(collisionDetection);
            SphereSphereAlgorithm     sphereSphereAlgorithm     = new SphereSphereAlgorithm(collisionDetection);
            TransformedShapeAlgorithm transformedShapeAlgorithm = new TransformedShapeAlgorithm(collisionDetection);
            TriangleMeshAlgorithm     triangleMeshAlgorithm     = new TriangleMeshAlgorithm(collisionDetection);
            RayCompositeAlgorithm     rayCompositeAlgorithm     = new RayCompositeAlgorithm(collisionDetection);
            RayTriangleMeshAlgorithm  rayTriangleMeshAlgorithm  = new RayTriangleMeshAlgorithm(collisionDetection);
            RayHeightFieldAlgorithm   rayHeightFieldAlgorithm   = new RayHeightFieldAlgorithm(collisionDetection);

            this[typeof(PointShape), typeof(PointShape)]        = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(LineShape)]         = lineAlgorithm;
            this[typeof(PointShape), typeof(RayShape)]          = rayConvexAlgorithm;
            this[typeof(PointShape), typeof(LineSegmentShape)]  = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(TriangleShape)]     = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(RectangleShape)]    = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(BoxShape)]          = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(ConvexShape)]       = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(ScaledConvexShape)] = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(SphereShape)]       = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(PointShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(PointShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(PointShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(PointShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(PointShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(PointShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(PointShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(LineShape), typeof(LineShape)]         = lineAlgorithm;
            this[typeof(LineShape), typeof(RayShape)]          = lineAlgorithm;
            this[typeof(LineShape), typeof(LineSegmentShape)]  = lineAlgorithm;
            this[typeof(LineShape), typeof(TriangleShape)]     = lineAlgorithm;
            this[typeof(LineShape), typeof(RectangleShape)]    = lineAlgorithm;
            this[typeof(LineShape), typeof(BoxShape)]          = lineAlgorithm;
            this[typeof(LineShape), typeof(ConvexShape)]       = lineAlgorithm;
            this[typeof(LineShape), typeof(ScaledConvexShape)] = lineAlgorithm;
            this[typeof(LineShape), typeof(CircleShape)]       = lineAlgorithm;
            this[typeof(LineShape), typeof(SphereShape)]       = lineAlgorithm;
            this[typeof(LineShape), typeof(CapsuleShape)]      = lineAlgorithm;
            this[typeof(LineShape), typeof(ConeShape)]         = lineAlgorithm;
            this[typeof(LineShape), typeof(CylinderShape)]     = lineAlgorithm;
            this[typeof(LineShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(LineShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(LineShape), typeof(PlaneShape)]        = noAlgo;
            this[typeof(LineShape), typeof(HeightField)]       = noAlgo;
            this[typeof(LineShape), typeof(TriangleMeshShape)] = lineAlgorithm;
            this[typeof(LineShape), typeof(TransformedShape)]  = lineAlgorithm;
            this[typeof(LineShape), typeof(CompositeShape)]    = lineAlgorithm;

            this[typeof(RayShape), typeof(RayShape)]          = noAlgo;
            this[typeof(RayShape), typeof(LineSegmentShape)]  = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(TriangleShape)]     = rayTriangleAlgorithm;
            this[typeof(RayShape), typeof(RectangleShape)]    = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(BoxShape)]          = rayBoxAlgorithm;
            this[typeof(RayShape), typeof(ConvexShape)]       = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(ScaledConvexShape)] = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(CircleShape)]       = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(SphereShape)]       = raySphereAlgorithm;
            this[typeof(RayShape), typeof(CapsuleShape)]      = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(ConeShape)]         = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(CylinderShape)]     = rayConvexAlgorithm;
            this[typeof(RayShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(RayShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(RayShape), typeof(PlaneShape)]        = planeRayAlgorithm;
            this[typeof(RayShape), typeof(HeightField)]       = rayHeightFieldAlgorithm;
            this[typeof(RayShape), typeof(TriangleMeshShape)] = rayTriangleMeshAlgorithm;
            this[typeof(RayShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(RayShape), typeof(CompositeShape)]    = rayCompositeAlgorithm;

            this[typeof(LineSegmentShape), typeof(LineSegmentShape)]  = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(TriangleShape)]     = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(RectangleShape)]    = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(BoxShape)]          = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(ConvexShape)]       = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(ScaledConvexShape)] = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(SphereShape)]       = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(LineSegmentShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(LineSegmentShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(LineSegmentShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(LineSegmentShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(LineSegmentShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(LineSegmentShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(LineSegmentShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(TriangleShape), typeof(TriangleShape)]     = gjkTriTriAlgorithm;
            this[typeof(TriangleShape), typeof(RectangleShape)]    = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(BoxShape)]          = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(ConvexShape)]       = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(ScaledConvexShape)] = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(SphereShape)]       = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(TriangleShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(TriangleShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(TriangleShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(TriangleShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(TriangleShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(TriangleShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(TriangleShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(RectangleShape), typeof(RectangleShape)]    = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(BoxShape)]          = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(ConvexShape)]       = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(ScaledConvexShape)] = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(SphereShape)]       = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(RectangleShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(RectangleShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(RectangleShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(RectangleShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(RectangleShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(RectangleShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(RectangleShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(BoxShape), typeof(BoxShape)]          = gjkBoxAlgorithm;
            this[typeof(BoxShape), typeof(ConvexShape)]       = gjkMprAlgorithm;
            this[typeof(BoxShape), typeof(ScaledConvexShape)] = gjkMprAlgorithm;
            this[typeof(BoxShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(BoxShape), typeof(SphereShape)]       = boxSphereAlgorithm;
            this[typeof(BoxShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(BoxShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(BoxShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(BoxShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(BoxShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(BoxShape), typeof(PlaneShape)]        = planeBoxAlgorithm;
            this[typeof(BoxShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(BoxShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(BoxShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(BoxShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(ConvexShape), typeof(ConvexShape)]       = gjkMprAlgorithm;
            this[typeof(ConvexShape), typeof(ScaledConvexShape)] = gjkMprAlgorithm;
            this[typeof(ConvexShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(ConvexShape), typeof(SphereShape)]       = gjkMprAlgorithm;
            this[typeof(ConvexShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(ConvexShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(ConvexShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(ConvexShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(ConvexShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(ConvexShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(ConvexShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(ConvexShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(ConvexShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(ConvexShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(ScaledConvexShape), typeof(ScaledConvexShape)] = gjkMprAlgorithm;
            this[typeof(ScaledConvexShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(ScaledConvexShape), typeof(SphereShape)]       = gjkMprAlgorithm;
            this[typeof(ScaledConvexShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(ScaledConvexShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(ScaledConvexShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(ScaledConvexShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(ScaledConvexShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(ScaledConvexShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(ScaledConvexShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(ScaledConvexShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(ScaledConvexShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(ScaledConvexShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(CircleShape), typeof(CircleShape)]       = gjkMprAlgorithm;
            this[typeof(CircleShape), typeof(SphereShape)]       = gjkMprAlgorithm;
            this[typeof(CircleShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(CircleShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(CircleShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(CircleShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(CircleShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(CircleShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(CircleShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(CircleShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(CircleShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(CircleShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(SphereShape), typeof(SphereShape)]       = sphereSphereAlgorithm;
            this[typeof(SphereShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(SphereShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(SphereShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(SphereShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(SphereShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(SphereShape), typeof(PlaneShape)]        = planeSphereAlgorithm;
            this[typeof(SphereShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(SphereShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(SphereShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(SphereShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(CapsuleShape), typeof(CapsuleShape)]      = gjkMprAlgorithm;
            this[typeof(CapsuleShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(CapsuleShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(CapsuleShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(CapsuleShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(CapsuleShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(CapsuleShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(CapsuleShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(CapsuleShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(CapsuleShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(ConeShape), typeof(ConeShape)]         = gjkMprAlgorithm;
            this[typeof(ConeShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(ConeShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(ConeShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(ConeShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(ConeShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(ConeShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(ConeShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(ConeShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(CylinderShape), typeof(CylinderShape)]     = gjkMprAlgorithm;
            this[typeof(CylinderShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(CylinderShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(CylinderShape), typeof(PlaneShape)]        = planeConvexAlgorithm;
            this[typeof(CylinderShape), typeof(HeightField)]       = heightFieldAlgorithm;
            this[typeof(CylinderShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(CylinderShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(CylinderShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(EmptyShape), typeof(EmptyShape)]        = noAlgo;
            this[typeof(EmptyShape), typeof(InfiniteShape)]     = noAlgo; // No collision between Empty and Infinite.
            this[typeof(EmptyShape), typeof(PlaneShape)]        = noAlgo;
            this[typeof(EmptyShape), typeof(HeightField)]       = noAlgo;
            this[typeof(EmptyShape), typeof(TriangleMeshShape)] = noAlgo;
            this[typeof(EmptyShape), typeof(TransformedShape)]  = noAlgo;
            this[typeof(EmptyShape), typeof(CompositeShape)]    = noAlgo;

            this[typeof(InfiniteShape), typeof(InfiniteShape)]     = infiniteAlgo;
            this[typeof(InfiniteShape), typeof(PlaneShape)]        = infiniteAlgo;
            this[typeof(InfiniteShape), typeof(HeightField)]       = infiniteAlgo;
            this[typeof(InfiniteShape), typeof(TriangleMeshShape)] = infiniteAlgo;
            this[typeof(InfiniteShape), typeof(TransformedShape)]  = infiniteAlgo;
            this[typeof(InfiniteShape), typeof(CompositeShape)]    = infiniteAlgo;

            this[typeof(PlaneShape), typeof(PlaneShape)]        = noAlgo;
            this[typeof(PlaneShape), typeof(HeightField)]       = noAlgo;
            this[typeof(PlaneShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(PlaneShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(PlaneShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(HeightField), typeof(HeightField)] = noAlgo;
            // We could also call triangleMeshAlgorithm. But since HeightField has usually larger parts it
            // is better to call the heightFieldAlgorithm. The heightFieldAlgorithm will cull all but a
            // few height field cells very quickly.
            this[typeof(HeightField), typeof(TriangleMeshShape)] = heightFieldAlgorithm;
            this[typeof(HeightField), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            // Same as for triangle meshes: Call height field algorithm first.
            this[typeof(HeightField), typeof(CompositeShape)] = heightFieldAlgorithm;

            this[typeof(TriangleMeshShape), typeof(TriangleMeshShape)] = triangleMeshAlgorithm;
            this[typeof(TriangleMeshShape), typeof(TransformedShape)]  = transformedShapeAlgorithm;
            this[typeof(TriangleMeshShape), typeof(CompositeShape)]    = compositeAlgorithm;

            this[typeof(TransformedShape), typeof(TransformedShape)] = transformedShapeAlgorithm;
            this[typeof(TransformedShape), typeof(CompositeShape)]   = transformedShapeAlgorithm;

            this[typeof(CompositeShape), typeof(CompositeShape)] = compositeAlgorithm;
        }
Exemplo n.º 8
0
        public void TestCoplanar()
        {
            var tta = new TriangleTriangleAlgorithm(new CollisionDetection());
              var gjk = new Gjk(new CollisionDetection());

              int numberOfContacts = 0;
              int numberOfTests = 1000;
              RandomHelper.Random = new Random(1234567);
              for (int i = 0; i < numberOfTests; i++)
              {
            // Create two triangles.
            var tA = new Triangle();
            tA.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tA.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tA.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

            var tB = new Triangle();
            tB.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tB.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tB.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

            var ttTest = GeometryHelper.HaveContact(tA, tB);

            if (ttTest)
              numberOfContacts++;

            var coA = new CollisionObject(new GeometricObject(new TriangleShape(tA)));
            var coB = new CollisionObject(new GeometricObject(new TriangleShape(tB)));

            var csTta = tta.GetContacts(coA, coB);
            var csGjk = gjk.GetClosestPoints(coA, coB);

            if (csTta.HaveContact != csGjk.HaveContact)
              Trace.WriteLine("Test failed: " + i + " GJK: " + csGjk.HaveContact + " TTA: " + csTta);

            Assert.AreEqual(ttTest, csGjk.HaveContact);
            Assert.AreEqual(ttTest, csTta.HaveContact);
              }

              //Trace.WriteLine("% hits:" + 100f * numberOfContacts / numberOfTests);
        }
Exemplo n.º 9
0
        public void TestCoplanarTriangles2()
        {
            var mpr = new MinkowskiPortalRefinement(new CollisionDetection());
            var gjk = new Gjk(new CollisionDetection());

            RandomHelper.Random = new Random(1234567);

            for (int i = 0; i < 100000; i++)
            {
                // Create two triangles in a plane.
                var tA = new Triangle();
                tA.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tA.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tA.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

                var tB = new Triangle();
                tB.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tB.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
                tB.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

                var coA = new CollisionObject(new GeometricObject(new TriangleShape(tA)));
                var coB = new CollisionObject(new GeometricObject(new TriangleShape(tB)));

                // Test if 2D triangles have contact
                bool haveContact = false;
                // Test if vertices are inside the other triangle.
                for (int j = 0; j < 2 && haveContact == false; j++)
                {
                    var t0 = tA;
                    var t1 = tB;
                    if (j == 1)
                    {
                        MathHelper.Swap(ref t0, ref t1);
                    }

                    for (int k = 0; k < 3 && haveContact == false; k++)
                    {
                        float u, v, w;
                        GeometryHelper.GetClosestPoint(t0, t1[k], out u, out v, out w);
                        if (Vector3F.AreNumericallyEqual(t0.Vertex0 * u + t0.Vertex1 * v + t0.Vertex2 * w, t1[k]))
                        {
                            haveContact = true;
                        }
                    }
                }
                // Test line segments.
                for (int j = 0; j < 3 && haveContact == false; j++)
                {
                    for (int k = 0; k < 3 && haveContact == false; k++)
                    {
                        var      lsA = new LineSegment(tA[j], tA[(j + 1) % 3]);
                        var      lsB = new LineSegment(tB[k], tB[(k + 1) % 3]);
                        Vector3F pA, pB;
                        haveContact = GeometryHelper.GetClosestPoints(lsA, lsB, out pA, out pB);
                    }
                }

                var csMpr = mpr.GetContacts(coA, coB);
                var csGjk = gjk.GetClosestPoints(coA, coB);

                // Test false positives.
                if (csMpr.HaveContact && !csGjk.HaveContact)
                {
                    Assert.Fail("False positive: MPR reports contact, GJK reports no contact");
                }
                if (csMpr.HaveContact && !haveContact)
                {
                    Assert.Fail("False positive: MPR reports contact, manual test reports no contact");
                }

                // Test again using boolean query.
                bool haveMprContact = mpr.HaveContact(coA, coB);
                csGjk = gjk.GetClosestPoints(coA, coB);
                if (haveMprContact && !csGjk.HaveContact)
                {
                    Assert.Fail("False positive: MPR reports contact, GJK reports no contact");
                }
                if (haveMprContact && !haveContact)
                {
                    Assert.Fail("False positive: MPR reports contact, manual test reports no contact");
                }

                //if (csMpr.HaveContact != haveContact)
                //  Debugger.Break();

                //Assert.AreEqual(csMpr.HaveContact, haveContact);

                //if (csGjk.HaveContact != csMpr.HaveContact)
                //  Debugger.Break();
                //Assert.AreEqual(csGjk.HaveContact, csMpr.HaveContact);
            }
        }
Exemplo n.º 10
0
        public void GjkBatteryTest()
        {
            Gjk gjk = new Gjk();

            const int iterations = 10000;

            //Point to point test
            for (int i = 0; i < iterations; ++i)
            {
                gjk.Reset();

                Vector3 point1   = Utilities.GenerateVector3();
                Vector3 point2   = Utilities.GenerateVector3();
                float   expected = Vector3.Distance(point1, point2);

                float actual = gjk.GetMinimumDistance(v =>
                {
                    return(point1 - point2);
                });

                Utilities.AreEqual(expected, actual);
            }

            //Sphere to sphere test
            for (int i = 0; i < iterations; ++i)
            {
                gjk.Reset();

                BoundingSphere shape1   = new BoundingSphere(Utilities.GenerateVector3(), Utilities.GenerateFloat());
                BoundingSphere shape2   = new BoundingSphere(Utilities.GenerateVector3(), Utilities.GenerateFloat());
                float          expected = Collision.DistanceSphereSphere(ref shape1, ref shape2);

                if (Collision.SphereIntersectsSphere(ref shape1, ref shape2))
                {
                    i--;
                    continue;
                }

                float actual = gjk.GetMinimumDistance(v =>
                {
                    Vector3 a = shape1.SupportMapping(v);
                    Vector3 b = shape2.SupportMapping(-v);

                    return(a - b);
                });

                Utilities.AreEqual(expected, actual);
            }

            //Box to box test
            for (int i = 0; i < iterations; ++i)
            {
                gjk.Reset();

                BoundingBox shape1   = new BoundingBox(Utilities.GenerateVector3(), Utilities.GenerateVector3());
                BoundingBox shape2   = new BoundingBox(Utilities.GenerateVector3(), Utilities.GenerateVector3());
                float       expected = Collision.DistanceBoxBox(ref shape1, ref shape2);

                if (Collision.BoxIntersectsBox(ref shape1, ref shape2))
                {
                    i--;
                    continue;
                }

                float actual = gjk.GetMinimumDistance(v =>
                {
                    Vector3 a = shape1.SupportMapping(v);
                    Vector3 b = shape2.SupportMapping(-v);

                    return(a - b);
                });

                Utilities.AreEqual(expected, actual);
            }
        }
Exemplo n.º 11
0
 public Epa(Gjk gjk)
 {
     this._gjk = gjk;
 }
Exemplo n.º 12
0
        public void TestTriangles()
        {
            var mpr = new MinkowskiPortalRefinement(new CollisionDetection());
              var gjk = new Gjk(new CollisionDetection());

              RandomHelper.Random = new Random(1234567);

              for (int i = 0; i < 100000; i++)
              {
            // Create two triangles in a plane.
            var tA = new Triangle();
            tA.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
            tA.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
            tA.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));

            var tB = new Triangle();
            tB.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
            tB.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));
            tB.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1), RandomHelper.Random.NextFloat(-1, 1));

            var coA = new CollisionObject(new GeometricObject(new TriangleShape(tA)));
            var coB = new CollisionObject(new GeometricObject(new TriangleShape(tB)));

            var csMpr = mpr.GetContacts(coA, coB);
            var csGjk = gjk.GetClosestPoints(coA, coB);

            // Test again using boolean query.
            bool haveMprContact = mpr.HaveContact(coA, coB);

            // The exceptions are tested cases - all extreme shallow surface contacts.
            if (i != 28487 && i != 47846 && i != 97305)
            {
              Assert.AreEqual(csGjk.HaveContact, haveMprContact);
              Assert.AreEqual(csGjk.HaveContact, csMpr.HaveContact);
            }
              }
        }
Exemplo n.º 13
0
        public void TestCoplanarTriangles2()
        {
            var mpr = new MinkowskiPortalRefinement(new CollisionDetection());
              var gjk = new Gjk(new CollisionDetection());

              RandomHelper.Random = new Random(1234567);

              for (int i = 0; i < 100000; i++)
              {
            // Create two triangles in a plane.
            var tA = new Triangle();
            tA.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tA.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tA.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

            var tB = new Triangle();
            tB.Vertex0 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tB.Vertex1 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));
            tB.Vertex2 = new Vector3F(RandomHelper.Random.NextFloat(-100, 100), -290, RandomHelper.Random.NextFloat(-100, 100));

            var coA = new CollisionObject(new GeometricObject(new TriangleShape(tA)));
            var coB = new CollisionObject(new GeometricObject(new TriangleShape(tB)));

            // Test if 2D triangles have contact
            bool haveContact = false;
            // Test if vertices are inside the other triangle.
            for (int j = 0; j < 2 && haveContact == false; j++)
            {
              var t0 = tA;
              var t1 = tB;
              if (j == 1)
            MathHelper.Swap(ref t0, ref t1);

              for (int k = 0; k < 3 && haveContact == false; k++)
              {
            float u, v, w;
            GeometryHelper.GetClosestPoint(t0, t1[k], out u, out v, out w);
            if (Vector3F.AreNumericallyEqual(t0.Vertex0 * u + t0.Vertex1 * v + t0.Vertex2 * w, t1[k]))
              haveContact = true;
              }
            }
            // Test line segments.
            for (int j = 0; j < 3 && haveContact == false; j++)
            {
              for (int k = 0; k < 3 && haveContact == false; k++)
              {
            var lsA = new LineSegment(tA[j], tA[(j + 1) % 3]);
            var lsB = new LineSegment(tB[k], tB[(k + 1) % 3]);
            Vector3F pA, pB;
            haveContact = GeometryHelper.GetClosestPoints(lsA, lsB, out pA, out pB);
              }
            }

            var csMpr = mpr.GetContacts(coA, coB);
            var csGjk = gjk.GetClosestPoints(coA, coB);

            // Test false positives.
            if (csMpr.HaveContact && !csGjk.HaveContact)
              Assert.Fail("False positive: MPR reports contact, GJK reports no contact");
            if (csMpr.HaveContact && !haveContact)
              Assert.Fail("False positive: MPR reports contact, manual test reports no contact");

            // Test again using boolean query.
            bool haveMprContact = mpr.HaveContact(coA, coB);
            csGjk = gjk.GetClosestPoints(coA, coB);
            if (haveMprContact && !csGjk.HaveContact)
              Assert.Fail("False positive: MPR reports contact, GJK reports no contact");
            if (haveMprContact && !haveContact)
              Assert.Fail("False positive: MPR reports contact, manual test reports no contact");

            //if (csMpr.HaveContact != haveContact)
            //  Debugger.Break();

            //Assert.AreEqual(csMpr.HaveContact, haveContact);

            //if (csGjk.HaveContact != csMpr.HaveContact)
            //  Debugger.Break();
            //Assert.AreEqual(csGjk.HaveContact, csMpr.HaveContact);
              }
        }