WillUpdateNode() public method

public WillUpdateNode ( Node node ) : void
node Node
return void
Example #1
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            Bounds bounds = o.bounds;

            // Bounding rectangle with floating point coordinates
            Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);

            // Bounding rectangle with int coordinates
            var r2 = new IntRect(
                Mathf.FloorToInt(bounds.min.x * Int3.Precision),
                Mathf.FloorToInt(bounds.min.z * Int3.Precision),
                Mathf.FloorToInt(bounds.max.x * Int3.Precision),
                Mathf.FloorToInt(bounds.max.z * Int3.Precision)
                );

            // Corners of the bounding rectangle
            var a = new Int3(r2.xmin, 0, r2.ymin);
            var b = new Int3(r2.xmin, 0, r2.ymax);
            var c = new Int3(r2.xmax, 0, r2.ymin);
            var d = new Int3(r2.xmax, 0, r2.ymax);

            var ymin = ((Int3)bounds.min).y;
            var ymax = ((Int3)bounds.max).y;

            // Loop through all nodes
            graph.GetNodes(_node => {
                var node = _node as TriangleMeshNode;

                bool inside = false;

                int allLeft   = 0;
                int allRight  = 0;
                int allTop    = 0;
                int allBottom = 0;

                // Check bounding box rect in XZ plane
                for (int v = 0; v < 3; v++)
                {
                    Int3 p   = node.GetVertex(v);
                    var vert = (Vector3)p;

                    if (r2.Contains(p.x, p.z))
                    {
                        inside = true;
                        break;
                    }

                    if (vert.x < r.xMin)
                    {
                        allLeft++;
                    }
                    if (vert.x > r.xMax)
                    {
                        allRight++;
                    }
                    if (vert.z < r.yMin)
                    {
                        allTop++;
                    }
                    if (vert.z > r.yMax)
                    {
                        allBottom++;
                    }
                }

                if (!inside)
                {
                    if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)
                    {
                        return(true);
                    }
                }

                // Check if the polygon edges intersect the bounding rect
                for (int v = 0; v < 3; v++)
                {
                    int v2 = v > 1 ? 0 : v + 1;

                    Int3 vert1 = node.GetVertex(v);
                    Int3 vert2 = node.GetVertex(v2);

                    if (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                }

                // Check if the node contains any corner of the bounding rect
                if (inside || node.ContainsPoint(a) || node.ContainsPoint(b) || node.ContainsPoint(c) || node.ContainsPoint(d))
                {
                    inside = true;
                }

                if (!inside)
                {
                    return(true);
                }

                int allAbove = 0;
                int allBelow = 0;

                // Check y coordinate
                for (int v = 0; v < 3; v++)
                {
                    Int3 p = node.GetVertex(v);
                    if (p.y < ymin)
                    {
                        allBelow++;
                    }
                    if (p.y > ymax)
                    {
                        allAbove++;
                    }
                }

                // Polygon is either completely above the bounding box or completely below it
                if (allBelow == 3 || allAbove == 3)
                {
                    return(true);
                }

                // Triangle is inside the bounding box!
                // Update it!
                o.WillUpdateNode(node);
                o.Apply(node);
                return(true);
            });
        }
Example #2
0
        /// <summary>
        /// Updates an area in the list graph.
        /// Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the guo will be recalculated
        /// </summary>
        void IUpdatableGraph.UpdateArea(GraphUpdateObject guo)
        {
            if (nodes == null)
            {
                return;
            }

            for (int i = 0; i < nodeCount; i++)
            {
                var node = nodes[i];
                if (guo.bounds.Contains((Vector3)node.position))
                {
                    guo.WillUpdateNode(node);
                    guo.Apply(node);
                }
            }

            if (guo.updatePhysics)
            {
                // Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates
                Bounds bounds = guo.bounds;

                if (thickRaycast)
                {
                    // Expand the bounding box to account for the thick raycast
                    bounds.Expand(thickRaycastRadius * 2);
                }

                // Create a temporary list used for holding connection data
                List <Connection> tmpList = Pathfinding.Util.ListPool <Connection> .Claim();

                for (int i = 0; i < nodeCount; i++)
                {
                    PointNode node    = nodes[i];
                    var       nodePos = (Vector3)node.position;

                    List <Connection> conn = null;

                    for (int j = 0; j < nodeCount; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }

                        var otherNodePos = (Vector3)nodes[j].position;
                        // Check if this connection intersects the bounding box.
                        // If it does we need to recalculate that connection.
                        if (VectorMath.SegmentIntersectsBounds(bounds, nodePos, otherNodePos))
                        {
                            float     dist;
                            PointNode other           = nodes[j];
                            bool      contains        = node.ContainsConnection(other);
                            bool      validConnection = IsValidConnection(node, other, out dist);

                            // Fill the 'conn' list when we need to change a connection
                            if (conn == null && (contains != validConnection))
                            {
                                tmpList.Clear();
                                conn = tmpList;
                                conn.AddRange(node.connections);
                            }

                            if (!contains && validConnection)
                            {
                                // A new connection should be added
                                uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision);
                                conn.Add(new Connection(other, cost));
                                RegisterConnectionLength((other.position - node.position).sqrMagnitudeLong);
                            }
                            else if (contains && !validConnection)
                            {
                                // A connection should be removed
                                for (int q = 0; q < conn.Count; q++)
                                {
                                    if (conn[q].node == other)
                                    {
                                        conn.RemoveAt(q);
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    // Save the new connections if any were changed
                    if (conn != null)
                    {
                        node.connections = conn.ToArray();
                        node.SetConnectivityDirty();
                    }
                }

                // Release buffers back to the pool
                Pathfinding.Util.ListPool <Connection> .Release(ref tmpList);
            }
        }
        // Token: 0x060004C2 RID: 1218 RVA: 0x000293EC File Offset: 0x000277EC
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            Bounds  bounds = o.bounds;
            Rect    r      = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);
            IntRect r2     = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f));
            Int3    a      = new Int3(r2.xmin, 0, r2.ymin);
            Int3    b      = new Int3(r2.xmin, 0, r2.ymax);
            Int3    c      = new Int3(r2.xmax, 0, r2.ymin);
            Int3    d      = new Int3(r2.xmax, 0, r2.ymax);
            Int3    ia     = a;
            Int3    ib     = b;
            Int3    ic     = c;
            Int3    id     = d;

            graph.GetNodes(delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode;
                bool flag = false;
                int num   = 0;
                int num2  = 0;
                int num3  = 0;
                int num4  = 0;
                for (int i = 0; i < 3; i++)
                {
                    Int3 vertex    = triangleMeshNode.GetVertex(i);
                    Vector3 vector = (Vector3)vertex;
                    if (r2.Contains(vertex.x, vertex.z))
                    {
                        flag = true;
                        break;
                    }
                    if (vector.x < r.xMin)
                    {
                        num++;
                    }
                    if (vector.x > r.xMax)
                    {
                        num2++;
                    }
                    if (vector.z < r.yMin)
                    {
                        num3++;
                    }
                    if (vector.z > r.yMax)
                    {
                        num4++;
                    }
                }
                if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3))
                {
                    return(true);
                }
                for (int j = 0; j < 3; j++)
                {
                    int i2       = (j <= 1) ? (j + 1) : 0;
                    Int3 vertex2 = triangleMeshNode.GetVertex(j);
                    Int3 vertex3 = triangleMeshNode.GetVertex(i2);
                    if (Polygon.Intersects(a, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (Polygon.Intersects(a, c, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (Polygon.Intersects(c, d, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (Polygon.Intersects(d, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                }
                if (triangleMeshNode.ContainsPoint(ia) || triangleMeshNode.ContainsPoint(ib) || triangleMeshNode.ContainsPoint(ic) || triangleMeshNode.ContainsPoint(id))
                {
                    flag = true;
                }
                if (!flag)
                {
                    return(true);
                }
                o.WillUpdateNode(triangleMeshNode);
                o.Apply(triangleMeshNode);
                return(true);
            });
        }
        public new void UpdateArea(GraphUpdateObject o)
        {
            if (nodes == null || nodes.Length != width*depth*layerCount) {
                Debug.LogWarning ("The Grid Graph is not scanned, cannot update area ");
                //Not scanned
                return;
            }

            //Copy the bounds
            Bounds b = o.bounds;

            //Matrix inverse
            //node.position = matrix.MultiplyPoint3x4 (new Vector3 (x+0.5F,0,z+0.5F));

            Vector3 min, max;
            GetBoundsMinMax (b,inverseMatrix,out min, out max);

            int minX = Mathf.RoundToInt (min.x-0.5F);
            int maxX = Mathf.RoundToInt (max.x-0.5F);

            int minZ = Mathf.RoundToInt (min.z-0.5F);
            int maxZ = Mathf.RoundToInt (max.z-0.5F);
            //We now have coordinates in local space (i.e 1 unit = 1 node)

            IntRect originalRect = new IntRect(minX,minZ,maxX,maxZ);
            IntRect affectRect = originalRect;

            IntRect gridRect = new IntRect(0,0,width-1,depth-1);

            IntRect physicsRect = originalRect;

            Matrix4x4 debugMatrix = matrix;
            debugMatrix *= Matrix4x4.TRS (new Vector3(0.5f,0,0.5f),Quaternion.identity,Vector3.one);

            #if ASTARDEBUG
            originalRect.DebugDraw (debugMatrix,Color.red);
            #endif

            bool willChangeWalkability = o.updatePhysics || o.modifyWalkability;

            bool willChangeNodeInstances = (o is LayerGridGraphUpdate ? ((LayerGridGraphUpdate)o).recalculateNodes : false);
            bool preserveExistingNodes = (o is LayerGridGraphUpdate ? ((LayerGridGraphUpdate)o).preserveExistingNodes : true);

            if (o.trackChangedNodes	&& willChangeNodeInstances) {
                Debug.LogError ("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph");
                return;
            }

            //Calculate the largest bounding box which might be affected

            if (o.updatePhysics && !o.modifyWalkability) {
                //Add the collision.diameter margin for physics calls
                if (collision.collisionCheck) {
                    Vector3 margin = new Vector3 (collision.diameter,0,collision.diameter)*0.5F;

                    min -= margin*1.02F;//0.02 safety margin, physics is rarely very accurate
                    max += margin*1.02F;

                    physicsRect = new IntRect(
                                                Mathf.RoundToInt (min.x-0.5F),
                                                Mathf.RoundToInt (min.z-0.5F),
                                                Mathf.RoundToInt (max.x-0.5F),
                                                Mathf.RoundToInt (max.z-0.5F)
                                                );

                    affectRect = IntRect.Union (physicsRect, affectRect);
                }
            }

            if (willChangeWalkability && erodeIterations > 0) {
                //Add affect radius for erosion. +1 for updating connectivity info at the border
                affectRect = affectRect.Expand (erodeIterations+1);
            }

            IntRect clampedRect = IntRect.Intersection (affectRect,gridRect);

            //Mark nodes that might be changed
            if (!willChangeNodeInstances) {
                for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
                    for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
                        for (int y=0;y<layerCount;y++) {
                            o.WillUpdateNode (nodes[y*width*depth + z*width+x]);
                        }
                    }
                }
            }

            //Update Physics
            if (o.updatePhysics && !o.modifyWalkability) {

                collision.Initialize (matrix,nodeSize);

                clampedRect = IntRect.Intersection (physicsRect,gridRect);

                bool addedNodes = false;

                for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
                    for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
                        /** \todo FIX */
                        addedNodes |= RecalculateCell (x,z,preserveExistingNodes);
                    }
                }

                for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
                    for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
                        for (int y=0;y<layerCount;y++) {
                            int index = y*width*depth + z*width+x;

                            LevelGridNode node = nodes[index] as LevelGridNode;

                            if (node == null) continue;

                            CalculateConnections (nodes,node,x,z,y);
                        }
                    }
                }
                if (addedNodes) {
                    AstarPath.active.DataUpdate();
                }
            }

            //Apply GUO

            clampedRect = IntRect.Intersection (originalRect, gridRect);
            for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
                for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
                    for (int y=0;y<layerCount;y++) {
                        int index = y*width*depth + z*width+x;

                        LevelGridNode node = nodes[index] as LevelGridNode;

                        if (node == null) continue;

                        if (willChangeWalkability) {
                            node.walkable = node.Bit15;
                            o.Apply (node);
                            node.Bit15 = node.walkable;
                        } else {
                            o.Apply (node);
                        }
                    }
                }
            }

            #if ASTARDEBUG
            physicsRect.DebugDraw (debugMatrix,Color.blue);
            affectRect.DebugDraw (debugMatrix,Color.black);
            #endif

            //Recalculate connections
            if (willChangeWalkability && erodeIterations == 0) {

                clampedRect = IntRect.Intersection (affectRect, gridRect);
                for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
                    for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
                        for (int y=0;y<layerCount;y++) {
                            int index = y*width*depth + z*width+x;

                            LevelGridNode node = nodes[index] as LevelGridNode;

                            if (node == null) continue;

                            CalculateConnections (nodes,node,x,z,y);
                        }
                    }
                }
            } else if (willChangeWalkability && erodeIterations > 0) {

                clampedRect = IntRect.Union (originalRect, physicsRect);

                IntRect erosionRect1 = clampedRect.Expand (erodeIterations);
                IntRect erosionRect2 = erosionRect1.Expand (erodeIterations);

                erosionRect1 = IntRect.Intersection (erosionRect1,gridRect);
                erosionRect2 = IntRect.Intersection (erosionRect2,gridRect);

            #if ASTARDEBUG
                erosionRect1.DebugDraw (debugMatrix,Color.magenta);
                erosionRect2.DebugDraw (debugMatrix,Color.cyan);
            #endif

                /*
                all nodes inside clampedRect might have had their walkability changed
                all nodes inside erosionRect1 might get affected by erosion from clampedRect and erosionRect2
                all nodes inside erosionRect2 (but outside erosionRect1) will be reset to previous walkability
                after calculation since their erosion might not be correctly calculated (nodes outside erosionRect2 would maybe have effect)
                */

                for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
                    for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
                        for (int y=0;y<layerCount;y++) {
                            int index = y*width*depth + z*width+x;

                            LevelGridNode node = nodes[index] as LevelGridNode;

                            if (node == null) continue;

                            bool tmp = node.walkable;
                            node.walkable = node.Bit15;

                            if (!erosionRect1.Contains (x,z)) {
                                //Save the border's walkabilty data in bit 16 (will be reset later)
                                node.Bit16 = tmp;
                            }
                        }
                    }
                }

                for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
                    for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
                        for (int y=0;y<layerCount;y++) {
                            int index = y*width*depth + z*width+x;

                            LevelGridNode node = nodes[index] as LevelGridNode;

                            if (node == null) continue;

            #if ASTARDEBUG
                            if (!node.walkable)
                                Debug.DrawRay ((Vector3)node.position, Vector3.up*2,Color.red);
            #endif
                            CalculateConnections (nodes,node,x,z,y);
                        }
                    }
                }

                //Erode the walkable area
                ErodeWalkableArea (erosionRect2.xmin,erosionRect2.ymin,erosionRect2.xmax+1,erosionRect2.ymax+1);

                for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
                    for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
                        if (erosionRect1.Contains (x,z)) continue;

                        for (int y=0;y<layerCount;y++) {
                            int index = y*width*depth + z*width+x;

                            LevelGridNode node = nodes[index] as LevelGridNode;

                            if (node == null) continue;

                            //Restore temporarily stored data
                            node.walkable = node.Bit16;
                        }
                    }
                }

                //Recalculate connections of all affected nodes
                for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
                    for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
                        for (int y=0;y<layerCount;y++) {
                            int index = y*width*depth + z*width+x;

                            LevelGridNode node = nodes[index] as LevelGridNode;

                            if (node == null) continue;

                            CalculateConnections (nodes,node,x,z,y);
                        }
                    }
                }
            }
            //Debug.LogError ("No support for Graph Updates to Layered Grid Graphs");
        }
        // Token: 0x060025C3 RID: 9667 RVA: 0x001A1AF0 File Offset: 0x0019FCF0
        void IUpdatableGraph.UpdateArea(GraphUpdateObject guo)
        {
            if (this.nodes == null)
            {
                return;
            }
            for (int i = 0; i < this.nodeCount; i++)
            {
                PointNode pointNode = this.nodes[i];
                if (guo.bounds.Contains((Vector3)pointNode.position))
                {
                    guo.WillUpdateNode(pointNode);
                    guo.Apply(pointNode);
                }
            }
            if (guo.updatePhysics)
            {
                Bounds bounds = guo.bounds;
                if (this.thickRaycast)
                {
                    bounds.Expand(this.thickRaycastRadius * 2f);
                }
                List <Connection> list = ListPool <Connection> .Claim();

                for (int j = 0; j < this.nodeCount; j++)
                {
                    PointNode         pointNode2 = this.nodes[j];
                    Vector3           a          = (Vector3)pointNode2.position;
                    List <Connection> list2      = null;
                    for (int k = 0; k < this.nodeCount; k++)
                    {
                        if (k != j)
                        {
                            Vector3 b = (Vector3)this.nodes[k].position;
                            if (VectorMath.SegmentIntersectsBounds(bounds, a, b))
                            {
                                PointNode pointNode3 = this.nodes[k];
                                bool      flag       = pointNode2.ContainsConnection(pointNode3);
                                float     num;
                                bool      flag2 = this.IsValidConnection(pointNode2, pointNode3, out num);
                                if (list2 == null && flag != flag2)
                                {
                                    list.Clear();
                                    list2 = list;
                                    list2.AddRange(pointNode2.connections);
                                }
                                if (!flag && flag2)
                                {
                                    uint cost = (uint)Mathf.RoundToInt(num * 1000f);
                                    list2.Add(new Connection(pointNode3, cost, byte.MaxValue));
                                }
                                else if (flag && !flag2)
                                {
                                    for (int l = 0; l < list2.Count; l++)
                                    {
                                        if (list2[l].node == pointNode3)
                                        {
                                            list2.RemoveAt(l);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (list2 != null)
                    {
                        pointNode2.connections = list2.ToArray();
                    }
                }
                ListPool <Connection> .Release(ref list);
            }
        }
Example #6
0
        /** Updates an area in the list graph.
         * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated
         * \astarpro */
        public void UpdateArea(GraphUpdateObject guo)
        {
            if (nodes == null) {
                return;
            }

            for (int i=0;i<nodes.Length;i++) {
                if (guo.bounds.Contains ((Vector3)nodes[i].position)) {
                    guo.WillUpdateNode (nodes[i]);
                    guo.Apply (nodes[i]);
                }
            }

            if (guo.updatePhysics) {

                //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates
                Bounds bounds = guo.bounds;

                if (thickRaycast) {
                    //Expand the bounding box to account for the thick raycast
                    bounds.Expand (thickRaycastRadius*2);
                }

                //Create two temporary arrays used for holding new connections and costs
                List<Node> tmp_arr = Pathfinding.Util.ListPool<Node>.Claim ();
                List<int>  tmp_arr2 =Pathfinding.Util.ListPool<int>.Claim ();

                for (int i=0;i<nodes.Length;i++) {
                    Node node = nodes[i];
                    Vector3 a = (Vector3)node.position;

                    List<Node> conn = null;
                    List<int> costs = null;

                    for (int j=0;j<nodes.Length;j++) {
                        if (j==i) continue;

                        Vector3 b = (Vector3)nodes[j].position;
                        if (Polygon.LineIntersectsBounds (bounds,a,b)) {

                            float dist;
                            Node other = nodes[j];
                            bool contains = node.ContainsConnection (other);

                            //Note, the IsValidConnection test will actually only be done once
                            //no matter what,so there is no performance penalty there
                            if (!contains && IsValidConnection (node,other, out dist)) {
                                //Debug.DrawLine (a+Vector3.up*0.1F,b+Vector3.up*0.1F,Color.green);
                                if (conn == null) {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear ();
                                    conn = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange (node.connections);
                                    costs.AddRange (node.connectionCosts);
                                }

                                int cost = Mathf.RoundToInt (dist*Int3.FloatPrecision);
                                conn.Add (other);
                                costs.Add (cost);

                            } else if (contains && !IsValidConnection (node,other, out dist)) {
                                //Debug.DrawLine (a+Vector3.up*0.5F*Random.value,b+Vector3.up*0.5F*Random.value,Color.red);
                                if (conn == null) {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear ();
                                    conn = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange (node.connections);
                                    costs.AddRange (node.connectionCosts);
                                }

                                int p = conn.IndexOf (other);

                                //Shouldn't have to check for it, but who knows what might go wrong
                                if (p != -1) {
                                    conn.RemoveAt (p);
                                    costs.RemoveAt (p);
                                }
                            }
                        }
                    }

                    if (conn != null) {
                        node.connections = conn.ToArray ();
                        node.connectionCosts = costs.ToArray ();
                    }
                }

                Pathfinding.Util.ListPool<Node>.Release (tmp_arr);
                Pathfinding.Util.ListPool<int>.Release (tmp_arr2);
            }
        }
		public static void UpdateArea (GraphUpdateObject o, NavGraph graph) {
			
			INavmesh navgraph = graph as INavmesh;
			
			if (navgraph == null) { Debug.LogError ("Update Area on NavMesh must be called with a graph implementing INavmesh"); return; }
			
			if (graph.nodes == null || graph.nodes.Length == 0) {
				Debug.LogError ("NavGraph hasn't been generated yet or does not contain any nodes");
				return;// new NNInfo ();
			}
			
			//System.DateTime startTime = System.DateTime.Now;
				
			Bounds bounds = o.bounds;
			
			Rect r = Rect.MinMaxRect (bounds.min.x,bounds.min.z,bounds.max.x,bounds.max.z);
			
			Vector3 a = new Vector3 (r.xMin,0,r.yMin);//	-1 	-1
			Vector3 b = new Vector3 (r.xMin,0,r.yMax);//	-1	 1 
			Vector3 c = new Vector3 (r.xMax,0,r.yMin);//	 1 	-1
			Vector3 d = new Vector3 (r.xMax,0,r.yMax);//	 1 	 1
			
			
			for (int i=0;i<graph.nodes.Length;i++) {
				MeshNode node = graph.nodes[i] as MeshNode;
				
				bool inside = false;
				
				int allLeft = 0;
				int allRight = 0;
				int allTop = 0;
				int allBottom = 0;
				
				for (int v=0;v<3;v++) {
					
					Vector3 vert = (Vector3)navgraph.vertices[node[v]];
					Vector2 vert2D = new Vector2 (vert.x,vert.z);
					
					if (r.Contains (vert2D)) {
						//Debug.DrawRay (vert,Vector3.up,Color.yellow);
						inside = true;
						break;
					}
					
					if (vert.x < r.xMin) allLeft++;
					if (vert.x > r.xMax) allRight++;
					if (vert.z < r.yMin) allTop++;
					if (vert.z > r.yMax) allBottom++;
					
					//if (!bounds.Contains (node[v]) {
					//	inside = false;
					//	break;
					//}
				}
				if (!inside) {
					if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) {
						continue;
					}
				}
				
				for (int v=0;v<3;v++) {
					int v2 = v > 1 ? 0 : v+1;
					
					Vector3 vert1 = (Vector3)navgraph.vertices[node[v]];
					Vector3 vert2 = (Vector3)navgraph.vertices[node[v2]];
					
					if (Polygon.Intersects (a,b,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (a,c,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (c,d,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (d,b,vert1,vert2)) { inside = true; break; }
				}
				
				
				
				if (!inside && ContainsPoint (node,a,navgraph.vertices)) { inside = true; }//Debug.DrawRay (a+Vector3.right*0.01F*i,Vector3.up,Color.red); }
				if (!inside && ContainsPoint (node,b,navgraph.vertices)) { inside = true; } //Debug.DrawRay (b+Vector3.right*0.01F*i,Vector3.up,Color.red); }
				if (!inside && ContainsPoint (node,c,navgraph.vertices)) { inside = true; }//Debug.DrawRay (c+Vector3.right*0.01F*i,Vector3.up,Color.red); }
				if (!inside && ContainsPoint (node,d,navgraph.vertices)) { inside = true; }//Debug.DrawRay (d+Vector3.right*0.01F*i,Vector3.up,Color.red); }
				
				if (!inside) {
					continue;
				}
				
				o.WillUpdateNode(node);
				o.Apply (node);
				//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);
				//Debug.Break ();
			}
			
			//System.DateTime endTime = System.DateTime.Now;
			//float theTime = (endTime-startTime).Ticks*0.0001F;
			//Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms");
		
		}
Example #8
0
        /** Updates an area in the list graph.
         * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated
         * \astarpro */
        public void UpdateArea(GraphUpdateObject guo)
        {
            if (nodes == null)
            {
                return;
            }

            for (int i = 0; i < nodeCount; i++)
            {
                if (guo.bounds.Contains((Vector3)nodes[i].position))
                {
                    guo.WillUpdateNode(nodes[i]);
                    guo.Apply(nodes[i]);
                }
            }

            if (guo.updatePhysics)
            {
                //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates
                Bounds bounds = guo.bounds;

                if (thickRaycast)
                {
                    //Expand the bounding box to account for the thick raycast
                    bounds.Expand(thickRaycastRadius * 2);
                }

                //Create two temporary arrays used for holding new connections and costs
                List <GraphNode> tmp_arr = Pathfinding.Util.ListPool <GraphNode> .Claim();

                List <uint> tmp_arr2 = Pathfinding.Util.ListPool <uint> .Claim();

                for (int i = 0; i < nodeCount; i++)
                {
                    PointNode node = nodes[i];
                    var       a    = (Vector3)node.position;

                    List <GraphNode> conn  = null;
                    List <uint>      costs = null;

                    for (int j = 0; j < nodeCount; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }

                        var b = (Vector3)nodes[j].position;
                        if (VectorMath.SegmentIntersectsBounds(bounds, a, b))
                        {
                            float     dist;
                            PointNode other           = nodes[j];
                            bool      contains        = node.ContainsConnection(other);
                            bool      validConnection = IsValidConnection(node, other, out dist);

                            if (!contains && validConnection)
                            {
                                // A new connection should be added

                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision);
                                conn.Add(other);
                                costs.Add(cost);
                            }
                            else if (contains && !validConnection)
                            {
                                // A connection should be removed

                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                int p = conn.IndexOf(other);

                                //Shouldn't have to check for it, but who knows what might go wrong
                                if (p != -1)
                                {
                                    conn.RemoveAt(p);
                                    costs.RemoveAt(p);
                                }
                            }
                        }
                    }

                    // Save the new connections if any were changed
                    if (conn != null)
                    {
                        node.connections     = conn.ToArray();
                        node.connectionCosts = costs.ToArray();
                    }
                }

                // Release buffers back to the pool
                Pathfinding.Util.ListPool <GraphNode> .Release(tmp_arr);

                Pathfinding.Util.ListPool <uint> .Release(tmp_arr2);
            }
        }
Example #9
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            Bounds  bounds = o.bounds;
            Rect    rect   = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);
            IntRect irect  = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.FloorToInt(bounds.max.x * 1000f), Mathf.FloorToInt(bounds.max.z * 1000f));
            Int3    a      = new Int3(irect.xmin, 0, irect.ymin);
            Int3    b      = new Int3(irect.xmin, 0, irect.ymax);
            Int3    c      = new Int3(irect.xmax, 0, irect.ymin);
            Int3    d      = new Int3(irect.xmax, 0, irect.ymax);
            int     ymin   = ((Int3)bounds.min).y;
            int     ymax   = ((Int3)bounds.max).y;

            graph.GetNodes(delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode;
                bool flag = false;
                int num   = 0;
                int num2  = 0;
                int num3  = 0;
                int num4  = 0;
                for (int i = 0; i < 3; i++)
                {
                    Int3 vertex    = triangleMeshNode.GetVertex(i);
                    Vector3 vector = (Vector3)vertex;
                    if (irect.Contains(vertex.x, vertex.z))
                    {
                        flag = true;
                        break;
                    }
                    if (vector.x < rect.xMin)
                    {
                        num++;
                    }
                    if (vector.x > rect.xMax)
                    {
                        num2++;
                    }
                    if (vector.z < rect.yMin)
                    {
                        num3++;
                    }
                    if (vector.z > rect.yMax)
                    {
                        num4++;
                    }
                }
                if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3))
                {
                    return;
                }
                for (int j = 0; j < 3; j++)
                {
                    int i2       = (j > 1) ? 0 : (j + 1);
                    Int3 vertex2 = triangleMeshNode.GetVertex(j);
                    Int3 vertex3 = triangleMeshNode.GetVertex(i2);
                    if (VectorMath.SegmentsIntersectXZ(a, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(a, c, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(c, d, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(d, b, vertex2, vertex3))
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag || triangleMeshNode.ContainsPoint(a) || triangleMeshNode.ContainsPoint(b) || triangleMeshNode.ContainsPoint(c) || triangleMeshNode.ContainsPoint(d))
                {
                    flag = true;
                }
                if (!flag)
                {
                    return;
                }
                int num5 = 0;
                int num6 = 0;
                for (int k = 0; k < 3; k++)
                {
                    Int3 vertex4 = triangleMeshNode.GetVertex(k);
                    if (vertex4.y < ymin)
                    {
                        num6++;
                    }
                    if (vertex4.y > ymax)
                    {
                        num5++;
                    }
                }
                if (num6 == 3 || num5 == 3)
                {
                    return;
                }
                o.WillUpdateNode(triangleMeshNode);
                o.Apply(triangleMeshNode);
            });
        }
        // Token: 0x06002570 RID: 9584 RVA: 0x001A2E38 File Offset: 0x001A1038
        public static void UpdateArea(GraphUpdateObject o, INavmeshHolder graph)
        {
            Bounds  bounds = graph.transform.InverseTransform(o.bounds);
            IntRect irect  = new IntRect(Mathf.FloorToInt(bounds.min.x * 1000f), Mathf.FloorToInt(bounds.min.z * 1000f), Mathf.CeilToInt(bounds.max.x * 1000f), Mathf.CeilToInt(bounds.max.z * 1000f));
            Int3    a      = new Int3(irect.xmin, 0, irect.ymin);
            Int3    b      = new Int3(irect.xmin, 0, irect.ymax);
            Int3    c      = new Int3(irect.xmax, 0, irect.ymin);
            Int3    d      = new Int3(irect.xmax, 0, irect.ymax);
            int     ymin   = ((Int3)bounds.min).y;
            int     ymax   = ((Int3)bounds.max).y;

            graph.GetNodes(delegate(GraphNode _node)
            {
                TriangleMeshNode triangleMeshNode = _node as TriangleMeshNode;
                bool flag = false;
                int num   = 0;
                int num2  = 0;
                int num3  = 0;
                int num4  = 0;
                for (int i = 0; i < 3; i++)
                {
                    Int3 vertexInGraphSpace = triangleMeshNode.GetVertexInGraphSpace(i);
                    if (irect.Contains(vertexInGraphSpace.x, vertexInGraphSpace.z))
                    {
                        flag = true;
                        break;
                    }
                    if (vertexInGraphSpace.x < irect.xmin)
                    {
                        num++;
                    }
                    if (vertexInGraphSpace.x > irect.xmax)
                    {
                        num2++;
                    }
                    if (vertexInGraphSpace.z < irect.ymin)
                    {
                        num3++;
                    }
                    if (vertexInGraphSpace.z > irect.ymax)
                    {
                        num4++;
                    }
                }
                if (!flag && (num == 3 || num2 == 3 || num3 == 3 || num4 == 3))
                {
                    return;
                }
                for (int j = 0; j < 3; j++)
                {
                    int i2 = (j > 1) ? 0 : (j + 1);
                    Int3 vertexInGraphSpace2 = triangleMeshNode.GetVertexInGraphSpace(j);
                    Int3 vertexInGraphSpace3 = triangleMeshNode.GetVertexInGraphSpace(i2);
                    if (VectorMath.SegmentsIntersectXZ(a, b, vertexInGraphSpace2, vertexInGraphSpace3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(a, c, vertexInGraphSpace2, vertexInGraphSpace3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(c, d, vertexInGraphSpace2, vertexInGraphSpace3))
                    {
                        flag = true;
                        break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(d, b, vertexInGraphSpace2, vertexInGraphSpace3))
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag || triangleMeshNode.ContainsPointInGraphSpace(a) || triangleMeshNode.ContainsPointInGraphSpace(b) || triangleMeshNode.ContainsPointInGraphSpace(c) || triangleMeshNode.ContainsPointInGraphSpace(d))
                {
                    flag = true;
                }
                if (!flag)
                {
                    return;
                }
                int num5 = 0;
                int num6 = 0;
                for (int k = 0; k < 3; k++)
                {
                    Int3 vertexInGraphSpace4 = triangleMeshNode.GetVertexInGraphSpace(k);
                    if (vertexInGraphSpace4.y < ymin)
                    {
                        num6++;
                    }
                    if (vertexInGraphSpace4.y > ymax)
                    {
                        num5++;
                    }
                }
                if (num6 == 3 || num5 == 3)
                {
                    return;
                }
                o.WillUpdateNode(triangleMeshNode);
                o.Apply(triangleMeshNode);
            });
        }
        /** Updates an area in the list graph.
         * Recalculates possibly affected connections, i.e all connectionlines passing trough the bounds of the \a guo will be recalculated
         * \astarpro */
        public void UpdateArea(GraphUpdateObject guo)
        {
            if (nodes == null)
            {
                return;
            }

            for (int i = 0; i < nodeCount; i++)
            {
                if (guo.bounds.Contains((Vector3)nodes[i].position))
                {
                    guo.WillUpdateNode(nodes[i]);
                    guo.Apply(nodes[i]);
                }
            }

            if (guo.updatePhysics)
            {
                //Use a copy of the bounding box, we should not change the GUO's bounding box since it might be used for other graph updates
                Bounds bounds = guo.bounds;

                if (thickRaycast)
                {
                    //Expand the bounding box to account for the thick raycast
                    bounds.Expand(thickRaycastRadius * 2);
                }

                //Create two temporary arrays used for holding new connections and costs
                List <GraphNode> tmp_arr = Pathfinding.Util.ListPool <GraphNode> .Claim();

                List <uint> tmp_arr2 = Pathfinding.Util.ListPool <uint> .Claim();

                for (int i = 0; i < nodeCount; i++)
                {
                    PointNode node = nodes[i] as PointNode;
                    Vector3   a    = (Vector3)node.position;

                    List <GraphNode> conn  = null;
                    List <uint>      costs = null;

                    for (int j = 0; j < nodeCount; j++)
                    {
                        if (j == i)
                        {
                            continue;
                        }

                        Vector3 b = (Vector3)nodes[j].position;
                        if (Polygon.LineIntersectsBounds(bounds, a, b))
                        {
                            float     dist;
                            PointNode other    = nodes[j] as PointNode;
                            bool      contains = node.ContainsConnection(other);

                            //Note, the IsValidConnection test will actually only be done once
                            //no matter what,so there is no performance penalty there
                            if (!contains && IsValidConnection(node, other, out dist))
                            {
                                //Debug.DrawLine (a+Vector3.up*0.1F,b+Vector3.up*0.1F,Color.green);
                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                uint cost = (uint)Mathf.RoundToInt(dist * Int3.FloatPrecision);
                                conn.Add(other);
                                costs.Add(cost);
                            }
                            else if (contains && !IsValidConnection(node, other, out dist))
                            {
                                //Debug.DrawLine (a+Vector3.up*0.5F*Random.value,b+Vector3.up*0.5F*Random.value,Color.red);
                                if (conn == null)
                                {
                                    tmp_arr.Clear();
                                    tmp_arr2.Clear();
                                    conn  = tmp_arr;
                                    costs = tmp_arr2;
                                    conn.AddRange(node.connections);
                                    costs.AddRange(node.connectionCosts);
                                }

                                int p = conn.IndexOf(other);

                                //Shouldn't have to check for it, but who knows what might go wrong
                                if (p != -1)
                                {
                                    conn.RemoveAt(p);
                                    costs.RemoveAt(p);
                                }
                            }
                        }
                    }

                    if (conn != null)
                    {
                        node.connections     = conn.ToArray();
                        node.connectionCosts = costs.ToArray();
                    }
                }

                Pathfinding.Util.ListPool <GraphNode> .Release(tmp_arr);

                Pathfinding.Util.ListPool <uint> .Release(tmp_arr2);
            }
        }
Example #12
0
		public static void UpdateArea (GraphUpdateObject o, INavmesh graph) {

			//System.DateTime startTime = System.DateTime.UtcNow;

			Bounds bounds = o.bounds;

			Rect r = Rect.MinMaxRect (bounds.min.x,bounds.min.z,bounds.max.x,bounds.max.z);

			var r2 = new IntRect(
				Mathf.FloorToInt(bounds.min.x*Int3.Precision),
				Mathf.FloorToInt(bounds.min.z*Int3.Precision),
				Mathf.FloorToInt(bounds.max.x*Int3.Precision),
				Mathf.FloorToInt(bounds.max.z*Int3.Precision)
			);

			var a = new Int3(r2.xmin,0,r2.ymin);
			var b = new Int3(r2.xmin,0,r2.ymax);
			var c = new Int3(r2.xmax,0,r2.ymin);
			var d = new Int3(r2.xmax,0,r2.ymax);

			graph.GetNodes (_node => {
				var node = _node as TriangleMeshNode;

				bool inside = false;

				int allLeft = 0;
				int allRight = 0;
				int allTop = 0;
				int allBottom = 0;

				for (int v=0;v<3;v++) {

					Int3 p = node.GetVertex(v);
					var vert = (Vector3)p;

					if (r2.Contains (p.x,p.z)) {
						inside = true;
						break;
					}

					if (vert.x < r.xMin) allLeft++;
					if (vert.x > r.xMax) allRight++;
					if (vert.z < r.yMin) allTop++;
					if (vert.z > r.yMax) allBottom++;
				}
				if (!inside) {
					if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) {
						return true;
					}
				}

				for (int v=0;v<3;v++) {
					int v2 = v > 1 ? 0 : v+1;

					Int3 vert1 = node.GetVertex(v);
					Int3 vert2 = node.GetVertex(v2);

					if (Polygon.Intersects (a,b,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (a,c,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (c,d,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (d,b,vert1,vert2)) { inside = true; break; }
				}

				if (node.ContainsPoint (a) || node.ContainsPoint (b) || node.ContainsPoint (c) || node.ContainsPoint (d)) {
					inside = true;
				}

				if (!inside) {
					return true;
				}

				o.WillUpdateNode(node);
				o.Apply (node);
				return true;
			});
		}
		public static void UpdateArea (GraphUpdateObject o, INavmesh graph) {
			Bounds bounds = o.bounds;

			// Bounding rectangle with floating point coordinates
			Rect r = Rect.MinMaxRect (bounds.min.x,bounds.min.z,bounds.max.x,bounds.max.z);

			// Bounding rectangle with int coordinates
			var r2 = new IntRect(
				Mathf.FloorToInt(bounds.min.x*Int3.Precision),
				Mathf.FloorToInt(bounds.min.z*Int3.Precision),
				Mathf.FloorToInt(bounds.max.x*Int3.Precision),
				Mathf.FloorToInt(bounds.max.z*Int3.Precision)
			);

			// Corners of the bounding rectangle
			var a = new Int3(r2.xmin,0,r2.ymin);
			var b = new Int3(r2.xmin,0,r2.ymax);
			var c = new Int3(r2.xmax,0,r2.ymin);
			var d = new Int3(r2.xmax,0,r2.ymax);

			var ymin = ((Int3)bounds.min).y;
			var ymax = ((Int3)bounds.max).y;

			// Loop through all nodes
			graph.GetNodes (_node => {
				var node = _node as TriangleMeshNode;

				bool inside = false;

				int allLeft = 0;
				int allRight = 0;
				int allTop = 0;
				int allBottom = 0;

				// Check bounding box rect in XZ plane
				for (int v=0;v<3;v++) {
					Int3 p = node.GetVertex(v);
					var vert = (Vector3)p;

					if (r2.Contains (p.x,p.z)) {
						inside = true;
						break;
					}

					if (vert.x < r.xMin) allLeft++;
					if (vert.x > r.xMax) allRight++;
					if (vert.z < r.yMin) allTop++;
					if (vert.z > r.yMax) allBottom++;
				}

				if (!inside) {
					if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) {
						return true;
					}
				}

				// Check if the polygon edges intersect the bounding rect
				for (int v = 0; v < 3; v++) {
					int v2 = v > 1 ? 0 : v+1;

					Int3 vert1 = node.GetVertex(v);
					Int3 vert2 = node.GetVertex(v2);

					if (Polygon.Intersects (a,b,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (a,c,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (c,d,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (d,b,vert1,vert2)) { inside = true; break; }
				}

				// Check if the node contains any corner of the bounding rect
				if (inside || node.ContainsPoint (a) || node.ContainsPoint (b) || node.ContainsPoint (c) || node.ContainsPoint (d)) {
					inside = true;
				}

				if (!inside) {
					return true;
				}

				int allAbove = 0;
				int allBelow = 0;

				// Check y coordinate
				for (int v = 0; v < 3; v++) {
					Int3 p = node.GetVertex(v);
					var vert = (Vector3)p;
					if (vert.y < ymin) allBelow++;
					if (vert.y > ymax) allAbove++;
				}

				// Polygon is either completely above the bounding box or completely below it
				if (allBelow == 3 || allAbove == 3) return true;

				// Triangle is inside the bounding box!
				// Update it!
				o.WillUpdateNode(node);
				o.Apply (node);
				return true;
			});
		}
        public static void UpdateArea(GraphUpdateObject o, NavGraph graph)
        {
            INavmesh navgraph = graph as INavmesh;

            if (navgraph == null)
            {
                Debug.LogError("Update Area on NavMesh must be called with a graph implementing INavmesh"); return;
            }

            if (graph.nodes == null || graph.nodes.Length == 0)
            {
                Debug.LogError("NavGraph hasn't been generated yet or does not contain any nodes");
                return;                // new NNInfo ();
            }

            //System.DateTime startTime = System.DateTime.UtcNow;

            Bounds bounds = o.bounds;

            Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);

            Vector3 a = new Vector3(r.xMin, 0, r.yMin);           //	-1  -1
            Vector3 b = new Vector3(r.xMin, 0, r.yMax);           //	-1	 1
            Vector3 c = new Vector3(r.xMax, 0, r.yMin);           //	 1  -1
            Vector3 d = new Vector3(r.xMax, 0, r.yMax);           //	 1   1


            for (int i = 0; i < graph.nodes.Length; i++)
            {
                MeshNode node = graph.nodes[i] as MeshNode;

                bool inside = false;

                int allLeft   = 0;
                int allRight  = 0;
                int allTop    = 0;
                int allBottom = 0;

                for (int v = 0; v < 3; v++)
                {
                    Vector3 vert   = (Vector3)navgraph.vertices[node[v]];
                    Vector2 vert2D = new Vector2(vert.x, vert.z);

                    if (r.Contains(vert2D))
                    {
                        //Debug.DrawRay (vert,Vector3.up,Color.yellow);
                        inside = true;
                        break;
                    }

                    if (vert.x < r.xMin)
                    {
                        allLeft++;
                    }
                    if (vert.x > r.xMax)
                    {
                        allRight++;
                    }
                    if (vert.z < r.yMin)
                    {
                        allTop++;
                    }
                    if (vert.z > r.yMax)
                    {
                        allBottom++;
                    }

                    //if (!bounds.Contains (node[v]) {
                    //	inside = false;
                    //	break;
                    //}
                }
                if (!inside)
                {
                    if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)
                    {
                        continue;
                    }
                }

                for (int v = 0; v < 3; v++)
                {
                    int v2 = v > 1 ? 0 : v + 1;

                    Vector3 vert1 = (Vector3)navgraph.vertices[node[v]];
                    Vector3 vert2 = (Vector3)navgraph.vertices[node[v2]];

                    if (Polygon.Intersects(a, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(a, c, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(c, d, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(d, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                }



                if (!inside && ContainsPoint(node, a, navgraph.vertices))
                {
                    inside = true;
                }                                                                                          //Debug.DrawRay (a+Vector3.right*0.01F*i,Vector3.up,Color.red); }
                if (!inside && ContainsPoint(node, b, navgraph.vertices))
                {
                    inside = true;
                }                                                                                           //Debug.DrawRay (b+Vector3.right*0.01F*i,Vector3.up,Color.red); }
                if (!inside && ContainsPoint(node, c, navgraph.vertices))
                {
                    inside = true;
                }                                                                                          //Debug.DrawRay (c+Vector3.right*0.01F*i,Vector3.up,Color.red); }
                if (!inside && ContainsPoint(node, d, navgraph.vertices))
                {
                    inside = true;
                }                                                                                          //Debug.DrawRay (d+Vector3.right*0.01F*i,Vector3.up,Color.red); }

                if (!inside)
                {
                    continue;
                }

                o.WillUpdateNode(node);
                o.Apply(node);
                //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);
                //Debug.Break ();
            }

            //System.DateTime endTime = System.DateTime.UtcNow;
            //float theTime = (endTime-startTime).Ticks*0.0001F;
            //Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms");
        }
        // Token: 0x0600253A RID: 9530 RVA: 0x001A1218 File Offset: 0x0019F418
        void IUpdatableGraph.UpdateArea(GraphUpdateObject o)
        {
            if (this.nodes == null || this.nodes.Length != this.width * this.depth * this.layerCount)
            {
                Debug.LogWarning("The Grid Graph is not scanned, cannot update area ");
                return;
            }
            IntRect a;
            IntRect a2;
            IntRect intRect;
            bool    flag;
            int     num;

            base.CalculateAffectedRegions(o, out a, out a2, out intRect, out flag, out num);
            bool flag2 = o is LayerGridGraphUpdate && ((LayerGridGraphUpdate)o).recalculateNodes;
            bool flag3 = (o is LayerGridGraphUpdate) ? ((LayerGridGraphUpdate)o).preserveExistingNodes : (!o.resetPenaltyOnPhysics);

            if (o.trackChangedNodes && flag2)
            {
                Debug.LogError("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph");
                return;
            }
            IntRect b        = new IntRect(0, 0, this.width - 1, this.depth - 1);
            IntRect intRect2 = IntRect.Intersection(a2, b);

            if (!flag2)
            {
                for (int i = intRect2.xmin; i <= intRect2.xmax; i++)
                {
                    for (int j = intRect2.ymin; j <= intRect2.ymax; j++)
                    {
                        for (int k = 0; k < this.layerCount; k++)
                        {
                            o.WillUpdateNode(this.nodes[k * this.width * this.depth + j * this.width + i]);
                        }
                    }
                }
            }
            if (o.updatePhysics && !o.modifyWalkability)
            {
                this.collision.Initialize(base.transform, this.nodeSize);
                intRect2 = IntRect.Intersection(intRect, b);
                for (int l = intRect2.xmin; l <= intRect2.xmax; l++)
                {
                    for (int m = intRect2.ymin; m <= intRect2.ymax; m++)
                    {
                        this.RecalculateCell(l, m, !flag3, false);
                    }
                }
                for (int n = intRect2.xmin; n <= intRect2.xmax; n++)
                {
                    for (int num2 = intRect2.ymin; num2 <= intRect2.ymax; num2++)
                    {
                        this.CalculateConnections(n, num2);
                    }
                }
            }
            intRect2 = IntRect.Intersection(a, b);
            for (int num3 = intRect2.xmin; num3 <= intRect2.xmax; num3++)
            {
                for (int num4 = intRect2.ymin; num4 <= intRect2.ymax; num4++)
                {
                    for (int num5 = 0; num5 < this.layerCount; num5++)
                    {
                        int           num6          = num5 * this.width * this.depth + num4 * this.width + num3;
                        LevelGridNode levelGridNode = this.nodes[num6];
                        if (levelGridNode != null)
                        {
                            if (flag)
                            {
                                levelGridNode.Walkable = levelGridNode.WalkableErosion;
                                if (o.bounds.Contains((Vector3)levelGridNode.position))
                                {
                                    o.Apply(levelGridNode);
                                }
                                levelGridNode.WalkableErosion = levelGridNode.Walkable;
                            }
                            else if (o.bounds.Contains((Vector3)levelGridNode.position))
                            {
                                o.Apply(levelGridNode);
                            }
                        }
                    }
                }
            }
            if (flag && num == 0)
            {
                intRect2 = IntRect.Intersection(a2, b);
                for (int num7 = intRect2.xmin; num7 <= intRect2.xmax; num7++)
                {
                    for (int num8 = intRect2.ymin; num8 <= intRect2.ymax; num8++)
                    {
                        this.CalculateConnections(num7, num8);
                    }
                }
                return;
            }
            if (flag && num > 0)
            {
                IntRect a3       = IntRect.Union(a, intRect).Expand(num);
                IntRect intRect3 = a3.Expand(num);
                a3       = IntRect.Intersection(a3, b);
                intRect3 = IntRect.Intersection(intRect3, b);
                for (int num9 = intRect3.xmin; num9 <= intRect3.xmax; num9++)
                {
                    for (int num10 = intRect3.ymin; num10 <= intRect3.ymax; num10++)
                    {
                        for (int num11 = 0; num11 < this.layerCount; num11++)
                        {
                            int           num12          = num11 * this.width * this.depth + num10 * this.width + num9;
                            LevelGridNode levelGridNode2 = this.nodes[num12];
                            if (levelGridNode2 != null)
                            {
                                bool walkable = levelGridNode2.Walkable;
                                levelGridNode2.Walkable = levelGridNode2.WalkableErosion;
                                if (!a3.Contains(num9, num10))
                                {
                                    levelGridNode2.TmpWalkable = walkable;
                                }
                            }
                        }
                    }
                }
                for (int num13 = intRect3.xmin; num13 <= intRect3.xmax; num13++)
                {
                    for (int num14 = intRect3.ymin; num14 <= intRect3.ymax; num14++)
                    {
                        this.CalculateConnections(num13, num14);
                    }
                }
                base.ErodeWalkableArea(intRect3.xmin, intRect3.ymin, intRect3.xmax + 1, intRect3.ymax + 1);
                for (int num15 = intRect3.xmin; num15 <= intRect3.xmax; num15++)
                {
                    for (int num16 = intRect3.ymin; num16 <= intRect3.ymax; num16++)
                    {
                        if (!a3.Contains(num15, num16))
                        {
                            for (int num17 = 0; num17 < this.layerCount; num17++)
                            {
                                int           num18          = num17 * this.width * this.depth + num16 * this.width + num15;
                                LevelGridNode levelGridNode3 = this.nodes[num18];
                                if (levelGridNode3 != null)
                                {
                                    levelGridNode3.Walkable = levelGridNode3.TmpWalkable;
                                }
                            }
                        }
                    }
                }
                for (int num19 = intRect3.xmin; num19 <= intRect3.xmax; num19++)
                {
                    for (int num20 = intRect3.ymin; num20 <= intRect3.ymax; num20++)
                    {
                        this.CalculateConnections(num19, num20);
                    }
                }
            }
        }
Example #16
0
        public new void UpdateArea(GraphUpdateObject o)
        {
            if (this.nodes == null || this.nodes.Length != this.width * this.depth * this.layerCount)
            {
                Debug.LogWarning("The Grid Graph is not scanned, cannot update area ");
                return;
            }
            Bounds  bounds = o.bounds;
            Vector3 a;
            Vector3 a2;

            GridGraph.GetBoundsMinMax(bounds, this.inverseMatrix, out a, out a2);
            int     xmin     = Mathf.RoundToInt(a.x - 0.5f);
            int     xmax     = Mathf.RoundToInt(a2.x - 0.5f);
            int     ymin     = Mathf.RoundToInt(a.z - 0.5f);
            int     ymax     = Mathf.RoundToInt(a2.z - 0.5f);
            IntRect intRect  = new IntRect(xmin, ymin, xmax, ymax);
            IntRect intRect2 = intRect;
            IntRect b        = new IntRect(0, 0, this.width - 1, this.depth - 1);
            IntRect intRect3 = intRect;
            bool    flag     = o.updatePhysics || o.modifyWalkability;
            bool    flag2    = o is LayerGridGraphUpdate && ((LayerGridGraphUpdate)o).recalculateNodes;
            bool    preserveExistingNodes = !(o is LayerGridGraphUpdate) || ((LayerGridGraphUpdate)o).preserveExistingNodes;
            int     num = (!o.updateErosion) ? 0 : this.erodeIterations;

            if (o.trackChangedNodes && flag2)
            {
                Debug.LogError("Cannot track changed nodes when creating or deleting nodes.\nWill not update LayerGridGraph");
                return;
            }
            if (o.updatePhysics && !o.modifyWalkability && this.collision.collisionCheck)
            {
                Vector3 a3 = new Vector3(this.collision.diameter, 0f, this.collision.diameter) * 0.5f;
                a       -= a3 * 1.02f;
                a2      += a3 * 1.02f;
                intRect3 = new IntRect(Mathf.RoundToInt(a.x - 0.5f), Mathf.RoundToInt(a.z - 0.5f), Mathf.RoundToInt(a2.x - 0.5f), Mathf.RoundToInt(a2.z - 0.5f));
                intRect2 = IntRect.Union(intRect3, intRect2);
            }
            if (flag || num > 0)
            {
                intRect2 = intRect2.Expand(num + 1);
            }
            IntRect intRect4 = IntRect.Intersection(intRect2, b);

            if (!flag2)
            {
                for (int i = intRect4.xmin; i <= intRect4.xmax; i++)
                {
                    for (int j = intRect4.ymin; j <= intRect4.ymax; j++)
                    {
                        for (int k = 0; k < this.layerCount; k++)
                        {
                            o.WillUpdateNode(this.nodes[k * this.width * this.depth + j * this.width + i]);
                        }
                    }
                }
            }
            if (o.updatePhysics && !o.modifyWalkability)
            {
                this.collision.Initialize(this.matrix, this.nodeSize);
                intRect4 = IntRect.Intersection(intRect3, b);
                bool flag3 = false;
                for (int l = intRect4.xmin; l <= intRect4.xmax; l++)
                {
                    for (int m = intRect4.ymin; m <= intRect4.ymax; m++)
                    {
                        flag3 |= this.RecalculateCell(l, m, preserveExistingNodes);
                    }
                }
                for (int n = intRect4.xmin; n <= intRect4.xmax; n++)
                {
                    for (int num2 = intRect4.ymin; num2 <= intRect4.ymax; num2++)
                    {
                        for (int num3 = 0; num3 < this.layerCount; num3++)
                        {
                            int           num4          = num3 * this.width * this.depth + num2 * this.width + n;
                            LevelGridNode levelGridNode = this.nodes[num4];
                            if (levelGridNode != null)
                            {
                                this.CalculateConnections(this.nodes, levelGridNode, n, num2, num3);
                            }
                        }
                    }
                }
            }
            intRect4 = IntRect.Intersection(intRect, b);
            for (int num5 = intRect4.xmin; num5 <= intRect4.xmax; num5++)
            {
                for (int num6 = intRect4.ymin; num6 <= intRect4.ymax; num6++)
                {
                    for (int num7 = 0; num7 < this.layerCount; num7++)
                    {
                        int           num8           = num7 * this.width * this.depth + num6 * this.width + num5;
                        LevelGridNode levelGridNode2 = this.nodes[num8];
                        if (levelGridNode2 != null)
                        {
                            if (flag)
                            {
                                levelGridNode2.Walkable = levelGridNode2.WalkableErosion;
                                if (o.bounds.Contains((Vector3)levelGridNode2.position))
                                {
                                    o.Apply(levelGridNode2);
                                }
                                levelGridNode2.WalkableErosion = levelGridNode2.Walkable;
                            }
                            else if (o.bounds.Contains((Vector3)levelGridNode2.position))
                            {
                                o.Apply(levelGridNode2);
                            }
                        }
                    }
                }
            }
            if (flag && num == 0)
            {
                intRect4 = IntRect.Intersection(intRect2, b);
                for (int num9 = intRect4.xmin; num9 <= intRect4.xmax; num9++)
                {
                    for (int num10 = intRect4.ymin; num10 <= intRect4.ymax; num10++)
                    {
                        for (int num11 = 0; num11 < this.layerCount; num11++)
                        {
                            int           num12          = num11 * this.width * this.depth + num10 * this.width + num9;
                            LevelGridNode levelGridNode3 = this.nodes[num12];
                            if (levelGridNode3 != null)
                            {
                                this.CalculateConnections(this.nodes, levelGridNode3, num9, num10, num11);
                            }
                        }
                    }
                }
            }
            else if (flag && num > 0)
            {
                IntRect a4 = IntRect.Union(intRect, intRect3).Expand(num);
                IntRect a5 = a4.Expand(num);
                a4 = IntRect.Intersection(a4, b);
                a5 = IntRect.Intersection(a5, b);
                for (int num13 = a5.xmin; num13 <= a5.xmax; num13++)
                {
                    for (int num14 = a5.ymin; num14 <= a5.ymax; num14++)
                    {
                        for (int num15 = 0; num15 < this.layerCount; num15++)
                        {
                            int           num16          = num15 * this.width * this.depth + num14 * this.width + num13;
                            LevelGridNode levelGridNode4 = this.nodes[num16];
                            if (levelGridNode4 != null)
                            {
                                bool walkable = levelGridNode4.Walkable;
                                levelGridNode4.Walkable = levelGridNode4.WalkableErosion;
                                if (!a4.Contains(num13, num14))
                                {
                                    levelGridNode4.TmpWalkable = walkable;
                                }
                            }
                        }
                    }
                }
                for (int num17 = a5.xmin; num17 <= a5.xmax; num17++)
                {
                    for (int num18 = a5.ymin; num18 <= a5.ymax; num18++)
                    {
                        for (int num19 = 0; num19 < this.layerCount; num19++)
                        {
                            int           num20          = num19 * this.width * this.depth + num18 * this.width + num17;
                            LevelGridNode levelGridNode5 = this.nodes[num20];
                            if (levelGridNode5 != null)
                            {
                                this.CalculateConnections(this.nodes, levelGridNode5, num17, num18, num19);
                            }
                        }
                    }
                }
                this.ErodeWalkableArea(a5.xmin, a5.ymin, a5.xmax + 1, a5.ymax + 1);
                for (int num21 = a5.xmin; num21 <= a5.xmax; num21++)
                {
                    for (int num22 = a5.ymin; num22 <= a5.ymax; num22++)
                    {
                        if (!a4.Contains(num21, num22))
                        {
                            for (int num23 = 0; num23 < this.layerCount; num23++)
                            {
                                int           num24          = num23 * this.width * this.depth + num22 * this.width + num21;
                                LevelGridNode levelGridNode6 = this.nodes[num24];
                                if (levelGridNode6 != null)
                                {
                                    levelGridNode6.Walkable = levelGridNode6.TmpWalkable;
                                }
                            }
                        }
                    }
                }
                for (int num25 = a5.xmin; num25 <= a5.xmax; num25++)
                {
                    for (int num26 = a5.ymin; num26 <= a5.ymax; num26++)
                    {
                        for (int num27 = 0; num27 < this.layerCount; num27++)
                        {
                            int           num28          = num27 * this.width * this.depth + num26 * this.width + num25;
                            LevelGridNode levelGridNode7 = this.nodes[num28];
                            if (levelGridNode7 != null)
                            {
                                this.CalculateConnections(this.nodes, levelGridNode7, num25, num26, num27);
                            }
                        }
                    }
                }
            }
        }
Example #17
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            //System.DateTime startTime = System.DateTime.UtcNow;

            Bounds bounds = o.bounds;

            Rect r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);

            var r2 = new IntRect(
                Mathf.FloorToInt(bounds.min.x * Int3.Precision),
                Mathf.FloorToInt(bounds.min.z * Int3.Precision),
                Mathf.FloorToInt(bounds.max.x * Int3.Precision),
                Mathf.FloorToInt(bounds.max.z * Int3.Precision)
                );

            var a = new Int3(r2.xmin, 0, r2.ymin);
            var b = new Int3(r2.xmin, 0, r2.ymax);
            var c = new Int3(r2.xmax, 0, r2.ymin);
            var d = new Int3(r2.xmax, 0, r2.ymax);

            graph.GetNodes(_node => {
                var node = _node as TriangleMeshNode;

                bool inside = false;

                int allLeft   = 0;
                int allRight  = 0;
                int allTop    = 0;
                int allBottom = 0;

                for (int v = 0; v < 3; v++)
                {
                    Int3 p   = node.GetVertex(v);
                    var vert = (Vector3)p;

                    if (r2.Contains(p.x, p.z))
                    {
                        inside = true;
                        break;
                    }

                    if (vert.x < r.xMin)
                    {
                        allLeft++;
                    }
                    if (vert.x > r.xMax)
                    {
                        allRight++;
                    }
                    if (vert.z < r.yMin)
                    {
                        allTop++;
                    }
                    if (vert.z > r.yMax)
                    {
                        allBottom++;
                    }
                }
                if (!inside)
                {
                    if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)
                    {
                        return(true);
                    }
                }

                for (int v = 0; v < 3; v++)
                {
                    int v2 = v > 1 ? 0 : v + 1;

                    Int3 vert1 = node.GetVertex(v);
                    Int3 vert2 = node.GetVertex(v2);

                    if (Polygon.Intersects(a, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(a, c, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(c, d, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(d, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                }

                if (node.ContainsPoint(a) || node.ContainsPoint(b) || node.ContainsPoint(c) || node.ContainsPoint(d))
                {
                    inside = true;
                }

                if (!inside)
                {
                    return(true);
                }

                o.WillUpdateNode(node);
                o.Apply(node);
                return(true);
            });
        }
Example #18
0
        // Token: 0x0600052A RID: 1322 RVA: 0x0002D6B8 File Offset: 0x0002BAB8
        public void UpdateArea(GraphUpdateObject guo)
        {
            if (this.nodes == null)
            {
                return;
            }
            for (int i = 0; i < this.nodeCount; i++)
            {
                if (guo.bounds.Contains((Vector3)this.nodes[i].position))
                {
                    guo.WillUpdateNode(this.nodes[i]);
                    guo.Apply(this.nodes[i]);
                }
            }
            if (guo.updatePhysics)
            {
                Bounds bounds = guo.bounds;
                if (this.thickRaycast)
                {
                    bounds.Expand(this.thickRaycastRadius * 2f);
                }
                List <GraphNode> list = ListPool <GraphNode> .Claim();

                List <uint> list2 = ListPool <uint> .Claim();

                for (int j = 0; j < this.nodeCount; j++)
                {
                    PointNode        pointNode = this.nodes[j];
                    Vector3          a         = (Vector3)pointNode.position;
                    List <GraphNode> list3     = null;
                    List <uint>      list4     = null;
                    for (int k = 0; k < this.nodeCount; k++)
                    {
                        if (k != j)
                        {
                            Vector3 b = (Vector3)this.nodes[k].position;
                            if (Polygon.LineIntersectsBounds(bounds, a, b))
                            {
                                PointNode pointNode2 = this.nodes[k];
                                bool      flag       = pointNode.ContainsConnection(pointNode2);
                                float     num;
                                if (!flag && this.IsValidConnection(pointNode, pointNode2, out num))
                                {
                                    if (list3 == null)
                                    {
                                        list.Clear();
                                        list2.Clear();
                                        list3 = list;
                                        list4 = list2;
                                        list3.AddRange(pointNode.connections);
                                        list4.AddRange(pointNode.connectionCosts);
                                    }
                                    uint item = (uint)Mathf.RoundToInt(num * 1000f);
                                    list3.Add(pointNode2);
                                    list4.Add(item);
                                }
                                else if (flag && !this.IsValidConnection(pointNode, pointNode2, out num))
                                {
                                    if (list3 == null)
                                    {
                                        list.Clear();
                                        list2.Clear();
                                        list3 = list;
                                        list4 = list2;
                                        list3.AddRange(pointNode.connections);
                                        list4.AddRange(pointNode.connectionCosts);
                                    }
                                    int num2 = list3.IndexOf(pointNode2);
                                    if (num2 != -1)
                                    {
                                        list3.RemoveAt(num2);
                                        list4.RemoveAt(num2);
                                    }
                                }
                            }
                        }
                    }
                    if (list3 != null)
                    {
                        pointNode.connections     = list3.ToArray();
                        pointNode.connectionCosts = list4.ToArray();
                    }
                }
                ListPool <GraphNode> .Release(list);

                ListPool <uint> .Release(list2);
            }
        }
Example #19
0
        /** Internal function to update an area of the graph.
         * \todo Messy code, clean it up. */
        public void UpdateArea(GraphUpdateObject o)
        {
            if (nodes == null) {
                Debug.LogWarning ("The Grid Graph is not scanned, cannot update area ");
                //Not scanned
                return;
            }

            //Copy the bounds
            Bounds b = o.bounds;

            //Matrix inverse
            //node.position = matrix.MultiplyPoint3x4 (new Vector3 (x+0.5F,0,z+0.5F));

            Vector3 min, max;
            GetBoundsMinMax (b,inverseMatrix,out min, out max);

            int minX = Mathf.RoundToInt (min.x-0.5F);
            int maxX = Mathf.RoundToInt (max.x-0.5F);

            int minZ = Mathf.RoundToInt (min.z-0.5F);
            int maxZ = Mathf.RoundToInt (max.z-0.5F);

            //We now have coordinates in local space (i.e 1 unit = 1 node)

            int ominx = minX;
            int omaxx = maxX;
            int ominz = minZ;
            int omaxz = maxZ;

            if (o.updatePhysics && !o.modifyWalkability) {
                //Add the collision.diameter margin for physics calls
                if (collision.collisionCheck) {
                    Vector3 margin = new Vector3 (collision.diameter,0,collision.diameter)*0.5F;

                    min -= margin*1.02F;//0.02 safety margin, physics is rarely very accurate
                    max += margin*1.02F;
            #if DEBUG
                    Debug.DrawLine (matrix.MultiplyPoint3x4(min),matrix.MultiplyPoint3x4(max),Color.cyan);
            #endif

                    minX = Mathf.RoundToInt (min.x-0.5F);
                    maxX = Mathf.RoundToInt (max.x-0.5F);

                    minZ = Mathf.RoundToInt (min.z-0.5F);
                    maxZ = Mathf.RoundToInt (max.z-0.5F);

                }

                collision.Initialize (matrix,nodeSize);

                for (int x = minX;x <= maxX;x++) {
                    for (int z = minZ;z <= maxZ;z++) {

                        if (x < 0 || z < 0) {
                            continue;
                        }
                        if (z >= depth || x >= width) {
                            break;
                        }

                        int index = z*width+x;

                        GridNode node = nodes[index] as GridNode;

                        //Register that this node will eventually have some settings changed
                        o.WillUpdateNode (node);

                        UpdateNodePositionCollision (node,x,z);
                    }
                }
            }

            //This is the area inside the bounding box, call Apply on it
            for (int x = ominx;x <= omaxx;x++) {
                for (int z = ominz;z <= omaxz;z++) {

                    if (x < 0 || z < 0) {
                        continue;
                    }
                    if (z >= depth || x >= width) {
                        break;
                    }

                    int index = z*width+x;

                    GridNode node = nodes[index] as GridNode;

                    if (!o.updatePhysics || o.modifyWalkability) {
                        //Register that this node will eventually have some settings changed
                        //If the above IF evaluates to false, the node will already have been added before in the function
                        o.WillUpdateNode (node);
                    }

                    node.walkable = node.WalkableErosion;
                    o.Apply (node);
                    node.WalkableErosion = node.walkable;
                }
            }

            //Recalculate connections
            if ((o.updatePhysics || o.modifyWalkability) && erodeIterations == 0) {

                //Add some margin
                minX--;
                maxX++;
                minZ--;
                maxZ++;
                for (int x = minX;x <= maxX;x++) {
                    for (int z = minZ;z <= maxZ;z++) {

                        if (x < 0 || z < 0 || x >= width || z >= depth) {
                            continue;
                        }

                        int index = z*width+x;

                        GridNode node = nodes[index] as GridNode;

                        CalculateConnections (graphNodes,x,z,node);

                    }
                }

                //Remove margin
                minX++;
                maxX--;
                minZ++;
                maxZ--;
            }

            if ((o.updatePhysics || o.modifyWalkability) && erodeIterations > 0) {
                minX -= erodeIterations;
                maxX += erodeIterations;
                minZ -= erodeIterations;
                maxZ += erodeIterations;

                for (int x = minX;x <= maxX;x++) {
                    for (int z = minZ;z <= maxZ;z++) {

                        if (x < 0 || z < 0 || x >= width || z >= depth) {
                            continue;
                        }

                        int index = z*width+x;

                        GridNode node = nodes[index] as GridNode;

                        node.walkable = node.WalkableErosion;
                    }
                }

                //Add some margin
                minX--;
                maxX++;
                minZ--;
                maxZ++;

                //Loop through all nodes at the edge of the current bounds and swap their walkable and WalkableErosion flags
                for (int x=minX, z=minZ;x<= maxX;x++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    //Debug.DrawRay (node.position,Vector3.up,Color.red);
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }
                for (int x=minX, z=maxZ;x<= maxX;x++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    //Debug.DrawRay (node.position,Vector3.up,Color.red);
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }
                for (int z=minZ, x=minX;z<= maxZ;z++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    //Debug.DrawRay (node.position,Vector3.up,Color.red);
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }
                for (int z=minZ, x=maxX;z<= maxZ;z++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    //Debug.DrawRay (node.position,Vector3.up,Color.red);
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }

                //Remove margin
                minX++;
                maxX--;
                minZ++;
                maxZ--;

                //Calculate connections for all nodes
                for (int x = minX;x <= maxX;x++) {
                    for (int z = minZ;z <= maxZ;z++) {

                        if (x < 0 || z < 0 || x >= width || z >= depth) {
                            continue;
                        }

                        int index = z*width+x;

                        GridNode node = nodes[index] as GridNode;

                        CalculateConnections (graphNodes,x,z,node);

                    }
                }

                //Erode function uses < not <=
                maxX++;
                maxZ++;

                /*for (int x = minX;x < maxX;x++) {
                    for (int z = minZ;z < maxZ;z++) {

                        if (x < 0 || z < 0 || x >= width || z >= depth) {
                            continue;
                        }

                        int index = z*width+x;

                        GridNode node = graphNodes[index];
                        //Debug.DrawRay (node.position,Vector3.up*0.5F,Color.green);
                    }
                }*/

                //Erode area
                ErodeWalkableArea (minX,minZ,maxX,maxZ);

                maxX--;
                maxZ--;

                //Add some margin
                minX--;
                maxX++;
                minZ--;
                maxZ++;

                for (int x=minX, z=minZ;x<= maxX;x++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }
                for (int x=minX, z=maxZ;x<= maxX;x++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }
                for (int z=minZ, x=minX;z<= maxZ;z++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }
                for (int z=minZ, x=maxX;z<= maxZ;z++) {
                    if (x < 0 || z < 0 || x >= width || z >= depth) continue;
                    GridNode node = nodes[z*width+x] as GridNode;
                    bool tmp = node.walkable;
                    node.walkable = node.WalkableErosion;
                    node.WalkableErosion = tmp;
                }

                for (int x = minX;x <= maxX;x++) {
                    for (int z = minZ;z <= maxZ;z++) {

                        if (x < 0 || z < 0 || x >= width || z >= depth) {
                            continue;
                        }

                        int index = z*width+x;

                        GridNode node = nodes[index] as GridNode;

                        CalculateConnections (graphNodes,x,z,node);

                    }
                }

                //Remove margin
                minX++;
                maxX--;
                minZ++;
                maxZ--;
            }
        }
Example #20
0
        public static void UpdateArea(GraphUpdateObject o, INavmesh graph)
        {
            //System.DateTime startTime = System.DateTime.UtcNow;

            var bounds = o.bounds;

            var r = Rect.MinMaxRect(bounds.min.x, bounds.min.z, bounds.max.x, bounds.max.z);

            var r2 = new IntRect(
                Mathf.FloorToInt(bounds.min.x * Int3.Precision),
                Mathf.FloorToInt(bounds.min.z * Int3.Precision),
                Mathf.FloorToInt(bounds.max.x * Int3.Precision),
                Mathf.FloorToInt(bounds.max.z * Int3.Precision)
                );

            var a = new Int3(r2.xmin, 0, r2.ymin);
            var b = new Int3(r2.xmin, 0, r2.ymax);
            var c = new Int3(r2.xmax, 0, r2.ymin);
            var d = new Int3(r2.xmax, 0, r2.ymax);

            var ia = (Int3)a;
            var ib = (Int3)b;
            var ic = (Int3)c;
            var id = (Int3)d;


            //for (int i=0;i<nodes.Length;i++) {
            graph.GetNodes(delegate(GraphNode _node) {
                var node = _node as TriangleMeshNode;

                var inside = false;

                var allLeft   = 0;
                var allRight  = 0;
                var allTop    = 0;
                var allBottom = 0;

                for (var v = 0; v < 3; v++)
                {
                    var p    = node.GetVertex(v);
                    var vert = (Vector3)p;
                    //Vector2 vert2D = new Vector2 (vert.x,vert.z);

                    if (r2.Contains(p.x, p.z))
                    {
                        //Debug.DrawRay (vert,Vector3.up*10,Color.yellow);
                        inside = true;
                        break;
                    }

                    if (vert.x < r.xMin)
                    {
                        allLeft++;
                    }
                    if (vert.x > r.xMax)
                    {
                        allRight++;
                    }
                    if (vert.z < r.yMin)
                    {
                        allTop++;
                    }
                    if (vert.z > r.yMax)
                    {
                        allBottom++;
                    }
                }
                if (!inside)
                {
                    if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3)
                    {
                        return(true);
                    }
                }

                //Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.yellow);
                //Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.yellow);
                //Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.yellow);

                for (var v = 0; v < 3; v++)
                {
                    var v2 = v > 1 ? 0 : v + 1;

                    var vert1 = node.GetVertex(v);
                    var vert2 = node.GetVertex(v2);

                    if (Polygon.Intersects(a, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(a, c, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(c, d, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (Polygon.Intersects(d, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                }



                if (node.ContainsPoint(ia) || node.ContainsPoint(ib) || node.ContainsPoint(ic) || node.ContainsPoint(id))
                {
                    inside = true;
                }

                if (!inside)
                {
                    return(true);
                }

                o.WillUpdateNode(node);
                o.Apply(node);

                /*Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.blue);
                 * Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.blue);
                 * Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.blue);
                 * Debug.Break ();*/
                return(true);
            });

            //System.DateTime endTime = System.DateTime.UtcNow;
            //float theTime = (endTime-startTime).Ticks*0.0001F;
            //Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms");
        }
Example #21
0
		public static void UpdateArea (GraphUpdateObject o, INavmesh graph) {
			
			//System.DateTime startTime = System.DateTime.UtcNow;
				
			Bounds bounds = o.bounds;
			
			Rect r = Rect.MinMaxRect (bounds.min.x,bounds.min.z,bounds.max.x,bounds.max.z);
			
			IntRect r2 = new IntRect(
				Mathf.FloorToInt(bounds.min.x*Int3.Precision),
				Mathf.FloorToInt(bounds.min.z*Int3.Precision),
				Mathf.FloorToInt(bounds.max.x*Int3.Precision),
				Mathf.FloorToInt(bounds.max.z*Int3.Precision)
			);
			
			/*Vector3 a = new Vector3 (r.xMin,0,r.yMin);//	-1 	-1
			Vector3 b = new Vector3 (r.xMin,0,r.yMax);//	-1	 1 
			Vector3 c = new Vector3 (r.xMax,0,r.yMin);//	 1 	-1
			Vector3 d = new Vector3 (r.xMax,0,r.yMax);//	 1 	 1
			*/
			Int3 a = new Int3(r2.xmin,0,r2.ymin);
			Int3 b = new Int3(r2.xmin,0,r2.ymax);
			Int3 c = new Int3(r2.xmax,0,r2.ymin);
			Int3 d = new Int3(r2.xmax,0,r2.ymax);
			
			Int3 ia = (Int3)a;
			Int3 ib = (Int3)b;
			Int3 ic = (Int3)c;
			Int3 id = (Int3)d;
			
#if ASTARDEBUG
			Debug.DrawLine (a,b,Color.white);
			Debug.DrawLine (a,c,Color.white);
			Debug.DrawLine (c,d,Color.white);
			Debug.DrawLine (d,b,Color.white);
#endif
			
			//for (int i=0;i<nodes.Length;i++) {
			graph.GetNodes (delegate (GraphNode _node) {
				TriangleMeshNode node = _node as TriangleMeshNode;
				
				bool inside = false;
				
				int allLeft = 0;
				int allRight = 0;
				int allTop = 0;
				int allBottom = 0;
				
				for (int v=0;v<3;v++) {
					
					Int3 p = node.GetVertex(v);
					Vector3 vert = (Vector3)p;
					//Vector2 vert2D = new Vector2 (vert.x,vert.z);
					
					if (r2.Contains (p.x,p.z)) {
						//Debug.DrawRay (vert,Vector3.up*10,Color.yellow);
						inside = true;
						break;
					}
					
					if (vert.x < r.xMin) allLeft++;
					if (vert.x > r.xMax) allRight++;
					if (vert.z < r.yMin) allTop++;
					if (vert.z > r.yMax) allBottom++;
					
					//if (!bounds.Contains (node[v]) {
					//	inside = false;
					//	break;
					//}
				}
				if (!inside) {
					if (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3) {
						return true;
					}
				}
				
				//Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.yellow);
				//Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.yellow);
				//Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.yellow);
				
				for (int v=0;v<3;v++) {
					int v2 = v > 1 ? 0 : v+1;
					
					Int3 vert1 = node.GetVertex(v);
					Int3 vert2 = node.GetVertex(v2);
					
					if (Polygon.Intersects (a,b,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (a,c,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (c,d,vert1,vert2)) { inside = true; break; }
					if (Polygon.Intersects (d,b,vert1,vert2)) { inside = true; break; }
				}
				
				
				
				if (node.ContainsPoint (ia) || node.ContainsPoint (ib) || node.ContainsPoint (ic) || node.ContainsPoint (id)) {
					inside = true;
				}
				
				if (!inside) {
					return true;
				}
				
				o.WillUpdateNode(node);
				o.Apply (node);
				/*Debug.DrawLine ((Vector3)node.GetVertex(0),(Vector3)node.GetVertex(1),Color.blue);
				Debug.DrawLine ((Vector3)node.GetVertex(1),(Vector3)node.GetVertex(2),Color.blue);
				Debug.DrawLine ((Vector3)node.GetVertex(2),(Vector3)node.GetVertex(0),Color.blue);
				Debug.Break ();*/
				return true;
			});
			
			//System.DateTime endTime = System.DateTime.UtcNow;
			//float theTime = (endTime-startTime).Ticks*0.0001F;
			//Debug.Log ("Intersecting bounds with navmesh took "+theTime.ToString ("0.000")+" ms");
		
		}
        public static void UpdateArea(GraphUpdateObject o, INavmeshHolder graph)
        {
            Bounds bounds = graph.transform.InverseTransform(o.bounds);

            // Bounding rectangle with integer coordinates
            var irect = new IntRect(
                Mathf.FloorToInt(bounds.min.x * Int3.Precision),
                Mathf.FloorToInt(bounds.min.z * Int3.Precision),
                Mathf.CeilToInt(bounds.max.x * Int3.Precision),
                Mathf.CeilToInt(bounds.max.z * Int3.Precision)
                );

            // Corners of the bounding rectangle
            var a = new Int3(irect.xmin, 0, irect.ymin);
            var b = new Int3(irect.xmin, 0, irect.ymax);
            var c = new Int3(irect.xmax, 0, irect.ymin);
            var d = new Int3(irect.xmax, 0, irect.ymax);

            var ymin = ((Int3)bounds.min).y;
            var ymax = ((Int3)bounds.max).y;

            // Loop through all nodes and check if they intersect the bounding box
            graph.GetNodes(_node =>
            {
                var node = _node as TriangleMeshNode;

                bool inside = false;

                int allLeft   = 0;
                int allRight  = 0;
                int allTop    = 0;
                int allBottom = 0;

                // Check bounding box rect in XZ plane
                for (int v = 0; v < 3; v++)
                {
                    Int3 p = node.GetVertexInGraphSpace(v);

                    if (irect.Contains(p.x, p.z))
                    {
                        inside = true;
                        break;
                    }

                    if (p.x < irect.xmin)
                    {
                        allLeft++;
                    }
                    if (p.x > irect.xmax)
                    {
                        allRight++;
                    }
                    if (p.z < irect.ymin)
                    {
                        allTop++;
                    }
                    if (p.z > irect.ymax)
                    {
                        allBottom++;
                    }
                }

                if (!inside && (allLeft == 3 || allRight == 3 || allTop == 3 || allBottom == 3))
                {
                    return;
                }

                // Check if the polygon edges intersect the bounding rect
                for (int v = 0; v < 3; v++)
                {
                    int v2 = v > 1 ? 0 : v + 1;

                    Int3 vert1 = node.GetVertexInGraphSpace(v);
                    Int3 vert2 = node.GetVertexInGraphSpace(v2);

                    if (VectorMath.SegmentsIntersectXZ(a, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(a, c, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(c, d, vert1, vert2))
                    {
                        inside = true; break;
                    }
                    if (VectorMath.SegmentsIntersectXZ(d, b, vert1, vert2))
                    {
                        inside = true; break;
                    }
                }

                // Check if the node contains any corner of the bounding rect
                if (inside || node.ContainsPointInGraphSpace(a) || node.ContainsPointInGraphSpace(b) || node.ContainsPointInGraphSpace(c) || node.ContainsPointInGraphSpace(d))
                {
                    inside = true;
                }

                if (!inside)
                {
                    return;
                }

                int allAbove = 0;
                int allBelow = 0;

                // Check y coordinate
                for (int v = 0; v < 3; v++)
                {
                    Int3 p = node.GetVertexInGraphSpace(v);
                    if (p.y < ymin)
                    {
                        allBelow++;
                    }
                    if (p.y > ymax)
                    {
                        allAbove++;
                    }
                }

                // Polygon is either completely above the bounding box or completely below it
                if (allBelow == 3 || allAbove == 3)
                {
                    return;
                }

                // Triangle is inside the bounding box!
                // Update it!
                o.WillUpdateNode(node);
                o.Apply(node);
            });
        }
Example #23
0
		/** Internal function to update an area of the graph.
		  */
		public void UpdateArea (GraphUpdateObject o) {
			
			if (nodes == null || nodes.Length != width*depth) {
				Debug.LogWarning ("The Grid Graph is not scanned, cannot update area ");
				//Not scanned
				return;
			}
			
			//Copy the bounds
			Bounds b = o.bounds;
			
			Vector3 min, max;
			GetBoundsMinMax (b,inverseMatrix,out min, out max);
			
			int minX = Mathf.RoundToInt (min.x-0.5F);
			int maxX = Mathf.RoundToInt (max.x-0.5F);
			
			int minZ = Mathf.RoundToInt (min.z-0.5F);
			int maxZ = Mathf.RoundToInt (max.z-0.5F);
			//We now have coordinates in local space (i.e 1 unit = 1 node)
			
			IntRect originalRect = new IntRect(minX,minZ,maxX,maxZ);
			IntRect affectRect = originalRect;
			
			IntRect gridRect = new IntRect(0,0,width-1,depth-1);
			
			IntRect physicsRect = originalRect;
			
			int erosion = o.updateErosion ? erodeIterations : 0;
			
#if ASTARDEBUG
			Matrix4x4 debugMatrix = matrix;
			debugMatrix *= Matrix4x4.TRS (new Vector3(0.5f,0,0.5f),Quaternion.identity,Vector3.one);
			
			originalRect.DebugDraw (debugMatrix,Color.red);
#endif
			
			bool willChangeWalkability = o.updatePhysics || o.modifyWalkability;
			
			//Calculate the largest bounding box which might be affected
			
			if (o.updatePhysics && !o.modifyWalkability) {
				//Add the collision.diameter margin for physics calls
				if (collision.collisionCheck) {
					Vector3 margin = new Vector3 (collision.diameter,0,collision.diameter)*0.5F;
					
					min -= margin*1.02F;//0.02 safety margin, physics is rarely very accurate
					max += margin*1.02F;
					
					physicsRect = new IntRect(
					                            Mathf.RoundToInt (min.x-0.5F),
					                            Mathf.RoundToInt (min.z-0.5F),
					                            Mathf.RoundToInt (max.x-0.5F),
					                            Mathf.RoundToInt (max.z-0.5F)
					                            );
					
					affectRect = IntRect.Union (physicsRect, affectRect);
				}
			}
			
			if (willChangeWalkability || erosion > 0) {
				//Add affect radius for erosion. +1 for updating connectivity info at the border
				affectRect = affectRect.Expand (erosion + 1);
			}
			
			IntRect clampedRect = IntRect.Intersection (affectRect,gridRect);
			
			//Mark nodes that might be changed
			for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
				for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
					o.WillUpdateNode (nodes[z*width+x]);
				}
			}
			
			//Update Physics
			if (o.updatePhysics && !o.modifyWalkability) {
				
				collision.Initialize (matrix,nodeSize);
				
				clampedRect = IntRect.Intersection (physicsRect,gridRect);
				
				for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
					for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
						
						int index = z*width+x;
						
						GridNode node = nodes[index];
						
						UpdateNodePositionCollision (node,x,z, o.resetPenaltyOnPhysics);
					}
				}
			}
			
			//Apply GUO
			
			clampedRect = IntRect.Intersection (originalRect, gridRect);
			for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
				for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
					int index = z*width+x;
					
					GridNode node = nodes[index];
					
					if (willChangeWalkability) {
						node.Walkable = node.WalkableErosion;
						if (o.bounds.Contains ((Vector3)node.position)) o.Apply (node);
						node.WalkableErosion = node.Walkable;
					} else {
						if (o.bounds.Contains ((Vector3)node.position)) o.Apply (node);
					}
				}
			}
		
#if ASTARDEBUG
			physicsRect.DebugDraw (debugMatrix,Color.blue);
			affectRect.DebugDraw (debugMatrix,Color.black);
#endif
			
			//Recalculate connections
			if (willChangeWalkability && erosion == 0) {
				
				clampedRect = IntRect.Intersection (affectRect, gridRect);
				for (int x = clampedRect.xmin; x <= clampedRect.xmax;x++) {
					for (int z = clampedRect.ymin;z <= clampedRect.ymax;z++) {
						int index = z*width+x;
						
						GridNode node = nodes[index];
						
						CalculateConnections (nodes,x,z,node);
					}
				}
			} else if (willChangeWalkability && erosion > 0) {
				
				
				clampedRect = IntRect.Union (originalRect, physicsRect);
				
				IntRect erosionRect1 = clampedRect.Expand (erosion);
				IntRect erosionRect2 = erosionRect1.Expand (erosion);
				
				erosionRect1 = IntRect.Intersection (erosionRect1,gridRect);
				erosionRect2 = IntRect.Intersection (erosionRect2,gridRect);
				
#if ASTARDEBUG
				erosionRect1.DebugDraw (debugMatrix,Color.magenta);
				erosionRect2.DebugDraw (debugMatrix,Color.cyan);
#endif
				
				/*
				all nodes inside clampedRect might have had their walkability changed
				all nodes inside erosionRect1 might get affected by erosion from clampedRect and erosionRect2
				all nodes inside erosionRect2 (but outside erosionRect1) will be reset to previous walkability
				after calculation since their erosion might not be correctly calculated (nodes outside erosionRect2 would maybe have effect)
				*/
				
				for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
					for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
						
						int index = z*width+x;
						
						GridNode node = nodes[index];
						
						bool tmp = node.Walkable;
						node.Walkable = node.WalkableErosion;
						
						if (!erosionRect1.Contains (x,z)) {
							//Save the border's walkabilty data (will be reset later)
							node.TmpWalkable = tmp;
						}
					}
				}
				
				for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
					for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
						int index = z*width+x;
						
						GridNode node = nodes[index];
						
#if ASTARDEBUG
						if (!node.Walkable)
							Debug.DrawRay ((Vector3)node.position, Vector3.up*2,Color.red);
#endif
						
						CalculateConnections (nodes,x,z,node);
					}
				}
				
				//Erode the walkable area
				ErodeWalkableArea (erosionRect2.xmin,erosionRect2.ymin,erosionRect2.xmax+1,erosionRect2.ymax+1);
				
				for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
					for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
						if (erosionRect1.Contains (x,z)) continue;
						
						int index = z*width+x;
						
						GridNode node = nodes[index];
						
						//Restore temporarily stored data
						node.Walkable = node.TmpWalkable;
					}
				}
				
				//Recalculate connections of all affected nodes
				for (int x = erosionRect2.xmin; x <= erosionRect2.xmax;x++) {
					for (int z = erosionRect2.ymin;z <= erosionRect2.ymax;z++) {
						int index = z*width+x;
						
						GridNode node = nodes[index];
						CalculateConnections (nodes,x,z,node);
					}
				}
			}
		}
		public void UpdateArea (GraphUpdateObject o) {
			
			if (graphNodes == null || nodes == null) {
				Debug.LogWarning ("The Grid Graph is not scanned, cannot update area ");
				//Not scanned
				return;
			}
			
			//Copy the bounds
			Bounds b = o.bounds;
			
			//Matrix inverse 
			//node.position = matrix.MultiplyPoint3x4 (new Vector3 (x+0.5F,0,z+0.5F));
			
			Vector3 min = inverseMatrix.MultiplyPoint3x4 (b.min);
			Vector3 max = inverseMatrix.MultiplyPoint3x4 (b.max);
			
			int minX = Mathf.RoundToInt (min.x-0.5F);
			int maxX = Mathf.RoundToInt (max.x-0.5F);
			
			int minZ = Mathf.RoundToInt (min.z-0.5F);
			int maxZ = Mathf.RoundToInt (max.z-0.5F);
			
			//We now have coordinates in local space (i.e 1 unit = 1 node)
			
			int ominx = minX;
			int omaxx = maxX;
			int ominz = minZ;
			int omaxz = maxZ;
			
			if (o.updatePhysics && !o.modifyWalkability) {
				//Add the collision.diameter margin for physics calls
				if (collision.collisionCheck) {
					Vector3 margin = new Vector3 (collision.diameter,0,collision.diameter)*0.5F;
				
					min -= margin*1.02F;//0.02 safety margin, physics is rarely very accurate
					max += margin*1.02F;
					Debug.DrawLine (matrix.MultiplyPoint3x4(min),matrix.MultiplyPoint3x4(max),Color.cyan);
					
					minX = Mathf.RoundToInt (min.x-0.5F);
					maxX = Mathf.RoundToInt (max.x-0.5F);
				
					minZ = Mathf.RoundToInt (min.z-0.5F);
					maxZ = Mathf.RoundToInt (max.z-0.5F);
					
				}
				
				collision.Initialize (matrix,nodeSize);
				
				for (int x = minX;x <= maxX;x++) {
					for (int z = minZ;z <= maxZ;z++) {
						
						if (x < 0 || z < 0) {
							continue;
						}
						if (z >= depth || x >= width) {
							break;
						}
						
						int index = z*width+x;
						
						GridNode node = graphNodes[index];
						
						//Register that this node will eventually have some settings changed
						o.WillUpdateNode (node);
						
						UpdateNodePositionCollision (node,x,z);
					}
				}
			}
			
			//This is the area inside the bounding box, call Apply on it
			for (int x = ominx;x <= omaxx;x++) {
				for (int z = ominz;z <= omaxz;z++) {
					
					if (x < 0 || z < 0) {
						continue;
					}
					if (z >= depth || x >= width) {
						break;
					}
					
					int index = z*width+x;
					
					GridNode node = graphNodes[index];
					
					if (!o.updatePhysics || o.modifyWalkability) {
						//Register that this node will eventually have some settings changed
						//If the above IF evaluates to false, the node will already have been added before in the function
						o.WillUpdateNode (node);
					}
					
					o.Apply (node);
				}
			}
			
			//Recalculate connections
			if (o.updatePhysics || o.modifyWalkability) {
				//Add some margin
				minX--; //Mathf.Clamp (minX-1,0,width);
				maxX++; //Mathf.Clamp (maxX+1,0,width);
				minZ--; //Mathf.Clamp (minZ-1,0,depth);
				maxZ++; //Mathf.Clamp (maxZ+1,0,depth);
				
				for (int x = minX;x <= maxX;x++) {
					for (int z = minZ;z <= maxZ;z++) {
						
						if (x < 0 || z < 0 || x >= width || z >= depth) {
							continue;
						}
						
						int index = z*width+x;
						
						GridNode node = graphNodes[index];
						
						CalculateConnections (graphNodes,x,z,node);
						
					}
				}
			}
		}