Exemplo n.º 1
0
    //public GameObject meshRenderer;

    public override void OnInspectorGUI(NavGraph target)
    {
        NavMeshGraph graph = target as NavMeshGraph;

#if UNITY_3_3
        graph.sourceMesh = EditorGUILayout.ObjectField("Source Mesh", graph.sourceMesh, typeof(Mesh)) as Mesh;
#else
        graph.sourceMesh = EditorGUILayout.ObjectField("Source Mesh", graph.sourceMesh, typeof(Mesh), true) as Mesh;
#endif
        graph.offset   = EditorGUILayout.Vector3Field("Offset", graph.offset);
        graph.rotation = EditorGUILayout.Vector3Field("Rotation", graph.rotation);
        graph.scale    = EditorGUILayout.FloatField("Scale", graph.scale);
        graph.scale    = (graph.scale <0.01F && graph.scale> -0.01F) ? (graph.scale >= 0 ? 0.01F : -0.01F) : graph.scale;
    }
Exemplo n.º 2
0
        // --------------------------------------------------------------------------------

        public void SaveGraph(NavMeshGraph graph)
        {
            if (graph == null)
            {
                Debug.LogError("[NavMeshData::SaveData] Failed, graph is null");
                return;
            }

            var mappedNodes = new List <NodeToUID>();
            int nextId      = 0;

            // map graph nodes to an id
            var nodeEnumerator = graph.NodeEnumerator;

            while (nodeEnumerator.MoveNext())
            {
                NodeToUID mappedNode = new NodeToUID()
                {
                    m_node = nodeEnumerator.Current,
                    m_uid  = nextId++,
                };
                mappedNodes.Add(mappedNode);
            }

            // save node position and connections
            m_nodeData.Clear();
            for (int i = 0; i < mappedNodes.Count; ++i)
            {
                var node = mappedNodes[i].m_node;
                // position & uid
                NavMeshNodeData nodeData = new NavMeshNodeData()
                {
                    m_position = node.Data,
                    m_uid      = mappedNodes[i].m_uid,
                };

                // connections
                var edgeEnumerator = node.EdgeEnumerator;
                while (edgeEnumerator.MoveNext())
                {
                    var connectedNode = edgeEnumerator.Current.GetOther(node);
                    nodeData.m_connections.Add(mappedNodes.Find(n => n.m_node == connectedNode).m_uid);
                }

                m_nodeData.Add(nodeData);
            }
        }
Exemplo n.º 3
0
    private static Int3 InternalMove(Int3 srcLoc, Int3 delta, ref Int groundY)
    {
        Int3 num4;

        if ((delta.x == 0) && (delta.z == 0))
        {
            return(delta);
        }
        Int3         end   = srcLoc + delta;
        int          edge  = -1;
        NavMeshGraph graph = PathFindingMachine.Instance.navgationGraph as NavMeshGraph;
        NavMeshNode  node  = graph.bbTree.QueryInside(srcLoc, null);

        if (node == null)
        {
            NavMeshNode node2 = graph.bbTree.QueryInside(end, null);
            if (node2 == null)
            {
                return(Int3.zero);
            }
            else
            {
                edge = node2.EdgeIntersect(srcLoc, end);
                node = node2;
            }
        }

        MoveFromNode(node, edge, srcLoc, end, out num4);

        checkedNodes.Clear();
        groundY = num4.y;
        if (!MoveAxisY)
        {
            num4.y = srcLoc.y;
        }
        return(num4 - srcLoc);
    }
Exemplo n.º 4
0
    /** Applies constrained movement from \a startPos to \a endPos.
     * The result is stored in \a clampedPos.
     * Returns the new current node */
    public GraphNode ClampAlongNavmesh(Vector3 startPos, GraphNode _startNode, Vector3 endPos, out Vector3 clampedPos)
    {
        ConvexMeshNode startNode = (ConvexMeshNode)_startNode;

        clampedPos = endPos;

        Stack <ConvexMeshNode> stack  = tmpStack;               // Tiny stack
        List <ConvexMeshNode>  closed = tmpClosed;              // Tiny closed list

        stack.Clear();
        closed.Clear();

        Vector3        bestPos, p;
        float          bestDist = float.PositiveInfinity;
        float          d;
        ConvexMeshNode bestRef = null;
        // Search constraint
        Vector3 searchPos    = (startPos + endPos) / 2;
        float   searchRadius = Mathfx.MagnitudeXZ(startPos, endPos) / 2;

        // Init
        bestPos = startPos;
        stack.Push(startNode);
        closed.Add(startNode);         // Self ref, start maker.

        INavmesh graph = AstarData.GetGraph(startNode) as INavmesh;

        if (graph == null)
        {
            //Debug.LogError ("Null graph, or the graph was no NavMeshGraph");
            return(startNode);
        }

#if ASTARDEBUG
        Debug.DrawLine(startPos, endPos, Color.blue);
#endif

        while (stack.Count > 0)
        {
            // Pop front.
            ConvexMeshNode cur = stack.Pop();

            // If target is inside the cur, stop search.
            if (NavMeshGraph.ContainsPoint(cur, endPos, graph.vertices))
            {
#if ASTARDEBUG
                Debug.DrawRay(endPos, Vector3.up, Color.red);
#endif
                bestRef = cur;
                bestPos = endPos;
                break;
            }
            // Follow edges or keep track of nearest point on blocking edge.
            for (int i = 0, j = 2; i < 3; j = i++)
            {
                int sp = cur.GetVertexIndex(j);
                int sq = cur.GetVertexIndex(i);

                bool           blocking = true;
                ConvexMeshNode conn     = null;

                for (int q = 0; q < cur.connections.Length; q++)
                {
                    conn = cur.connections[q] as ConvexMeshNode;
                    if (conn == null)
                    {
                        continue;
                    }

                    for (int i2 = 0, j2 = 2; i2 < 3; j2 = i2++)
                    {
                        int sp2 = conn.GetVertexIndex(j2);
                        int sq2 = conn.GetVertexIndex(i2);
                        if ((sp2 == sp && sq2 == sq) || (sp2 == sq && sq2 == sp))
                        {
                            blocking = false;
                            break;
                        }
                    }

                    if (!blocking)
                    {
                        break;
                    }
                }

                //Node neiRef = cur->nei[j];

                if (blocking)
                {
                    // Blocked edge, calc distance.
                    p = Mathfx.NearestPointStrictXZ((Vector3)graph.vertices[sp], (Vector3)graph.vertices[sq], endPos);

#if ASTARDEBUG
                    Debug.DrawLine((Vector3)graph.vertices[sp] + Vector3.up * 0.1F, (Vector3)graph.vertices[sq] + Vector3.up * 0.1F, Color.black);
#endif
                    d = Mathfx.MagnitudeXZ(p, endPos);
                    if (d < bestDist)
                    {
                        // Update nearest distance.
                        bestPos  = p;
                        bestDist = d;
                        bestRef  = cur;
                    }
                }
                else
                {
                    // Skip already visited.
                    if (closed.Contains(conn))
                    {
                        continue;
                    }
                    // Store to closed with parent for trace back.
                    closed.Add(conn);
#if ASTARDEBUG
                    Debug.DrawLine((Vector3)cur.position, (Vector3)conn.position, Color.black);
                    Debug.DrawLine((Vector3)graph.vertices[sp] + Vector3.up * 0.1F, (Vector3)graph.vertices[sq] + Vector3.up * 0.1F, Color.blue);
#endif

                    // Non-blocked edge, follow if within search radius.
                    p = Mathfx.NearestPointStrictXZ((Vector3)graph.vertices[sp], (Vector3)graph.vertices[sq], searchPos);

                    d = Mathfx.MagnitudeXZ(p, searchPos);
                    if (d <= searchRadius)
                    {
#if ASTARDEBUG
                        Debug.DrawLine((Vector3)searchPos - Vector3.up * 0.1F, p - Vector3.up * 0.1F, Color.cyan);
#endif
                        stack.Push(conn);
                    }
#if ASTARDEBUG
                    else
                    {
                        Debug.DrawLine((Vector3)searchPos - Vector3.up * 0.1F, p - Vector3.up * 0.1F, Color.red);
                    }
#endif
                }
            }
        }
        // Trace back and store visited curgons.

        /* followVisited(bestRef,visited,closed);
         * // Store best movement position.*/
        clampedPos = bestPos;
        // Return number of visited curs.
        return(bestRef);       //visited.size();
    }
Exemplo n.º 5
0
    public static Vector3 GetNextTarget(Path path, Vector3 currPosition, float offset, float pickNextWaypointMargin)
    {
        if (path.error)
        {
            return(currPosition);
        }

        Int3 currentPosition = (Int3)currPosition;

        int startIndex = 0;
        int endIndex   = path.path.Length;

        //Int3 pos = (Int3)currentPosition;

        //int minDist = -1;
        //int minNode = -1;

        INavmesh navmeshGraph = AstarData.GetGraph(path.path[0]) as INavmesh;

        if (navmeshGraph == null)
        {
            Debug.LogError("Couldn't cast graph to the appropriate type (graph isn't a Navmesh type graph, it doesn't implement the INavmesh interface)");
            return(currPosition);           ///Apply (path,start,end, startIndex, endIndex, graph);
        }

        Int3[] vertices = navmeshGraph.vertices;

        //float minDist2 = -1;
        //int minNode2 = -1;

        //Debug.Log (meshPath.Length + " "+path.Length +" "+startIndex+" "+endIndex);

        /*for (int i=startIndex;i< endIndex;i++) {
         *      MeshNode node = path.path[i] as MeshNode;
         *
         *      if (node == null) {
         *              Debug.LogWarning ("Path could not be casted to Mesh Nodes");
         *              return currentPosition;//return base.Apply (path,start,end, startIndex, endIndex, graph);
         *      }
         *
         *      //if (Polygon.TriangleArea2 (vertices[node.v1],vertices[node.v2],currentPosition) >= 0 || Polygon.TriangleArea2 (vertices[node.v2],vertices[node.v3],currentPosition) >= 0 || Polygon.TriangleArea2 (vertices[node.v3],vertices[node.v1],currentPosition) >= 0) {
         *
         *      if (!Polygon.IsClockwise (vertices[node.v1],vertices[node.v2],pos) || !Polygon.IsClockwise (vertices[node.v2],vertices[node.v3],pos) || !Polygon.IsClockwise (vertices[node.v3],vertices[node.v1],pos)) {
         *
         *              if (minDist == -1) {
         *                      float dist2 = (node.position-pos).sqrMagnitude;
         *                      if (minDist2 == -1 || dist2 < minDist2) {
         *                              minDist2 = dist2;
         *                              minNode2 = i;
         *                      }
         *              }
         *              continue;
         *      }
         *
         *      Debug.DrawLine (vertices[node.v1],vertices[node.v2],Color.blue);
         *      Debug.DrawLine (vertices[node.v2],vertices[node.v3],Color.blue);
         *      Debug.DrawLine (vertices[node.v3],vertices[node.v1],Color.blue);
         *
         *
         *      int dist = node.position.y-pos.y;
         *
         *      if (minDist == -1 || dist < minDist) {
         *              minDist = dist;
         *              minNode = i;
         *      }
         *
         * }*/

        MeshNode lastNode = path.path[endIndex - 1] as MeshNode;

        if (lastNode == null)
        {
            Debug.LogWarning("Path could not be casted to Mesh Nodes");
            return(currentPosition);           //return base.Apply (path,start,end, startIndex, endIndex, graph);
        }

        PathNNConstraint constraint = PathNNConstraint.Default;

        constraint.SetStart(lastNode);
        NNInfo nninfo = NavMeshGraph.GetNearestForce(path.path, vertices, currPosition, constraint);

        currentPosition = nninfo.clampedPosition;

        /*for (int i=startIndex;i< endIndex;i++) {
         *      if (nninfo.node == path.path[i]) {
         *              minNode = i;
         *      }
         * }*/

        //Node minNode = nninfo.node;

        /*startIndex = minNode;
         * if (startIndex == -1) {
         *      startIndex = minNode2;
         *      currentPosition = path.path[minNode2].position;
         * }
         * if (startIndex == -1) {
         *      Debug.Log ("Couldn't find current node");
         *      return currentPosition;
         * }*/

        MeshNode[] meshPath = new MeshNode[endIndex - startIndex];

        for (int i = startIndex; i < endIndex; i++)
        {
            meshPath[i - startIndex] = path.path[i] as MeshNode;
        }
        //return Vector3.zero;

        //Vector3[] vertices = null;

        if (leftFunnel == null || leftFunnel.Length < meshPath.Length + 1)
        {
            leftFunnel = new Int3[meshPath.Length + 1];
        }
        if (rightFunnel == null || rightFunnel.Length < meshPath.Length + 1)
        {
            rightFunnel = new Int3[meshPath.Length + 1];
        }
        int leftFunnelLength = meshPath.Length + 1;

        //int rightFunnelLength = meshPath.Length+1;

        leftFunnel[0]  = currentPosition;
        rightFunnel[0] = currentPosition;

        leftFunnel[meshPath.Length]  = path.endPoint;
        rightFunnel[meshPath.Length] = path.endPoint;

        int lastLeftIndex  = -1;
        int lastRightIndex = -1;

        for (int i = 0; i < meshPath.Length - 1; i++)
        {
            //Find the connection between the nodes

            MeshNode n1 = meshPath[i];
            MeshNode n2 = meshPath[i + 1];

            bool foundFirst = false;

            int first  = -1;
            int second = -1;

            for (int x = 0; x < 3; x++)
            {
                //Vector3 vertice1 = vertices[n1.vertices[x]];
                //n1[x] gets the vertice index for vertex number 'x' in the node. Equal to n1.GetVertexIndex (x)
                int vertice1 = n1[x];
                for (int y = 0; y < 3; y++)
                {
                    //Vector3 vertice2 = vertices[n2.vertices[y]];
                    int vertice2 = n2[y];

                    if (vertice1 == vertice2)
                    {
                        if (foundFirst)
                        {
                            second = vertice2;
                            break;
                        }
                        else
                        {
                            first      = vertice2;
                            foundFirst = true;
                        }
                    }
                }
            }

            //Debug.DrawLine ((Vector3)vertices[first]+Vector3.up*0.1F,(Vector3)vertices[second]+Vector3.up*0.1F,Color.cyan);
            //Debug.Log (first+" "+second);
            if (first == lastLeftIndex)
            {
                leftFunnel[i + 1]  = vertices[first];
                rightFunnel[i + 1] = vertices[second];
                lastLeftIndex      = first;
                lastRightIndex     = second;
            }
            else if (first == lastRightIndex)
            {
                leftFunnel[i + 1]  = vertices[second];
                rightFunnel[i + 1] = vertices[first];
                lastLeftIndex      = second;
                lastRightIndex     = first;
            }
            else if (second == lastLeftIndex)
            {
                leftFunnel[i + 1]  = vertices[second];
                rightFunnel[i + 1] = vertices[first];
                lastLeftIndex      = second;
                lastRightIndex     = first;
            }
            else
            {
                leftFunnel[i + 1]  = vertices[first];
                rightFunnel[i + 1] = vertices[second];
                lastLeftIndex      = first;
                lastRightIndex     = second;
            }
        }

        //Switch the arrays so the right funnel really is on the right side (and vice versa)
        if (!Polygon.IsClockwise(currentPosition, leftFunnel[1], rightFunnel[1]))
        {
            Int3[] tmp = leftFunnel;
            leftFunnel  = rightFunnel;
            rightFunnel = tmp;
        }

        for (int i = 1; i < leftFunnelLength - 1; i++)
        {
            //float unitWidth = 2;
            Int3 normal = (rightFunnel[i] - leftFunnel[i]);

            float magn = normal.worldMagnitude;
            normal         /= magn;
            normal         *= Mathf.Clamp(offset, 0, (magn / 2F));
            leftFunnel[i]  += normal;
            rightFunnel[i] -= normal;
            //Debug.DrawLine (rightFunnel[i],leftFunnel[i],Color.blue);
        }

        /*for (int i=0;i<path.Length-1;i++) {
         *      Debug.DrawLine (path[i].position,path[i+1].position,Color.blue);
         * }*/

        /*for (int i=0;i<leftFunnel.Length-1;i++) {
         *      Debug.DrawLine (leftFunnel[i],leftFunnel[i+1],Color.red);
         *      Debug.DrawLine (rightFunnel[i],rightFunnel[i+1],Color.magenta);
         * }*/

        if (tmpList == null)
        {
            tmpList = new List <Vector3>(3);
        }

        List <Vector3> funnelPath = tmpList;

        funnelPath.Clear();

        funnelPath.Add(currentPosition);

        Int3 portalApex  = currentPosition;
        Int3 portalLeft  = leftFunnel[0];
        Int3 portalRight = rightFunnel[0];

        int apexIndex  = 0;
        int rightIndex = 0;
        int leftIndex  = 0;

        //yield return 0;

        for (int i = 1; i < leftFunnelLength; i++)
        {
            Int3 left  = leftFunnel[i];
            Int3 right = rightFunnel[i];

            /*Debug.DrawLine (portalApex,portalLeft,Color.red);
             * Debug.DrawLine (portalApex,portalRight,Color.yellow);
             * Debug.DrawLine (portalApex,left,Color.cyan);
             * Debug.DrawLine (portalApex,right,Color.cyan);*/

            if (Polygon.TriangleArea2(portalApex, portalRight, right) >= 0)
            {
                if (portalApex == portalRight || Polygon.TriangleArea2(portalApex, portalLeft, right) <= 0)
                {
                    portalRight = right;
                    rightIndex  = i;
                }
                else
                {
                    funnelPath.Add((Vector3)portalLeft);

                    //if (funnelPath.Count > 3)
                    //break;

                    portalApex = portalLeft;
                    apexIndex  = leftIndex;

                    portalLeft  = portalApex;
                    portalRight = portalApex;

                    leftIndex  = apexIndex;
                    rightIndex = apexIndex;

                    i = apexIndex;

                    //yield return 0;
                    continue;
                }
            }

            if (Polygon.TriangleArea2(portalApex, portalLeft, left) <= 0)
            {
                if (portalApex == portalLeft || Polygon.TriangleArea2(portalApex, portalRight, left) >= 0)
                {
                    portalLeft = left;
                    leftIndex  = i;
                }
                else
                {
                    funnelPath.Add((Vector3)portalRight);

                    //if (funnelPath.Count > 3)
                    //break;

                    portalApex = portalRight;
                    apexIndex  = rightIndex;

                    portalLeft  = portalApex;
                    portalRight = portalApex;

                    leftIndex  = apexIndex;
                    rightIndex = apexIndex;

                    i = apexIndex;

                    //yield return 0;
                    continue;
                }
            }

            //yield return 0;
        }

        //yield return 0;

        funnelPath.Add(path.endPoint);

        Vector3[] p = funnelPath.ToArray();


        if (p.Length <= 1)
        {
            return(currentPosition);
        }

        for (int i = 1; i < p.Length - 1; i++)
        {
            Vector3 closest = Mathfx.NearestPointStrict(p[i], p[i + 1], currentPosition);
            if ((closest - (Vector3)currentPosition).sqrMagnitude < pickNextWaypointMargin * pickNextWaypointMargin)
            {
                continue;
            }
            else
            {
                return(p[i]);
            }
        }
        return(p[p.Length - 1]);
    }
Exemplo n.º 6
0
    // Token: 0x0600001A RID: 26 RVA: 0x00002B84 File Offset: 0x00000F84
    public GraphNode ClampAlongNavmesh(Vector3 startPos, GraphNode _startNode, Vector3 endPos, out Vector3 clampedPos)
    {
        TriangleMeshNode triangleMeshNode = (TriangleMeshNode)_startNode;

        clampedPos = endPos;
        Stack <TriangleMeshNode> stack = this.tmpStack;
        List <TriangleMeshNode>  list  = this.tmpClosed;

        stack.Clear();
        list.Clear();
        float            num     = float.PositiveInfinity;
        TriangleMeshNode result  = null;
        Vector3          vector  = (startPos + endPos) / 2f;
        float            num2    = AstarMath.MagnitudeXZ(startPos, endPos) / 2f;
        Vector3          vector2 = startPos;

        stack.Push(triangleMeshNode);
        list.Add(triangleMeshNode);
        INavmesh navmesh = AstarData.GetGraph(triangleMeshNode) as INavmesh;

        if (navmesh == null)
        {
            return(triangleMeshNode);
        }
        while (stack.Count > 0)
        {
            TriangleMeshNode triangleMeshNode2 = stack.Pop();
            int    tileIndex         = ((RecastGraph)navmesh).GetTileIndex(triangleMeshNode2.GetVertexIndex(0));
            Int3[] verts             = ((RecastGraph)navmesh).GetTiles()[tileIndex].verts;
            int    vertexArrayIndex  = triangleMeshNode2.GetVertexArrayIndex(triangleMeshNode2.v0);
            int    vertexArrayIndex2 = triangleMeshNode2.GetVertexArrayIndex(triangleMeshNode2.v1);
            int    vertexArrayIndex3 = triangleMeshNode2.GetVertexArrayIndex(triangleMeshNode2.v2);
            if (NavMeshGraph.ContainsPoint(vertexArrayIndex, vertexArrayIndex2, vertexArrayIndex3, endPos, verts))
            {
                result  = triangleMeshNode2;
                vector2 = endPos;
                break;
            }
            int i  = 0;
            int i2 = 2;
            while (i < 3)
            {
                int              vertexIndex       = triangleMeshNode2.GetVertexIndex(i2);
                int              vertexIndex2      = triangleMeshNode2.GetVertexIndex(i);
                bool             flag              = true;
                TriangleMeshNode triangleMeshNode3 = null;
                for (int j = 0; j < triangleMeshNode2.connections.Length; j++)
                {
                    triangleMeshNode3 = (triangleMeshNode2.connections[j] as TriangleMeshNode);
                    if (triangleMeshNode3 != null)
                    {
                        int k  = 0;
                        int i3 = 2;
                        while (k < 3)
                        {
                            int vertexIndex3 = triangleMeshNode3.GetVertexIndex(i3);
                            int vertexIndex4 = triangleMeshNode3.GetVertexIndex(k);
                            if ((vertexIndex3 == vertexIndex && vertexIndex4 == vertexIndex2) || (vertexIndex3 == vertexIndex2 && vertexIndex4 == vertexIndex))
                            {
                                flag = false;
                                break;
                            }
                            i3 = k++;
                        }
                        if (!flag)
                        {
                            break;
                        }
                    }
                }
                if (flag)
                {
                    Vector3 vector3 = AstarMath.NearestPointStrictXZ((Vector3)verts[vertexIndex], (Vector3)verts[vertexIndex2], endPos);
                    float   num3    = AstarMath.MagnitudeXZ(vector3, endPos);
                    if (num3 < num)
                    {
                        vector2 = vector3;
                        num     = num3;
                        result  = triangleMeshNode2;
                    }
                }
                else if (!list.Contains(triangleMeshNode3))
                {
                    list.Add(triangleMeshNode3);
                    Vector3 vector3 = AstarMath.NearestPointStrictXZ((Vector3)verts[vertexIndex], (Vector3)verts[vertexIndex2], vector);
                    float   num3    = AstarMath.MagnitudeXZ(vector3, vector);
                    if (num3 <= num2)
                    {
                        stack.Push(triangleMeshNode3);
                    }
                }
                i2 = i++;
            }
        }
        clampedPos = vector2;
        return(result);
    }
Exemplo n.º 7
0
    private IEnumerator UpdateGraphRoutine(NavMeshGraph graph)
    {
        updateInProgress = true;

        pathing.AddWorkItem(() =>
        {
            UnstitchFromNeighbors(graph);
        });

        pathing.FlushWorkItems();
        while (pathing.IsAnyWorkItemInProgress)
        {
            yield return(null);
        }

        if (toRemove.Contains(graph))
        {
            pathing.data.RemoveGraph(graph);


            toRemove.Remove(graph);
        }

        else
        {
            while (pathing.isScanning)
            {
                yield return(null);
            }
            pathing.Scan(graph);
            while (pathing.isScanning)
            {
                yield return(null);
            }



            pathing.AddWorkItem(() =>
            {
                StitchToNeighbors(graph);
            });
            pathing.FlushWorkItems();

            while (pathing.IsAnyWorkItemInProgress)
            {
                yield return(null);
            }

            if (!lastUpdate.ContainsKey(graph))
            {
                lastUpdate.Add(graph, Time.time);
            }
            else
            {
                lastUpdate[graph] = Time.time;
            }
        }

        updateInProgress = false;
        if (updateQueue.Count > 0)
        {
            StartCoroutine(UpdateGraphRoutine(updateQueue.Dequeue()));
        }
    }
Exemplo n.º 8
0
 private void UnstitchFromNeighbors(NavMeshGraph myGraph)
 {
     myGraph.GetNodes(node =>
                      RemoveOffGraphConnections(node));
 }