// 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); }