Example #1
0
        //detailed x, z
        //dx ~ (0, setting.maxX * power(2, subdivision)), dx ~ (0, setting.maxZ * power(2, subdivision))
        public void Reset(uint header, int dx, int dz, uint ih, int sub, int maxSub,
                          float centerx, float centerz, ulong val)
        {
            SliceHeader = header;
            HIdx        = ih;
            Subdivision = sub;
            X           = centerx;
            Z           = centerz;
            HeightGrade = SliceAccessor.heightGrade(val);
            Flag        = SliceAccessor.flag(val);
            mSlopeU     = SliceAccessor.slopeUGrade(val) / SliceAccessor.slopeMagnify;
            mSlopeV     = SliceAccessor.slopeVGrade(val) / SliceAccessor.slopeMagnify;
            //boundary
            BoundaryXMin = 0;
            BoundaryZMin = 0;
            int detail = 1 << sub;

            if (sub == 0)
            {
                BoundaryXMin = dx;
                BoundaryZMin = dz;
            }
            else
            {
                for (int s = maxSub; s >= sub; --s)
                {
                    detail = 1 << s;
                    int u = dx >> s; // x / power(2, subdivision);
                    int v = dz >> s;
                    BoundaryXMin += u * detail;
                    BoundaryZMin += v * detail;
                    dx           -= u * detail;
                    dz           -= v * detail;
                }
            }
            BoundaryXMax  = BoundaryXMin + detail;
            BoundaryZMax  = BoundaryZMin + detail;
            BoundaryXMin -= 1;
            BoundaryZMin -= 1;
        }
Example #2
0
        private QuadTreeLeaf Combine(float dx, float dz, float sliceThickness, float slopeErr)
        {
            if (Children[0] == null || !(Children[0] is QuadTreeLeaf))
            {
                return(null);
            }
            QuadTreeLeaf leaf = (QuadTreeLeaf)Children[0];

            for (int i = 1; i < Children.Length; ++i)
            {
                if (Children[i] == null || !(Children[i] is QuadTreeLeaf))
                {
                    return(null);
                }
                if (!leaf.IsCombinable((QuadTreeLeaf)Children[i]))
                {
                    return(null);
                }
            }
            for (int s = 0; s < leaf.Slices.Length; ++s)
            {
                ulong leafS = leaf.Slices[s];
                byte  flag  = SliceAccessor.flag(leafS);
                //x axis
                short slopeU  = GetSlope(leafS, ((QuadTreeLeaf)Children[1]).Slices[s], dx, sliceThickness);
                short slopeU1 = GetSlope(((QuadTreeLeaf)Children[2]).Slices[s], ((QuadTreeLeaf)Children[3]).Slices[s],
                                         dx, sliceThickness);
                if ((slopeU != 0 && slopeU1 != 0 && Math.Abs(slopeU1 - slopeU) > slopeErr * SliceAccessor.slopeMagnify))
                {
                    return(null);
                }
                slopeU += slopeU1; slopeU /= 2;
                //z axis
                short slopeV  = GetSlope(leafS, ((QuadTreeLeaf)Children[2]).Slices[s], dz, sliceThickness);
                short slopeV1 = GetSlope(((QuadTreeLeaf)Children[1]).Slices[s], ((QuadTreeLeaf)Children[3]).Slices[s],
                                         dz, sliceThickness);
                if ((slopeV != 0 && slopeV1 != 0 && Math.Abs(slopeV1 - slopeV) > slopeErr * SliceAccessor.slopeMagnify))
                {
                    return(null);
                }
                slopeV += slopeV1; slopeV /= 2;
                ushort updateH = 0;
                for (int i = 0; i < Children.Length; ++i)
                {
                    QuadTreeLeaf l  = (QuadTreeLeaf)Children[i];
                    ulong        lS = l.Slices[s];
                    if (leaf.HashVal != l.HashVal)
                    {
                        byte  f  = SliceAccessor.flag(lS);
                        short sU = SliceAccessor.slopeUGrade(lS);
                        short sV = SliceAccessor.slopeVGrade(lS);
                        //floor cant match ceiling
                        if (flag != f)
                        {
                            return(null);
                        }
                        //slope error
                        if ((sU != 0 && Math.Abs(sU - slopeU) > slopeErr * SliceAccessor.slopeMagnify) ||
                            (sV != 0 && Math.Abs(sV - slopeV) > slopeErr * SliceAccessor.slopeMagnify))
                        {
                            return(null);
                        }
                    }
                    updateH += SliceAccessor.heightGrade(lS);
                }
                updateH      >>= 2;//average height
                leaf.Slices[s] = SliceAccessor.packVal(updateH, slopeU, slopeV, flag);
            }
            leaf.RefreshHash();
            return(leaf);
        }