public void generateNeighborLinks(OpenHeightfield field)
        {
            if( field == null )
            {
                Logger.LogError("[OpenHeightfieldBuilder][generateNeighborLinks]field Empty"); 
                return; 
            }

            OpenHeightfield.OpenHeightFieldIterator iter = field.GetEnumerator(); 
            while( iter.MoveNext() )
            {
                OpenHeightSpan span = iter.Current; 
                for(int dir = 0; dir < 4; ++dir)
                {
                    //邻居的GirdIndex
                    int nWidthIndex = (iter.widthIndex() + BoundeField.getDirOffsetWidth(dir));
                    int nDepthIndex = (iter.depthIndex() + BoundeField.getDirOffsetDepth(dir)); 
                    
                    for(OpenHeightSpan nSpan = field.getData(nWidthIndex,nDepthIndex);
                        nSpan != null;
                        nSpan = nSpan.next())
                    {
                        int maxFloor = Math.Max(span.floor(), nSpan.floor());
                        int minCeling = Math.Min(span.ceiling(), nSpan.ceiling()); 

                        
                        if( (minCeling - maxFloor) >= mMinTraversableHeight   //邻居之间的通道足够高,可以通过 
                            && Math.Abs(nSpan.floor() - span.floor()) <= mMaxTraversableStep )  //两邻居之间的落差足够小
                        {
                            span.setNeighbor(dir, nSpan);
                            break; 
                        }
                    }

                }
            }
        }
        /// <summary>
        /// 边缘裁剪,那种像断崖式的Span也不可走的
        /// </summary>
        /// <param name="field"></param>
        private void markLedgeSpans(SolidHeightfield field)
        {
            SolidHeightfield.SolidHeightfieldIterator iter = field.GetEnumerator();
            while (iter.MoveNext())
            {
                HeightSpan span = iter.Current;

                if ((span.flags() & SpanFlags.WALKABLE) == 0)
                {
                    continue;
                }

                int widthIndex = iter.widthIndex();
                int depthIndex = iter.depthIndex();

                int currFloor   = span.max();
                int currCeiling = (span.next() != null)
                    ? span.next().min() : int.MaxValue;


                int minDistanceToNeighbor = int.MaxValue;

                for (int dir = 0; dir < 4; dir++)
                {
                    int nWidthIndex = widthIndex
                                      + BoundeField.getDirOffsetWidth(dir);
                    int nDepthIndex = depthIndex
                                      + BoundeField.getDirOffsetDepth(dir);


                    HeightSpan nSpan = field.getData(nWidthIndex, nDepthIndex);
                    if (null == nSpan)
                    {
                        //TODO 这里没有搞懂为啥是 -mMaxTraversableStep - currFloor,是为了比-mMaxTraversableStep更小,以便直接判断不能行走吗?
                        // 用大可行的距离,再减去currFloor,得到的肯定是一个更小的值。
                        // currFloor - mMaxTraversableStep 是一个最大允许的落差地板距离。注意这里只考虑下落的情况
                        minDistanceToNeighbor = Math.Min(minDistanceToNeighbor, -mMaxTraversableStep - currFloor);
                        continue;
                    }


                    /*
                     *  先考虑一种特殊情况 ,那就是
                     *  那就是nSpan.min也比currFloor要高,那么对应的
                     *  的邻居相当于也是没有Floor的,所以默认取-mMaxTraversableStep吧。
                     */

                    int nFloor   = -mMaxTraversableStep;
                    int nCeiling = nSpan.min();

                    //当前Span所处列的currCeiling和邻居的nCeiling相比,取最低的
                    if (Math.Min(currCeiling, nCeiling) - currFloor > mMinTraversableHeight)
                    {
                        minDistanceToNeighbor = Math.Min(minDistanceToNeighbor, (nFloor - currFloor));
                    }

                    for (nSpan = field.getData(nWidthIndex, nDepthIndex); nSpan != null; nSpan = nSpan.next())
                    {
                        nFloor   = nSpan.max(); //现在才开始用max考虑真正存在的Floor
                        nCeiling = (nSpan.next() != null)
                            ? nSpan.next().min() : int.MaxValue;

                        if (Math.Min(currCeiling, nCeiling) - Math.Max(currFloor, nFloor) > mMinTraversableHeight)
                        {
                            minDistanceToNeighbor = Math.Min(minDistanceToNeighbor, (nFloor - currFloor));
                        }
                    }
                }

                //如果最近的距离比较最大掉落还小的放在,那么就是不可行走的
                if (minDistanceToNeighbor < -mMaxTraversableStep)
                {
                    span.setFlags(span.flags() & ~SpanFlags.WALKABLE);
                }
            }
        }