bool collidePolygonCircle(PolygonShape polygon, ref FSTransform polyTransform, CircleShape circle, ref FSTransform circleTransform, out FSCollisionResult result)
        {
            result = new FSCollisionResult();
            Collision.collidePolygonAndCircle(ref _manifold, polygon, ref polyTransform, circle, ref circleTransform);
            if (_manifold.pointCount > 0)
            {
                FixedArray2 <Vector2> points;
                ContactSolver.WorldManifold.initialize(ref _manifold, ref polyTransform, polygon.radius, ref circleTransform, circle.radius, out result.normal, out points);

                //var circleInPolySpace = polygonFixture.Body.GetLocalPoint( circleFixture.Body.Position );
                var circleInPolySpace = MathUtils.mulT(ref polyTransform, circleTransform.p);
                var value1            = circleInPolySpace - _manifold.localPoint;
                var value2            = _manifold.localNormal;
                var separation        = circle.radius - (value1.X * value2.X + value1.Y * value2.Y);

                if (separation <= 0)
                {
                    return(false);
                }

                result.point = points[0] * FSConvert.simToDisplay;
                result.minimumTranslationVector = result.normal * separation;

#if DEBUG_FSCOLLISIONS
                Debug.drawPixel(result.point, 2, Color.Red, 0.2f);
                Debug.drawLine(result.point, result.point + result.normal * 20, Color.Yellow, 0.2f);
#endif

                return(true);
            }
            return(false);
        }
        private bool collideWithHole(Fixture fixtureA, ref FSTransform transformA, Fixture fixtureB, ref FSTransform transformB, out FSCollisionResult result)
        {
            result         = new FSCollisionResult();
            result.fixture = fixtureB;

            if (!ContactManager.shouldCollide(fixtureA, fixtureB))
            {
                return(false);
            }

            if (fixtureA.body.world.contactManager.onContactFilter != null && !fixtureA.body.world.contactManager.onContactFilter(fixtureA, fixtureB))
            {
                return(false);
            }

            return(collidePolygonCircle(fixtureB.shape as PolygonShape, ref transformB, fixtureA.shape as CircleShape, ref transformA, out result));
        }
        private bool colliderWithHole(Fixture self, ref Vector2 motion, out FSCollisionResult result)
        {
            result  = new FSCollisionResult();
            motion *= FSConvert.displayToSim;
            AABB        aabb;
            FSTransform xf;
            var         didCollide = false;

            self.body.getTransform(out xf);
            xf.p += motion;

            self.shape.computeAABB(out aabb, ref xf, 0);
            var neighbors = ListPool <Fixture> .obtain();

            self.body.world.queryAABB(ref aabb, neighbors);

            if (neighbors.Count > 1)
            {
                for (var i = 0; i < neighbors.Count; i++)
                {
                    if (neighbors[i].fixtureId == self.fixtureId)
                    {
                        continue;
                    }
                    if (neighbors[i].collisionCategories != CollisionSetting.tiledHoleCategory)
                    {
                        continue;
                    }

                    if (collideWithHole(self, ref motion, neighbors[i], out result))
                    {
                        xf.p += result.minimumTranslationVector;
                    }
                }
            }

            ListPool <Fixture> .free(neighbors);

            motion *= FSConvert.simToDisplay;

            return(didCollide);
        }
        private bool collideWithHole(Fixture fixtureA, ref Vector2 motion, Fixture fixtureB, out FSCollisionResult result)
        {
            FSTransform transformA;

            fixtureA.body.getTransform(out transformA);
            transformA.p += motion;

            FSTransform transformB;

            fixtureB.body.getTransform(out transformB);

            if (collideWithHole(fixtureA, ref transformA, fixtureB, ref transformB, out result))
            {
                motion += result.minimumTranslationVector;
                return(true);
            }
            return(false);
        }