예제 #1
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++)
            {
                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);
                    }
                }
            }
        }
예제 #2
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, bool 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++)
            {
                var funnelPart  = parts[i] as RichFunnel;
                var specialPart = parts[i] as RichSpecial;
                if (funnelPart != null)
                {
                    ObjectPool <RichFunnel> .Release(ref funnelPart);
                }
                else if (specialPart != null)
                {
                    ObjectPool <RichSpecial> .Release(ref specialPart);
                }
            }

            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.funnelSimplification = 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);
                }
            }
        }