コード例 #1
0
ファイル: Game.cs プロジェクト: Guardian820/OpenMOBA
        internal static TerrainStaticMetadata Twitch(this TerrainStaticMetadata tsm)
        {
            var offsetX = -(tsm.LocalBoundary.X + tsm.LocalBoundary.Width / 2);
            var offsetY = -(tsm.LocalBoundary.Y + tsm.LocalBoundary.Height / 2);

            var scaleX = 2 * DesiredSectorExtents / (double)tsm.LocalBoundary.Width;
            var scaleY = 2 * DesiredSectorExtents / (double)tsm.LocalBoundary.Height;

            void TransformPolygonInPlace(Polygon2 poly)
            {
                for (var i = 0; i < poly.Points.Count; i++)
                {
                    var p = poly.Points[i];
                    var x = (int)((p.X + offsetX) * scaleX);
                    var y = (int)((p.Y + offsetY) * scaleY);
                    poly.Points[i] = new IntVector2(x, y);
                }
            }

            tsm.LocalBoundary.Offset(offsetX, offsetY);

            tsm.LocalBoundary = new Rectangle(
                (int)(tsm.LocalBoundary.X * scaleX), (int)(tsm.LocalBoundary.Y * scaleY),
                (int)(tsm.LocalBoundary.Width * scaleX), (int)(tsm.LocalBoundary.Height * scaleY));

            foreach (var contour in tsm.LocalIncludedContours)
            {
                TransformPolygonInPlace(contour);
            }
            foreach (var contour in tsm.LocalExcludedContours)
            {
                TransformPolygonInPlace(contour);
            }
            return(tsm);
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: Guardian820/OpenMOBA
        public static void Main(string[] args)
        {
            var sectorMetadataPresets = SectorMetadataPresets.HashCircle2;
            var terrainStaticMetadata = new TerrainStaticMetadata {
                LocalBoundary         = sectorMetadataPresets.LocalBoundary,
                LocalIncludedContours = sectorMetadataPresets.LocalIncludedContours,
                LocalExcludedContours = sectorMetadataPresets.LocalExcludedContours
            };

            var(localGeometryView, landPolyNode, crossoverPointManager) = BenchmarkAddCrossoverPoints(terrainStaticMetadata);
            var canvas = host.CreateAndAddCanvas(0);

            canvas.Transform = Matrix4x4.CreateScale(1000 / 60000.0f) * Matrix4x4.CreateTranslation(500, 500, 0);
            canvas.DrawPolyNode((PolyTree)landPolyNode.Parent);
            canvas.DrawVisibilityGraph(landPolyNode.ComputeVisibilityGraph());
            canvas.DrawLineList(landPolyNode.FindContourAndChildHoleBarriers(), StrokeStyle.BlackHairLineSolid);
            canvas.DrawPoints(crossoverPointManager.CrossoverPoints, StrokeStyle.RedThick5Solid);

            // var a = landPolyNode.FindAggregateContourCrossoverWaypoints()[6];
            // var b = landPolyNode.FindAggregateContourCrossoverWaypoints()[13];
            // var q = new IntLineSegment2(a, b);
            // canvas.DrawPoint(a, StrokeStyle.RedThick5Solid);
            // canvas.DrawPoint(b, StrokeStyle.RedThick5Solid);
            // var bvh = landPolyNode.FindContourAndChildHoleBarriersBvh();
            // canvas.DrawBvh(bvh);
            // foreach (var (i, val) in bvh.BoundingBoxes.Enumerate()) {
            //    if (val.Intersects(q)) Console.WriteLine(i + " " + val);
            // }
            // var intersects = bvh.Intersects(q);
            // canvas.DrawLine(a, b, intersects ? StrokeStyle.RedHairLineSolid : StrokeStyle.LimeHairLineSolid);

            PolyNodeCrossoverPointManager.DumpPerformanceCounters();

            while (true)
            {
                const int ntrials = 10;
                var       sw      = new Stopwatch();
                sw.Start();
                for (var i = 0; i < ntrials; i++)
                {
                    BenchmarkAddCrossoverPoints(terrainStaticMetadata);
                }
                Console.WriteLine($"{ntrials} trials in {sw.ElapsedMilliseconds} ms");
            }
        }
コード例 #3
0
        private LocalGeometryView BuildLgv(TerrainStaticMetadata mapStaticMetadata, double holeDilationRadius, params IHoleStaticMetadata[] holeMetadatas)
        {
            var store          = new SectorGraphDescriptionStore();
            var terrainService = new TerrainService(store, new TerrainSnapshotCompiler(store));

            var sector = terrainService.CreateSectorNodeDescription(mapStaticMetadata);

            sector.WorldTransform = Matrix4x4.Multiply(Matrix4x4.CreateScale(1), Matrix4x4.CreateTranslation(-500, -500, 0));
            terrainService.AddSectorNodeDescription(sector);

            var left2 = new IntLineSegment2(new IntVector2(0, 600), new IntVector2(0, 800));

            terrainService.AddSectorEdgeDescription(PortalSectorEdgeDescription.Build(sector, sector, left2, left2));

            foreach (var holeMetadata in holeMetadatas)
            {
                var terrainHole = terrainService.CreateHoleDescription(holeMetadata);
                terrainService.AddTemporaryHoleDescription(terrainHole);
            }

            var terrainOverlayNetwork = terrainService.CompileSnapshot().OverlayNetworkManager.CompileTerrainOverlayNetwork(holeDilationRadius);

            return(terrainOverlayNetwork.TerrainNodes.First().LocalGeometryView);
        }
コード例 #4
0
        public static void Main(string[] args)
        {
            Environment.CurrentDirectory = @"V:\my-repositories\miyu\derp\RoboticsMotionPlan\Assets";
            //MapPolygonizerForm.Run(@"C:\Users\Warty\occ.txt", "sieg_floor3.poly", "sieg_plan.plan");
            //MapPolygonizerForm.Run("gates.png", "gates.poly", "gates.plan");
            MapPolygonizerForm.Run("de_dust2.png", "de_dust2.poly", "de_dust2.plan");
            //         MapPolygonizerForm.Run("gates.png", "gates.poly");

            var(landPolys, holePolys) = FileLoader.LoadMap("gates.poly");
            var tsm = new TerrainStaticMetadata {
                LocalBoundary         = new Rectangle(0, 0, MapWidth, MapHeight),
                LocalIncludedContours = landPolys.Map(p => new Polygon2(p, true)),
                LocalExcludedContours = holePolys.Map(p => new Polygon2(p.Select(x => x).Reverse().ToList(), true)),
            };

            var start         = FileLoader.LoadPoints("start.csv").First();
            var goodWaypoints = FileLoader.LoadPoints("good_waypoints.csv");
            var badWaypoints  = FileLoader.LoadPoints("bad_waypoints.csv");
            var holeMetadata  = new SphereHoleStaticMetadata {
                Radius = 13
            };

            var gf = new GameFactory();

            gf.GameCreated += (s, game) => {
                var debugger = GameDebugger.AttachToWithSoftwareRendering(game);
                game.TerrainService.Clear();
                var snd = game.TerrainService.CreateSectorNodeDescription(tsm);
                game.TerrainService.AddSectorNodeDescription(snd);

                foreach (var hsm in badWaypoints)
                {
                    var hd = game.TerrainService.CreateHoleDescription(holeMetadata);
                    hd.WorldTransform = Matrix4x4.CreateTranslation(hsm.X, hsm.Y, 0);
                    game.TerrainService.AddTemporaryHoleDescription(hd);
                }

                debugger.RenderHook += (_, canvas) => {
                    var snapshot = game.TerrainService.SnapshotCompiler.CompileSnapshot();

                    // uneroded network
                    var unerodedOverlayNetwork = snapshot.OverlayNetworkManager.CompileTerrainOverlayNetwork(0);
                    Trace.Assert(unerodedOverlayNetwork.TerrainNodes.Count == 1);
                    var unerodedTerrainNode = unerodedOverlayNetwork.TerrainNodes.First();

                    // eroded network
                    var overlayNetwork = snapshot.OverlayNetworkManager.CompileTerrainOverlayNetwork(15); //1 unit = 0.02m
                    Trace.Assert(overlayNetwork.TerrainNodes.Count == 1);
                    var terrainNode = overlayNetwork.TerrainNodes.First();

                    // draw uneroded map
                    canvas.DrawPolyNode(unerodedTerrainNode.LocalGeometryView.PunchedLand, StrokeStyle.BlackHairLineSolid, StrokeStyle.RedHairLineSolid);

                    // draw eroded map
                    canvas.DrawPolyNode(terrainNode.LocalGeometryView.PunchedLand, new StrokeStyle(Color.Gray), new StrokeStyle(Color.DarkRed));

                    // draw waypoints
                    canvas.DrawPoints(goodWaypoints, new StrokeStyle(Color.Blue, 25));
                    canvas.DrawPoints(badWaypoints, new StrokeStyle(Color.Red, 25));

                    void DrawThetaedPoint(DoubleVector2 p, double theta, bool highlight)
                    {
                        canvas.DrawPoint(p, highlight ? StrokeStyle.OrangeThick35Solid : StrokeStyle.BlackThick25Solid);
                        canvas.DrawLine(
                            p,
                            p + DoubleVector2.FromRadiusAngle(50, theta),
                            new StrokeStyle(Color.Magenta, 3));
                    }

                    var emittedPoints = new List <(DoubleVector2, double, bool)>();

                    // find big waypoints
                    var bigWaypoints = new List <(DoubleVector2, bool)>();
                    for (var i = 0; i < goodWaypoints.Count; i++)
                    {
                        var from = i == 0 ? start : goodWaypoints[i - 1];
                        var to   = goodWaypoints[i];

                        var ok = game.PathfinderCalculator.TryFindPath(terrainNode, from, terrainNode, to, out var roadmap);
                        Trace.Assert(ok);
                        var actions   = roadmap.Plan.OfType <MotionRoadmapWalkAction>().ToArray();
                        var waypoints = new[] { actions[0].Source.ToDoubleVector2() }
                        .Concat(actions.Map(a => a.Destination.ToDoubleVector2())).ToArray();
                        bigWaypoints.AddRange(waypoints.Map((w, ind) => (w, ind == waypoints.Length - 1)));
                    }

                    var thetas = bigWaypoints.Zip(bigWaypoints.Skip(1), (a, b) => Math.Atan2(b.Item1.Y - a.Item1.Y, b.Item1.X - a.Item1.X))
                                 .ToArray();
                    var chamferSpacing          = 10;
                    var chamferSpacingThreshold = 100;
                    for (var i = 0; i < thetas.Length; i++)
                    {
                        var(src, srcIsRoi) = bigWaypoints[i];
                        var(dst, dstIsRoi) = bigWaypoints[i + 1];
                        var srcToDstTheta = thetas[i];

                        // if close or last goal, don't chamfer
                        if (i + 1 == thetas.Length)
                        {
                            emittedPoints.Add((dst, srcToDstTheta, dstIsRoi));
                            continue;
                        }

                        var dstToFollowingTheta = thetas[i + 1];
                        if (src.To(dst).Norm2D() < chamferSpacingThreshold)
                        {
                            emittedPoints.Add((dst, dstToFollowingTheta, dstIsRoi));
                            continue;
                        }
                        var chamfer1 = dst - DoubleVector2.FromRadiusAngle(chamferSpacing, dstToFollowingTheta) - DoubleVector2.FromRadiusAngle(chamferSpacing, srcToDstTheta);
                        var chamfer2 = dst + DoubleVector2.FromRadiusAngle(chamferSpacing, dstToFollowingTheta) + 2 * DoubleVector2.FromRadiusAngle(chamferSpacing, srcToDstTheta);
                        emittedPoints.Add((chamfer1, srcToDstTheta, false));
                        if (dstIsRoi)
                        {
                            emittedPoints.Add((dst, srcToDstTheta, true));
                        }
                        emittedPoints.Add((chamfer2, dstToFollowingTheta, false));
                    }

                    for (var i = 0; i < emittedPoints.Count - 1; i++)
                    {
                        canvas.DrawLine(emittedPoints[i].Item1, emittedPoints[i + 1].Item1, StrokeStyle.CyanThick3Solid);
                    }

                    void PrintPoint(DoubleVector2 p) => Console.Write("(" + p.X.ToString("F3") + ", " + (MapHeight - p.Y).ToString("F3") + ")");

                    Console.WriteLine("[");
                    for (var i = 0; i < emittedPoints.Count; i++)
                    {
                        var(p, theta, isRoi) = emittedPoints[i];
                        DrawThetaedPoint(p, theta, isRoi);
                        Console.Write("(");
                        PrintPoint(p);
                        Console.Write(", ");
                        Console.Write((-theta).ToString("F3"));
                        Console.Write(", ");
                        Console.Write(isRoi ? "True" : "False");
                        Console.Write(")");
                        if (i + 1 != emittedPoints.Count)
                        {
                            Console.Write(", ");
                        }
                        Console.WriteLine();
                    }
                    Console.WriteLine("]");
                };
            };
            gf.Create().Run();
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: Guardian820/OpenMOBA
        private static (LocalGeometryView, PolyNode, PolyNodeCrossoverPointManager) BenchmarkAddCrossoverPoints(TerrainStaticMetadata terrainStaticMetadata)
        {
            /*
             * var left1 = new IntLineSegment2(new IntVector2(-30000, -18000), new IntVector2(-30000, -6000));
             * var left2 = new IntLineSegment2(new IntVector2(-30000, 6000), new IntVector2(-30000, 18000));
             * var right1 = new IntLineSegment2(new IntVector2(30000, -18000), new IntVector2(30000, -6000));
             * var right2 = new IntLineSegment2(new IntVector2(30000, 6000), new IntVector2(30000, 18000));*/

            var crossoverSegments = new[] {