예제 #1
0
        private void GenerateTerrain(int gx, int gy)
        {
            FP ax = gx * CellSize;
            FP ay = gy * CellSize;

            List <Vertices> polys = MarchingSquares.DetectSquares(new AABB(new FPVector2(ax, ay), new FPVector2(ax + CellSize, ay + CellSize)), SubCellSize, SubCellSize, _terrainMap, Iterations, true);

            if (polys.Count == 0)
            {
                return;
            }

            _bodyMap[gx, gy] = new List <Body>();

            // create the scale vector
            FPVector2 scale = new FPVector2(1f / PointsPerUnit, 1f / -PointsPerUnit);

            // create physics object for this grid cell
            foreach (Vertices item in polys)
            {
                // does this need to be negative?
                item.Scale(ref scale);
                item.Translate(ref _topLeft);
                Vertices simplified = SimplifyTools.CollinearSimplify(item, FP.Zero);

                List <Vertices> decompPolys = Triangulate.ConvexPartition(simplified, Decomposer, true, FP.EN3);

                foreach (Vertices poly in decompPolys)
                {
                    if (poly.Count > 2)
                    {
                        _bodyMap[gx, gy].Add(BodyFactory.CreatePolygon(World, poly, 1, null));
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// This is a high-level function to cuts fixtures inside the given world, using the start and end points.
        /// Note: We don't support cutting when the start or end is inside a shape.
        /// </summary>
        /// <param name="world">The world.</param>
        /// <param name="start">The startpoint.</param>
        /// <param name="end">The endpoint.</param>
        /// <returns>True if the cut was performed.</returns>
        public static bool Cut(World world, FPVector2 start, FPVector2 end)
        {
            List <Fixture>   fixtures    = new List <Fixture>();
            List <FPVector2> entryPoints = new List <FPVector2>();
            List <FPVector2> exitPoints  = new List <FPVector2>();

            //We don't support cutting when the start or end is inside a shape.
            if (world.TestPoint(start) != null || world.TestPoint(end) != null)
            {
                return(false);
            }

            //Get the entry points
            world.RayCast((f, p, n, fr) =>
            {
                fixtures.Add(f);
                entryPoints.Add(p);
                return(1);
            }, start, end);

            //Reverse the ray to get the exitpoints
            world.RayCast((f, p, n, fr) =>
            {
                exitPoints.Add(p);
                return(1);
            }, end, start);

            //We only have a single point. We need at least 2
            if (entryPoints.Count + exitPoints.Count < 2)
            {
                return(false);
            }

            for (int i = 0; i < fixtures.Count; i++)
            {
                // can't cut circles or edges yet !
                if (fixtures[i].Shape.ShapeType != ShapeType.Polygon)
                {
                    continue;
                }

                if (fixtures[i].Body.BodyType != BodyType.Static)
                {
                    //Split the shape up into two shapes
                    Vertices first;
                    Vertices second;
                    SplitShape(fixtures[i], entryPoints[i], exitPoints[i], out first, out second);

                    //Delete the original shape and create two new. Retain the properties of the body.
                    if (first.CheckPolygon() == PolygonError.NoError)
                    {
                        Body firstFixture = BodyFactory.CreatePolygon(world, first, fixtures[i].Shape.Density, fixtures[i].Body.Position);
                        firstFixture.Rotation        = fixtures[i].Body.Rotation;
                        firstFixture.LinearVelocity  = fixtures[i].Body.LinearVelocity;
                        firstFixture.AngularVelocity = fixtures[i].Body.AngularVelocity;
                        firstFixture.BodyType        = BodyType.Dynamic;
                    }

                    if (second.CheckPolygon() == PolygonError.NoError)
                    {
                        Body secondFixture = BodyFactory.CreatePolygon(world, second, fixtures[i].Shape.Density, fixtures[i].Body.Position);
                        secondFixture.Rotation        = fixtures[i].Body.Rotation;
                        secondFixture.LinearVelocity  = fixtures[i].Body.LinearVelocity;
                        secondFixture.AngularVelocity = fixtures[i].Body.AngularVelocity;
                        secondFixture.BodyType        = BodyType.Dynamic;
                    }

                    world.RemoveBody(fixtures[i].Body);
                }
            }

            return(true);
        }