Beispiel #1
0
        /** Use this for initialization.
         *
         * \param s Optionally provide in order to take tag penalties into account. May be null if you do not use a Seeker\
         * \param p Path to follow
         * \param mergePartEndpoints If true, then adjacent parts that the path is split up in will
         * try to use the same start/end points. For example when using a link on a navmesh graph
         * Instead of first following the path to the center of the node where the link is and then
         * follow the link, the path will be adjusted to go to the exact point where the link starts
         * which usually makes more sense.
         * \param simplificationMode The path can optionally be simplified. This can be a bit expensive for long paths.
         */
        public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode)
        {
            if (p.error)
            {
                throw new System.ArgumentException("Path has an error");
            }

            List <GraphNode> nodes = p.path;

            if (nodes.Count == 0)
            {
                throw new System.ArgumentException("Path traverses no nodes");
            }

            seeker = s;
            // Release objects back to object pool
            // Yeah, I know, it's casting... but this won't be called much
            for (int i = 0; i < parts.Count; i++)
            {
                if (parts[i] is RichFunnel)
                {
                    ObjectPool <RichFunnel> .Release(parts[i] as RichFunnel);
                }
                else if (parts[i] is RichSpecial)
                {
                    ObjectPool <RichSpecial> .Release(parts[i] as RichSpecial);
                }
            }

            parts.Clear();
            currentPart = 0;

            // Initialize new

            //Break path into parts
            for (int i = 0; i < nodes.Count; i++)
            {
                if (nodes[i] is TriangleMeshNode)
                {
                    var        graph = AstarData.GetGraph(nodes[i]);
                    RichFunnel f     = ObjectPool <RichFunnel> .Claim().Initialize(this, graph);

                    f.funnelSimplificationMode = simplificationMode;

                    int  sIndex            = i;
                    uint currentGraphIndex = nodes[sIndex].GraphIndex;


                    for (; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex && !(nodes[i] is NodeLink3Node))
                        {
                            break;
                        }
                    }
                    i--;

                    if (sIndex == 0)
                    {
                        f.exactStart = p.vectorPath[0];
                    }
                    else
                    {
                        f.exactStart = (Vector3)nodes[mergePartEndpoints ? sIndex - 1 : sIndex].position;
                    }

                    if (i == nodes.Count - 1)
                    {
                        f.exactEnd = p.vectorPath[p.vectorPath.Count - 1];
                    }
                    else
                    {
                        f.exactEnd = (Vector3)nodes[mergePartEndpoints ? i + 1 : i].position;
                    }

                    f.BuildFunnelCorridor(nodes, sIndex, i);

                    parts.Add(f);
                }
                else if (NodeLink2.GetNodeLink(nodes[i]) != null)
                {
                    NodeLink2 nl = NodeLink2.GetNodeLink(nodes[i]);

                    int  sIndex            = i;
                    uint currentGraphIndex = nodes[sIndex].GraphIndex;

                    for (i++; i < nodes.Count; i++)
                    {
                        if (nodes[i].GraphIndex != currentGraphIndex)
                        {
                            break;
                        }
                    }
                    i--;

                    if (i - sIndex > 1)
                    {
                        throw new System.Exception("NodeLink2 path length greater than two (2) nodes. " + (i - sIndex));
                    }
                    else if (i - sIndex == 0)
                    {
                        //Just continue, it might be the case that a NodeLink was the closest node
                        continue;
                    }

                    RichSpecial rps = ObjectPool <RichSpecial> .Claim().Initialize(nl, nodes[sIndex]);

                    parts.Add(rps);
                }
            }
        }
Beispiel #2
0
        public void BuildFunnelCorridor(List <GraphNode> nodes, int start, int end)
        {
            this.exactStart = (nodes[start] as MeshNode).ClosestPointOnNode(this.exactStart);
            this.exactEnd   = (nodes[end] as MeshNode).ClosestPointOnNode(this.exactEnd);
            this.left.Clear();
            this.right.Clear();
            this.left.Add(this.exactStart);
            this.right.Add(this.exactStart);
            this.nodes.Clear();
            IRaycastableGraph raycastableGraph = this.graph as IRaycastableGraph;

            if (raycastableGraph != null && this.funnelSimplificationMode != RichFunnel.FunnelSimplification.None)
            {
                List <GraphNode> list = ListPool <GraphNode> .Claim(end - start);

                RichFunnel.FunnelSimplification funnelSimplification = this.funnelSimplificationMode;
                if (funnelSimplification != RichFunnel.FunnelSimplification.Iterative)
                {
                    if (funnelSimplification != RichFunnel.FunnelSimplification.RecursiveBinary)
                    {
                        if (funnelSimplification == RichFunnel.FunnelSimplification.RecursiveTrinary)
                        {
                            RichFunnel.SimplifyPath3(raycastableGraph, nodes, start, end, list, this.exactStart, this.exactEnd, 0);
                        }
                    }
                    else
                    {
                        RichFunnel.SimplifyPath2(raycastableGraph, nodes, start, end, list, this.exactStart, this.exactEnd);
                    }
                }
                else
                {
                    this.SimplifyPath(raycastableGraph, nodes, start, end, list, this.exactStart, this.exactEnd);
                }
                if (this.nodes.Capacity < list.Count)
                {
                    this.nodes.Capacity = list.Count;
                }
                for (int i = 0; i < list.Count; i++)
                {
                    TriangleMeshNode triangleMeshNode = list[i] as TriangleMeshNode;
                    if (triangleMeshNode != null)
                    {
                        this.nodes.Add(triangleMeshNode);
                    }
                }
                ListPool <GraphNode> .Release(list);
            }
            else
            {
                if (this.nodes.Capacity < end - start)
                {
                    this.nodes.Capacity = end - start;
                }
                for (int j = start; j <= end; j++)
                {
                    TriangleMeshNode triangleMeshNode2 = nodes[j] as TriangleMeshNode;
                    if (triangleMeshNode2 != null)
                    {
                        this.nodes.Add(triangleMeshNode2);
                    }
                }
            }
            for (int k = 0; k < this.nodes.Count - 1; k++)
            {
                this.nodes[k].GetPortal(this.nodes[k + 1], this.left, this.right, false);
            }
            this.left.Add(this.exactEnd);
            this.right.Add(this.exactEnd);
        }
Beispiel #3
0
        // Token: 0x06000033 RID: 51 RVA: 0x0000417C File Offset: 0x0000257C
        public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode)
        {
            if (p.error)
            {
                throw new ArgumentException("Path has an error");
            }
            List <GraphNode> path = p.path;

            if (path.Count == 0)
            {
                throw new ArgumentException("Path traverses no nodes");
            }
            this.seeker = s;
            for (int i = 0; i < this.parts.Count; i++)
            {
                if (this.parts[i] is RichFunnel)
                {
                    ObjectPool <RichFunnel> .Release(this.parts[i] as RichFunnel);
                }
                else if (this.parts[i] is RichSpecial)
                {
                    ObjectPool <RichSpecial> .Release(this.parts[i] as RichSpecial);
                }
            }
            this.parts.Clear();
            this.currentPart = 0;
            for (int j = 0; j < path.Count; j++)
            {
                if (path[j] is TriangleMeshNode)
                {
                    IFunnelGraph graph      = AstarData.GetGraph(path[j]) as IFunnelGraph;
                    RichFunnel   richFunnel = ObjectPool <RichFunnel> .Claim().Initialize(this, graph);

                    richFunnel.funnelSimplificationMode = simplificationMode;
                    int  num        = j;
                    uint graphIndex = path[num].GraphIndex;
                    while (j < path.Count)
                    {
                        if (path[j].GraphIndex != graphIndex && !(path[j] is NodeLink3Node))
                        {
                            break;
                        }
                        j++;
                    }
                    j--;
                    if (num == 0)
                    {
                        richFunnel.exactStart = p.vectorPath[0];
                    }
                    else if (mergePartEndpoints)
                    {
                        richFunnel.exactStart = (Vector3)path[num - 1].position;
                    }
                    else
                    {
                        richFunnel.exactStart = (Vector3)path[num].position;
                    }
                    if (j == path.Count - 1)
                    {
                        richFunnel.exactEnd = p.vectorPath[p.vectorPath.Count - 1];
                    }
                    else if (mergePartEndpoints)
                    {
                        richFunnel.exactEnd = (Vector3)path[j + 1].position;
                    }
                    else
                    {
                        richFunnel.exactEnd = (Vector3)path[j].position;
                    }
                    richFunnel.BuildFunnelCorridor(path, num, j);
                    this.parts.Add(richFunnel);
                }
                else if (path[j] != null && NodeLink2.GetNodeLink(path[j]) != null)
                {
                    NodeLink2 nodeLink    = NodeLink2.GetNodeLink(path[j]);
                    int       num2        = j;
                    uint      graphIndex2 = path[num2].GraphIndex;
                    for (j++; j < path.Count; j++)
                    {
                        if (path[j].GraphIndex != graphIndex2)
                        {
                            break;
                        }
                    }
                    j--;
                    if (j - num2 > 1)
                    {
                        throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num2));
                    }
                    if (j - num2 != 0)
                    {
                        RichSpecial item = ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path[num2]);

                        this.parts.Add(item);
                    }
                }
            }
        }
Beispiel #4
0
        public void Initialize(Seeker s, Path p, bool mergePartEndpoints, RichFunnel.FunnelSimplification simplificationMode)
        {
            if (p.error)
            {
                throw new ArgumentException("Path has an error");
            }
            List <GraphNode> path = p.path;

            if (path.Count == 0)
            {
                throw new ArgumentException("Path traverses no nodes");
            }
            this.seeker = s;
            for (int i = 0; i < this.parts.Count; i++)
            {
                RichFunnel  funnel  = this.parts[i] as RichFunnel;
                RichSpecial special = this.parts[i] as RichSpecial;
                if (funnel != null)
                {
                    Pathfinding.Util.ObjectPool <RichFunnel> .Release(ref funnel);
                }
                else if (special != null)
                {
                    Pathfinding.Util.ObjectPool <RichSpecial> .Release(ref special);
                }
            }
            this.parts.Clear();
            this.currentPart = 0;
            for (int j = 0; j < path.Count; j++)
            {
                if (path[j] is TriangleMeshNode)
                {
                    NavGraph   graph = AstarData.GetGraph(path[j]);
                    RichFunnel item  = Pathfinding.Util.ObjectPool <RichFunnel> .Claim().Initialize(this, graph);

                    item.funnelSimplificationMode = simplificationMode;
                    int  start      = j;
                    uint graphIndex = path[start].GraphIndex;
                    while (j < path.Count)
                    {
                        if ((path[j].GraphIndex != graphIndex) && !(path[j] is NodeLink3Node))
                        {
                            break;
                        }
                        j++;
                    }
                    j--;
                    if (start == 0)
                    {
                        item.exactStart = p.vectorPath[0];
                    }
                    else
                    {
                        item.exactStart = (Vector3)path[!mergePartEndpoints ? start : (start - 1)].position;
                    }
                    if (j == (path.Count - 1))
                    {
                        item.exactEnd = p.vectorPath[p.vectorPath.Count - 1];
                    }
                    else
                    {
                        item.exactEnd = (Vector3)path[!mergePartEndpoints ? j : (j + 1)].position;
                    }
                    item.BuildFunnelCorridor(path, start, j);
                    this.parts.Add(item);
                    continue;
                }
                if (NodeLink2.GetNodeLink(path[j]) != null)
                {
                    NodeLink2 nodeLink = NodeLink2.GetNodeLink(path[j]);
                    int       num5     = j;
                    uint      num6     = path[num5].GraphIndex;
                    j++;
                    while (j < path.Count)
                    {
                        if (path[j].GraphIndex != num6)
                        {
                            break;
                        }
                        j++;
                    }
                    j--;
                    if ((j - num5) > 1)
                    {
                        throw new Exception("NodeLink2 path length greater than two (2) nodes. " + (j - num5));
                    }
                    if ((j - num5) != 0)
                    {
                        RichSpecial special2 = Pathfinding.Util.ObjectPool <RichSpecial> .Claim().Initialize(nodeLink, path[num5]);

                        this.parts.Add(special2);
                    }
                }
            }
        }