static bool isWalkableNode(PNavPoint self, PNavPoint max, PNavPoint delta, PNavColumn[,] columns)
        {
            PNavPoint pOut;
            bool      valid = PNavMeshHelper.GetPoint(self, max, delta, out pOut);

            if (valid)
            {
                PNavNode n = columns[pOut.x, pOut.z].SurfaceNode();

                valid = (n != null && n.walkable);
            }

            return(valid);
        }
        static bool isInnerNode(PNavPoint point, PNavPoint max, PNavPoint delta, int nodes, PNavColumn[,] columns)
        {
            PNavPoint pOut;
            PNavPoint newDelta = new PNavPoint(delta.x * nodes, delta.z * nodes);
            bool      valid    = PNavMeshHelper.GetPoint(point, max, newDelta, out pOut);

            if (valid)
            {
                PNavNode n = columns[pOut.x, pOut.z].SurfaceNode();

                valid = (n != null && n.IsInner);
            }

            return(valid);
        }
        static bool isEdgeNode(PNavPoint point, PNavPoint max, PNavPoint delta, PNavColumn[,] columns)
        {
            PNavPoint pOut;
            bool      valid = PNavMeshHelper.GetPoint(point, max, delta, out pOut);

            if (valid)
            {
                PNavNode n = columns[pOut.x, pOut.z].SurfaceNode();

                if (n == null)
                {
                    return(false);
                }

                return(n.IsLeftEdge || n.IsRghtEdge || n.IsBackEdge || n.IsFrontEdge);
            }

            return(false);
        }
        static bool CheckIfNodeIsValidEdge(PNavNode node, PNavColumn[,] columns, PNavPoint pointMax)
        {
            node.isEdge = false;

            node.edgeFlag = 0;

            bool allSurroundingAreInner = true;

            for (int i = 0; i < 8; i++)
            {
                walkables[i] = false;

                PNavPoint pOut;
                bool      valid = PNavMeshHelper.GetPoint(node.point, pointMax, points2[i], out pOut);

                if (valid)
                {
                    PNavNode n = columns[pOut.x, pOut.z].SurfaceNode();

                    if (n != null)
                    {
                        if (n.walkable)
                        {
                            walkables[i]  = true;
                            node.edgeFlag = (byte)(node.edgeFlag | 1 << i);
                        }

                        if (!n.IsInner)
                        {
                            allSurroundingAreInner = false;
                        }
                    }
                }
            }

            if (!allSurroundingAreInner)
            {
                node.isEdge = true;
            }

            if (walkables[0] != walkables[4]) //left and right
            {
                node.isEdge = true;

                // if top and bot are not walkable, not valid
                if (!walkables[2] && !walkables[6])
                {
                    node.isEdge = false;
                }
            }

            if (walkables[2] != walkables[6]) // top and bot
            {
                node.isEdge = true;

                // if left and right are not walkable, not valid
                if (!walkables[0] && !walkables[4])
                {
                    node.isEdge = false;
                }
            }

            // if all diagonal nodes are not walkable, not valid
            if (!walkables[1] && !walkables[3] && !walkables[5] && !walkables[7])
            {
                node.isEdge = false;
            }

            return(node.isEdge);
        }
        static bool DetectEdgeLoop(PNavNode node, PNavEdgeLoop edgeLoop, int edgeLoopIndex, PNavColumn[,] columns, PNavPoint pointMax)
        {
            bool foundLoop = false;

            if (node == null || !node.walkable || node.edgeLoopIndex >= 0)
            {
                return(false);
            }

            bool isEdge = CheckIfNodeIsValidEdge(node, columns, pointMax);

            if (!isEdge)
            {
                return(false);
            }

            Stack <PNavNode> stack = new Stack <PNavNode>();

            stack.Push(node);

            while (stack.Count > 0)
            {
                PNavNode n = stack.Pop();

                //possible to be added more than once
                if (n.edgeLoopIndex >= 0)
                {
                    continue;
                }

                edgeLoop.nodes.Add(n);
                n.edgeLoopIndex = edgeLoopIndex;
                foundLoop       = true;

                for (int i = 0; i < 8; i++)
                {
                    PNavPoint pOut;
                    bool      valid = PNavMeshHelper.GetPoint(n.point, pointMax, points[i], out pOut);

                    if (valid)
                    {
                        PNavNode nPush = columns[pOut.x, pOut.z].SurfaceNode();
                        if (nPush != null)
                        {
                            if (!nPush.walkable || nPush.edgeLoopIndex >= 0)
                            {
                                continue;
                            }

                            bool isEdge1 = CheckIfNodeIsValidEdge(nPush, columns, pointMax);

                            if (!isEdge1)
                            {
                                continue;
                            }

                            stack.Push(nPush);
                        }
                    }
                }
            }

            return(foundLoop);
        }