예제 #1
0
        //populate the cached path of the given AI with the path from startPoint to endPoint
        private void GeneratePath(int aiAgentIndex, NodeIndex startPoint, NodeIndex endPoint, Node topLevelNode)
        {
            bool destinationWithinCurrentNode = startPoint.EqualAtDepth(endPoint, index.GetMaxDepth());

            Node start = internalNodes[startPoint.GetIndexAtDepth(index.GetMaxDepth() + 1)];
            Node end;

            if (!destinationWithinCurrentNode)
            {
                end = topLevelNode.GetNode(endPoint);
            }
            else
            {
                end = internalNodes[endPoint.GetIndexAtDepth(index.GetMaxDepth() + 1)];
            }


            //If pathfinding in the lowest layer use the cheaper pathfinding method, else use A*
            if (startPoint.GetMaxDepth() == index.GetMaxDepth() + 1)
            {
                lastPaths[aiAgentIndex] = Pathfinder.GetNextDestNode(start, end, internalNodes, topLevelNode);
            }
            else
            {
                lastPaths[aiAgentIndex] = Pathfinder.AstarPathfind(start, end, internalNodes);
            }
        }
예제 #2
0
        //obtain the next node that the specified AI should move to
        public Node GetNextDestination(int aiAgentIndex, Node currentPosition)
        {
            if (paths == null || paths.Count <= aiAgentIndex)
            {
                return(null);
            }
            if (paths[aiAgentIndex] == null || paths[aiAgentIndex].Count == 0)
            {
                return(null);
            }

            //if the current position is null, then the AI is not on any node. Return the start of the path.
            if (currentPosition == null)
            {
                return(topLevelNode.GetNode(paths[aiAgentIndex][0]));
            }

            //if the AI is currently on a node, return the last node of the current rigidbody, or the first node of the next rigidbody
            NodeIndex finalNodeOnCurrentRB = null;

            for (int i = 0; i < paths[aiAgentIndex].Count; ++i)
            {
                if (finalNodeOnCurrentRB == null)
                {
                    finalNodeOnCurrentRB = paths[aiAgentIndex][i];
                }
                else if (finalNodeOnCurrentRB.EqualAtDepth(paths[aiAgentIndex][i], finalNodeOnCurrentRB.GetMaxDepth() - 1))
                {
                    finalNodeOnCurrentRB = paths[aiAgentIndex][i];
                }
            }

            return(topLevelNode.GetNode(finalNodeOnCurrentRB));
        }
예제 #3
0
        //return the path from the start point to the destination point
        public List <NodeIndex> GetPath(int aiAgentIndex, NodeIndex startPoint, NodeIndex endPoint, Node topLevelNode)
        {
            if (lastPaths == null || lastPaths.Count <= aiAgentIndex)
            {
                return(null);
            }

            if (startPoint == endPoint)
            {
                return(null);
            }

            //if the start and end point are both in the same child node, delegate to that child
            int nextDepth = index.GetMaxDepth() + 1;

            if (startPoint.EqualAtDepth(endPoint, nextDepth))
            {
                if (startPoint.GetIndexAtDepth(nextDepth) >= internalNodes.Count)
                {
                    return(null);
                }
                if (startPoint.GetIndexAtDepth(nextDepth) < 0)
                {
                    return(null);
                }

                return(internalNodes[startPoint.GetIndexAtDepth(nextDepth)].GetPath(aiAgentIndex, startPoint, endPoint, topLevelNode));
            }


            //if there is no cached path for the specified AI
            if (lastPaths[aiAgentIndex] == null || lastPaths[aiAgentIndex].Count < 1 || lastDestinations[aiAgentIndex] != endPoint || lastOrigins[aiAgentIndex] != startPoint)
            {
                bool present = false;

                //check the cached paths of the other AI's to see if any of them would be suitable
                for (int i = 0; i < lastOrigins.Count; ++i)
                {
                    if (i != aiAgentIndex && (lastOrigins[i] == startPoint) && (lastDestinations[i] == endPoint))
                    {
                        lastPaths[aiAgentIndex]        = new List <NodeIndex>(lastPaths[i]);
                        lastOrigins[aiAgentIndex]      = startPoint;
                        lastDestinations[aiAgentIndex] = endPoint;

                        i       = lastOrigins.Count;
                        present = true;
                    }
                }

                //if not then generate the path
                if (!present)
                {
                    GeneratePath(aiAgentIndex, startPoint, endPoint, topLevelNode);
                    if (lastPaths[aiAgentIndex] == null || lastPaths[aiAgentIndex].Count < 1)
                    {
                        return(null);
                    }
                    lastDestinations[aiAgentIndex] = endPoint;
                    lastOrigins[aiAgentIndex]      = startPoint;
                }
            }


            //if the next level is the deepest level then return this level's path
            if (startPoint.GetMaxDepth() == nextDepth)
            {
                return(lastPaths[aiAgentIndex]);
            }

            //If there is only one node in the path then something is wrong, because by this point the start and endpoint should be in different nodes
            if (lastPaths[aiAgentIndex].Count < 2)
            {
                return(null);
            }


            int       localStart = lastPaths[aiAgentIndex][0].GetIndexAtDepth(nextDepth);
            NodeIndex localDest  = lastPaths[aiAgentIndex][1];

            //find the path within the first node of the current level path and return that
            //Once the path has been found, pathfind within it's first node to determine how to get to the second node of the path
            return(internalNodes[localStart].GetPath(aiAgentIndex, startPoint, localDest, topLevelNode));
        }