Ejemplo n.º 1
0
 public HeightmapChunk(Rectangle range, int mipLevel, HeightmapChunk left, HeightmapChunk top) : base(null, range)
 {
     Adjacent[3] = left;
     Adjacent[0] = top;
     if (left != null)
     {
         left.Adjacent[1] = this;
     }
     if (top != null)
     {
         top.Adjacent[2] = this;
     }
     MipLevel = mipLevel;
 }
Ejemplo n.º 2
0
        //how the simplification works:
        //we generate a "maximum second derivative" map from the heightmap.
        //we then create a maximum value image pyramid with the maximum value in the 4 pixels beneath
        //when generating the mesh, we fall into quadrants below if the second derivative is above a threshold.

        public void GenerateFullTree()
        {
            //how the algorithm works:
            //build a base structure with quad trees
            Chunks = new List <HeightmapChunk>();

            var levels    = SecondDerivativePyramid.Length;
            var chunkSize = 1 << levels;

            var cw = Size / chunkSize;

            for (int y = 0; y < Size; y += chunkSize)
            {
                for (int x = 0; x < Size; x += chunkSize)
                {
                    var chunk = new HeightmapChunk(new Rectangle(x, y, chunkSize, chunkSize), levels,
                                                   (x == 0) ? null : Chunks.Last(),
                                                   (y == 0) ? null : Chunks[Chunks.Count - cw]);
                    Chunks.Add(chunk);
                }
            }

            var thresholds = HighDetailThresholds;
            var toTraverse = new Queue <HeightmapQuadTreeNode>(Chunks);

            while (toTraverse.Count > 0)
            {
                var node     = toTraverse.Dequeue();
                var mipLevel = node.MipLevel;
                var sd       = SecondDerivativePyramid[mipLevel - 1];
                var mipWidth = Size >> (mipLevel - 1);
                var pos      = (node.Range.X >> (mipLevel - 1)) + (node.Range.Y >> (mipLevel - 1)) * mipWidth;

                //check the max second derivative of the 4 potential derivatives.
                var threshold = HighDetailThresholds[mipLevel - 1];
                if (sd[pos] >= threshold) //top left
                {
                    var newNode = node.GetOrAdd(0, true);
                    if (mipLevel > 1)
                    {
                        toTraverse.Enqueue(newNode);
                    }
                }
                if (sd[pos + 1] >= threshold) //top right
                {
                    var newNode = node.GetOrAdd(1, true);
                    if (mipLevel > 1)
                    {
                        toTraverse.Enqueue(newNode);
                    }
                }
                if (sd[pos + mipWidth] >= threshold) //bottom left
                {
                    var newNode = node.GetOrAdd(2, true);
                    if (mipLevel > 1)
                    {
                        toTraverse.Enqueue(newNode);
                    }
                }
                if (sd[pos + mipWidth + 1] >= threshold) //top right
                {
                    var newNode = node.GetOrAdd(3, true);
                    if (mipLevel > 1)
                    {
                        toTraverse.Enqueue(newNode);
                    }
                }
            }
        }