Beispiel #1
0
        public void GetPathNeighbours(MPPathNode current, int maxX, int maxZ, MPNeigbours neighbours)
        {
            ulong[] curSlices = HeightSlicePool.GetSlices(current.SliceHeader);
            if (curSlices == null)
            {
                return;
            }
            //get current ceiling, where I can't go across
            ushort maxH = ushort.MaxValue;

            if (current.HIdx < curSlices.Length - 1)
            {
                ulong  higherSlice  = curSlices[current.HIdx + 1];
                ushort higherf      = SliceAccessor.flag(higherSlice);
                ushort higherheight = SliceAccessor.heightGrade(higherSlice);
                if ((higherf & SliceAccessor.SliceCeiling) > 0)
                {
                    maxH = higherheight;
                }
            }
            for (int u = current.BoundaryXMin; u <= current.BoundaryXMax; ++u)
            {
                if (u < 0 || u >= maxX)
                {
                    continue;
                }
                if (current.BoundaryZMin >= 0 && current.BoundaryZMin < maxZ)
                {
                    GetPathNeighbour(current.HeightGrade, maxH, u, current.BoundaryZMin, neighbours);
                }
                if (current.BoundaryZMax >= 0 && current.BoundaryZMax < maxZ)
                {
                    GetPathNeighbour(current.HeightGrade, maxH, u, current.BoundaryZMax, neighbours);
                }
            }
            for (int v = current.BoundaryZMin; v <= current.BoundaryZMax; ++v)
            {
                if (v < 0 || v >= maxZ)
                {
                    continue;
                }
                if (current.BoundaryXMin >= 0 && current.BoundaryXMin < maxX)
                {
                    GetPathNeighbour(current.HeightGrade, maxH, current.BoundaryXMin, v, neighbours);
                }
                if (current.BoundaryXMax >= 0 && current.BoundaryXMax < maxX)
                {
                    GetPathNeighbour(current.HeightGrade, maxH, current.BoundaryXMax, v, neighbours);
                }
            }
        }
Beispiel #2
0
 //
 public MPAStarPath(PillarData data)
 {
     mData        = data;
     mDetail      = 1 << data.setting.subdivision;
     mMaxDeatailX = data.setting.maxX * mDetail;
     mMaxDeatailZ = data.setting.maxZ * mDetail;
     mVolumeSizeX = data.setting.maxX * GridX;
     mVolumeSizeZ = data.setting.maxZ * GridZ;
     mDetailGridX = GridX / mDetail;
     mDetailGridZ = GridZ / mDetail;
     //each pillar height slice max to 64
     mNeighbourCache = new MPNeigbours((mDetail + 1) * 4 * SliceAccessor.MaxHeightSliceCount);
     MPPathNodePool.AllocatePool(128);
 }
Beispiel #3
0
        private void GetPathNeighbour(ushort curH, ushort maxH, int u, int v, MPNeigbours neighbours)
        {
            float        centerx     = 0;
            float        centerz     = 0;
            int          subdivision = setting.subdivision;
            QuadTreeLeaf leaf        = GetLeaf(u, v, ref centerx, ref centerz, ref subdivision);

            if (leaf == null || leaf.Slices == null)
            {
                return;
            }
            //bigger subdivision may has the same slice structure, add only one
            if (neighbours.Contains(leaf.Header))
            {
                return;
            }
            //each height slice could be a neighbour
            if (leaf.Slices.Length == 1)
            {
                ulong  floorSlice = leaf.Slices[0];
                ushort height     = SliceAccessor.heightGrade(floorSlice);
                byte   flag       = SliceAccessor.flag(floorSlice);
                if (CanMove2Neighbour(setting, curH, maxH, height, ushort.MaxValue))
                {
                    neighbours.Add(leaf.Header, u, v, 0, subdivision, setting.subdivision, centerx, centerz, floorSlice);
                }
            }
            else
            {
                for (uint i = 0; i < leaf.Slices.Length - 1; ++i)
                {
                    ulong  currentSlice  = leaf.Slices[i];
                    byte   currentf      = SliceAccessor.flag(currentSlice);
                    ushort currentheight = SliceAccessor.heightGrade(currentSlice);
                    ulong  higherSlice   = leaf.Slices[i + 1];
                    byte   higherf       = SliceAccessor.flag(higherSlice);
                    ushort higherheight  = SliceAccessor.heightGrade(higherSlice);
                    if (i == leaf.Slices.Length - 2 && (higherf & SliceAccessor.SliceCeiling) == 0)
                    {//pillar roof
                        if (CanMove2Neighbour(setting, curH, maxH, higherheight, ushort.MaxValue))
                        {
                            neighbours.Add(leaf.Header, u, v, i + 1, subdivision, setting.subdivision,
                                           centerx, centerz, higherSlice);
                        }
                        break;
                    }
                    if ((currentf & SliceAccessor.SliceCeiling) > 0)
                    {
                        continue;
                    }
                    ushort currentMaxH = ushort.MaxValue;
                    if ((higherf & SliceAccessor.SliceCeiling) > 0)
                    {//check standable
                        float holeHeight = (higherheight - currentheight) * setting.heightPerGrade;
                        if (holeHeight < setting.boundHeight)
                        {
                            continue;
                        }
                        currentMaxH = higherheight;
                    }
                    if (CanMove2Neighbour(setting, curH, maxH, currentheight, currentMaxH))
                    {
                        neighbours.Add(leaf.Header, u, v, i, subdivision, setting.subdivision,
                                       centerx, centerz, currentSlice);
                    }
                }
            }
        }