Esempio n. 1
0
 public void Add(T item)
 {
     if (Data == null || Length >= Data.Length)
     {
         MPLog.LogError("MPArray overflow : " + typeof(T));
     }
     Data[Length] = item;
     ++Length;
 }
Esempio n. 2
0
        public static PillarData LoadData(string path, string dataName)
        {
            FileStream stream = File.Open(path, FileMode.Open);
            PillarData data   = new PillarData();

            data.DataName = dataName;
            int readOffset = 0;
            //read setting
            int settingSize = data.setting.byteSize();

            if (stream.Length - readOffset >= settingSize)
            {
                byte[] buff = new byte[settingSize];
                int    len  = stream.Read(buff, readOffset, settingSize);
                data.setting.Reset(buff);
                readOffset += len;
            }
            else
            {
                MPLog.LogError("load setting failed");
                return(null);
            }
            //read header
            int headerSize = data.setting.maxX * data.setting.maxZ;

            if (stream.Length - readOffset < headerSize * sizeof(uint))
            {
                MPLog.LogError("load header failed");
                return(null);
            }
            data.tree = new QuadTreeBase[headerSize];
            byte[] bBuff = new byte[1] {
                0
            };
            byte bRootLeafBuff = 1 << 4;

            for (int i = 0; i < headerSize; ++i)
            {
                //root mask
                stream.Read(bBuff, 0, 1);
                //
                if ((bBuff[0] & bRootLeafBuff) > 0)
                {
                    data.tree[i] = new QuadTreeLeafSerializable(stream);
                }
                else
                {
                    data.tree[i] = new QuadTreeNodeSerializable(bBuff[0], stream);
                }
            }
            MPLog.Log("load successed !");
            stream.Close();
            return(data);
        }
Esempio n. 3
0
        public void Enqueue(T item)
        {
            if (mHead == null)
            {
                mHead = item;
                return;
            }
            else if (item.Priority <= mHead.Priority)
            {
                item.Next = mHead;
                mHead     = item;
                return;
            }
            else if (mHead.Next == null)
            {
                mHead.Next = item;
                return;
            }
            T check = mHead;

            while (check.Next != null)
            {
                if (item.Priority <= check.Next.Priority)
                {
                    item.Next  = check.Next;
                    check.Next = item;
                    return;
                }
                else
                {
                    check = check.Next;
                }
            }
            if (check.Next == null)
            {
                check.Next = item;
            }
            else
            {
                MPLog.LogError("item is not add into queue");
            }
        }
Esempio n. 4
0
        //dynamically add pillars in
        //x ~ (0, setting.maxX * power(2, subdivision)), x ~ (0, setting.maxZ * power(2, subdivision))
        public void AddPillar(int subdivision, int x, int z, OrderedSlices rawSlices)
        {
            //first grade
            int u    = x >> subdivision; // x / power(2, subdivision);
            int v    = z >> subdivision;
            int subx = x - u * (1 << subdivision);
            int subz = z - v * (1 << subdivision);

            --subdivision;
            int idx = (subx >> subdivision) * 2 + (subz >> subdivision);

            if (subdivision > 0)
            {
                if (Children[idx] is QuadTreeLeaf)
                {
                    SubdividLeaf(idx);
                }
                QuadTreeNode node = (QuadTreeNode)Children[idx];
                node.AddPillar(subdivision, subx, subz, rawSlices);
            }
            else
            {
                if (Children[idx] is QuadTreeNode)
                {
                    MPLog.LogError("AddPillar leaf still a tree : " + subdivision);
                    return;
                }
                QuadTreeLeaf leaf = (QuadTreeLeaf)Children[idx];
                if (leaf.Slices != null)
                {
                    HeightSlicePool.Push(leaf.Header, leaf.Slices);
                }
                leaf.Reset(rawSlices.Count, rawSlices.HashValue);
                for (int i = 0; i < rawSlices.Count; ++i)
                {
                    leaf.Slices[i] = SliceAccessor.packVal(rawSlices[i].heightGrade, 0, 0, rawSlices[i].flag);
                }
            }
        }
Esempio n. 5
0
        public void Unify(float startHeight, float heightPerGrade)
        {
            SortSlices();
            if (Count == 0)
            {
                MPLog.LogError("pillar is empty.");
            }
            //merge the slices, slices should be floor|ceiling|floor|ceiling....|floor
            bool bNeedMerge = true;

            while (bNeedMerge && Count > 0)
            {
                bNeedMerge = false;
                for (int i = 0; i < Count - 1; ++i)
                {
                    if (this[i].flag == this[i + 1].flag)
                    {
                        if ((this[i].flag & SliceAccessor.SliceCeiling) > 0)
                        {//ceiling use lower one
                            RemoveAt(i + 1);
                        }
                        else
                        {//floor use higher one
                            RemoveAt(i);
                        }
                        bNeedMerge = true;
                        break;
                    }
                }
            }
            HashValue = 0;
            for (int i = 0; i < Count; ++i)
            {
                RawSlice slice = this[i];
                slice.heightGrade = (ushort)Math.Ceiling((slice.height - startHeight) / heightPerGrade);
                HashValue        += SliceAccessor.packVal(slice.heightGrade, 0, 0, slice.flag);
            }
        }
Esempio n. 6
0
        public static bool SaveData(string path, PillarSetting setting, QuadTreeBase[] trees)
        {
            if (File.Exists(path))
            {
                File.Delete(path);
            }
            FileStream stream = File.Open(path, FileMode.Create);

            byte[] stbuff = setting.ToArray();
            stream.Write(stbuff, 0, stbuff.Length);
            //trees
            byte[] bRootLeafBuff = new byte[1] {
                1 << 4
            };
            for (int x = 0; x < setting.maxX; ++x)
            {
                for (int z = 0; z < setting.maxZ; ++z)
                {
                    QuadTreeBase subTree = trees[x * setting.maxZ + z];
                    if (subTree is QuadTreeLeafSerializable)
                    {
                        stream.Write(bRootLeafBuff, 0, 1);
                        QuadTreeLeafSerializable leaf = (QuadTreeLeafSerializable)subTree;
                        leaf.Serialize(stream);
                    }
                    else
                    {
                        QuadTreeNodeSerializable node = (QuadTreeNodeSerializable)subTree;
                        node.Serialize(stream);
                    }
                }
            }
            stream.Close();
            MPLog.Log("create data successed!");
            return(true);
        }
Esempio n. 7
0
        public void FindPath(Vector3 start, Vector3 dest, Stack <MPPathResult> result, Queue <MPDebugPlane> qDebug = null)
        {
            int    srcx = 0;
            int    srcz = 0;
            ushort srcH = (ushort)(Mathf.Clamp(start.y - VolumeFloor, 0, VolumeCeiling) / VolumeHSliceT);

            TransformPos2UV(start, ref srcx, ref srcz);
            ushort     fixH    = srcH;
            MPPathNode srcNode = mData.GetStandablePathNode(srcx, srcz, srcH);

            if (srcNode == null)
            {
                return;
            }
            int    destx = 0;
            int    destz = 0;
            ushort destH = (ushort)(Mathf.Clamp(dest.y - VolumeFloor, 0, VolumeCeiling) / VolumeHSliceT);

            TransformPos2UV(dest, ref destx, ref destz);
            MPPathNode destNode = mData.GetStandablePathNode(destx, destz, destH);

            if (destNode == null)
            {
                return;
            }
            //
            result.Push(MPPathResultPool.Pop(dest, fixH, 0));
            if (srcNode.UID == destNode.UID)
            {
                MPPathNodePool.Push(srcNode);
                MPPathNodePool.Push(destNode);
                return;
            }
            //
            Vector3 volumnMin = new Vector3(VolumeCenterX - 0.5f * mVolumeSizeX, VolumeFloor,
                                            VolumeCenterZ - 0.5f * mVolumeSizeZ);
            Vector2 minCellSize = new Vector2(mDetailGridX, mDetailGridZ);

            if (qDebug != null)
            {
                isDebug = true;
            }
            if (FindPath(srcNode, destNode))
            {
                while (pathResult.Count > 0)
                {
                    MPPathNode node = pathResult.Dequeue();
                    //use request node as final node
                    if (node.UID == destNode.UID)
                    {
                        continue;
                    }
                    if (node.UID == srcNode.UID)
                    {
                        result.Push(MPPathResultPool.Pop(start, node.HeightGrade, node.Flag));
                        continue;
                    }
                    Vector3 nodeCenter = volumnMin + node.X * Vector3.right + node.Z * Vector3.forward +
                                         node.HeightGrade * VolumeHSliceT * Vector3.up;
                    result.Push(MPPathResultPool.Pop(nodeCenter, node.HeightGrade, node.Flag));
                }
            }
            else
            {
                MPLog.Log("no path result.");
                result.Pop();
            }
            //debug
            while (isDebug && debugnodes.Count > 0)
            {
                MPPathNode   node  = debugnodes.Dequeue();
                MPDebugPlane plane = new MPDebugPlane();
                plane.center = volumnMin + node.X * Vector3.right + node.Z * Vector3.forward +
                               (node.HeightGrade + 2) * VolumeHSliceT * Vector3.up;
                plane.size = (1 << node.Subdivision) * minCellSize;
                qDebug.Enqueue(plane);
            }
            EndFindPath();
        }