Ejemplo n.º 1
0
        public override void UpdateRecursiveG(Path path, PathNode pathNode, PathHandler handler)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            base.UpdateG(path, pathNode);
            handler.heap.Add(pathNode);
            ushort pathID          = handler.PathID;
            int    nodeInGridIndex = base.NodeInGridIndex;

            for (int i = 0; i < 8; i++)
            {
                if (this.HasConnectionInDirection(i))
                {
                    GridNode gridNode  = nodes[nodeInGridIndex + neighbourOffsets[i]];
                    PathNode pathNode2 = handler.GetPathNode(gridNode);
                    if (pathNode2.parent == pathNode && pathNode2.pathID == pathID)
                    {
                        gridNode.UpdateRecursiveG(path, pathNode2, handler);
                    }
                }
            }
            base.UpdateRecursiveG(path, pathNode, handler);
        }
Ejemplo n.º 2
0
        // Token: 0x060025D1 RID: 9681 RVA: 0x001A6030 File Offset: 0x001A4230
        public override Vector3 RandomPointOnSurface()
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
            Vector3   a         = gridGraph.transform.InverseTransform((Vector3)this.position);

            return(gridGraph.transform.Transform(a + new Vector3(UnityEngine.Random.value - 0.5f, 0f, UnityEngine.Random.value - 0.5f)));
        }
Ejemplo n.º 3
0
        /** Helper method to set PathNode.flag1 to a specific value for all nodes adjacent to a grid node */
        void SetFlag1OnSurroundingGridNodes(GridNode gridNode, bool flag1State)
        {
            // Loop through all adjacent grid nodes
            var gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);

            // Number of neighbours as an int
            int mxnum = gridGraph.neighbours == NumNeighbours.Four ? 4 : (gridGraph.neighbours == NumNeighbours.Eight ? 8 : 6);

            // Calculate the coordinates of the node
            var x = gridNode.NodeInGridIndex % gridGraph.width;
            var z = gridNode.NodeInGridIndex / gridGraph.width;

            for (int i = 0; i < mxnum; i++)
            {
                int nx, nz;
                if (gridGraph.neighbours == NumNeighbours.Six)
                {
                    // Hexagon graph
                    nx = x + gridGraph.neighbourXOffsets[GridGraph.hexagonNeighbourIndices[i]];
                    nz = z + gridGraph.neighbourZOffsets[GridGraph.hexagonNeighbourIndices[i]];
                }
                else
                {
                    nx = x + gridGraph.neighbourXOffsets[i];
                    nz = z + gridGraph.neighbourZOffsets[i];
                }

                // Check if the position is still inside the grid
                if (nx >= 0 && nz >= 0 && nx < gridGraph.width && nz < gridGraph.depth)
                {
                    var adjacentNode = gridGraph.nodes[nz * gridGraph.width + nx];
                    pathHandler.GetPathNode(adjacentNode).flag1 = flag1State;
                }
            }
        }
Ejemplo n.º 4
0
        public override void UpdateRecursiveG(Path path, PathNode pathNode, PathHandler handler)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            base.UpdateG(path, pathNode);
            handler.PushNode(pathNode);
            ushort pathID = handler.PathID;

            for (int i = 0; i < 8; i++)
            {
                if (this.GetConnectionInternal(i))
                {
                    GridNode gridNode  = nodes[this.nodeInGridIndex + neighbourOffsets[i]];
                    PathNode pathNode2 = handler.GetPathNode(gridNode);
                    if (pathNode2.parent == pathNode && pathNode2.pathID == pathID)
                    {
                        gridNode.UpdateRecursiveG(path, pathNode2, handler);
                    }
                }
            }
            if (this.connections != null)
            {
                for (int j = 0; j < this.connections.Length; j++)
                {
                    GraphNode graphNode = this.connections[j];
                    PathNode  pathNode3 = handler.GetPathNode(graphNode);
                    if (pathNode3.parent == pathNode && pathNode3.pathID == pathID)
                    {
                        graphNode.UpdateRecursiveG(path, pathNode3, handler);
                    }
                }
            }
        }
Ejemplo n.º 5
0
 public override void ClearConnections(bool alsoReverse)
 {
     if (alsoReverse)
     {
         GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
         for (int i = 0; i < 8; i++)
         {
             GridNode nodeConnection = gridGraph.GetNodeConnection(this, i);
             if (nodeConnection != null)
             {
                 nodeConnection.SetConnectionInternal((i >= 4) ? 7 : ((i + 2) % 4), false);
             }
         }
     }
     this.ResetConnectionsInternal();
     if (alsoReverse && this.connections != null)
     {
         for (int j = 0; j < this.connections.Length; j++)
         {
             this.connections[j].RemoveConnection(this);
         }
     }
     this.connections     = null;
     this.connectionCosts = null;
 }
Ejemplo n.º 6
0
        public override void GetConnections(GraphNodeDelegate del)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            for (int i = 0; i < 8; i++)
            {
                if (this.GetConnectionInternal(i))
                {
                    GridNode gridNode = nodes[this.nodeInGridIndex + neighbourOffsets[i]];
                    if (gridNode != null)
                    {
                        del(gridNode);
                    }
                }
            }
            if (this.connections != null)
            {
                for (int j = 0; j < this.connections.Length; j++)
                {
                    del(this.connections[j]);
                }
            }
        }
Ejemplo n.º 7
0
        public override void FloodFill(Stack <GraphNode> stack, uint region)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            for (int i = 0; i < 8; i++)
            {
                if (this.GetConnectionInternal(i))
                {
                    GridNode gridNode = nodes[this.nodeInGridIndex + neighbourOffsets[i]];
                    if (gridNode != null && gridNode.Area != region)
                    {
                        gridNode.Area = region;
                        stack.Push(gridNode);
                    }
                }
            }
            if (this.connections != null)
            {
                for (int j = 0; j < this.connections.Length; j++)
                {
                    GraphNode graphNode = this.connections[j];
                    if (graphNode.Area != region)
                    {
                        graphNode.Area = region;
                        stack.Push(graphNode);
                    }
                }
            }
        }
Ejemplo n.º 8
0
        public Vector3 Point2GraphSpace(float height)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
            int       num       = this.nodeInGridIndex % gridGraph.width;
            int       num2      = this.nodeInGridIndex / gridGraph.width;

            return(new Vector3((float)num, height, (float)num2));
        }
Ejemplo n.º 9
0
        public override Vector3 RandomPointOnSurface()
        {
            GridGraph gg = GridNode.GetGridGraph(GraphIndex);

            var graphSpacePosition = gg.transform.InverseTransform((Vector3)position);

            return(gg.transform.Transform(graphSpacePosition + new Vector3(Random.value - 0.5f, 0, Random.value - 0.5f)));
        }
Ejemplo n.º 10
0
 public override GridNodeBase GetNeighbourAlongDirection(int direction)
 {
     if (this.HasConnectionInDirection(direction))
     {
         GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
         return(gridGraph.nodes[base.NodeInGridIndex + gridGraph.neighbourOffsets[direction]]);
     }
     return(null);
 }
Ejemplo n.º 11
0
        public override bool GetPortal(GraphNode other, List <Vector3> left, List <Vector3> right, bool backwards)
        {
            if (backwards)
            {
                return(true);
            }
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            for (int i = 0; i < 4; i++)
            {
                if (this.GetConnectionInternal(i) && other == nodes[this.nodeInGridIndex + neighbourOffsets[i]])
                {
                    Vector3 a      = (Vector3)(this.position + other.position) * 0.5f;
                    Vector3 vector = Vector3.Cross(gridGraph.collision.up, (Vector3)(other.position - this.position));
                    vector.Normalize();
                    vector *= gridGraph.nodeSize * 0.5f;
                    left.Add(a - vector);
                    right.Add(a + vector);
                    return(true);
                }
            }
            for (int j = 4; j < 8; j++)
            {
                if (this.GetConnectionInternal(j) && other == nodes[this.nodeInGridIndex + neighbourOffsets[j]])
                {
                    bool flag  = false;
                    bool flag2 = false;
                    if (this.GetConnectionInternal(j - 4))
                    {
                        GridNode gridNode = nodes[this.nodeInGridIndex + neighbourOffsets[j - 4]];
                        if (gridNode.Walkable && gridNode.GetConnectionInternal((j - 4 + 1) % 4))
                        {
                            flag = true;
                        }
                    }
                    if (this.GetConnectionInternal((j - 4 + 1) % 4))
                    {
                        GridNode gridNode2 = nodes[this.nodeInGridIndex + neighbourOffsets[(j - 4 + 1) % 4]];
                        if (gridNode2.Walkable && gridNode2.GetConnectionInternal(j - 4))
                        {
                            flag2 = true;
                        }
                    }
                    Vector3 a2      = (Vector3)(this.position + other.position) * 0.5f;
                    Vector3 vector2 = Vector3.Cross(gridGraph.collision.up, (Vector3)(other.position - this.position));
                    vector2.Normalize();
                    vector2 *= gridGraph.nodeSize * 1.4142f;
                    left.Add(a2 - ((!flag2) ? Vector3.zero : vector2));
                    right.Add(a2 + ((!flag) ? Vector3.zero : vector2));
                    return(true);
                }
            }
            return(false);
        }
Ejemplo n.º 12
0
        //GG
        //public override Vector3 RandomPointOnSurface () {
        public override VInt3 RandomPointOnSurface()
        {
            GridGraph gg = GridNode.GetGridGraph(GraphIndex);

            //GG
            //var graphSpacePosition = gg.transform.InverseTransform((Vector3)position);
            var graphSpacePosition = gg.transform.InverseTransform(position);

            //GG
            //return gg.transform.Transform(graphSpacePosition + new Vector3(Random.value - 0.5f, 0, Random.value - 0.5f));
            return(gg.transform.Transform(graphSpacePosition + new VInt3(VRandom.Random(1, 1000) - 500, 0, VRandom.Random(1, 1000) - 500)));
        }
Ejemplo n.º 13
0
        // Token: 0x06002568 RID: 9576 RVA: 0x0019FE30 File Offset: 0x0019E030
        public Vector3 ClosestPointOnNode(Vector3 p)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            p = gridGraph.transform.InverseTransform(p);
            int     num   = base.NodeInGridIndex % gridGraph.width;
            int     num2  = base.NodeInGridIndex / gridGraph.width;
            float   y     = gridGraph.transform.InverseTransform((Vector3)this.position).y;
            Vector3 point = new Vector3(Mathf.Clamp(p.x, (float)num, (float)num + 1f), y, Mathf.Clamp(p.z, (float)num2, (float)num2 + 1f));

            return(gridGraph.transform.Transform(point));
        }
Ejemplo n.º 14
0
        public Vector3 ClosestPointOnNode(Vector3 p)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            p = gridGraph.inverseMatrix.MultiplyPoint3x4(p);
            float   value  = (float)this.position.x - 0.5f;
            float   value2 = (float)this.position.z - 0.5f;
            int     num    = this.nodeInGridIndex % gridGraph.width;
            int     num2   = this.nodeInGridIndex / gridGraph.width;
            float   y      = gridGraph.inverseMatrix.MultiplyPoint3x4(p).y;
            Vector3 v      = new Vector3(Mathf.Clamp(value, (float)num - 0.5f, (float)num + 0.5f) + 0.5f, y, Mathf.Clamp(value2, (float)num2 - 0.5f, (float)num2 + 0.5f) + 0.5f);

            return(gridGraph.matrix.MultiplyPoint3x4(v));
        }
Ejemplo n.º 15
0
        public Vector3 ClosestPointOnNode(Vector3 p)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            p = gridGraph.transform.InverseTransform(p);
            float   value  = (float)this.position.x - 0.5f;
            float   value2 = (float)this.position.z - 0.5f;
            int     num    = base.NodeInGridIndex % gridGraph.width;
            int     num2   = base.NodeInGridIndex / gridGraph.width;
            float   y      = gridGraph.transform.InverseTransform((Vector3)this.position).y;
            Vector3 p2     = new Vector3(Mathf.Clamp(value, (float)num - 0.5f, (float)num + 0.5f) + 0.5f, y, Mathf.Clamp(value2, (float)num2 - 0.5f, (float)num2 + 0.5f) + 0.5f);

            return(gridGraph.transform.Transform(p2));
        }
Ejemplo n.º 16
0
        /// <summary>Helper method to set PathNode.flag1 to a specific value for all nodes adjacent to a grid node</summary>
        private void SetFlagOnSurroundingGridNodes(GridNode gridNode, int flag, bool flagState)
        {
            // Loop through all adjacent grid nodes
            var gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);

            // Number of neighbours as an int
            var mxnum = gridGraph.neighbours == NumNeighbours.Four ? 4 :
                        gridGraph.neighbours == NumNeighbours.Eight ? 8 : 6;

            // Calculate the coordinates of the node
            var x = gridNode.NodeInGridIndex % gridGraph.width;
            var z = gridNode.NodeInGridIndex / gridGraph.width;

            if (flag != 1 && flag != 2)
            {
                throw new System.ArgumentOutOfRangeException("flag");
            }

            for (var i = 0; i < mxnum; i++)
            {
                int nx, nz;
                if (gridGraph.neighbours == NumNeighbours.Six)
                {
                    // Hexagon graph
                    nx = x + gridGraph.neighbourXOffsets[GridGraph.hexagonNeighbourIndices[i]];
                    nz = z + gridGraph.neighbourZOffsets[GridGraph.hexagonNeighbourIndices[i]];
                }
                else
                {
                    nx = x + gridGraph.neighbourXOffsets[i];
                    nz = z + gridGraph.neighbourZOffsets[i];
                }

                // Check if the position is still inside the grid
                if (nx >= 0 && nz >= 0 && nx < gridGraph.width && nz < gridGraph.depth)
                {
                    var adjacentNode = gridGraph.nodes[nz * gridGraph.width + nx];
                    var pathNode     = pathHandler.GetPathNode(adjacentNode);
                    if (flag == 1)
                    {
                        pathNode.flag1 = flagState;
                    }
                    else
                    {
                        pathNode.flag2 = flagState;
                    }
                }
            }
        }
Ejemplo n.º 17
0
 // Token: 0x060004E2 RID: 1250 RVA: 0x0002AB84 File Offset: 0x00028F84
 public override void ClearConnections(bool alsoReverse)
 {
     if (alsoReverse)
     {
         GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
         for (int i = 0; i < 8; i++)
         {
             GridNode nodeConnection = gridGraph.GetNodeConnection(this, i);
             if (nodeConnection != null)
             {
                 nodeConnection.SetConnectionInternal((i >= 4) ? 7 : ((i + 2) % 4), false);
             }
         }
     }
     this.ResetConnectionsInternal();
 }
Ejemplo n.º 18
0
        public override void Open(Path path, PathNode pathNode, PathHandler handler)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
            ushort    pathID    = handler.PathID;

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            uint[]     neighbourCosts   = gridGraph.neighbourCosts;
            GridNode[] nodes            = gridGraph.nodes;
            int        nodeInGridIndex  = base.NodeInGridIndex;

            for (int i = 0; i < 8; i++)
            {
                if (this.HasConnectionInDirection(i))
                {
                    GridNode gridNode = nodes[nodeInGridIndex + neighbourOffsets[i]];
                    if (path.CanTraverse(gridNode))
                    {
                        PathNode pathNode2 = handler.GetPathNode(gridNode);
                        uint     num       = neighbourCosts[i];
                        if (pathNode2.pathID != pathID)
                        {
                            pathNode2.parent = pathNode;
                            pathNode2.pathID = pathID;
                            pathNode2.cost   = num;
                            pathNode2.H      = path.CalculateHScore(gridNode);
                            gridNode.UpdateG(path, pathNode2);
                            handler.heap.Add(pathNode2);
                        }
                        else if (pathNode.G + num + path.GetTraversalCost(gridNode) < pathNode2.G)
                        {
                            pathNode2.cost   = num;
                            pathNode2.parent = pathNode;
                            gridNode.UpdateRecursiveG(path, pathNode2, handler);
                        }
                        else if (pathNode2.G + num + path.GetTraversalCost(this) < pathNode.G)
                        {
                            pathNode.parent = pathNode2;
                            pathNode.cost   = num;
                            this.UpdateRecursiveG(path, pathNode, handler);
                        }
                    }
                }
            }
            base.Open(path, pathNode, handler);
        }
Ejemplo n.º 19
0
        // Token: 0x06002567 RID: 9575 RVA: 0x0019FDDC File Offset: 0x0019DFDC
        public override void GetConnections(Action <GraphNode> action)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            for (int i = 0; i < 8; i++)
            {
                if (this.HasConnectionInDirection(i))
                {
                    GridNode gridNode = nodes[base.NodeInGridIndex + neighbourOffsets[i]];
                    if (gridNode != null)
                    {
                        action(gridNode);
                    }
                }
            }
        }
Ejemplo n.º 20
0
        public override bool ContainsConnection(GraphNode node)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            for (int i = 0; i < 8; i++)
            {
                if (this.GetConnectionInternal(i))
                {
                    GridNode gridNode = nodes[this.nodeInGridIndex + neighbourOffsets[i]];
                    if (gridNode == node)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 21
0
        // Token: 0x0600256A RID: 9578 RVA: 0x001A0104 File Offset: 0x0019E304
        public override void FloodFill(Stack <GraphNode> stack, uint region)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            GridNode[] nodes            = gridGraph.nodes;
            int        nodeInGridIndex  = base.NodeInGridIndex;

            for (int i = 0; i < 8; i++)
            {
                if (this.HasConnectionInDirection(i))
                {
                    GridNode gridNode = nodes[nodeInGridIndex + neighbourOffsets[i]];
                    if (gridNode != null && gridNode.Area != region)
                    {
                        gridNode.Area = region;
                        stack.Push(gridNode);
                    }
                }
            }
        }
Ejemplo n.º 22
0
        private void SetFlagOnSurroundingGridNodes(GridNode gridNode, int flag, bool flagState)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);
            int       num       = (gridGraph.neighbours != NumNeighbours.Four) ? ((gridGraph.neighbours != NumNeighbours.Eight) ? 6 : 8) : 4;
            int       num2      = gridNode.NodeInGridIndex % gridGraph.width;
            int       num3      = gridNode.NodeInGridIndex / gridGraph.width;

            if ((flag != 1) && (flag != 2))
            {
                throw new ArgumentOutOfRangeException("flag");
            }
            for (int i = 0; i < num; i++)
            {
                int num5;
                int num6;
                if (gridGraph.neighbours == NumNeighbours.Six)
                {
                    num5 = num2 + gridGraph.neighbourXOffsets[GridGraph.hexagonNeighbourIndices[i]];
                    num6 = num3 + gridGraph.neighbourZOffsets[GridGraph.hexagonNeighbourIndices[i]];
                }
                else
                {
                    num5 = num2 + gridGraph.neighbourXOffsets[i];
                    num6 = num3 + gridGraph.neighbourZOffsets[i];
                }
                if (((num5 >= 0) && (num6 >= 0)) && ((num5 < gridGraph.width) && (num6 < gridGraph.depth)))
                {
                    GridNode node     = gridGraph.nodes[(num6 * gridGraph.width) + num5];
                    PathNode pathNode = base.pathHandler.GetPathNode(node);
                    if (flag == 1)
                    {
                        pathNode.flag1 = flagState;
                    }
                    else
                    {
                        pathNode.flag2 = flagState;
                    }
                }
            }
        }
Ejemplo n.º 23
0
        // Token: 0x06002719 RID: 10009 RVA: 0x001AF3CC File Offset: 0x001AD5CC
        private void SetFlagOnSurroundingGridNodes(GridNode gridNode, int flag, bool flagState)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);
            int       num       = (gridGraph.neighbours == NumNeighbours.Four) ? 4 : ((gridGraph.neighbours == NumNeighbours.Eight) ? 8 : 6);
            int       num2      = gridNode.NodeInGridIndex % gridGraph.width;
            int       num3      = gridNode.NodeInGridIndex / gridGraph.width;

            if (flag != 1 && flag != 2)
            {
                throw new ArgumentOutOfRangeException("flag");
            }
            for (int i = 0; i < num; i++)
            {
                int num4;
                int num5;
                if (gridGraph.neighbours == NumNeighbours.Six)
                {
                    num4 = num2 + gridGraph.neighbourXOffsets[GridGraph.hexagonNeighbourIndices[i]];
                    num5 = num3 + gridGraph.neighbourZOffsets[GridGraph.hexagonNeighbourIndices[i]];
                }
                else
                {
                    num4 = num2 + gridGraph.neighbourXOffsets[i];
                    num5 = num3 + gridGraph.neighbourZOffsets[i];
                }
                if (num4 >= 0 && num5 >= 0 && num4 < gridGraph.width && num5 < gridGraph.depth)
                {
                    GridNode node     = gridGraph.nodes[num5 * gridGraph.width + num4];
                    PathNode pathNode = this.pathHandler.GetPathNode(node);
                    if (flag == 1)
                    {
                        pathNode.flag1 = flagState;
                    }
                    else
                    {
                        pathNode.flag2 = flagState;
                    }
                }
            }
        }
Ejemplo n.º 24
0
        /** Applies a special case for grid nodes.
         *
         * Assume the closest walkable node is a grid node.
         * We will now apply a special case only for grid graphs.
         * In tile based games, an obstacle often occupies a whole
         * node. When a path is requested to the position of an obstacle
         * (single unwalkable node) the closest walkable node will be
         * one of the 8 nodes surrounding that unwalkable node
         * but that node is not neccessarily the one that is most
         * optimal to walk to so in this special case
         * we mark all nodes around the unwalkable node as targets
         * and when we search and find any one of them we simply exit
         * and set that first node we found to be the 'real' end node
         * because that will be the optimal node (this does not apply
         * in general unless the heuristic is set to None, but
         * for a single unwalkable node it does).
         * This also applies if the nearest node cannot be traversed for
         * some other reason like restricted tags.
         *
         * \returns True if the workaround was applied. If this happens the
         * endPoint, endNode, hTarget and hTargetNode fields will be modified.
         *
         * Image below shows paths when this special case is applied. The path goes from the white sphere to the blue orange box.
         * \shadowimage{abpath_grid_special.gif}
         *
         * Image below shows paths when this special case has been disabled
         * \shadowimage{abpath_grid_not_special.gif}
         */
        protected virtual bool EndPointGridGraphSpecialCase(GraphNode closestWalkableEndNode)
        {
            var gridNode = closestWalkableEndNode as GridNode;

            if (gridNode != null)
            {
                var gridGraph = GridNode.GetGridGraph(gridNode.GraphIndex);

                // Find the closest node, not neccessarily walkable
                var endNNInfo2 = AstarPath.active.GetNearest(originalEndPoint, NNConstraint.None, endHint);
                var gridNode2  = endNNInfo2.node as GridNode;

                if (gridNode != gridNode2 && gridNode2 != null && gridNode.GraphIndex == gridNode2.GraphIndex)
                {
                    // Calculate the coordinates of the nodes
                    var x1 = gridNode.NodeInGridIndex % gridGraph.width;
                    var z1 = gridNode.NodeInGridIndex / gridGraph.width;

                    var x2 = gridNode2.NodeInGridIndex % gridGraph.width;
                    var z2 = gridNode2.NodeInGridIndex / gridGraph.width;

                    bool wasClose = false;
                    switch (gridGraph.neighbours)
                    {
                    case NumNeighbours.Four:
                        if ((x1 == x2 && System.Math.Abs(z1 - z2) == 1) || (z1 == z2 && System.Math.Abs(x1 - x2) == 1))
                        {
                            // If 'O' is gridNode2, then gridNode is one of the nodes marked with an 'x'
                            //    x
                            //  x O x
                            //    x
                            wasClose = true;
                        }
                        break;

                    case NumNeighbours.Eight:
                        if (System.Math.Abs(x1 - x2) <= 1 && System.Math.Abs(z1 - z2) <= 1)
                        {
                            // If 'O' is gridNode2, then gridNode is one of the nodes marked with an 'x'
                            //  x x x
                            //  x O x
                            //  x x x
                            wasClose = true;
                        }
                        break;

                    case NumNeighbours.Six:
                        // Hexagon graph
                        for (int i = 0; i < 6; i++)
                        {
                            var nx = x2 + gridGraph.neighbourXOffsets[GridGraph.hexagonNeighbourIndices[i]];
                            var nz = z2 + gridGraph.neighbourZOffsets[GridGraph.hexagonNeighbourIndices[i]];
                            if (x1 == nx && z1 == nz)
                            {
                                // If 'O' is gridNode2, then gridNode is one of the nodes marked with an 'x'
                                //    x x
                                //  x O x
                                //  x x
                                wasClose = true;
                                break;
                            }
                        }
                        break;

                    default:
                        // Should not happen unless NumNeighbours is modified in the future
                        throw new System.Exception("Unhandled NumNeighbours");
                    }

                    if (wasClose)
                    {
                        // We now need to find all nodes marked with an x to be able to mark them as targets
                        SetFlagOnSurroundingGridNodes(gridNode2, 1, true);

                        // Note, other methods assume hTarget is (Int3)endPoint
                        endPoint = (Vector3)gridNode2.position;
                        hTarget  = gridNode2.position;
                        endNode  = gridNode2;

                        // hTargetNode is used for heuristic optimizations
                        // (also known as euclidean embedding).
                        // Even though the endNode is not walkable
                        // we can use it for better heuristics since
                        // there is a workaround added (EuclideanEmbedding.ApplyGridGraphEndpointSpecialCase)
                        // which is there to support this case.
                        hTargetNode = endNode;

                        // We need to save this node
                        // so that we can reset flag1 on all nodes later
                        gridSpecialCaseNode = gridNode2;
                        return(true);
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 25
0
		/** Returns randomly selected points on the specified nodes with each point being separated by \a clearanceRadius from each other.
		 * Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph).
		 * For other node types, only the positions of the nodes will be used.
		 * 
		 * clearanceRadius will be reduced if no valid points can be found.
		 */
		public static List<Vector3> GetPointsOnNodes (List<GraphNode> nodes, int count, float clearanceRadius = 0) {
			
			if (nodes == null) throw new ArgumentNullException ("nodes");
			if (nodes.Count == 0) throw new ArgumentException ("no nodes passed");
			
			var rnd = new System.Random();
			
			var pts = ListPool<Vector3>.Claim(count);
			
			// Square
			clearanceRadius *= clearanceRadius;
			
			if (nodes[0] is TriangleMeshNode || nodes[0] is GridNode) {
				//Assume all nodes are triangle nodes or grid nodes
				
				var accs = ListPool<float>.Claim(nodes.Count);
					
				float tot = 0;
				
				for (var i=0;i<nodes.Count;i++) {
					var tnode = nodes[i] as TriangleMeshNode;
					if (tnode != null) {
						float a = Math.Abs(Polygon.TriangleArea(tnode.GetVertex(0), tnode.GetVertex(1), tnode.GetVertex(2)));
						tot += a;
						accs.Add (tot);
					}
					 else {
						var gnode = nodes[i] as GridNode;
						
						if (gnode != null) {
							var gg = GridNode.GetGridGraph (gnode.GraphIndex);
							var a = gg.nodeSize*gg.nodeSize;
							tot += a;
							accs.Add (tot);
						} else {
							accs.Add(tot);
						}
					}
				}
				
				for (var i=0;i<count;i++) {
					
					//Pick point
					var testCount = 0;
					var testLimit = 10;
					var worked = false;
					
					while (!worked) {
						worked = true;
						
						//If no valid points can be found, progressively lower the clearance radius until such a point is found
						if (testCount >= testLimit) {
							clearanceRadius *= 0.8f;
							testLimit += 10;
							if (testLimit > 100) clearanceRadius = 0;
						}
					
						var tg = (float)rnd.NextDouble()*tot;
						var v = accs.BinarySearch(tg);
						if (v < 0) v = ~v;
						
						if (v >= nodes.Count) {
							// This shouldn't happen, due to NextDouble being smaller than 1... but I don't trust floating point arithmetic.
							worked = false;
							continue;
						}
						
						var node = nodes[v] as TriangleMeshNode;
						
						Vector3 p;
						
						if (node != null) {
							// Find a random point inside the triangle
							float v1;
							float v2;
							do {
								v1 = (float)rnd.NextDouble();
								v2 = (float)rnd.NextDouble();
							} while (v1+v2 > 1);
							
							p = ((Vector3)(node.GetVertex(1)-node.GetVertex(0)))*v1 + ((Vector3)(node.GetVertex(2)-node.GetVertex(0)))*v2 + (Vector3)node.GetVertex(0);
						} else {
							var gnode = nodes[v] as GridNode;
							
							if (gnode != null) {
								var gg = GridNode.GetGridGraph (gnode.GraphIndex);
								
								var v1 = (float)rnd.NextDouble();
								var v2 = (float)rnd.NextDouble();
								p = (Vector3)gnode.position + new Vector3(v1 - 0.5f, 0, v2 - 0.5f) * gg.nodeSize;
							} else
							{
								//Point nodes have no area, so we break directly instead
								pts.Add ((Vector3)nodes[v].position);
								break;
							}
						}
						
						// Test if it is some distance away from the other points
						if (clearanceRadius > 0) {
							for (var j=0;j<pts.Count;j++) {
								if ((pts[j]-p).sqrMagnitude < clearanceRadius) {
									worked = false;
									break;
								}
							}
						}
						
						if (worked) {
							pts.Add (p);
							break;
						} else {
							testCount++;
						}
					}
				}
				
				ListPool<float>.Release(accs);
				
			} else {
				for (var i=0;i<count;i++) {
					pts.Add ((Vector3)nodes[rnd.Next (nodes.Count)].position);
				}
			}
			
			return pts;
		}
Ejemplo n.º 26
0
        public override Vector3 RandomPointOnSurface()
        {
            GridGraph gg = GridNode.GetGridGraph(GraphIndex);

            return((Vector3)position + new Vector3(Random.value - 0.5f, 0, Random.value - 0.5f) * gg.nodeSize);
        }
Ejemplo n.º 27
0
        public override float SurfaceArea()
        {
            GridGraph gg = GridNode.GetGridGraph(GraphIndex);

            return(gg.nodeSize * gg.nodeSize);
        }
Ejemplo n.º 28
0
        // Token: 0x060025D0 RID: 9680 RVA: 0x001A6008 File Offset: 0x001A4208
        public override float SurfaceArea()
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);

            return(gridGraph.nodeSize * gridGraph.nodeSize);
        }
Ejemplo n.º 29
0
        public override void Open(Path path, PathNode pathNode, PathHandler handler)
        {
            GridGraph gridGraph = GridNode.GetGridGraph(base.GraphIndex);
            ushort    pathID    = handler.PathID;

            int[]      neighbourOffsets = gridGraph.neighbourOffsets;
            uint[]     neighbourCosts   = gridGraph.neighbourCosts;
            GridNode[] nodes            = gridGraph.nodes;
            for (int i = 0; i < 8; i++)
            {
                if (this.GetConnectionInternal(i))
                {
                    GridNode gridNode = nodes[this.nodeInGridIndex + neighbourOffsets[i]];
                    if (path.CanTraverse(gridNode))
                    {
                        PathNode pathNode2 = handler.GetPathNode(gridNode);
                        uint     num       = neighbourCosts[i];
                        if (pathNode2.pathID != pathID)
                        {
                            pathNode2.parent = pathNode;
                            pathNode2.pathID = pathID;
                            pathNode2.cost   = num;
                            pathNode2.H      = path.CalculateHScore(gridNode);
                            gridNode.UpdateG(path, pathNode2);
                            handler.PushNode(pathNode2);
                        }
                        else if (pathNode.G + num + path.GetTraversalCost(gridNode) < pathNode2.G)
                        {
                            pathNode2.cost   = num;
                            pathNode2.parent = pathNode;
                            gridNode.UpdateRecursiveG(path, pathNode2, handler);
                        }
                        else if (pathNode2.G + num + path.GetTraversalCost(this) < pathNode.G)
                        {
                            pathNode.parent = pathNode2;
                            pathNode.cost   = num;
                            this.UpdateRecursiveG(path, pathNode, handler);
                        }
                    }
                }
            }
            if (this.connections != null)
            {
                for (int j = 0; j < this.connections.Length; j++)
                {
                    GraphNode graphNode = this.connections[j];
                    if (path.CanTraverse(graphNode))
                    {
                        PathNode pathNode3 = handler.GetPathNode(graphNode);
                        uint     num2      = this.connectionCosts[j];
                        if (pathNode3.pathID != pathID)
                        {
                            pathNode3.parent = pathNode;
                            pathNode3.pathID = pathID;
                            pathNode3.cost   = num2;
                            pathNode3.H      = path.CalculateHScore(graphNode);
                            graphNode.UpdateG(path, pathNode3);
                            handler.PushNode(pathNode3);
                        }
                        else if (pathNode.G + num2 + path.GetTraversalCost(graphNode) < pathNode3.G)
                        {
                            pathNode3.cost   = num2;
                            pathNode3.parent = pathNode;
                            graphNode.UpdateRecursiveG(path, pathNode3, handler);
                        }
                        else if (pathNode3.G + num2 + path.GetTraversalCost(this) < pathNode.G && graphNode.ContainsConnection(this))
                        {
                            pathNode.parent = pathNode3;
                            pathNode.cost   = num2;
                            this.UpdateRecursiveG(path, pathNode, handler);
                        }
                    }
                }
            }
        }
Ejemplo n.º 30
0
        /** Returns randomly selected points on the specified nodes with each point being separated by \a clearanceRadius from each other.
         * Selecting points ON the nodes only works for TriangleMeshNode (used by Recast Graph and Navmesh Graph) and GridNode (used by GridGraph).
         * For other node types, only the positions of the nodes will be used.
         *
         * clearanceRadius will be reduced if no valid points can be found.
         */
        public static List <Vector3> GetPointsOnNodes(List <GraphNode> nodes, int count, float clearanceRadius = 0)
        {
            if (nodes == null)
            {
                throw new System.ArgumentNullException("nodes");
            }
            if (nodes.Count == 0)
            {
                throw new System.ArgumentException("no nodes passed");
            }

            var rnd = new System.Random();

            List <Vector3> pts = ListPool <Vector3> .Claim(count);

            // Square
            clearanceRadius *= clearanceRadius;

            if (nodes[0] is TriangleMeshNode
#if !ASTAR_NO_GRID_GRAPH
                || nodes[0] is GridNode
#endif
                )
            {
                // Accumulated area of all nodes
                List <float> accs = ListPool <float> .Claim(nodes.Count);

                // Total area of all nodes so far
                float tot = 0;

                for (int i = 0; i < nodes.Count; i++)
                {
                    var tnode = nodes[i] as TriangleMeshNode;
                    if (tnode != null)
                    {
                        /** \bug Doesn't this need to be divided by 2? */
                        float a = System.Math.Abs(VectorMath.SignedTriangleAreaTimes2XZ(tnode.GetVertex(0), tnode.GetVertex(1), tnode.GetVertex(2)));
                        tot += a;
                        accs.Add(tot);
                    }
#if !ASTAR_NO_GRID_GRAPH
                    else
                    {
                        var gnode = nodes[i] as GridNode;

                        if (gnode != null)
                        {
                            GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex);
                            float     a  = gg.nodeSize * gg.nodeSize;
                            tot += a;
                            accs.Add(tot);
                        }
                        else
                        {
                            accs.Add(tot);
                        }
                    }
#endif
                }

                for (int i = 0; i < count; i++)
                {
                    //Pick point
                    int  testCount = 0;
                    int  testLimit = 10;
                    bool worked    = false;

                    while (!worked)
                    {
                        worked = true;

                        //If no valid points can be found, progressively lower the clearance radius until such a point is found
                        if (testCount >= testLimit)
                        {
                            clearanceRadius *= 0.8f;
                            testLimit       += 10;
                            if (testLimit > 100)
                            {
                                clearanceRadius = 0;
                            }
                        }

                        // Pick a random node among the ones in the list weighted by their area
                        float tg = (float)rnd.NextDouble() * tot;
                        int   v  = accs.BinarySearch(tg);
                        if (v < 0)
                        {
                            v = ~v;
                        }

                        if (v >= nodes.Count)
                        {
                            // This shouldn't happen, due to NextDouble being smaller than 1... but I don't trust floating point arithmetic.
                            worked = false;
                            continue;
                        }

                        var node = nodes[v] as TriangleMeshNode;

                        Vector3 p;

                        if (node != null)
                        {
                            // Find a random point inside the triangle
                            // This generates uniformly distributed trilinear coordinates
                            // See http://mathworld.wolfram.com/TrianglePointPicking.html
                            float v1;
                            float v2;
                            do
                            {
                                v1 = (float)rnd.NextDouble();
                                v2 = (float)rnd.NextDouble();
                            } while (v1 + v2 > 1);

                            // Pick the point corresponding to the trilinear coordinate
                            p = ((Vector3)(node.GetVertex(1) - node.GetVertex(0))) * v1 + ((Vector3)(node.GetVertex(2) - node.GetVertex(0))) * v2 + (Vector3)node.GetVertex(0);
                        }
                        else
                        {
#if !ASTAR_NO_GRID_GRAPH
                            var gnode = nodes[v] as GridNode;

                            if (gnode != null)
                            {
                                GridGraph gg = GridNode.GetGridGraph(gnode.GraphIndex);

                                float v1 = (float)rnd.NextDouble();
                                float v2 = (float)rnd.NextDouble();
                                p = (Vector3)gnode.position + new Vector3(v1 - 0.5f, 0, v2 - 0.5f) * gg.nodeSize;
                            }
                            else
#endif
                            {
                                //Point nodes have no area, so we break directly instead
                                pts.Add((Vector3)nodes[v].position);
                                break;
                            }
                        }

                        // Test if it is some distance away from the other points
                        if (clearanceRadius > 0)
                        {
                            for (int j = 0; j < pts.Count; j++)
                            {
                                if ((pts[j] - p).sqrMagnitude < clearanceRadius)
                                {
                                    worked = false;
                                    break;
                                }
                            }
                        }

                        if (worked)
                        {
                            pts.Add(p);
                            break;
                        }
                        testCount++;
                    }
                }

                ListPool <float> .Release(accs);
            }
            else
            {
                for (int i = 0; i < count; i++)
                {
                    pts.Add((Vector3)nodes[rnd.Next(nodes.Count)].position);
                }
            }

            return(pts);
        }