Ejemplo n.º 1
0
    private static List <PathNode> RefineAbstractPath(HierarchicalMap map, List <PathNode> path, int level, ref int maxRefineCount)
    {
        var result = new List <PathNode>();

        if (path.Count == 0)
        {
            return(result);
        }

        int calculatedPaths = 0;

        result.Add(new PathNode(path[0].Id, path[0].Pos, path[0].Level - 1));
        for (int i = 1; i < path.Count; i++)
        {
            if (path[i].Level == level && path[i].Level == path[i - 1].Level && map.BelongToSameCluster(path[i].Pos, path[i - 1].Pos, level) && calculatedPaths < maxRefineCount)
            {
                var interPath = GetPath(map, path[i - 1].Id, path[i].Id, level - 1, false);
                result.AddRange(interPath);
                calculatedPaths++;
            }
            else
            {
                result.Add(new PathNode(path[i].Id, path[i].Pos, path[i].Level - 1));
            }
        }

        maxRefineCount -= calculatedPaths;

        return(result);
    }
Ejemplo n.º 2
0
    /// <summary>
    /// 获得指定层的路径
    /// </summary>
    private static List <PathNode> GetPath(HierarchicalMap map, int startAbsId, int goalAbsId, int level, bool isMainSearch)
    {
        map.SetCurrentLevelForSearch(level);

        AbstractNode startAbsNode = map.AbstractGraph.GetNode(startAbsId);
        AbstractNode goalAbsNode  = map.AbstractGraph.GetNode(goalAbsId);

        Path path;

        if (isMainSearch)
        {
            map.SetAllMapAsCurrentCluster();
            var planner = new PathPlanner(map, null);
            path = planner.Search(startAbsNode, goalAbsNode);
        }
        else
        {
            map.SetCurrentClusterAndLevel(startAbsNode.Pos, level + 1); //因为每一层节点都保存的是下一层的路径,所以要通过上一层来找到当层的路径
            AbstractEdge edge = map.AbstractGraph.GetNode(startAbsNode.Id).Edges[goalAbsNode.Id];
            path = new Path(edge.InnerLowerLevelPath, edge.Cost);
        }

        if (path == null)
        {
            return(new List <PathNode>());
        }

        var result = new List <PathNode>(path.Nodes.Count);

        foreach (var node in path.Nodes)
        {
            result.Add(new PathNode(node.Id, node.Pos, level));
        }
        return(result);
    }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            Console.WriteLine("Presse Enter");
            Console.ReadKey();
            HierarchicalMap.RelativeScales = new int[] { 2, 2 };
            var map = new HierarchicalMap(10, 10, new Random(0));

            //map.SetTestPortals();
            //map.CreatePaths();
            //map.CoverPathsWithZones(3,2);
            map.SpawnZoneAtClusterPosition(3, 2);
            map.PrintToConsole();
            Console.ReadLine();
            map.SpawnZoneAtClusterPosition(3, 2, null, true);
            map.PrintToConsole();
            Console.ReadLine();
            map.SpawnZoneAtClusterPosition(3, 2, null, true);
            map.PrintToConsole();
            Console.ReadLine();
            map.SpawnZoneAtClusterPosition(3, 2, null, true);
            map.PrintToConsole();
            Console.ReadLine();
            map.CreateSubMaps();
            map.PrintMasterToConsole();
            map.PrintMasterToBitmap(ConfigurationManager.AppSettings["BitmapOutput"]);
            for (var i = 0; i < map.flatZones.Count(); i++)
            {
                var submap = map.flatZones[i].SubMap;
                submap.PrintMasterToBitmap(ConfigurationManager.AppSettings["BitmapOutput"].Replace(".bmp", i.ToString() + ".bmp"));
            }
        }
Ejemplo n.º 4
0
    private static List <PathNode> SearchImpl(HierarchicalMap map, int startAbsId, int goalAbsId, int maxSearchLevel, int maxRefineCount = int.MaxValue)
    {
        //找出最高层的抽象路径
        List <PathNode> path = GetPath(map, startAbsId, goalAbsId, maxSearchLevel, true);

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

        //一层层具化路径直到最低层抽象
        for (int level = maxSearchLevel; level > 1; level--)
        {
            if (maxRefineCount <= 0)
            {
                break;
            }

            path = RefineAbstractPath(map, path, level, ref maxRefineCount);
        }

        //找到具体的路径
        path = AbstractPathToConcretePath(map, path, maxRefineCount);

        return(path);
    }
        public List <AbstractPathNode> RefineAbstractPath(HierarchicalMap map, List <AbstractPathNode> path, int level, int maxPathsToRefine = int.MaxValue)
        {
            var refinedAbstractPath = new List <AbstractPathNode>();
            var calculatedPaths     = 0;

            if (path.Count == 0)
            {
                return(refinedAbstractPath);
            }

            refinedAbstractPath.Add(new AbstractPathNode(path[0].Id, level - 1));
            for (var i = 1; i < path.Count; i++)
            {
                if (path[i].Level == level && path[i].Level == path[i - 1].Level &&
                    map.BelongToSameCluster(path[i].Id, path[i - 1].Id, level) && calculatedPaths < maxPathsToRefine)
                {
                    var interNodePath = GetPath(map, path[i - 1].Id, path[i].Id, level - 1, false);
                    for (int j = 1; j < interNodePath.Count; j++)
                    {
                        refinedAbstractPath.Add(interNodePath[j]);
                    }

                    calculatedPaths++;
                }
                else
                {
                    refinedAbstractPath.Add(new AbstractPathNode(path[i].Id, level - 1));
                }
            }

            return(refinedAbstractPath);
        }
    /// <summary>
    /// 恢复寻路新增节点导致的变化
    /// </summary>
    private void RestoreNodeBackup(HierarchicalMap map, int nodeId, NodeBackup backup)
    {
        AbstractGraph graph = map.AbstractGraph;
        AbstractNode  node  = graph.GetNode(nodeId);

        //恢复节点的级别
        node.Level = backup.Level;

        //恢复相关的边
        graph.RemoveEdgeFromAndToNode(nodeId);
        foreach (var edge in backup.Edges)
        {
            int targetNodeId = edge.TargetNodeId;
            var targetNode   = map.GetAbstractNode(targetNodeId);

            AbstractEdge abstractEdge = HPADemo.Instance.CreateEdge(node.Pos, targetNode.Pos, edge.Level, edge.IsInterEdge);
            abstractEdge.Init(targetNodeId, edge.Cost, edge.Level, edge.IsInterEdge);
            abstractEdge.SetInnerLowerLevelPath(edge.InnerLowerLevelPath);
            graph.AddEdge(nodeId, abstractEdge);

            edge.InnerLowerLevelPath?.Reverse();

            abstractEdge = HPADemo.Instance.CreateEdge(targetNode.Pos, node.Pos, edge.Level, edge.IsInterEdge);
            abstractEdge.Init(nodeId, edge.Cost, edge.Level, edge.IsInterEdge);
            abstractEdge.SetInnerLowerLevelPath(edge.InnerLowerLevelPath);
            graph.AddEdge(targetNodeId, abstractEdge);
        }

        m_backupDict.Remove(nodeId);
    }
Ejemplo n.º 7
0
        private void RestoreNodeBackup(HierarchicalMap map, Id <AbstractNode> nodeId)
        {
            var abstractGraph = map.AbstractGraph;
            var nodeBackup    = nodeBackups[nodeId];
            var nodeInfo      = abstractGraph.GetNodeInfo(nodeId);

            nodeInfo.Level = nodeBackup.Level;
            abstractGraph.RemoveEdgesFromAndToNode(nodeId);
            abstractGraph.AddNode(nodeId, nodeInfo);
            foreach (var edge in nodeBackup.Edges)
            {
                var targetNodeId = edge.TargetNodeId;

                map.AddEdge(nodeId, targetNodeId, edge.Info.Cost,
                            edge.Info.Level, edge.Info.IsInterClusterEdge,
                            edge.Info.InnerLowerLevelPath != null ? new List <Id <AbstractNode> >(edge.Info.InnerLowerLevelPath) : null);

                edge.Info.InnerLowerLevelPath?.Reverse();

                map.AddEdge(targetNodeId, nodeId, edge.Info.Cost,
                            edge.Info.Level, edge.Info.IsInterClusterEdge, edge.Info.InnerLowerLevelPath);
            }

            nodeBackups.Remove(nodeId);
        }
    public int InsertAbstractNode(HierarchicalMap map, Vector2Int concretePos)
    {
        int abstractId = InsertAbstractNodeInClusterLevel(map, concretePos);

        map.AddHierarchicalEdgesForAbstractNode(abstractId);
        return(abstractId);
    }
Ejemplo n.º 9
0
        public void RemoveAbstractNode(HierarchicalMap map, Id <AbstractNode> nodeId, int stal)
        {
            var abstractGraph = map.AbstractGraph;

            if (m_stalUsed[stal])
            {
                // The node was an existing entrance point in the graph. Restore it with
                // the information we kept when inserting
                var nodeInfo = abstractGraph.GetNodeInfo(nodeId);
                nodeInfo.Level = m_stalLevel[stal];
                abstractGraph.RemoveEdgesFromAndToNode(nodeId);
                abstractGraph.AddNode(nodeId, nodeInfo);
                foreach (var edge in m_stalEdges[stal])
                {
                    var targetNodeId = edge.TargetNodeId;

                    map.AddEdge(nodeId, targetNodeId, edge.Info.Cost,
                                edge.Info.Level, edge.Info.IsInterClusterEdge);
                    map.AddEdge(targetNodeId, nodeId, edge.Info.Cost,
                                edge.Info.Level, edge.Info.IsInterClusterEdge);
                }
            }
            else
            {
                // Just delete the node from the graph
                var currentNodeInfo = abstractGraph.GetNodeInfo(nodeId);
                var clusterId       = currentNodeInfo.ClusterId;
                var cluster         = map.Clusters[clusterId.IdValue];
                cluster.RemoveLastEntranceRecord();
                map.ConcreteNodeIdToAbstractNodeIdMap.Remove(currentNodeInfo.ConcreteNodeId);
                abstractGraph.RemoveEdgesFromAndToNode(nodeId);
                abstractGraph.RemoveLastNode();
            }
        }
Ejemplo n.º 10
0
 public void UpdateGraph(ICellMap map, IEnumerable <ICellFragment> obstacles, HierarchicalMap graph, NeighbourMode neighbourMode)
 {
     foreach (var obstacle in obstacles)
     {
         UpdateGraph(map, obstacle, graph, neighbourMode);
     }
 }
Ejemplo n.º 11
0
        private List <AbstractPathNode> GetPath(HierarchicalMap map, Id <AbstractNode> startNodeId, Id <AbstractNode> targetNodeId, int level, bool mainSearch)
        {
            map.SetCurrentLevelForSearches(level);
            var nodeInfo = map.AbstractGraph.GetNodeInfo(startNodeId);

            // TODO: This could be perfectly replaced by cached paths in the clusters!
            Path <AbstractNode> path;

            if (!mainSearch)
            {
                map.SetCurrentClusterByPositionAndLevel(nodeInfo.Position, level + 1);
                var edgeInfo = map.AbstractGraph.GetEdges(startNodeId)[targetNodeId].Info;
                path = new Path <AbstractNode>(edgeInfo.InnerLowerLevelPath, edgeInfo.Cost);
            }
            else
            {
                map.SetAllMapAsCurrentCluster();
                var search = new AStar <AbstractNode>(map, startNodeId, targetNodeId);
                path = search.FindPath();
            }

            if (path.PathCost == -1)
            {
                return(new List <AbstractPathNode>());
            }

            var result = new List <AbstractPathNode>(path.PathNodes.Count);

            foreach (Id <AbstractNode> abstractNodeId in path.PathNodes)
            {
                result.Add(new AbstractPathNode(abstractNodeId, level));
            }

            return(result);
        }
        /// <summary>
        /// Refines all the nodes that belong to a certain level to a lower level
        /// </summary>
        public List<PathNode> RefineAbstractPath(HierarchicalMap map, List<PathNode> path, int level, int maxPathsToRefine = int.MaxValue)
        {
            var result = new List<PathNode>();
            var calculatedPaths = 0;

            for (var i = 0; i < path.Count - 1; i++)
            {
                // if the two consecutive points belong to the same cluster, compute the path between them and
                // add the resulting nodes of that path to the list
                if (path[i].Level == path[i + 1].Level && path[i].Level == level &&
                    map.BelongToSameCluster(path[i].Id, path[i + 1].Id, level) && calculatedPaths < maxPathsToRefine)
                {
                    var tmp = this.PerformSearch(map, path[i].Id, path[i + 1].Id, level - 1, false)
                        .Select(n => new PathNode(n, level - 1))
                        .ToList();
                    result.AddRange(tmp);

                    calculatedPaths++;

                    // When we have calculated a path between 2 nodes, the next path in the search
                    // will be an interEdge node. We can safely skip it
                    i++;
                }
                else
                    result.Add(path[i]);
            }

            // make sure last elem is added
            if (result[result.Count - 1].Id != path[path.Count - 1].Id)
                result.Add(path[path.Count - 1]);

            return result;
        }
Ejemplo n.º 13
0
        public static Room ToRoom(this HierarchicalMap hMap, int scale = 1)
        {
            ///MAYBE THIS IS MESSED UP //confirming other stuff first.
            var room = new Room();

            room.Height = hMap._MapHeight * scale;
            room.Width  = hMap._MapWidth * scale;
            if (room.Height < room.Width && hMap._Portals.Any(x => x.direction.Y == 1))
            {
                var breaka = "here";
            }
            room.DistanceBetweenPathAndEdge = 2;//scale - 1;
            room.portals = new List <Portal>();
            room.FromMap = hMap;
            foreach (var portal in hMap._Portals)
            {
                if (portal.destination == null)
                {
                    continue;
                }
                if (portal.point.X != 0 && portal.point.X != hMap._MapWidth - 1 && portal.point.Y != 0 && portal.point.Y != hMap._MapHeight - 1)
                {
                    continue;
                }
                var x = portal.point.X * scale;
                var y = portal.point.Y * scale;
                if (portal.direction.X == 0)
                {
                    x += (int)Math.Floor((double)scale / 2);
                }
                else
                {
                    y += (int)Math.Floor((double)scale / 2);
                }
                //if (portal.direction.X == 0 && x == 0)
                //    x = room.DistanceBetweenPathAndEdge;
                //if (portal.direction.Y == 0 && y == 0)
                //    y = room.DistanceBetweenPathAndEdge;

                if (portal.direction.X == 0 && y != 0)
                {
                    y = (hMap._MapHeight * scale) - 1;
                }
                else if (portal.direction.Y == 0 && x != 0)
                {
                    x = (hMap._MapWidth * scale) - 1;
                }
                var p = new Portal()
                {
                    point     = new System.Drawing.Point(x, y),
                    direction = portal.direction
                };
                p.fromPortal = portal;
                portal.portalOffsetFromRoom = new System.Drawing.Point(x, y);
                room.portals.Add(p);
            }

            return(room);
        }
Ejemplo n.º 14
0
        public Id <AbstractNode> InsertAbstractNode(HierarchicalMap map, Position pos, int start)
        {
            var nodeId = Id <ConcreteNode> .From(pos.Y *map.Width + pos.X);

            var result = InsertStal(map, nodeId, pos, start);

            InsertStalHEdges(map, nodeId);
            return(result);
        }
Ejemplo n.º 15
0
        public Id <AbstractNode> InsertAbstractNode(HierarchicalMap map, Position pos)
        {
            var nodeId = Id <ConcreteNode> .From(pos.Y *map.Width + pos.X);

            var abstractNodeId = InsertNodeIntoHierarchicalMap(map, nodeId, pos);

            map.AddHierarchicalEdgesForAbstractNode(abstractNodeId);
            return(abstractNodeId);
        }
Ejemplo n.º 16
0
        private static void RemoveNode(HierarchicalMap graph, HierarchicalGraphNode node)
        {
            foreach (var child in graph.Nodes)
            {
                child.Remove(node);
            }

            graph.Nodes.Remove(node);
        }
Ejemplo n.º 17
0
        private HierarchicalMap GenerateTwoLevelMap(ICellMap cellMap, NeighbourMode neighbourMode,
                                                    int levelZeroClusterSize)
        {
            CellCluster[,] clusterMatrix = CreateClusters(cellMap, levelZeroClusterSize);
            GeneratedClusters            = clusterMatrix;

            HierarchicalMap levelOneMap = new HierarchicalMap(levelZeroClusterSize, levelZeroClusterSize);

            for (int i = 0; i < clusterMatrix.GetLength(0); i++)
            {
                for (int j = 0; j < clusterMatrix.GetLength(1); j++)
                {
                    CellCluster currentCluster = clusterMatrix[i, j];

                    int prevI = i - 1;
                    int prevJ = j - 1;
                    int nextJ = j + 1;
                    if (prevI >= 0)
                    {
                        CellCluster neighbourCluster = clusterMatrix[prevI, j];
                        ProceedNeighbourClusters(currentCluster, neighbourCluster, levelOneMap);
                    }

                    if (prevJ >= 0)
                    {
                        CellCluster neighbourCluster = clusterMatrix[i, prevJ];
                        ProceedNeighbourClusters(currentCluster, neighbourCluster, levelOneMap);
                    }

                    if (prevJ >= 0 && prevI >= 0 && neighbourMode == NeighbourMode.SidesAndDiagonals)
                    {
                        CellCluster neighbourCluster = clusterMatrix[prevI, prevJ];
                        ProceedNeighbourClusters(currentCluster, neighbourCluster, levelOneMap);
                    }

                    if (nextJ < cellMap.Height && prevI >= 0 && neighbourMode == NeighbourMode.SidesAndDiagonals)
                    {
                        CellCluster neighbourCluster = clusterMatrix[prevI, nextJ];
                        ProceedNeighbourClusters(currentCluster, neighbourCluster, levelOneMap);
                    }
                }
            }

            for (int i = 0; i < clusterMatrix.GetLength(0); i++)
            {
                for (int j = 0; j < clusterMatrix.GetLength(1); j++)
                {
                    _currentCellCluster = clusterMatrix[i, j];
                    clusterMatrix[i, j].CalculatePaths(neighbourMode, OnCellClusterCellViewed);
                }
            }

            levelOneMap.ZeroLevelClusters = clusterMatrix;

            return(levelOneMap);
        }
Ejemplo n.º 18
0
 public void RemoveAbstractNode(HierarchicalMap map, Id <AbstractNode> nodeId)
 {
     if (nodeBackups.ContainsKey(nodeId))
     {
         RestoreNodeBackup(map, nodeId);
     }
     else
     {
         map.RemoveAbstractNode(nodeId);
     }
 }
Ejemplo n.º 19
0
        /// <summary>
        /// Inserts a node and creates edges around the local points of the cluster it the
        /// node we try to insert belongs to at each level
        /// </summary>
        private static void InsertStalHEdges(HierarchicalMap map, Id <ConcreteNode> concreteNodeId)
        {
            var abstractNodeId   = map.ConcreteNodeIdToAbstractNodeIdMap[concreteNodeId];
            var abstractNodeInfo = map.AbstractGraph.GetNodeInfo(abstractNodeId);
            var oldLevel         = abstractNodeInfo.Level;

            abstractNodeInfo.Level = map.MaxLevel;
            for (var level = oldLevel + 1; level <= map.MaxLevel; level++)
            {
                map.AddEdgesToOtherEntrancesInCluster(abstractNodeInfo, level);
            }
        }
        public List<PathNode> DoHierarchicalSearch(HierarchicalMap map, int startNodeId, int targetNodeId, int maxSearchLevel, int maxPathsToRefine = int.MaxValue)
        {
            var path = this.PerformSearch(map, startNodeId, targetNodeId, maxSearchLevel, true)
                .Select(n => new PathNode(n, maxSearchLevel)).ToList();

            if (path.Count == 0) return path;

            for (var level = maxSearchLevel; level > 1; level--)
                path = this.RefineAbstractPath(map, path, level, maxPathsToRefine);

            return path;
        }
Ejemplo n.º 21
0
    private void Generate()
    {
        HierarchicalMapFactory factory         = new HierarchicalMapFactory();
        HierarchicalMap        hierarchicalMap = factory.CreateHierarchicalMap(m_concreteMap, m_clusterSize, m_maxLevel);
        List <PathNode>        path            = HierarchicalSearch.Search(factory, hierarchicalMap, m_maxLevel, m_startNode.Pos, m_goalNode.Pos);

        for (int i = 0; i < path.Count; i++)
        {
            var node = m_concreteMap.Get(path[i].Pos);
            node.SetSearchType(SearchType.Path);
        }
    }
Ejemplo n.º 22
0
        // insert a new node, such as start or target, to the abstract graph and
        // returns the id of the newly created node in the abstract graph
        // x and y are the positions where I want to put the node
        private Id <AbstractNode> InsertNodeIntoHierarchicalMap(HierarchicalMap map, Id <ConcreteNode> concreteNodeId, Position pos)
        {
            // If the node already existed (for instance, it was the an entrance point already
            // existing in the graph, we need to keep track of the previous status in order
            // to be able to restore it once we delete this STAL
            if (map.ConcreteNodeIdToAbstractNodeIdMap.ContainsKey(concreteNodeId))
            {
                var existingAbstractNodeId = map.ConcreteNodeIdToAbstractNodeIdMap[concreteNodeId];
                var nodeBackup             = new NodeBackup(
                    map.AbstractGraph.GetNodeInfo(existingAbstractNodeId).Level,
                    map.GetNodeEdges(concreteNodeId));
                nodeBackups[existingAbstractNodeId] = nodeBackup;
                return(map.ConcreteNodeIdToAbstractNodeIdMap[concreteNodeId]);
            }

            var cluster = map.FindClusterForPosition(pos);

            // create global entrance
            var abstractNodeId = Id <AbstractNode> .From(map.NrNodes);

            var entrance = cluster.AddEntrance(abstractNodeId, new Position(pos.X - cluster.Origin.X, pos.Y - cluster.Origin.Y));

            cluster.UpdatePathsForLocalEntrance(entrance);

            map.ConcreteNodeIdToAbstractNodeIdMap[concreteNodeId] = abstractNodeId;

            var info = new AbstractNodeInfo(
                abstractNodeId,
                1,
                cluster.Id,
                pos,
                concreteNodeId);

            map.AbstractGraph.AddNode(abstractNodeId, info);

            foreach (var entrancePoint in cluster.EntrancePoints)
            {
                if (cluster.AreConnected(abstractNodeId, entrancePoint.AbstractNodeId))
                {
                    map.AddEdge(
                        entrancePoint.AbstractNodeId,
                        abstractNodeId,
                        cluster.GetDistance(entrancePoint.AbstractNodeId, abstractNodeId));
                    map.AddEdge(
                        abstractNodeId,
                        entrancePoint.AbstractNodeId,
                        cluster.GetDistance(abstractNodeId, entrancePoint.AbstractNodeId));
                }
            }

            return(abstractNodeId);
        }
Ejemplo n.º 23
0
    /// <summary>
    /// 移除寻路时新增的抽象节点
    /// </summary>
    public void RemoveAbstractNode(HierarchicalMap map, int nodeId)
    {
        NodeBackup backup;

        if (m_backupDict.TryGetValue(nodeId, out backup))
        {
            RestoreNodeBackup(map, nodeId, backup); //如果寻路时新增的节点在图中原本就存在,则重置相关数据
        }
        else
        {
            map.RemoveAbstractNode(nodeId); //如果的确新增了节点,则直接移除该节点
        }
    }
Ejemplo n.º 24
0
        public void UpdateGraph(ICellMap map, ICellFragment cellFragment, HierarchicalMap graph, NeighbourMode neighbourMode)
        {
            var        clusterMatrix = graph.ZeroLevelClusters;
            int        clusterWidth  = graph.ClusterDefaultWidth;
            int        clusterHeight = graph.ClusterDefaultHeight;
            Vector2Int fragmentSize  = new Vector2Int(cellFragment.Width, cellFragment.Height);

            Vector2Int leftBottomClusterPosition = GetContainingClusterPosition(clusterMatrix, clusterWidth, clusterHeight, cellFragment.LeftBottom);
            Vector2Int rightTopClusterPosition   = GetContainingClusterPosition(clusterMatrix, clusterWidth, clusterHeight, cellFragment.LeftBottom + fragmentSize);

            int iMin = leftBottomClusterPosition.X;
            int iMax = rightTopClusterPosition.X;
            int jMin = leftBottomClusterPosition.Y;
            int jMax = rightTopClusterPosition.Y;

            for (int i = iMin; i <= iMax; i++)
            {
                for (int j = jMin; j <= jMax; j++)
                {
                    CellCluster currentCluster = clusterMatrix[i, j];

                    int prevI = i - 1;
                    int prevJ = j - 1;
                    int nextJ = j + 1;
                    if (prevI >= iMin)
                    {
                        CellCluster neighbourCluster = clusterMatrix[prevI, j];
                        RemoveTransitionNodes(currentCluster, neighbourCluster, graph);
                        ProceedNeighbourClusters(currentCluster, neighbourCluster, graph);
                    }

                    if (prevJ >= jMin)
                    {
                        CellCluster neighbourCluster = clusterMatrix[i, prevJ];
                        RemoveTransitionNodes(currentCluster, neighbourCluster, graph);
                        ProceedNeighbourClusters(currentCluster, neighbourCluster, graph);
                    }
                }
            }

            for (int i = iMin; i <= iMax; i++)
            {
                for (int j = jMin; j <= jMax; j++)
                {
                    CellCluster currentCluster = clusterMatrix[i, j];
                    currentCluster.CalculatePaths(neighbourMode, null);
                }
            }
        }
Ejemplo n.º 25
0
        private void CreateEdgesNP(List <Entrance> entrances, List <Cluster> clusters)
        {
            foreach (var entrance in entrances)
            {
                CreateEntranceEdges(entrance, HierarchicalMap.Type);
            }

            //foreach (var cluster in clusters)
            //{
            //    cluster.CreateIntraClusterEdges();
            //    CreateIntraClusterEdges(cluster);
            //}

            HierarchicalMap.CreateHierarchicalEdges();
        }
Ejemplo n.º 26
0
        public List <AbstractPathNode> DoHierarchicalSearch(HierarchicalMap map, Id <AbstractNode> startNodeId, Id <AbstractNode> targetNodeId, int maxSearchLevel, int maxPathsToRefine = int.MaxValue)
        {
            List <AbstractPathNode> path = GetPath(map, startNodeId, targetNodeId, maxSearchLevel, true);

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

            for (var level = maxSearchLevel; level > 1; level--)
            {
                path = RefineAbstractPath(map, path, level, maxPathsToRefine);
            }

            return(path);
        }
Ejemplo n.º 27
0
    public static List <PathNode> Search(HierarchicalMapFactory factory, HierarchicalMap map, int maxLevel, Vector2Int startPos, Vector2Int goalPos, int maxRefineCount = int.MaxValue)
    {
        //首先插入起点和终点到图中
        var startAbsId = factory.InsertAbstractNode(map, startPos);
        var goalAbsId  = factory.InsertAbstractNode(map, goalPos);

        var path = SearchImpl(map, startAbsId, goalAbsId, maxLevel, maxRefineCount);

        //可以在这里应用路径平滑

        //搜索完毕后就移除起点和终点(如果常用,也可以留着)
        factory.RemoveAbstractNode(map, goalAbsId);
        factory.RemoveAbstractNode(map, startAbsId);

        return(path);
    }
Ejemplo n.º 28
0
    /// <summary>
    /// 插入节点到Cluster内,并构建相关节点和边到图中
    /// </summary>
    private int InsertAbstractNodeInClusterLevel(HierarchicalMap map, Vector2Int concretePos)
    {
        AbstractNode abstractNode = map.GetAbstractNode(concretePos);

        //如果要插入的位置已经存在节点,则保存相关信息,以便之后删除时恢复
        if (abstractNode != null)
        {
            NodeBackup backup = new NodeBackup(abstractNode.Level, abstractNode.Edges.Values.ToList());

            if (m_backupDict.ContainsKey(abstractNode.Id))
            {
                Debug.LogError("已经存在一个NodeBackup,逻辑上出错了");
            }

            m_backupDict[abstractNode.Id] = backup;
            return(abstractNode.Id);
        }

        //把节点插入到Cluster内
        int abstractId = map.NodeCount();
        var cluster    = map.FindClusterForPosition(concretePos);
        var entrance   = cluster.AddEntrancePoint(abstractId, m_concreteMap.Get(concretePos));

        cluster.AddIntraEdgesData(entrance);
        //把节点插入到图中
        abstractNode = HPADemo.Instance.CreateAbstractNode(1, concretePos);
        abstractNode.Init(abstractId, 1, cluster.Id, concretePos);
        map.AddAbstractNode(abstractNode);
        map.AbstractGraph.AddNode(abstractNode);
        //把该节点相关的边插入到图中
        foreach (var otherEntrance in cluster.EntrancePoints)
        {
            if (cluster.IsConnected(abstractId, otherEntrance.AbstractId))
            {
                float        distance = cluster.Distance(abstractId, otherEntrance.AbstractId);
                AbstractEdge edge     = HPADemo.Instance.CreateEdge(concretePos, otherEntrance.ConcreteNode.Pos, 1, false);
                edge.Init(otherEntrance.AbstractId, distance, 1, false);
                map.AbstractGraph.AddEdge(abstractId, edge);

                edge = HPADemo.Instance.CreateEdge(otherEntrance.ConcreteNode.Pos, concretePos, 1, false);
                edge.Init(abstractId, distance, 1, false);
                map.AbstractGraph.AddEdge(otherEntrance.AbstractId, edge);
            }
        }

        return(abstractId);
    }
Ejemplo n.º 29
0
        public void CreateHierarchicalMapNP(ConcreteMap concreteMap, int clusterSize, int maxLevel, EntranceStyle style)
        {
            ClusterSize     = clusterSize;
            EntranceStyle   = style;
            MaxLevel        = maxLevel;
            ConcreteMap     = concreteMap;
            HierarchicalMap = new HierarchicalMap(concreteMap, clusterSize, maxLevel);

            List <Entrance> entrances;
            List <Cluster>  clusters;

            CreateEntrancesAndClusters(out entrances, out clusters);
            HierarchicalMap.Clusters = clusters;

            CreateAbstractNodes(entrances);
            CreateEdgesNP(entrances, clusters);
        }
Ejemplo n.º 30
0
    public HierarchicalMap CreateHierarchicalMap(ConcreteMap concreteMap, int clusterSize, int maxLevel)
    {
        m_concreteMap     = concreteMap;
        m_clusterSize     = clusterSize;
        m_maxLevel        = maxLevel;
        m_hierarchicalMap = new HierarchicalMap(concreteMap, clusterSize, maxLevel);

        List <Cluster>  clusters  = new List <Cluster>();
        List <Entrance> entrances = new List <Entrance>();

        CreateClustersAndEntrances(clusters, entrances);
        m_hierarchicalMap.InitClusters(clusters);

        CreateAbstractNodes(entrances);
        CreateEdges(clusters, entrances);

        return(m_hierarchicalMap);
    }
Ejemplo n.º 31
0
        private static void ProceedNeighbourClusters(CellCluster currentCluster, CellCluster neighbourCluster,
                                                     HierarchicalMap graph)
        {
            List <Vector2Int> currentPoints   = new List <Vector2Int>(2);
            List <Vector2Int> neighbourPoints = new List <Vector2Int>(2);

            GetTransitionCells(currentCluster, neighbourCluster, currentPoints, neighbourPoints);
            for (var k = 0; k < currentPoints.Count; k++)
            {
                var currentPoint = currentPoints[k];
                var neighbourPoint = neighbourPoints[k];
                HierarchicalGraphNode transitionNodeCurrent, transitionNodeNeighbour;

                transitionNodeCurrent =
                    (HierarchicalGraphNode)currentCluster.TransitionNodes.FirstOrDefault(node =>
                                                                                         node.Position == currentPoint);
                transitionNodeNeighbour =
                    (HierarchicalGraphNode)neighbourCluster.TransitionNodes.FirstOrDefault(node =>
                                                                                           node.Position == neighbourPoint);
                if (transitionNodeCurrent == null)
                {
                    transitionNodeCurrent = new HierarchicalGraphNode();
                    currentCluster.TransitionNodes.Add(transitionNodeCurrent);
                    graph.Nodes.Add(transitionNodeCurrent);
                }

                if (transitionNodeNeighbour == null)
                {
                    transitionNodeNeighbour = new HierarchicalGraphNode();
                    neighbourCluster.TransitionNodes.Add(transitionNodeNeighbour);
                    graph.Nodes.Add(transitionNodeNeighbour);
                }

                transitionNodeCurrent.SetWeight(transitionNodeNeighbour, 1);
                transitionNodeNeighbour.SetWeight(transitionNodeCurrent, 1);

                transitionNodeCurrent.Position   = currentPoint;
                transitionNodeNeighbour.Position = neighbourPoint;

                transitionNodeCurrent.ParentCluster   = currentCluster;
                transitionNodeNeighbour.ParentCluster = neighbourCluster;
            }
        }
Ejemplo n.º 32
0
        public HierarchicalMap CreateHierarchicalMap(ConcreteMap concreteMap, int clusterSize, int maxLevel, EntranceStyle style)
        {
            _clusterSize     = clusterSize;
            _entranceStyle   = style;
            _maxLevel        = maxLevel;
            _concreteMap     = concreteMap;
            _hierarchicalMap = new HierarchicalMap(concreteMap, clusterSize, maxLevel);

            List <Entrance> entrances;
            List <Cluster>  clusters;

            CreateEntrancesAndClusters(out entrances, out clusters);
            _hierarchicalMap.Clusters = clusters;

            CreateAbstractNodes(entrances);
            CreateEdges(entrances, clusters);

            return(_hierarchicalMap);
        }
        public List<int> PerformSearch(HierarchicalMap map, int startNodeId, int targetNodeId, int level, bool mainSearch)
        {
            var search = new AStar();
            map.SetCurrentLevel(level);
            var nodeInfo = map.AbstractGraph.GetNodeInfo(startNodeId);
            if (mainSearch)
                map.SetCurrentCluster(nodeInfo.Position, map.MaxLevel + 1);
            else
                map.SetCurrentCluster(nodeInfo.Position, level + 1);

            // TODO: This could be perfectly replaced by cached paths in the clusters!
            var path = search.FindPath(map, startNodeId, targetNodeId);
            if (path.PathCost == -1)
            {
                // No path found
                return new List<int>();
            }

            var result = path.PathNodes;
            result.Reverse();
            return result;
        }
        public List<PathNode> AbstractPathToLowLevelPath(HierarchicalMap map, List<PathNode> absPath, int width, int maxPathsToCalculate = int.MaxValue)
        {
            var result = new List<PathNode>(absPath.Count * 10);
            if (absPath.Count == 0) return result;

            var calculatedPaths = 0;
            var lastAbsNodeId = absPath[0].Id;

            for (var j = 1; j < absPath.Count; j++)
            {
                var currentAbsNodeId = absPath[j].Id;
                var currentNodeInfo = map.AbstractGraph.GetNodeInfo(currentAbsNodeId);
                var lastNodeInfo = map.AbstractGraph.GetNodeInfo(lastAbsNodeId);

                // We cannot compute a low level path from a level which is higher than lvl 1
                // (obvious...) therefore, ignore any non-refined path
                if (absPath[j].Level > 1)
                {
                    result.Add(absPath[j]);
                    continue;
                }

                var eClusterId = currentNodeInfo.ClusterId;
                var leClusterId = lastNodeInfo.ClusterId;

                if (eClusterId == leClusterId && calculatedPaths < maxPathsToCalculate)
                {
                    // insert the local solution into the global one
                    // var cluster = map.GetCluster(eClusterId);
                    //var localpos1 = cluster.GetLocalPosition(lastNodeInfo.LocalEntranceId);
                    //var localpos2 = cluster.GetLocalPosition(currentNodeInfo.LocalEntranceId);
                    if (lastNodeInfo.LocalEntranceId != currentNodeInfo.LocalEntranceId)
                    {
						var cluster = map.GetCluster(eClusterId);
						var localPath = cluster.GetPath(lastNodeInfo.LocalEntranceId, currentNodeInfo.LocalEntranceId)
                            .Select(
                                localId =>
                                {
                                    int localPoint = LocalClusterId2GlobalId(localId, cluster, width);
                                    return new PathNode(localPoint, 0);
                                });

                        result.AddRange(localPath);

                        calculatedPaths++;
                    }
                }
                else
                {
                    var lastVal = lastNodeInfo.CenterId;
                    var currentVal = currentNodeInfo.CenterId;
                    if (result[result.Count - 1].Id != lastVal)
                        result.Add(new PathNode(lastVal, 0));

                    result.Add(new PathNode(currentVal, 0));
                }

                lastAbsNodeId = currentAbsNodeId;
            }

            return result;
        }