Пример #1
0
	    public void LoadOrCreateChunk(Vector3Int position, Block[] blocks, MappingFunction mappingFunction)
        {
            var pagePositionX = position.X / Page.PageSizeInBlocks;
            var pagePositionY = position.Y / Page.PageSizeInBlocks;
            var pagePositionZ = position.Z / Page.PageSizeInBlocks;
            var pageId = CreatePageId(pagePositionX, pagePositionY, pagePositionZ);
            if (m_pageCache.ContainsPage(pageId))
            {
                var page = m_pageCache.GetPage(pageId);
                CopyPageToChunk(page, position, blocks, mappingFunction);
            }
            else if (m_directory.Pages.Contains(pageId))
            {
                var page = DecompressPage(pageId);
                CopyPageToChunk(page, position, blocks, mappingFunction);
                m_pageCache.InsertPage(page);
            }
            else if (!m_pagesPendingWrite.Contains(pageId))
            {
                m_pagesPendingWrite.Add(pageId);
                var page = new Page(position.X, position.Y, position.Z, pageId);
                var worldPosX = pagePositionX * Page.PageSizeInBlocks;
                var worldPosY = pagePositionY * Page.PageSizeInBlocks;
                var worldPosZ = pagePositionZ * Page.PageSizeInBlocks;
                TerrainGenerator.Instance.GenerateDataForChunk(worldPosX, worldPosY, worldPosZ,
                                                               Page.PageSizeInBlocks, page.Data, (x, y, z) => Page.BlockIndexFromRelativePosition(
                                                                   x - worldPosX, y - worldPosY, z - worldPosZ));

                //BlockDataUtilities.SetupScanDirectedHilbertCurve(Page.PageSizeInBlocks);
               // ChunkCompressor.GetHilbertCurve(32);
                var timer = Stopwatch.StartNew();
                float compressionRatio;
                //ChunkCompressor.ScanDirection scanDir;
                var tree = ChunkCompressor.GetCompressor(Page.PageSizeInBlocks).ConvertArrayToIntervalTree(page.Data,
                    out compressionRatio);
                Console.WriteLine("tree creation time: " + timer.ElapsedMilliseconds);
              //  Console.WriteLine("h: " + scanDir);
              //  Console.WriteLine("tree compresion ratio: " + compressionRatio);
              //  timer.Restart();
            //    var tree2 = ChunkCompressor.ConvertArrayToIntervalTreeLinear(page.Data, Page.PageSizeInBlocks,
            //       out compressionRatio, out scanDir);
                //Console.WriteLine("linear tree creation time: " + timer.ElapsedMilliseconds);
               // Console.WriteLine("l: " + scanDir);
              //  Console.WriteLine("l: " + compressionRatio);

               // tree.

                timer.Restart();
                var res = tree[new Interval(17490)];
                Console.WriteLine("tree query time: " + timer.ElapsedMilliseconds);
                using (var fileStream = new FileStream(Path.Combine(m_dataDirectory, page.PageId + "_tree.page"), FileMode.Create))
                {
                    using (var compressor = new GZipStream(fileStream, CompressionLevel.Optimal))
                    {
                        //Serializer.Serialize(compressor, tree);
                    }
                }
                Console.WriteLine("tree compressionTime time: " + timer.ElapsedMilliseconds);

                timer.Restart();
                CompressPage(page);
                Console.WriteLine("normal compressionTime time: " + timer.ElapsedMilliseconds);

                m_pageCache.InsertPage(page);
                m_directory.Pages.Add(pageId);
                CopyPageToChunk(page, position, blocks, mappingFunction);
                //m_jsonWriter.Write("SaveDirectory", m_directory);
              /*  Task.Run(() =>
                {
                    CompressPage(page);
                    m_pagesPendingWrite.Remove(page.PageId);
                });*/
            }
	    }
Пример #2
0
		public Page DecompressPage(string pageId)
		{
		    var buffer = CheckOutBuffer();
			Page page;
            using (var fileStream = new FileStream(Path.Combine(m_dataDirectory, pageId + ".page"), FileMode.Open))
			{
				using(var decompressor = new GZipStream(fileStream, CompressionMode.Decompress))
				{
				    decompressor.Read(buffer, 0, BufferSize);
                    var pageX = GetInt(buffer, 0);
                    var pageY = GetInt(buffer, 4);
                    var pageZ = GetInt(buffer, 8);
                    page = new Page(pageX, pageY, pageZ, pageId);
                    for (var curveIndex = 0; curveIndex < BlockCount; ++curveIndex)
                    {
                        var offset = HeaderSize + curveIndex * 2;
                        var block = new Block(GetShort(buffer, offset));
                        offset = HeaderSize + BlockCount * 2 + curveIndex;
                        block.LightSun = buffer[offset];
                        offset = HeaderSize + BlockCount * 3 + curveIndex;
                        block.LightRed = buffer[offset];
                        offset = HeaderSize + BlockCount * 4 + curveIndex;
                        block.LightGreen = buffer[offset];
                        offset = HeaderSize + BlockCount * 5 + curveIndex;
                        block.LightBlue = buffer[offset];
                        offset = HeaderSize + BlockCount * 6 + curveIndex * 2;
                        block.Color = GetShort(buffer, offset);
                        page.Data[m_hilbertCurve[curveIndex]] = block;
                    }
				}
            }
		    CheckInBuffer(buffer);
            return page;
		}
Пример #3
0
 public void CompressPage(Page page)
 {
     var buffer = CheckOutBuffer();
     PutInt(buffer, page.X, 0);
     PutInt(buffer, page.Y, 4);
     PutInt(buffer, page.Z, 8);
     for (var curveIndex = 0; curveIndex < BlockCount; ++curveIndex)
     {
         var block = page.Data[m_hilbertCurve[curveIndex]];
         var offset = HeaderSize + curveIndex * 2;
         PutShort(buffer, block.Type, offset);
         offset = HeaderSize + BlockCount * 2 + curveIndex;
         buffer[offset] = block.LightSun;
         offset = HeaderSize + BlockCount * 3 + curveIndex;
         buffer[offset] = block.LightRed;
         offset = HeaderSize + BlockCount * 4 + curveIndex;
         buffer[offset] = block.LightGreen;
         offset = HeaderSize + BlockCount * 5 + curveIndex;
         buffer[offset] = block.LightBlue;
         offset = HeaderSize + BlockCount * 6 + curveIndex * 2;
         PutShort(buffer, block.Color, offset);
     }
     using (var fileStream = new FileStream(Path.Combine(m_dataDirectory, page.PageId + ".page"), FileMode.Create))
     {
         using (var compressor = new GZipStream(fileStream, CompressionLevel.Optimal))
         {
             compressor.Write(buffer, 0, BufferSize);
         }
     }
     CheckInBuffer(buffer);
 }
Пример #4
0
	    public void TestCompression(Page page)
	    {
	        CompressPage(page);
            var decompPage = DecompressPage(page.PageId);
            Debug.Assert(page.X == decompPage.X);
            Debug.Assert(page.Y == decompPage.Y);
            Debug.Assert(page.Z == decompPage.Z);
	        for (var i = 0; i < page.Data.Length; ++i)
            {
                Debug.Assert(page.Data[i].Type == decompPage.Data[i].Type, "Type on block index: " + i);
                Debug.Assert(page.Data[i].LightRed == decompPage.Data[i].LightRed, "Red on block index: " + i);
                Debug.Assert(page.Data[i].LightGreen == decompPage.Data[i].LightGreen, "Green on block index: " + i);
                Debug.Assert(page.Data[i].LightBlue == decompPage.Data[i].LightBlue, "Blue on block index: " + i);
                Debug.Assert(page.Data[i].LightSun == decompPage.Data[i].LightSun, "Sun on block index: " + i);
                Debug.Assert(page.Data[i].Color == decompPage.Data[i].Color, "Color on block index: " + i);
	        }

	    }
Пример #5
0
        private static void CopyCunkToPage(Page page, Vector3Int position, Block[] blocks, MappingFunction mappingFunction)
        {
            var originX = MathUtilities.Modulo(position.X, Page.PageSizeInBlocks);
            var originY = MathUtilities.Modulo(position.Y, Page.PageSizeInBlocks);
            var originZ = MathUtilities.Modulo(position.Z, Page.PageSizeInBlocks);
            for (var x = originX; x < originX + Chunk.SizeInBlocks; x++)
            {
                for (var y = originY; y < originY + Chunk.SizeInBlocks; y++)
                {
                    for (var z = originZ; z < originZ + Chunk.SizeInBlocks; z++)
                    {
                        page.Data[Page.BlockIndexFromRelativePosition(x, y, z)] =
                            blocks[mappingFunction(position.X + x, position.Y + y, position.Z + z)];
                    }
                }
            }
	    }
Пример #6
0
	    public void SaveChunk(Vector3Int position, Block[] blocks, MappingFunction mappingFunction, Action<bool> callback)
        {
            var pagePositionX = position.X >> 6;
            var pagePositionY = position.Y >> 6;
            var pagePositionZ = position.Z >> 6;
	        var pageId = CreatePageId(pagePositionX, pagePositionY, pagePositionZ);
	        if (m_pagesPendingWrite.Contains(pageId))
	        {
                if (callback != null)
                {
                    callback(false);
                }
	        }
	        else
	        {
	            Page page;
	            if (m_pageCache.ContainsPage(pageId))
	            {
                    page = m_pageCache.GetPage(pageId);
                    CopyCunkToPage(page, position, blocks, mappingFunction);
	            }
                else if (m_directory.Pages.Contains(pageId))
                {
                    page = DecompressPage(pageId);
                    CopyCunkToPage(page, position, blocks, mappingFunction);
                    m_pageCache.InsertPage(page);
                }
	            else
	            {
                    page = new Page(position.X, position.Y, position.Z, pageId);
                    for (var x = 0; x < Page.PageSizeInBlocks; x++)
                    {
                        for (var y = 0; y < Page.PageSizeInBlocks; y++)
                        {
                            for (var z = 0; z < Page.PageSizeInBlocks; z++)
                            {
                                page.Data[Page.BlockIndexFromRelativePosition(x, y, z)] =
                                    blocks[mappingFunction(position.X + x, position.Y + y, position.Z + z)];
                            }
                        }
                    }
                    m_pageCache.InsertPage(page);
                    m_directory.Pages.Add(pageId);
                   // m_jsonWriter.Write("SaveDirectory", m_directory);
	            }
	            m_pagesPendingWrite.Add(pageId);
	            Task.Run(() =>
	            {
	                CompressPage(page);
	                if (callback != null)
	                {
	                    callback(true);
	                }
	                m_pagesPendingWrite.Remove(page.PageId);
	            });
	        }
	    }