public void Add(T item) { if (Data == null || Length >= Data.Length) { MPLog.LogError("MPArray overflow : " + typeof(T)); } Data[Length] = item; ++Length; }
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); }
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"); } }
//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); } } }
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); } }
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); }
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(); }