public void ReplaceChunkDatas(List <IntVector4> newChunkPosList, ProcToMergeChunkAtPos mergeChunkDataAtPos) { Dictionary <IntVector4, Dictionary <IntVector4, List <IntVector4> > > file2piece2chunkList = new Dictionary <IntVector4, Dictionary <IntVector4, List <IntVector4> > >(); int n = newChunkPosList.Count; int px, py, pz; int fx, fz; for (int i = 0; i < n; i++) { IntVector4 chunkPos = newChunkPosList[i]; VFFileUtil.WorldChunkPosToPiecePos(chunkPos, out px, out py, out pz); VFFileUtil.PiecePos2FilePos(px, py, pz, chunkPos.w, out fx, out fz); IntVector4 filePos = new IntVector4(fx, 0, fz, chunkPos.w); IntVector4 piecePos = new IntVector4(px, py, pz, chunkPos.w); if (!file2piece2chunkList.ContainsKey(filePos)) { file2piece2chunkList.Add(filePos, new Dictionary <IntVector4, List <IntVector4> >()); } if (!file2piece2chunkList[filePos].ContainsKey(piecePos)) { file2piece2chunkList[filePos].Add(piecePos, new List <IntVector4>()); } file2piece2chunkList[filePos][piecePos].Add(chunkPos); } List <IntVector4> fileIndexList = file2piece2chunkList.Keys.Cast <IntVector4>().ToList(); int nFileIndexList = fileIndexList.Count; for (int i = 0; i < nFileIndexList; i++) { IntVector4 fileIndex = fileIndexList[i]; ReplacePiecesInFile(file2piece2chunkList[fileIndex], mergeChunkDataAtPos, fileIndex); } }
// 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); }
public void ReplacePiecesInFile(Dictionary <IntVector4, List <IntVector4> > piece2chunkList, ProcToMergeChunkAtPos mergeChunkDataAtPos, IntVector4 fileIndex) { int lod = fileIndex.w; string newFileName = _dataFilePrefix + "_x" + fileIndex.x + "_y" + fileIndex.z + (lod != 0 ? ("_" + lod + ".tmp") : ".tmp"); string fileName = _dataFilePrefix + "_x" + fileIndex.x + "_y" + fileIndex.z + (lod != 0 ? ("_" + lod + ".voxelform") : ".voxelform"); using (FileStream fsOld = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (FileStream fsNew = new FileStream(newFileName, FileMode.Create)) { int nMaxPieceCount = (VoxelTerrainConstants._mapPieceCountXorZ >> lod) * (VoxelTerrainConstants._mapPieceCountXorZ >> lod) * (VoxelTerrainConstants._mapPieceCountY >> lod); int fSetOfsDataLenLod = nMaxPieceCount * 4; byte[] ofsDataOld = new byte[fSetOfsDataLenLod]; fsOld.Read(ofsDataOld, 0, fSetOfsDataLenLod); byte[] ofsDataNew = new byte[fSetOfsDataLenLod]; fsNew.Seek(fSetOfsDataLenLod, SeekOrigin.Begin); List <IntVector4> piecePosList = piece2chunkList.Keys.Cast <IntVector4>().ToList(); List <IntVector4> sortedPiecePosList = piecePosList.OrderBy(p => VFFileUtil.PiecePos2IndexInFile(p.x, p.y, p.z, p.w)).ToList(); int idx = 0; int idxInFile = 0; int pieceDataOfs = 0; int pieceDataLen = 0; int curFilePos = 0; byte[] tmpBuff = new byte[(int)((VoxelTerrainConstants.VOXEL_NUM_PER_PIECE * VFVoxel.c_VTSize + 256) * 1.004f)]; int n = sortedPiecePosList.Count; for (int i = 0; i < n; i++) { IntVector4 piecePos = sortedPiecePosList[i]; int idxPiece = VFFileUtil.PiecePos2IndexInFile(piecePos.x, piecePos.y, piecePos.z, piecePos.w); while (idxInFile < idxPiece) { idx = idxInFile * 4; pieceDataOfs = ofsDataOld[idx] + (ofsDataOld[idx + 1] << 8) + (ofsDataOld[idx + 2] << 16) + (ofsDataOld[idx + 3] << 24); if (idx >= fSetOfsDataLenLod - 4) { pieceDataLen = (int)fsOld.Length - pieceDataOfs; } else { pieceDataLen = ofsDataOld[idx + 4] + (ofsDataOld[idx + 5] << 8) + (ofsDataOld[idx + 6] << 16) + (ofsDataOld[idx + 7] << 24) - pieceDataOfs; } fsOld.Seek(pieceDataOfs, SeekOrigin.Begin); fsOld.Read(tmpBuff, 0, pieceDataLen); curFilePos = (int)fsNew.Position; ofsDataNew[idx] = (byte)(curFilePos & 0xff); ofsDataNew[idx + 1] = (byte)((curFilePos >> 8) & 0xff); ofsDataNew[idx + 2] = (byte)((curFilePos >> 16) & 0xff); ofsDataNew[idx + 3] = (byte)((curFilePos >> 24) & 0xff); fsNew.Write(tmpBuff, 0, pieceDataLen); idxInFile++; } ReplaceChunksInPiece(piece2chunkList[piecePos], mergeChunkDataAtPos, piecePos); curFilePos = (int)fsNew.Position; idx = idxPiece * 4; ofsDataNew[idx] = (byte)(curFilePos & 0xff); ofsDataNew[idx + 1] = (byte)((curFilePos >> 8) & 0xff); ofsDataNew[idx + 2] = (byte)((curFilePos >> 16) & 0xff); ofsDataNew[idx + 3] = (byte)((curFilePos >> 24) & 0xff); fsNew.Write(_buff.zippedDataBuffer, 0, _buff.zippedDataLen); idxInFile++; } while (idxInFile < nMaxPieceCount) { idx = idxInFile * 4; pieceDataOfs = ofsDataOld[idx] + (ofsDataOld[idx + 1] << 8) + (ofsDataOld[idx + 2] << 16) + (ofsDataOld[idx + 3] << 24); if (idx >= fSetOfsDataLenLod - 4) { pieceDataLen = (int)fsOld.Length - pieceDataOfs; } else { pieceDataLen = ofsDataOld[idx + 4] + (ofsDataOld[idx + 5] << 8) + (ofsDataOld[idx + 6] << 16) + (ofsDataOld[idx + 7] << 24) - pieceDataOfs; } fsOld.Seek(pieceDataOfs, SeekOrigin.Begin); fsOld.Read(tmpBuff, 0, pieceDataLen); curFilePos = (int)fsNew.Position; ofsDataNew[idx] = (byte)(curFilePos & 0xff); ofsDataNew[idx + 1] = (byte)((curFilePos >> 8) & 0xff); ofsDataNew[idx + 2] = (byte)((curFilePos >> 16) & 0xff); ofsDataNew[idx + 3] = (byte)((curFilePos >> 24) & 0xff); fsNew.Write(tmpBuff, 0, pieceDataLen); idxInFile++; } fsNew.Seek(0, SeekOrigin.Begin); fsNew.Write(ofsDataNew, 0, fSetOfsDataLenLod); } } VFFileUtil.CloseAllFiles(ref _curFileStream, ref _fileStreams, ref _fileLens); string oldFileName = string.Format(fileName + ".{0:MMdd_hhmmss}", DateTime.Now); File.Move(fileName, oldFileName); File.Move(newFileName, fileName); }