Beispiel #1
0
        private void FindNewSegments(Ets2NavigationRoute route, Ets2Point me)
        {
            if (route == null || route.Segments == null)
                return;
            var segs = new List<Ets2NavigationSegment>();

            var dstLimit = 1250;
            rescan:

            foreach (var seg in route.Segments)
            {
                var dstEntry = seg.Entry.Point.DistanceTo(me) < dstLimit;
                var dstExit = seg.Exit.Point.DistanceTo(me) < dstLimit;

                if (dstEntry || dstExit)
                    segs.Add(seg);
            }
            if (!segs.Any() && dstLimit == 1250)
            {
                dstLimit = 5000;
                goto rescan;
            }
            NearbySegments = segs;
        }
Beispiel #2
0
        public static int RenderMap(Rectangle clip, Graphics g, bool dedicated, ref float scale)
        {
            var ets2Tel = (Main.Data.Active == null)
                ? default(Ets2Telemetry)
                : ((Ets2DataMiner)Main.Data.Active).MyTelemetry;

            // Search the map
            var map = FrmMain.Ets2Map;

            g.FillRectangle(map.Loading ? Brushes.DarkOrange : Brushes.Black, clip);
            g.SmoothingMode = mapScale < 1000 ? SmoothingMode.AntiAlias : SmoothingMode.HighSpeed;
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            g.PixelOffsetMode = PixelOffsetMode.None;

            float tx = 0.0f;
            float ty = 0.0f;
            float baseScale = 0.0f;

            if (Main.Data.Active == null || (dedicated && locationOverride))
            {
                tx = location.X;
                ty = location.Y;
                baseScale = mapScale;
            }
            else
            {
                var d = GetLivePoint();
                tx = d.Item1.X;
                ty = d.Item1.Y;
                baseScale = d.Item2;
            }

            var totalX = 0.0f;
            var totalY = 0.0f;

            // Input scale value is max scale
            var maxScale = scale;
            if (baseScale > maxScale)
                baseScale = scale;
            scale = baseScale;

            if (clip.Width > clip.Height)
            {
                totalX = baseScale;
                totalY = (int)(baseScale * (float)clip.Height / clip.Width);
            }
            else
            {
                totalY = baseScale;
                totalX = (int)(baseScale * (float)clip.Width / clip.Height);
            }

            var startX = clip.X + tx - totalX;
            var endX = clip.X + tx + totalX;
            var startY = clip.Y + ty - totalY;
            var endY = clip.Y + ty + totalY;

            var scaleX = clip.Width / (endX - startX);
            var scaleY = clip.Height / (endY - startY);

            if (float.IsInfinity(scaleX) || float.IsNaN(scaleX))
                scaleX = clip.Width;
            if (float.IsInfinity(scaleY) || float.IsNaN(scaleY))
                scaleY = clip.Height;

            var nodesNearby =
                map.Nodes.Values.Where(
                    x => x.X >= startX - 1500 && x.X <= endX + 1500 && x.Z >= startY -1500 && x.Z <= endY + 1500);
            var itemsNearby = nodesNearby.SelectMany(x => x.GetItems()).Where(x => x.HideUI == false).ToList();

            var roads = itemsNearby.Where(x => x.Type == Ets2ItemType.Road);
            var prefabs = itemsNearby.Where(x => x.Type == Ets2ItemType.Prefab);

            var gpsPen = new Pen(Brushes.MediumPurple, 22*scaleX);
            var localPen = new Pen(Brushes.Orange, 7.5f * scaleX);
            var prefabLane = new Pen(Brushes.Yellow, 3 * scaleX);
            var expressPen = new Pen(Brushes.Yellow, 19 * scaleX);
            var highwayPen = new Pen(Brushes.Red, 22*scaleX);

            List<ulong> nodesPassed = new List<ulong>();
            List<List<PointF>> roadPoints = new List<List<PointF>>();
            var nodesToFollow = prefabs.SelectMany(x => x.NodesList.Values).Distinct();

            // Gather all prefabs, and issue a drawing command
            foreach (var node in nodesToFollow)
            {
                if (node == null)
                    continue;

                bool isHighway = false;
                bool isExpress = false;
                bool isLocal = false;

                // Nodes from prefab are always like:
                // Prefab = Forward
                // Road=backward
                var road = node.ForwardItem != null && node.ForwardItem.Type == Ets2ItemType.Prefab
                    ? node.BackwardItem
                    : node.ForwardItem;
                var roadStart = road;
                isHighway = road == null || road.RoadLook == null ? false : road.RoadLook.IsHighway;
                isExpress = road == null || road.RoadLook == null ? false : road.RoadLook.IsExpress;
                isLocal = road == null || road.RoadLook == null ? false : road.RoadLook.IsLocal;
                var fw = node.ForwardItem != null && node.ForwardItem.Type == Ets2ItemType.Road;

                if (road == null)
                {
                    // DEAD END
                    //Console.WriteLine("Dead-end from prefab..");
                    continue;
                }

                var roadChain = new List<Ets2Item>();

                // Start drawing at start road
                if (fw)
                {
                    do
                    {
                        roadChain.Add(road);
                        road = road.EndNode == null ? null : road.EndNode.ForwardItem;
                    } while (road != null && road.Type == Ets2ItemType.Road);
                }
                else
                {
                    do
                    {
                        roadChain.Add(road);
                        road = road.StartNode == null ? null : road.StartNode.BackwardItem;
                    } while (road != null && road.Type == Ets2ItemType.Road);
                }

                if (!fw)
                    roadChain.Reverse();

                foreach (var n in roadChain.Where(x => x.HideUI == false))
                {
                    n.GenerateRoadPolygon(64);
                }
                var pen = isHighway ? highwayPen : isExpress ? expressPen : localPen;

                var roadPoly =
                    roadChain.Where(x => x.HideUI == false)
                        .SelectMany(x => x.RoadPolygons)
                        .Select(x => new PointF((x.X - startX)*scaleX, (x.Y - startY)*scaleY));

                if (roadPoly.Any())
                {
                    g.DrawLines(pen, roadPoly.ToArray());
                }
            }

            // Draw GPS routes if any
            if (route != null && route.Segments != null && route.Segments.Any())
            {
                foreach (var seg in route.Segments)
                {
                    if (seg.Solutions.Any())
                    {
                        foreach (var opt in seg.Solutions)
                        {
                            var pt = opt.Points.Select(x => new PointF((x.X - startX) * scaleX, (x.Z - startY) * scaleY));

                            g.DrawLines(new Pen(Color.SpringGreen, 5.0f), pt.ToArray());
                        }
                    }
                    else
                    {
                        foreach (var opt in seg.Options)
                        {
                            var pt = opt.Points.Select(x => new PointF((x.X - startX) * scaleX, (x.Z - startY) * scaleY));

                            g.DrawLines(new Pen(Color.LightSkyBlue, 5.0f), pt.ToArray());
                        }
                    }
                }
            }

            if (LaneAssistance.hook != null)
            {
                var d = new PointF((LaneAssistance.hook.X - startX) * scaleX, (LaneAssistance.hook.Z - startY) * scaleY);
                g.FillEllipse(Brushes.GreenYellow, d.X - 5, d.Y - 5, 10, 10);
                var d2 = new PointF(d.X + (float)Math.Sin(LaneAssistance.yawRoad) * 25, d.Y + (float)Math.Cos(LaneAssistance.yawRoad) * 25);
                g.DrawLine(new Pen(Color.GreenYellow, 3.0f), d, d2);
            }
            if (LaneAssistance.lookPoint != null)
            {
                var d = new PointF((LaneAssistance.lookPoint.X - startX) * scaleX, (LaneAssistance.lookPoint.Y - startY) * scaleY);
                g.FillEllipse(Brushes.Pink, d.X - 5, d.Y - 5, 10, 10);
            }
            // Cities?
            var cityFont = new Font("Arial", 10.0f);
            foreach (var cities in itemsNearby.Where(x => x.Type == Ets2ItemType.City && x.StartNode!=null))
            {
                var centerX = cities.StartNode.X;
                var centerY = cities.StartNode.Z;

                var mapX = (centerX - startX)*scaleX;
                var mapY = (centerY - startY)*scaleY;
                //
                g.DrawString(cities.City, cityFont, Brushes.White, mapX,mapY);
            }

            // Draw all prefab curves
            foreach (var prefabItem in prefabs.Where(x => x.Prefab != null && x.HideUI == false).Distinct())
            {
                if (prefabItem.Prefab.Company != null)
                {
                    var nx = prefabItem.NodesList.FirstOrDefault().Value.X;
                    var ny = prefabItem.NodesList.FirstOrDefault().Value.Z;

                    var companyRect = new PointF[]
                    {
                        new PointF(nx - prefabItem.Prefab.Company.MinX, ny - prefabItem.Prefab.Company.MinY),
                        new PointF(nx - prefabItem.Prefab.Company.MinX, ny + prefabItem.Prefab.Company.MaxY),
                        new PointF(nx + prefabItem.Prefab.Company.MaxX, ny + prefabItem.Prefab.Company.MaxY),
                        new PointF(nx + prefabItem.Prefab.Company.MaxX, ny - prefabItem.Prefab.Company.MinY),
                    };

                    var offsetPoly = companyRect.Select(x => new PointF((x.X - startX) * scaleX, (x.Y - startY) * scaleY)).ToArray();

                    //g.FillPolygon(Brushes.Orange, offsetPoly);
                }
                else
                {
                    // Then it's likely a road prefab.
                    //prefab.Origin = 0;
                    // TODO: find origin
                    var originNode = prefabItem.NodesList.FirstOrDefault().Value;
                    if (originNode != null)
                    {
                        foreach (
                            var poly in
                                prefabItem.Prefab.GeneratePolygonCurves(originNode, prefabItem.Origin))
                        {
                            var offsetPoly = poly.Select(x => new PointF((x.X - startX) * scaleX, (x.Y - startY) * scaleY)).ToArray();

                            var p = new Pen(prefabLane.Color, 1.0f);
                            g.DrawLines(p, offsetPoly);
                        }
                    }
                }
            }

            var rotation = ets2Tel == null ? 0 : ets2Tel.Physics.RotationX*2*Math.PI;

            //g.FillEllipse(Brushes.Turquoise, scaleX*totalX-5, scaleY*totalY-5,10,10);
            g.DrawLine(new Pen(Brushes.Cyan, 5.0f), scaleX*totalX + (float) Math.Sin(rotation)*localPen.Width*2,
                scaleY*totalY + (float) Math.Cos(rotation)*localPen.Width*2, scaleX*totalX, scaleY*totalY);

            if (dedicated && ProcessDoubleClick)
            {
                ProcessDoubleClick = false;

                // Calculate the coordinate
                var clkX = 2 * (-0.5f + DoubleClickPoint.X / (float)clip.Width) * totalX + tx;
                var clkY = 2 * (-0.5f + DoubleClickPoint.Y / (float)clip.Height) * totalY + ty;

                var currentLocation = GetLivePoint();
                // Navigate to this point
                route = map.NavigateTo(currentLocation.Item1, new PointF(clkX, clkY));
            }

            // At 50 speed: 20fps
            // At 100 speed: 2fps
            var fps = 15.0f;
            if (ets2Tel != null && ets2Tel.Drivetrain.SpeedKmh > 50)
                fps -= (ets2Tel.Drivetrain.SpeedKmh - 50) * 0.43f; // 2.777spd = -1fps
            if (fps < 2) fps = 2;

            var interval = 1000.0f/fps;

            return (int) interval;
        }