Beispiel #1
0
 public bool IsEqual(OrderedSlices other)
 {
     if (this.Count != other.Count || HashValue != other.HashValue)
     {
         return(false);
     }
     return(true);
 }
Beispiel #2
0
        public void RunScan(Vector3 topOrigin, float heightPerGrade, float[] hRange, OrderedSlices slices)
        {
            float rayLen = hRange[1] - hRange[0];
            int   len    = Physics.BoxCastNonAlloc(topOrigin, checkHalfExtent, Vector3.down, hitResultBuff,
                                                   Quaternion.identity, 1.1f * rayLen);

            //floor
            for (int h = 0; h < len && h < SliceAccessor.MaxHeightSliceCount / 2; ++h)
            {
                RaycastHit hit = hitResultBuff[h];
                if (Vector3.Dot(hit.normal, Vector3.up) < 0)
                {
                    continue;
                }
                RawSlice rs = new RawSlice();
                rs.height = hit.point.y;
                rs.flag   = 0;
                slices.Add(rs);
                //Debug.Log(string.Format("u : {0}, v : {1}, height : {2}, flag : {3}", curXIdx, curZIdx, rs.height, rs.flag));
            }
            slices.SortSlices();
            if (slices.Count == 0)
            {
                slices.Add(infinitRoof);
            }
            //ceiling
            Vector3 down = topOrigin;

            down.y = slices[0].height + 2f * heightPerGrade;
            len    = Physics.BoxCastNonAlloc(down, checkHalfExtent, Vector3.up, hitResultBuff, Quaternion.identity, 1.1f * rayLen);
            for (int h = 0; h < len && h < SliceAccessor.MaxHeightSliceCount / 2; ++h)
            {
                RaycastHit hit = hitResultBuff[h];
                if (Vector3.Dot(hit.normal, Vector3.down) < 0)
                {
                    continue;
                }
                RawSlice rs = new RawSlice();
                rs.height = hit.point.y;
                rs.flag   = 1;
                slices.Add(rs);
                //Debug.Log(string.Format("u : {0}, v : {1}, height : {2}, flag : {3}", curXIdx, curZIdx, rs.height, rs.flag));
            }
            slices.Unify(hRange[0], heightPerGrade);
        }
Beispiel #3
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);
                }
            }
        }
Beispiel #4
0
        //dynamic obstacles
        public void DynamicAddPillar(Vector3 pos, Bounds bnd)
        {
            Vector3 min = pos - bnd.extents;
            Vector3 max = pos + bnd.extents;
            int     startU = 0, startV = 0, endU = mData.setting.maxX, endV = mData.setting.maxZ;

            TransformPos2UV(min, ref startU, ref startV);
            TransformPos2UV(max, ref endU, ref endV);
            Vector3 volumnMin = new Vector3(VolumeCenterX - 0.5f * mVolumeSizeX, VolumeFloor,
                                            VolumeCenterZ - 0.5f * mVolumeSizeZ);
            Vector3 checkHalfExtent = new Vector3(GridX / 2, VolumeHSliceT, GridZ / 2);

            mHeightScanner.Reset(checkHalfExtent);
            HashSet <uint> dirtyNodes   = new HashSet <uint>();
            OrderedSlices  slices       = new OrderedSlices();
            int            detailedSize = 1 << mData.setting.subdivision;

            for (int u = startU; u <= endU; ++u)
            {
                for (int v = startV; v <= endV; ++v)
                {
                    int          curXIdx = u >> mData.setting.subdivision;
                    int          curZIdx = v >> mData.setting.subdivision;
                    QuadTreeBase subtree = mData.tree[curXIdx * mData.setting.maxZ + curZIdx];
                    QuadTreeNode node    = null;
                    if (subtree is QuadTreeLeaf)
                    {
                        QuadTreeLeaf leaf = (QuadTreeLeaf)subtree;
                        node = QuadTreeNode.SubdivideLeaf(leaf);
                        mData.tree[curXIdx * mData.setting.maxZ + curZIdx] = node;
                    }
                    else
                    {
                        node = (QuadTreeNode)subtree;
                    }
                    uint dirtyId = (uint)curXIdx;
                    dirtyId = (dirtyId << 16) | (uint)curZIdx;
                    if (!dirtyNodes.Contains(dirtyId))
                    {
                        dirtyNodes.Add(dirtyId);
                    }
                    float   fx  = (float)(u + 0.5f) * mDetailGridX;
                    float   fz  = (float)(v + 0.5f) * mDetailGridZ;
                    Vector3 top = volumnMin + fx * Vector3.right +
                                  (VolumeCeiling + 10f * VolumeHSliceT) * Vector3.up +
                                  fz * Vector3.forward;
                    slices.Clear();
                    mHeightScanner.RunScan(top, VolumeHSliceT, mData.setting.heightValRange, slices);
                    node.AddPillar(mData.setting.subdivision, u, v, slices);
                }
            }
            //merge
            foreach (var dirtyId in dirtyNodes)
            {
                uint         x           = dirtyId >> 16;
                uint         z           = dirtyId & 0x0000ffff;
                int          idx         = (int)(x * mData.setting.maxZ + z);
                QuadTreeNode node        = (QuadTreeNode)mData.tree[idx];
                QuadTreeBase replaceLeaf = QuadTreeNode.CombineTree(node, 0.5f * GridX, 0.5f * GridZ, VolumeHSliceT,
                                                                    mData.setting.slopeErr);
                if (replaceLeaf != null)
                {
                    mData.tree[idx] = replaceLeaf;
                }
            }
        }