public void Reset(int len, ulong hash) { Header = _uid_seed; if (_uid_seed + len >= uint.MaxValue) { _uid_seed = 0; } _uid_seed += (uint)len; Slices = HeightSlicePool.Pop(Header, len); HashVal = hash; }
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); } } }
//note : this function can't be used to subdivide inherented node public static QuadTreeNode SubdivideLeaf(QuadTreeLeaf leaf) { if (leaf == null) { return(null); } QuadTreeNode node = new QuadTreeNode(0); for (int i = 0; i < 4; ++i) { QuadTreeLeaf childLeaf = (QuadTreeLeaf)node.Children[i]; childLeaf.Reset(leaf.Slices.Length, leaf.HashVal); Array.Copy(leaf.Slices, childLeaf.Slices, leaf.Slices.Length); } HeightSlicePool.Push(leaf.Header, leaf.Slices); return(node); }
//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); } } }