示例#1
0
        private void FlattenRoad(RoadGraphNode node1, RoadGraphNode node2)
        {
            Point start  = node1.Position;
            Point end    = node2.Position;
            var   vector = (end - start).Normalize();

            if (node1.Neighbors.Count > 2)
            {
                start += vector * Map.TileWidth * crossroadFlatteningRadius;
            }
            else
            {
                start -= vector * Map.TileWidth * overlapRadius;
            }

            if (node2.Neighbors.Count > 2)
            {
                end -= vector * Map.TileWidth * crossroadFlatteningRadius;
            }
            else
            {
                end += vector * Map.TileWidth * overlapRadius;
            }

            rampGenerator.GenerateRamp(map, start, end, 30, 15);
            if (AddWaypaths)
            {
                var path = new[] { info.ObjectFactory.CreateWaypoint(start.X, start.Y), info.ObjectFactory.CreateWaypoint(end.X, end.Y) };
                map.AddWaypath(string.Empty, path);
            }
        }
示例#2
0
        private ICurve GetCurve(RoadGraphNode node1, RoadGraphNode node2)
        {
            ICurve curve;

            if (node1.Neighbors.Count == 1 && node2.Neighbors.Count == 1)
            {
                curve = new CubicBezierCurve(
                    node1.Position,
                    GetControlPoint(node1),
                    GetControlPoint(node2),
                    node2.Position);
            }
            else if (node1.Neighbors.Count == 1 && node2.Neighbors.Count > 1)
            {
                curve = new QuadraticBezierCurve(
                    node1.Position,
                    GetControlPoint(node1),
                    node2.Position);
            }
            else if (node2.Neighbors.Count == 1 && node1.Neighbors.Count > 1)
            {
                curve = new QuadraticBezierCurve(
                    node1.Position,
                    GetControlPoint(node2),
                    node2.Position);
            }
            else
            {
                curve = new LinearBezierCurve(node1.Position, node2.Position);
            }

            return(curve);
        }
示例#3
0
        private void AddAdditionalRoadsLeadingOutOfMap()
        {
            int count = -1;

            while (roadsLeadingOutOfMap.Count < MinimumRoadsLeadingOutOfMap &&
                   roadsLeadingOutOfMap.Count != count)
            {
                count = roadsLeadingOutOfMap.Count;
                var pointsNextToBorder = from n in info.Roads.Nodes
                                         where n.CanBeConnected &&
                                         n.Neighbors.Count == 2 &&
                                         map.IsWithinMap(n.Position) //&&
                                                                     //!roadsLeadingOutOfMap.Select(r => r.Node2.Position)
                                                                     //                     .Any(p => (p - n.Position).VectorLengthSquared() < MinimumDistanceBetweenRoadsLeadingOutOfMap * MinimumDistanceBetweenRoadsLeadingOutOfMap)
                                         let x                 = System.Math.Min(n.Position.X, map.HeightMap.MapWidth * Map.TileWidth - n.Position.X)
                                                         let y = System.Math.Min(n.Position.Y, map.HeightMap.MapHeight * Map.TileWidth - n.Position.Y)
                                                                 orderby System.Math.Min(x, y)
                                                                 select new { X = x, Y = y, Node = n };

                foreach (var point in pointsNextToBorder)
                {
                    if (info.IsCancellationRequested)
                    {
                        return;
                    }

                    Point destination;
                    if (point.X < point.Y)
                    {
                        if (point.X < point.Node.Position.X)
                        {
                            destination = new Point((map.HeightMap.MapWidth + outOfMapDestinationDistance) * Map.TileWidth, point.Node.Position.Y);
                        }
                        else
                        {
                            destination = new Point(-outOfMapDestinationDistance * Map.TileWidth, point.Node.Position.Y);
                        }
                    }
                    else
                    {
                        if (point.Y < point.Node.Position.Y)
                        {
                            destination = new Point(point.Node.Position.X, (map.HeightMap.MapHeight + outOfMapDestinationDistance) * Map.TileWidth);
                        }
                        else
                        {
                            destination = new Point(point.Node.Position.X, -outOfMapDestinationDistance * Map.TileWidth);
                        }
                    }

                    var destinationNode = new RoadGraphNode(destination, false, false);
                    var edge            = new RoadGraphEdge(point.Node, destinationNode, (destination - point.Node.Position).VectorLength());
                    if (TryAddRoadLeadingOutOfMap(point.Node, destination))
                    {
                        break;
                    }
                }
            }
        }
示例#4
0
 public RoadGraphEdge FindJoiningIntersection(RoadGraphNode start, RoadGraphEdge target)
 {
     return(start.edges.Find(e =>
     {
         return roadGraph.GetNode(e.id, e.subId).edges.Exists(edge =>
         {
             return edge.id == target.id && edge.subId == target.subId;
         });
     }));
 }
示例#5
0
        private Point GetControlPoint(RoadGraphNode node)
        {
            const float minLength     = 100;
            var         incoming      = (node.Position - node.Neighbors.First().Position);
            var         lengthSquared = incoming.VectorLengthSquared();

            if (lengthSquared < minLength * minLength)
            {
                incoming = incoming / (float)System.Math.Sqrt(lengthSquared) * minLength;
            }
            return(node.Position + incoming);
        }
示例#6
0
        private void AddRoadsFromTemplateToMap(ObjectTemplate template, Map map, MapInfo info, string roadType)
        {
            var tileGraph = new TileGraph(info.Tiles, TileInfo.Free);
            var roads     = template.Objects.Where(o => o.RoadOptions != RoadOptions.None && o.Type == ObjectTemplate.RoadTemplate).ToArray();
            int count     = info.Roads.Nodes.Count;

            ScriptObject road1, road2;

            for (int i = 0; i < roads.Length; i += 2)
            {
                road1 = roads[i];
                road2 = roads[i + 1];

                var start = info.Roads.FindNode(new Point(road1.X, road1.Y));
                if (start == null)
                {
                    start = new RoadGraphNode(new Point(road1.X, road1.Y), !road1.RoadOptions.HasFlag(RoadOptions.Join) && roads.Count(r2 => road1.X == r2.X && road1.Y == r2.Y) == 1, true);
                    info.Roads.Nodes.AddLast(start);
                }

                var end = info.Roads.FindNode(new Point(road2.X, road2.Y));
                if (end == null)
                {
                    end = new RoadGraphNode(new Point(road2.X, road2.Y), !road2.RoadOptions.HasFlag(RoadOptions.Join) && roads.Count(r2 => road2.X == r2.X && road2.Y == r2.Y) == 1, true);
                    info.Roads.Nodes.AddLast(end);
                }

                start.LinkTo(end);

                road1.Type = roadType;
                road2.Type = roadType;

                info.Roads.Segments.Add(new Tuple <ScriptObject, ScriptObject>(road1, road2));
                tileGraph.UpdateTiles(new[] { map.PositionToCoordinates(start.Position), map.PositionToCoordinates(end.Position) }, TileInfo.Road);
            }

            IEnumerable <RoadGraphNode> nodes = info.Roads.Nodes.Skip(count).ToArray();

            var endpoints = from r in nodes
                            where !r.CanBeConnected && r.Neighbors.Count == 1
                            select r;

            foreach (var endpoint in endpoints)
            {
                foreach (var node in nodes)
                {
                    if (node != endpoint && (node.Position - endpoint.Position).VectorLengthSquared() < endpointConnectionRange * endpointConnectionRange)
                    {
                        endpoint.LinkTo(node);
                    }
                }
            }
        }
示例#7
0
    private void RemoveEdge(RoadGraphNode[] roadGraph, int id, int subId, int toId, int toSubId)
    {
        if (roadGraph[id * 50 + subId] == null)
        {
            roadGraph[id * 50 + subId]       = new RoadGraphNode();
            roadGraph[id * 50 + subId].edges = new List <RoadGraphEdge>();
        }

        if (roadGraph[id * 50 + subId].edges.Any(e => e.id == toId && e.subId == toSubId))
        {
            //remove only exist
            roadGraph[id * 50 + subId].edges.RemoveAll(e => e.id == toId && e.subId == toSubId);
        }
        else
        {
            Debug.Log("No corresponding edge exist, stop removing");
        }
    }
示例#8
0
        private bool TryAddRoadLeadingOutOfMap(RoadGraphNode node, Point destination)
        {
            if (roadsLeadingOutOfMap.Any(r => (destination - r.Node2.Position).VectorLengthSquared() < MinimumDistanceBetweenRoadsLeadingOutOfMap * MinimumDistanceBetweenRoadsLeadingOutOfMap))
            {
                return(false);
            }

            var destinationNode = new RoadGraphNode(destination, false, false);
            var edge            = new RoadGraphEdge(node, destinationNode, (destination - node.Position).VectorLength());

            if (TryAddEdge(edge))
            {
                info.Roads.Nodes.AddLast(destinationNode);
                roadsLeadingOutOfMap.Add(edge);
                return(true);
            }

            return(false);
        }
示例#9
0
    private void AddEdge(RoadGraphNode[] roadGraph, int id, int subId, int toId, int toSubId)
    {
        if (roadGraph[id * 50 + subId] == null)
        {
            roadGraph[id * 50 + subId]       = new RoadGraphNode();
            roadGraph[id * 50 + subId].edges = new List <RoadGraphEdge>();
        }

        if (roadGraph[id * 50 + subId].edges.Any(e => e.id == toId && e.subId == toSubId))
        {
            //already exists
        }
        else
        {
            roadGraph[id * 50 + subId].edges.Add(new RoadGraphEdge()
            {
                id = toId, subId = toSubId
            });
        }
    }
示例#10
0
 private double CalculateSquaredDistance(RoadGraphNode node1, RoadGraphNode node2)
 {
     return((node1.Position - node2.Position).VectorLength());
 }
示例#11
0
        private bool CanAddIncomingRoad(RoadGraphNode node, Point position)
        {
            var incoming = node.Position - position;

            return(node.Neighbors.All(n => Angle.Between(incoming, node.Position - n.Position) >= Angle.ToRadians(minAngleBetweenCrossroads)));
        }
示例#12
0
 public RoadGraphEdge(RoadGraphNode node1, RoadGraphNode node2, float length)
 {
     Node1  = node1;
     Node2  = node2;
     Length = length;
 }