public void GetSubPageHeightBounds(int xOff, int zOff, int xSize, int zSize, out float minHeight, out float maxHeight)
        {
            // convert coords/sizes to number of subpages
            xOff  = xOff / subPageSize;
            zOff  = zOff / subPageSize;
            xSize = xSize / subPageSize;
            zSize = zSize / subPageSize;

            minHeight = float.MaxValue;
            maxHeight = float.MinValue;
            for (int z = zOff; z < (zOff + zSize); z++)
            {
                for (int x = xOff; x < (xOff + xSize); x++)
                {
                    SubPageHeightMap subPage = subPages[x + z * subPagesPerPage];
                    if (subPage.MaxHeight > maxHeight)
                    {
                        maxHeight = subPage.MaxHeight;
                    }
                    if (subPage.MinHeight < minHeight)
                    {
                        minHeight = subPage.MinHeight;
                    }
                }
            }
        }
        /// <summary>
        /// Get the height of the sample at the given coordinates within the page.
        /// Coordinates are in meters, and are relative to the page.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public float GetHeight(int x, int z)
        {
            int subPageMask = subPageSize - 1;

            // figure X and Z offsets of the subpage that contains the given point
            int subPageX = x / subPageSize;
            int subPageZ = z / subPageSize;

            SubPageHeightMap subPage = subPages[subPageX + subPageZ * subPagesPerPage];

            return(subPage.GetHeight(x & subPageMask, z & subPageMask));
        }
        public PageHeightMap(int subPagesPerPage, int pageSize, int maxMetersPerSample, int minMetersPerSample)
        {
            this.subPagesPerPage = subPagesPerPage;
            this.pageSize        = pageSize;
            subPageSize          = pageSize / subPagesPerPage;

            // allocate the array to hold the subpages
            subPages = new SubPageHeightMap[subPagesPerPage * subPagesPerPage];

            // allocate all the subpages
            for (int z = 0; z < subPagesPerPage; z++)
            {
                for (int x = 0; x < subPagesPerPage; x++)
                {
                    subPages[x + z * subPagesPerPage] = new SubPageHeightMap(pageSize / subPagesPerPage, maxMetersPerSample, minMetersPerSample, x, z);
                }
            }
        }