Ejemplo n.º 1
0
    // Output : _buff.zippedDataBuffer, _buff.zippedDataLen
    public void ReplaceChunksInPiece(List <IntVector4> chunkPosList, ProcToMergeChunkAtPos mergeChunkDataAtPos, IntVector4 piecePos)
    {
        ReadPieceDataToBuff(piecePos.x, piecePos.y, piecePos.z, piecePos.w);
        _buff.Decompress(piecePos.x, piecePos.y, piecePos.z, piecePos.w);

        List <IntVector4> sortedChunkPosList = chunkPosList.OrderBy(pos => VFFileUtil.ChunkPos2IndexInPiece(pos)).ToList();

        byte[] chunkDataSet    = _buff.unzippedDataBuffer;
        int    lenChunkDataSet = _buff.unzippedDataLen;

        byte[] hollowData = null;
        if (_buff.IsHollow())
        {
            hollowData = new byte[_buff.zippedDataLen];
            Array.Copy(_buff.zippedDataBuffer, hollowData, _buff.zippedDataLen);
        }
        int           idxChunkMax   = VoxelTerrainConstants._ChunksPerPiece - 1;
        int           idxInPiece    = 0;
        List <byte[]> chunkDataList = new List <byte[]>();

        byte[] chunkData  = null;
        int    sumDataLen = 0;
        int    n          = sortedChunkPosList.Count;

        for (int i = 0; i < n; i++)
        {
            IntVector4 chunkPos = sortedChunkPosList[i];
            int        idxChunk = VFFileUtil.ChunkPos2IndexInPiece(chunkPos);
            while (idxInPiece <= idxChunk)
            {
                if (_buff.IsHollow())
                {
                    chunkDataList.Add(hollowData);
                    sumDataLen += hollowData.Length;
                }
                else
                {
                    int ofsDataAddr    = 4 * idxInPiece;
                    int vxDataAddr     = (chunkDataSet[ofsDataAddr]) + (chunkDataSet[ofsDataAddr + 1] << 8) + (chunkDataSet[ofsDataAddr + 2] << 16) + (chunkDataSet[ofsDataAddr + 3] << 24);
                    int vxDataNextAddr = (idxInPiece < idxChunkMax) ? (chunkDataSet[ofsDataAddr + 4]) + (chunkDataSet[ofsDataAddr + 5] << 8) + (chunkDataSet[ofsDataAddr + 6] << 16) + (chunkDataSet[ofsDataAddr + 7] << 24)
                                                : lenChunkDataSet;
                    int len = vxDataNextAddr - vxDataAddr;
                    chunkData = new byte[len];
                    Array.Copy(chunkDataSet, vxDataAddr, chunkData, 0, len);
                    chunkDataList.Add(chunkData);
                    sumDataLen += len;
                }
                idxInPiece++;
            }
            // merge chunk
            sumDataLen -= chunkDataList[idxChunk].Length;
            chunkDataList[idxChunk] = mergeChunkDataAtPos(chunkPos, chunkDataList[idxChunk]);
            sumDataLen += chunkDataList[idxChunk].Length;
        }
        while (idxInPiece <= idxChunkMax)
        {
            if (_buff.IsHollow())
            {
                chunkDataList.Add(hollowData);
                sumDataLen += hollowData.Length;
            }
            else
            {
                int ofsDataAddr    = 4 * idxInPiece;
                int vxDataAddr     = (chunkDataSet[ofsDataAddr]) + (chunkDataSet[ofsDataAddr + 1] << 8) + (chunkDataSet[ofsDataAddr + 2] << 16) + (chunkDataSet[ofsDataAddr + 3] << 24);
                int vxDataNextAddr = (idxInPiece < idxChunkMax) ? (chunkDataSet[ofsDataAddr + 4]) + (chunkDataSet[ofsDataAddr + 5] << 8) + (chunkDataSet[ofsDataAddr + 6] << 16) + (chunkDataSet[ofsDataAddr + 7] << 24)
                                        : lenChunkDataSet;
                int len = vxDataNextAddr - vxDataAddr;
                chunkData = new byte[len];
                Array.Copy(chunkDataSet, vxDataAddr, chunkData, 0, len);
                chunkDataList.Add(chunkData);
                sumDataLen += len;
            }
            idxInPiece++;
        }

        int ofsDataLen = 4 * VoxelTerrainConstants._ChunksPerPiece;

        _buff.unzippedDataLen = ofsDataLen + sumDataLen;
        byte[] pieceData = _buff.unzippedDataBuffer;
        int    ofs       = ofsDataLen;

        for (int i = 0; i < VoxelTerrainConstants._ChunksPerPiece; i++)
        {
            byte[] data = chunkDataList[i];
            Array.Copy(data, 0, pieceData, ofs, data.Length);
            pieceData[i * 4]     = (byte)(ofs & 0xff);
            pieceData[i * 4 + 1] = (byte)((ofs >> 8) & 0xff);
            pieceData[i * 4 + 2] = (byte)((ofs >> 16) & 0xff);
            pieceData[i * 4 + 3] = (byte)((ofs >> 24) & 0xff);
            ofs += data.Length;
        }
        //Compress
        _buff.zippedDataLen = LZ4.LZ4_compress(_buff.unzippedDataBuffer, _buff.zippedDataBuffer, _buff.unzippedDataLen);
    }