Expand() 공개 메소드

public Expand ( int range ) : IntRect
range int
리턴 IntRect
예제 #1
0
        public void RecalculateConnections(QuadtreeNodeHolder holder, int depth, int x, int y)
        {
            if (this.root == null)
            {
                throw new InvalidOperationException("Graph contains no nodes");
            }
            if (holder.node == null)
            {
                throw new ArgumentException("No leaf node specified. Holder has no node.");
            }
            int num = 1 << Math.Min(this.editorHeightLog2, this.editorWidthLog2) - depth;
            List <QuadtreeNode> list     = new List <QuadtreeNode>();
            List <QuadtreeNode> arg_75_1 = list;
            QuadtreeNodeHolder  arg_75_2 = this.root;
            int     arg_75_3             = 0;
            int     arg_75_4             = 0;
            int     arg_75_5             = 0;
            IntRect intRect = new IntRect(x, y, x + num, y + num);

            this.AddNeighboursRec(arg_75_1, arg_75_2, arg_75_3, arg_75_4, arg_75_5, intRect.Expand(0), holder.node);
            holder.node.connections     = list.ToArray();
            holder.node.connectionCosts = new uint[list.Count];
            for (int i = 0; i < list.Count; i++)
            {
                uint costMagnitude = (uint)(list[i].position - holder.node.position).costMagnitude;
                holder.node.connectionCosts[i] = costMagnitude;
            }
        }
예제 #2
0
        public void RecalculateConnections(QuadtreeNodeHolder holder, int depth, int x, int y)
        {
            if (this.root == null)
            {
                throw new InvalidOperationException("Graph contains no nodes");
            }
            if (holder.node == null)
            {
                throw new ArgumentException("No leaf node specified. Holder has no node.");
            }
            int num = ((int)1) << (Math.Min(this.editorHeightLog2, this.editorWidthLog2) - depth);
            ListLinqView <QuadtreeNode> arr = new ListLinqView <QuadtreeNode>();
            IntRect rect = new IntRect(x, y, x + num, y + num);

            this.AddNeighboursRec(arr, this.root, 0, 0, 0, rect.Expand(0), holder.node);
            holder.node.connections     = arr.ToArray();
            holder.node.connectionCosts = new uint[arr.Count];
            for (int i = 0; i < arr.Count; i++)
            {
                VInt3 num4 = arr[i].position - holder.node.position;
                holder.node.connectionCosts[i] = (uint)num4.costMagnitude;
            }
        }
예제 #3
0
        /// <summary>Async method for moving the graph</summary>
        IEnumerator UpdateGraphCoroutine()
        {
            // Find the direction that we want to move the graph in.
            // Calcuculate this in graph space (where a distance of one is the size of one node)
            Vector3 dir = PointToGraphSpace(target.position) - PointToGraphSpace(graph.center);

            // Snap to a whole number of nodes
            dir.x = Mathf.Round(dir.x);
            dir.z = Mathf.Round(dir.z);
            dir.y = 0;

            // Nothing do to
            if (dir == Vector3.zero)
            {
                yield break;
            }

            // Number of nodes to offset in each direction
            Int2 offset = new Int2(-Mathf.RoundToInt(dir.x), -Mathf.RoundToInt(dir.z));

            // Move the center (this is in world units, so we need to convert it back from graph space)
            graph.center += graph.transform.TransformVector(dir);
            graph.UpdateTransform();

            // Cache some variables for easier access
            int width = graph.width;
            int depth = graph.depth;

            GridNodeBase[] nodes;
            // Layers are required when handling LayeredGridGraphs
            int layers       = graph.LayerCount;
            var layeredGraph = graph as LayerGridGraph;

            if (layeredGraph != null)
            {
                nodes = layeredGraph.nodes;
            }
            else
            {
                nodes = graph.nodes;
            }

            // Create a temporary buffer required for the calculations
            if (buffer == null || buffer.Length != width * depth)
            {
                buffer = new GridNodeBase[width * depth];
            }

            // Check if we have moved less than a whole graph width all directions
            // If we have moved more than this we can just as well recalculate the whole graph
            if (Mathf.Abs(offset.x) <= width && Mathf.Abs(offset.y) <= depth)
            {
                IntRect recalculateRect = new IntRect(0, 0, offset.x, offset.y);

                // If offset.x < 0, adjust the rect
                if (recalculateRect.xmin > recalculateRect.xmax)
                {
                    int tmp2 = recalculateRect.xmax;
                    recalculateRect.xmax = width + recalculateRect.xmin;
                    recalculateRect.xmin = width + tmp2;
                }

                // If offset.y < 0, adjust the rect
                if (recalculateRect.ymin > recalculateRect.ymax)
                {
                    int tmp2 = recalculateRect.ymax;
                    recalculateRect.ymax = depth + recalculateRect.ymin;
                    recalculateRect.ymin = depth + tmp2;
                }

                // Connections need to be recalculated for the neighbours as well, so we need to expand the rect by 1
                var connectionRect = recalculateRect.Expand(1);

                // Makes sure the rect stays inside the grid
                connectionRect = IntRect.Intersection(connectionRect, new IntRect(0, 0, width, depth));

                // Offset each node by the #offset variable
                // nodes which would end up outside the graph
                // will wrap around to the other side of it
                for (int l = 0; l < layers; l++)
                {
                    int layerOffset = l * width * depth;
                    for (int z = 0; z < depth; z++)
                    {
                        int pz = z * width;
                        int tz = ((z + offset.y + depth) % depth) * width;
                        for (int x = 0; x < width; x++)
                        {
                            buffer[tz + ((x + offset.x + width) % width)] = nodes[layerOffset + pz + x];
                        }
                    }

                    yield return(null);

                    // Copy the nodes back to the graph
                    // and set the correct indices
                    for (int z = 0; z < depth; z++)
                    {
                        int pz = z * width;
                        for (int x = 0; x < width; x++)
                        {
                            int newIndex = pz + x;
                            var node     = buffer[newIndex];
                            if (node != null)
                            {
                                node.NodeInGridIndex = newIndex;
                            }
                            nodes[layerOffset + newIndex] = node;
                        }

                        // Calculate the limits for the region that has been wrapped
                        // to the other side of the graph
                        int xmin, xmax;
                        if (z >= recalculateRect.ymin && z < recalculateRect.ymax)
                        {
                            xmin = 0;
                            xmax = depth;
                        }
                        else
                        {
                            xmin = recalculateRect.xmin;
                            xmax = recalculateRect.xmax;
                        }

                        for (int x = xmin; x < xmax; x++)
                        {
                            var node = buffer[pz + x];
                            if (node != null)
                            {
                                // Clear connections on all nodes that are wrapped and placed on the other side of the graph.
                                // This is both to clear any custom connections (which do not really make sense after moving the node)
                                // and to prevent possible exceptions when the node will later (possibly) be destroyed because it was
                                // not needed anymore (only for layered grid graphs).
                                node.ClearConnections(false);
                            }
                        }
                    }

                    yield return(null);
                }

                // The calculation will only update approximately this number of
                // nodes per frame. This is used to keep CPU load per frame low
                int yieldEvery = 1000;
                // To avoid the update taking too long, make yieldEvery somewhat proportional to the number of nodes that we are going to update
                int approxNumNodesToUpdate = Mathf.Max(Mathf.Abs(offset.x), Mathf.Abs(offset.y)) * Mathf.Max(width, depth);
                yieldEvery = Mathf.Max(yieldEvery, approxNumNodesToUpdate / 10);
                int counter = 0;

                // Recalculate the nodes
                // Take a look at the image in the docs for the UpdateGraph method
                // to see which nodes are being recalculated.
                for (int z = 0; z < depth; z++)
                {
                    int xmin, xmax;
                    if (z >= recalculateRect.ymin && z < recalculateRect.ymax)
                    {
                        xmin = 0;
                        xmax = width;
                    }
                    else
                    {
                        xmin = recalculateRect.xmin;
                        xmax = recalculateRect.xmax;
                    }

                    for (int x = xmin; x < xmax; x++)
                    {
                        graph.RecalculateCell(x, z, false, false);
                    }

                    counter += (xmax - xmin);

                    if (counter > yieldEvery)
                    {
                        counter = 0;
                        yield return(null);
                    }
                }

                for (int z = 0; z < depth; z++)
                {
                    int xmin, xmax;
                    if (z >= connectionRect.ymin && z < connectionRect.ymax)
                    {
                        xmin = 0;
                        xmax = width;
                    }
                    else
                    {
                        xmin = connectionRect.xmin;
                        xmax = connectionRect.xmax;
                    }

                    for (int x = xmin; x < xmax; x++)
                    {
                        graph.CalculateConnections(x, z);
                    }

                    counter += (xmax - xmin);

                    if (counter > yieldEvery)
                    {
                        counter = 0;
                        yield return(null);
                    }
                }

                yield return(null);

                // Calculate all connections for the nodes along the boundary
                // of the graph, these always need to be updated
                /// <summary>TODO: Optimize to not traverse all nodes in the graph, only those at the edges</summary>
                for (int z = 0; z < depth; z++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        if (x == 0 || z == 0 || x == width - 1 || z == depth - 1)
                        {
                            graph.CalculateConnections(x, z);
                        }
                    }
                }
            }
            else
            {
                // The calculation will only update approximately this number of
                // nodes per frame. This is used to keep CPU load per frame low
                int yieldEvery = Mathf.Max(depth * width / 20, 1000);
                int counter    = 0;
                // Just update all nodes
                for (int z = 0; z < depth; z++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        graph.RecalculateCell(x, z);
                    }
                    counter += width;
                    if (counter > yieldEvery)
                    {
                        counter = 0;
                        yield return(null);
                    }
                }

                // Recalculate the connections of all nodes
                for (int z = 0; z < depth; z++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        graph.CalculateConnections(x, z);
                    }
                    counter += width;
                    if (counter > yieldEvery)
                    {
                        counter = 0;
                        yield return(null);
                    }
                }
            }
        }
예제 #4
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;
            }
            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)) ? (!o.resetPenaltyOnPhysics) : ((LayerGridGraphUpdate)o).preserveExistingNodes;

            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);
                    }
                }
            }
            else if (flag && num > 0)
            {
                IntRect a3 = IntRect.Union(a, intRect).Expand(num);
                IntRect a4 = a3.Expand(num);
                a3 = IntRect.Intersection(a3, b);
                a4 = IntRect.Intersection(a4, b);
                for (int num9 = a4.xmin; num9 <= a4.xmax; num9++)
                {
                    for (int num10 = a4.ymin; num10 <= a4.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 = a4.xmin; num13 <= a4.xmax; num13++)
                {
                    for (int num14 = a4.ymin; num14 <= a4.ymax; num14++)
                    {
                        this.CalculateConnections(num13, num14);
                    }
                }
                base.ErodeWalkableArea(a4.xmin, a4.ymin, a4.xmax + 1, a4.ymax + 1);
                for (int num15 = a4.xmin; num15 <= a4.xmax; num15++)
                {
                    for (int num16 = a4.ymin; num16 <= a4.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 = a4.xmin; num19 <= a4.xmax; num19++)
                {
                    for (int num20 = a4.ymin; num20 <= a4.ymax; num20++)
                    {
                        this.CalculateConnections(num19, num20);
                    }
                }
            }
        }
예제 #5
0
        // Token: 0x06002430 RID: 9264 RVA: 0x00196841 File Offset: 0x00194A41
        private IEnumerator UpdateGraphCoroutine()
        {
            Vector3 vector = this.PointToGraphSpace(this.target.position) - this.PointToGraphSpace(this.graph.center);

            vector.x = Mathf.Round(vector.x);
            vector.z = Mathf.Round(vector.z);
            vector.y = 0f;
            if (vector == Vector3.zero)
            {
                yield break;
            }
            Int2 offset = new Int2(-Mathf.RoundToInt(vector.x), -Mathf.RoundToInt(vector.z));

            this.graph.center += this.graph.transform.TransformVector(vector);
            this.graph.UpdateTransform();
            int            width          = this.graph.width;
            int            depth          = this.graph.depth;
            int            layers         = this.graph.LayerCount;
            LayerGridGraph layerGridGraph = this.graph as LayerGridGraph;

            GridNodeBase[] nodes;
            if (layerGridGraph != null)
            {
                GridNodeBase[] nodes2 = layerGridGraph.nodes;
                nodes = nodes2;
            }
            else
            {
                GridNodeBase[] nodes2 = this.graph.nodes;
                nodes = nodes2;
            }
            if (this.buffer == null || this.buffer.Length != width * depth)
            {
                this.buffer = new GridNodeBase[width * depth];
            }
            if (Mathf.Abs(offset.x) <= width && Mathf.Abs(offset.y) <= depth)
            {
                IntRect recalculateRect = new IntRect(0, 0, offset.x, offset.y);
                if (recalculateRect.xmin > recalculateRect.xmax)
                {
                    int xmax = recalculateRect.xmax;
                    recalculateRect.xmax = width + recalculateRect.xmin;
                    recalculateRect.xmin = width + xmax;
                }
                if (recalculateRect.ymin > recalculateRect.ymax)
                {
                    int ymax = recalculateRect.ymax;
                    recalculateRect.ymax = depth + recalculateRect.ymin;
                    recalculateRect.ymin = depth + ymax;
                }
                IntRect connectionRect = recalculateRect.Expand(1);
                connectionRect = IntRect.Intersection(connectionRect, new IntRect(0, 0, width, depth));
                int num7;
                for (int i = 0; i < layers; i = num7 + 1)
                {
                    int layerOffset = i * width * depth;
                    for (int j = 0; j < depth; j++)
                    {
                        int num  = j * width;
                        int num2 = (j + offset.y + depth) % depth * width;
                        for (int k = 0; k < width; k++)
                        {
                            this.buffer[num2 + (k + offset.x + width) % width] = nodes[layerOffset + num + k];
                        }
                    }
                    yield return(null);

                    for (int l = 0; l < depth; l++)
                    {
                        int num3 = l * width;
                        for (int m = 0; m < width; m++)
                        {
                            int          num4         = num3 + m;
                            GridNodeBase gridNodeBase = this.buffer[num4];
                            if (gridNodeBase != null)
                            {
                                gridNodeBase.NodeInGridIndex = num4;
                            }
                            nodes[layerOffset + num4] = gridNodeBase;
                        }
                        int num5;
                        int num6;
                        if (l >= recalculateRect.ymin && l < recalculateRect.ymax)
                        {
                            num5 = 0;
                            num6 = depth;
                        }
                        else
                        {
                            num5 = recalculateRect.xmin;
                            num6 = recalculateRect.xmax;
                        }
                        for (int n = num5; n < num6; n++)
                        {
                            GridNodeBase gridNodeBase2 = this.buffer[num3 + n];
                            if (gridNodeBase2 != null)
                            {
                                gridNodeBase2.ClearConnections(false);
                            }
                        }
                    }
                    yield return(null);

                    num7 = i;
                }
                int yieldEvery = 1000;
                int num8       = Mathf.Max(Mathf.Abs(offset.x), Mathf.Abs(offset.y)) * Mathf.Max(width, depth);
                yieldEvery = Mathf.Max(yieldEvery, num8 / 10);
                int counter = 0;
                for (int i = 0; i < depth; i = num7 + 1)
                {
                    int num9;
                    int num10;
                    if (i >= recalculateRect.ymin && i < recalculateRect.ymax)
                    {
                        num9  = 0;
                        num10 = width;
                    }
                    else
                    {
                        num9  = recalculateRect.xmin;
                        num10 = recalculateRect.xmax;
                    }
                    for (int num11 = num9; num11 < num10; num11++)
                    {
                        this.graph.RecalculateCell(num11, i, false, false);
                    }
                    counter += num10 - num9;
                    if (counter > yieldEvery)
                    {
                        counter = 0;
                        yield return(null);
                    }
                    num7 = i;
                }
                for (int i = 0; i < depth; i = num7 + 1)
                {
                    int num12;
                    int num13;
                    if (i >= connectionRect.ymin && i < connectionRect.ymax)
                    {
                        num12 = 0;
                        num13 = width;
                    }
                    else
                    {
                        num12 = connectionRect.xmin;
                        num13 = connectionRect.xmax;
                    }
                    for (int num14 = num12; num14 < num13; num14++)
                    {
                        this.graph.CalculateConnections(num14, i);
                    }
                    counter += num13 - num12;
                    if (counter > yieldEvery)
                    {
                        counter = 0;
                        yield return(null);
                    }
                    num7 = i;
                }
                yield return(null);

                for (int num15 = 0; num15 < depth; num15++)
                {
                    for (int num16 = 0; num16 < width; num16++)
                    {
                        if (num16 == 0 || num15 == 0 || num16 == width - 1 || num15 == depth - 1)
                        {
                            this.graph.CalculateConnections(num16, num15);
                        }
                    }
                }
                if (!this.floodFill)
                {
                    this.graph.GetNodes(delegate(GraphNode node)
                    {
                        node.Area = 1u;
                    });
                }
            }
            else
            {
                int counter    = Mathf.Max(depth * width / 20, 1000);
                int yieldEvery = 0;
                int num7;
                for (int i = 0; i < depth; i = num7 + 1)
                {
                    for (int num17 = 0; num17 < width; num17++)
                    {
                        this.graph.RecalculateCell(num17, i, true, true);
                    }
                    yieldEvery += width;
                    if (yieldEvery > counter)
                    {
                        yieldEvery = 0;
                        yield return(null);
                    }
                    num7 = i;
                }
                for (int i = 0; i < depth; i = num7 + 1)
                {
                    for (int num18 = 0; num18 < width; num18++)
                    {
                        this.graph.CalculateConnections(num18, i);
                    }
                    yieldEvery += width;
                    if (yieldEvery > counter)
                    {
                        yieldEvery = 0;
                        yield return(null);
                    }
                    num7 = i;
                }
            }
            yield break;
        }
예제 #6
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;

            base.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);
                            }
                        }
                    }
                }
            }
        }
예제 #7
0
		public void UpdateArea (GraphUpdateObject guo) {
			
			Bounds b = guo.bounds;
			b.center -= forcedBounds.min;
			
			//Figure out which tiles are affected
			IntRect r = new IntRect (Mathf.FloorToInt (b.min.x / (tileSizeX*cellSize)), Mathf.FloorToInt (b.min.z / (tileSizeZ*cellSize)), Mathf.FloorToInt (b.max.x / (tileSizeX*cellSize)), Mathf.FloorToInt (b.max.z / (tileSizeZ*cellSize)));
			//Clamp to bounds
			r = IntRect.Intersection (r, new IntRect (0,0,tileXCount-1,tileZCount-1));
			
			if (!guo.updatePhysics) {
				
				
				for ( int z=r.ymin;z<=r.ymax;z++) {
					for ( int x=r.xmin;x<=r.xmax;x++) {
						NavmeshTile tile = tiles[z*tileXCount + x];
						tile.flag = true;
					}
				}
				
				for ( int z=r.ymin;z<=r.ymax;z++) {
					for ( int x=r.xmin;x<=r.xmax;x++) {
						NavmeshTile tile = tiles[z*tileXCount + x];
						if ( tile.flag ) {
							tile.flag = false;
							
							NavMeshGraph.UpdateArea (guo, tile);
						}
					}
				}
				
				return;
			}
			
			if (!dynamic) {
				throw new System.Exception ("Recast graph must be marked as dynamic to enable graph updates with updatePhysics = true");
			}
			
			Voxelize vox = globalVox;
			
			if (vox == null) {
				throw new System.InvalidOperationException ("No Voxelizer object. UpdateAreaInit should have been called before this function.");
			}
			
			
			
			AstarProfiler.StartProfile ("Init");
				
			/** \bug No bounds checking */
			
			//r.DebugDraw (Matrix4x4.TRS (forcedBounds.min, Quaternion.identity, new Vector3 (tileSize*cellSize, 1, tileSize*cellSize)), Color.red);
			
			//Debug.Break ();
			
			
			
			AstarProfiler.StartProfile ("RemoveConnections");
			
			
			
			for (int x=r.xmin;x<=r.xmax;x++) {
				for (int z=r.ymin;z<=r.ymax;z++) {
					RemoveConnectionsFromTile (tiles[x + z*tileXCount]);
				}
			}
			
			
			
			AstarProfiler.EndProfile ("RemoveConnections");
			
			AstarProfiler.StartProfile ("Build Tiles");
			
			for (int x=r.xmin;x<=r.xmax;x++) {
				for (int z=r.ymin;z<=r.ymax;z++) {
					BuildTileMesh (vox, x,z);
				}
			}
			
			
			
			AstarProfiler.EndProfile ("Build Tiles");
			
			
			AstarProfiler.StartProfile ("ConnectTiles");
			uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex (this);
			
			for (int x=r.xmin;x<=r.xmax;x++) {
				for (int z=r.ymin;z<=r.ymax;z++) {
					NavmeshTile tile = tiles[x + z*tileXCount];
					GraphNode[] nodes = tile.nodes;
					
					for (int i=0;i<nodes.Length;i++) nodes[i].GraphIndex = graphIndex;
				}
			}
			
			
			
			//Connect the newly create tiles with the old tiles and with each other
			r = r.Expand (1);
			//Clamp to bounds
			r = IntRect.Intersection (r, new IntRect (0,0,tileXCount-1,tileZCount-1));
			
			for (int x=r.xmin;x<=r.xmax;x++) {
				for (int z=r.ymin;z<=r.ymax;z++) {
					if (x < tileXCount-1 && r.Contains (x+1, z)) {
						ConnectTiles (tiles[x + z*tileXCount], tiles[x+1 + z*tileXCount]);
					}
					if (z < tileZCount-1 && r.Contains (x, z+1)) {
						ConnectTiles (tiles[x + z*tileXCount], tiles[x + (z+1)*tileXCount]);
					}
				}
			}
			
			AstarProfiler.EndProfile ("ConnectTiles");
			AstarProfiler.PrintResults ();
		}
예제 #8
0
 public void UpdateArea(GraphUpdateObject guo)
 {
     Bounds bounds = guo.bounds;
     bounds.center -= this.forcedBounds.min;
     IntRect a = new IntRect(Mathf.FloorToInt(bounds.min.x / ((float)this.tileSizeX * this.cellSize)), Mathf.FloorToInt(bounds.min.z / ((float)this.tileSizeZ * this.cellSize)), Mathf.FloorToInt(bounds.max.x / ((float)this.tileSizeX * this.cellSize)), Mathf.FloorToInt(bounds.max.z / ((float)this.tileSizeZ * this.cellSize)));
     a = IntRect.Intersection(a, new IntRect(0, 0, this.tileXCount - 1, this.tileZCount - 1));
     if (!guo.updatePhysics)
     {
         for (int i = a.ymin; i <= a.ymax; i++)
         {
             for (int j = a.xmin; j <= a.xmax; j++)
             {
                 RecastGraph.NavmeshTile navmeshTile = this.tiles[i * this.tileXCount + j];
                 navmeshTile.flag = true;
             }
         }
         for (int k = a.ymin; k <= a.ymax; k++)
         {
             for (int l = a.xmin; l <= a.xmax; l++)
             {
                 RecastGraph.NavmeshTile navmeshTile2 = this.tiles[k * this.tileXCount + l];
                 if (navmeshTile2.flag)
                 {
                     navmeshTile2.flag = false;
                     NavMeshGraph.UpdateArea(guo, navmeshTile2);
                 }
             }
         }
         return;
     }
     if (!this.dynamic)
     {
         throw new Exception("Recast graph must be marked as dynamic to enable graph updates with updatePhysics = true");
     }
     Voxelize voxelize = this.globalVox;
     if (voxelize == null)
     {
         throw new InvalidOperationException("No Voxelizer object. UpdateAreaInit should have been called before this function.");
     }
     for (int m = a.xmin; m <= a.xmax; m++)
     {
         for (int n = a.ymin; n <= a.ymax; n++)
         {
             this.RemoveConnectionsFromTile(this.tiles[m + n * this.tileXCount]);
         }
     }
     for (int num = a.xmin; num <= a.xmax; num++)
     {
         for (int num2 = a.ymin; num2 <= a.ymax; num2++)
         {
             this.BuildTileMesh(voxelize, num, num2);
         }
     }
     uint graphIndex = (uint)AstarPath.active.astarData.GetGraphIndex(this);
     for (int num3 = a.xmin; num3 <= a.xmax; num3++)
     {
         for (int num4 = a.ymin; num4 <= a.ymax; num4++)
         {
             RecastGraph.NavmeshTile navmeshTile3 = this.tiles[num3 + num4 * this.tileXCount];
             GraphNode[] nodes = navmeshTile3.nodes;
             for (int num5 = 0; num5 < nodes.Length; num5++)
             {
                 nodes[num5].GraphIndex = graphIndex;
             }
         }
     }
     a = a.Expand(1);
     a = IntRect.Intersection(a, new IntRect(0, 0, this.tileXCount - 1, this.tileZCount - 1));
     for (int num6 = a.xmin; num6 <= a.xmax; num6++)
     {
         for (int num7 = a.ymin; num7 <= a.ymax; num7++)
         {
             if (num6 < this.tileXCount - 1 && a.Contains(num6 + 1, num7))
             {
                 this.ConnectTiles(this.tiles[num6 + num7 * this.tileXCount], this.tiles[num6 + 1 + num7 * this.tileXCount]);
             }
             if (num7 < this.tileZCount - 1 && a.Contains(num6, num7 + 1))
             {
                 this.ConnectTiles(this.tiles[num6 + num7 * this.tileXCount], this.tiles[num6 + (num7 + 1) * this.tileXCount]);
             }
         }
     }
 }