// write chunk data void WriteChunkData(List <B45ChunkDataBase> chunkDataList) { byte[] chunkDataBinaryBuffer = new byte[chunkOffsets[chunkOffsets.Length - 1]]; int updateVectorStOfs; for (int i = 0; i < chunkDataList.Count; i++) { B45ChunkDataBase cd = chunkDataList[i]; chunkDataBinaryBuffer[chunkOffsets[i]] = cd.IsHollow ? (byte)1:(byte)0; updateVectorStOfs = chunkOffsets[i] + ChunkBAHeaderOffsets.headerLength; if (cd.IsHollow) { Array.Copy(cd._chunkData, 0, chunkDataBinaryBuffer, chunkOffsets[i] + ChunkBAHeaderOffsets.headerLength, B45Block.Block45Size); updateVectorStOfs += B45Block.Block45Size; } else { Array.Copy(cd._chunkData, 0, chunkDataBinaryBuffer, chunkOffsets[i] + ChunkBAHeaderOffsets.headerLength, chunkRawDataLength); updateVectorStOfs += chunkRawDataLength; } } fs.Write(chunkDataBinaryBuffer, 0, chunkDataBinaryBuffer.Length); }
public List <B45ChunkDataBase> ReadAllChunkData(out int out_svn_key, int read_ref_svnkey) { int highest_svn_key = -1; List <B45ChunkDataBase> ret = new List <B45ChunkDataBase>(); fileBA.ReadHeader(); fileUV.ReadHeader(); int chunkCount = fileBA.GetChunkCount(); for (int i = 0; i < chunkCount; i++) { B45ChunkDataBase cd = fileBA.ReadChunkData(i); if (cd.svn_key_ba <= read_ref_svnkey) { continue; } fileUV.AttachUVData(i, cd); ret.Add(cd); if (highest_svn_key < cd.svn_key_ba) { highest_svn_key = cd.svn_key_ba; } } out_svn_key = highest_svn_key; return(ret); }
public B45ChunkDataBase ReadChunkData(int nth) { int thisChunkDataStartOfs = phase2StartOfs + chunkOffsets[nth]; byte RLE = binaryBuffer[thisChunkDataStartOfs + ChunkBAHeaderOffsets.RLE]; byte[] rawBuffer; B45ChunkDataBase cd; B45Block blk; if (RLE == 0) { rawBuffer = new byte[chunkRawDataLength]; Array.Copy(binaryBuffer, thisChunkDataStartOfs + ChunkBAHeaderOffsets.headerLength, rawBuffer, 0, chunkRawDataLength); cd = new B45ChunkDataBase(rawBuffer); } else { blk.blockType = binaryBuffer[thisChunkDataStartOfs + ChunkBAHeaderOffsets.headerLength]; blk.materialType = binaryBuffer[thisChunkDataStartOfs + ChunkBAHeaderOffsets.headerLength + 1]; // TODO cd = new B45ChunkDataBase(blk); } cd._chunkPos = new IntVector3(chunkCoords[nth]); cd.svn_key_ba = svn_keys_ba[nth]; return(cd); }
void WriteUVData(List <B45ChunkDataBase> chunkDataList) { byte[] chunkDataBinaryBuffer = new byte[chunkOffsets[chunkOffsets.Length - 1]]; int updateVectorStOfs; int uvKeyCountStOfs; for (int i = 0; i < chunkDataList.Count; i++) { B45ChunkDataBase cd = chunkDataList[i]; //chunkRawDataOffsetStart + chunkOffsets[nth] + ChunkBAHeaderOffsets.vectorCount if (cd.updateVectors == null) { ByteArrayHelper.int_to(chunkDataBinaryBuffer, chunkOffsets[i] + ChunkUVHeaderOffsets.vectorCount, 0); } else { ByteArrayHelper.int_to(chunkDataBinaryBuffer, chunkOffsets[i] + ChunkUVHeaderOffsets.vectorCount, cd.updateVectors.Count); } if (cd.uvVersionKeys == null) { ByteArrayHelper.int_to(chunkDataBinaryBuffer, chunkOffsets[i] + ChunkUVHeaderOffsets.svnkeyCount, 0); } else { ByteArrayHelper.int_to(chunkDataBinaryBuffer, chunkOffsets[i] + ChunkUVHeaderOffsets.svnkeyCount, cd.uvVersionKeys.Count); } uvKeyCountStOfs = chunkOffsets[i] + ChunkUVHeaderOffsets.headerLength; if (cd.uvVersionKeys != null) { for (int j = 0; j < cd.uvVersionKeys.Count; j++) { ByteArrayHelper.int_to(chunkDataBinaryBuffer, uvKeyCountStOfs + j * UVKeyCount.length, cd.uvVersionKeys[j].svn_key); ByteArrayHelper.ushort_to(chunkDataBinaryBuffer, uvKeyCountStOfs + j * UVKeyCount.length + 4, cd.uvVersionKeys[j].count); } updateVectorStOfs = uvKeyCountStOfs + cd.uvVersionKeys.Count * UVKeyCount.length; if (cd.updateVectors != null) { for (int j = 0; j < cd.updateVectors.Count; j++) { chunkDataBinaryBuffer[updateVectorStOfs + j * UpdateVector.length] = cd.updateVectors[j].xyz0; chunkDataBinaryBuffer[updateVectorStOfs + j * UpdateVector.length + 1] = cd.updateVectors[j].xyz1; chunkDataBinaryBuffer[updateVectorStOfs + j * UpdateVector.length + 2] = cd.updateVectors[j].voxelData0; chunkDataBinaryBuffer[updateVectorStOfs + j * UpdateVector.length + 3] = cd.updateVectors[j].voxelData1; } } } cd.updateVectors = null; } fs.Write(chunkDataBinaryBuffer, 0, chunkDataBinaryBuffer.Length); }
public static B45ChunkDataBase ReadChunkBase(uLink.BitStream stream, params object[] codecOptions) { B45ChunkDataBase data = new B45ChunkDataBase(null); stream.TryRead <IntVector3>(out data._chunkPos); stream.TryRead <int>(out data._lod); stream.TryRead <int>(out data.svn_key); stream.TryRead <int>(out data.svn_key_ba); stream.TryRead <byte[]>(out data._chunkData); return(data); }
public byte[] _chunkData; //tmp public public static void WriteChunkBase(uLink.BitStream stream, object obj, params object[] codecOptions) { B45ChunkDataBase data = obj as B45ChunkDataBase; if (null != data) { stream.Write(data._chunkPos); stream.Write(data._lod); stream.Write(data.svn_key); stream.Write(data.svn_key_ba); stream.Write(data._chunkData); } }
// yield to cd2 List <UpdateVector> computeDifferences(B45ChunkDataBase cd1, B45ChunkDataBase cd2) { List <UpdateVector> ret = new List <UpdateVector>(); for (int idx = 0; idx < Block45Constants.VOXEL_ARRAY_LENGTH; idx++) { if (cd1._chunkData[idx * 2] != cd2._chunkData[idx * 2] || cd1._chunkData[idx * 2 + 1] != cd2._chunkData[idx * 2 + 1]) { UpdateVector vu = new UpdateVector(); vu.xyz0 = (byte)(idx & 0xFF); vu.xyz1 = (byte)((idx >> 8) & 0xFF); vu.voxelData0 = cd2._chunkData[idx * 2]; vu.voxelData1 = cd2._chunkData[idx * 2 + 1]; ret.Add(vu); } } return(ret); }
public B45ChunkDataBase AttachUVData(int nth, B45ChunkDataBase cd) { int thisChunkDataStartOfs = phase2StartOfs + chunkOffsets[nth]; int vectorCount = ByteArrayHelper.to_int(binaryBuffer, thisChunkDataStartOfs + ChunkUVHeaderOffsets.vectorCount); int svnkeyCount = ByteArrayHelper.to_int(binaryBuffer, thisChunkDataStartOfs + ChunkUVHeaderOffsets.svnkeyCount); cd.svn_key = svn_keys_uv[nth]; cd.uvVersionKeys = new List <UVKeyCount>(); cd.updateVectors = new List <UpdateVector>(); for (int i = 0; i < svnkeyCount; i++) { int thisVersionKeyCountOfs = thisChunkDataStartOfs + ChunkUVHeaderOffsets.headerLength + i * UVKeyCount.length; UVKeyCount uvkc = new UVKeyCount(); uvkc.svn_key = ByteArrayHelper.to_int(binaryBuffer, thisVersionKeyCountOfs); uvkc.count = ByteArrayHelper.to_ushort(binaryBuffer, thisVersionKeyCountOfs + 4); cd.uvVersionKeys.Add(uvkc); } int svnkeyLength = UVKeyCount.length * svnkeyCount; for (int i = 0; i < vectorCount; i++) { int thisUpdateVectorOfs = thisChunkDataStartOfs + ChunkUVHeaderOffsets.headerLength + svnkeyLength + i * UpdateVector.length; UpdateVector uv = new UpdateVector(); uv.xyz0 = binaryBuffer[thisUpdateVectorOfs]; uv.xyz1 = binaryBuffer[thisUpdateVectorOfs + 1]; uv.voxelData0 = binaryBuffer[thisUpdateVectorOfs + 2]; uv.voxelData1 = binaryBuffer[thisUpdateVectorOfs + 3]; cd.updateVectors.Add(uv); } return(cd); }
public bool MergeChunkData(List <B45ChunkDataBase> cdl) { if (fileBA.ReadHeader() == false) { // init cdl's uv data for (int i = 0; i < cdl.Count; i++) { cdl[i].InitUpdateVectors(); cdl[i].svn_key_ba = 1; // MonoBehaviour.print("first write " + cdl[i].OccupiedVecsStr()); } fileBA.WriteBAHeader(false, cdl); fileUV.WriteUVHeader(false, cdl); return(true); } int tmp_svnkey = 0; //List<B45ChunkDataBase> disk_cdl = fileBA.ReadAllChunkData(out tmp_svnkey, 0); List <B45ChunkDataBase> disk_cdl = ReadAllChunkData(out tmp_svnkey, 0); tmp_svnkey++; bool addedNewBA = false; for (int i = 0; i < cdl.Count; i++) { B45ChunkDataBase cd = cdl[i]; bool found = false; for (int j = 0; j < disk_cdl.Count; j++) { B45ChunkDataBase disk_cd = disk_cdl[j]; if (cd._chunkPos.Equals(disk_cd._chunkPos)) { // MonoBehaviour.print("(svn) replace " + disk_cd._chunkPos.toDBStr() + " rev " + disk_cd.svn_key + " with " + svn_key); // MonoBehaviour.print("disk "+disk_cd.OccupiedVecsStr()); // MonoBehaviour.print("mem " + cd.OccupiedVecsStr()); List <UpdateVector> uvs = computeDifferences(disk_cd, cd); if (disk_cd.updateVectors == null) { disk_cd.updateVectors = new List <UpdateVector>(); } if (disk_cd.uvVersionKeys == null) { disk_cd.uvVersionKeys = new List <UVKeyCount>(); UVKeyCount uvkc = new UVKeyCount(); uvkc.svn_key = 0; uvkc.count = 0; disk_cd.uvVersionKeys.Add(uvkc); } int newkey = MergeUV(uvs, disk_cd.updateVectors, disk_cd.uvVersionKeys); //disk_cd.svn_key_ba = disk_cd.svn_key = newkey; found = true; } } if (found == false) { // MonoBehaviour.print("(svn) add " + cd._chunkPos.toDBStr() + " rev " + svn_key); addedNewBA = true; cd.InitUpdateVectors(); cd.svn_key = tmp_svnkey; disk_cdl.Add(cd); } } if (addedNewBA) { fileBA.WriteBAHeader(false, disk_cdl); } fileUV.WriteUVHeader(false, disk_cdl); return(true); }
public void WriteBAHeader(bool compressed, List <B45ChunkDataBase> chunkDataList) { fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write); byte[] tmp = new byte[2]; if (compressed) { // compressed tmp[1] = (byte)(tmp[1] | 0x1); } else { } fs.Write(tmp, 0, 2); byte[] headerBuffer = new byte[FileHeaderOffsets.headerLength]; headerBuffer[FileHeaderOffsets.cellLength] = fileHeader.cellLength; headerBuffer[FileHeaderOffsets.chunkType] = fileHeader.chunkType; headerBuffer[FileHeaderOffsets.chunkSize] = fileHeader.chunkSize; headerBuffer[FileHeaderOffsets.chunkPrefix] = fileHeader.chunkPrefix; headerBuffer[FileHeaderOffsets.chunkPostfix] = fileHeader.chunkPostfix; ByteArrayHelper.ushort_to(headerBuffer, FileHeaderOffsets.chunkCountX, fileHeader.chunkCountX); ByteArrayHelper.ushort_to(headerBuffer, FileHeaderOffsets.chunkCountY, fileHeader.chunkCountY); ByteArrayHelper.ushort_to(headerBuffer, FileHeaderOffsets.chunkCountZ, fileHeader.chunkCountZ); ByteArrayHelper.ushort_to(headerBuffer, FileHeaderOffsets.voxelRes, fileHeader.voxelRes); headerBuffer[FileHeaderOffsets.chunkOffsetDesc] = fileHeader.chunkOffsetDesc; fs.Write(headerBuffer, 0, (int)FileHeaderOffsets.headerLength); //chkOfsUnitLen = fileHeader.chunkOffsetDesc & 0x7; chkOfsInVectorForm = ((fileHeader.chunkOffsetDesc >> 4) > 0); int chkOfsLen = 4 + chunkDataList.Count * ChunkOffsetStructOffsets.length; byte[] chunkOffsetBinaryBuffer = new byte[chkOfsLen]; chunkRawDataLength = fileHeader.chunkSize * fileHeader.chunkSize * fileHeader.chunkSize * fileHeader.cellLength; if (chkOfsInVectorForm) { // write the chunk count ByteArrayHelper.int_to(chunkOffsetBinaryBuffer, 0, chunkDataList.Count); chunkOffsets = new int[chunkDataList.Count + 1]; // calculate the chunk offsets first chunkOffsets[0] = 0; int i; int lastChunkLength; for (i = 1; i <= chunkDataList.Count; i++) { lastChunkLength = chunkDataList[i - 1].IsHollow ? ChunkBAHeaderOffsets.headerLength + fileHeader.cellLength : ChunkBAHeaderOffsets.headerLength + chunkRawDataLength; chunkOffsets[i] = chunkOffsets[i - 1] + lastChunkLength; } // write the last length to the extra offset slot for write chunk data reference. // write the offsets into the buffer. phase 1 for (i = 0; i < chunkDataList.Count; i++) { B45ChunkDataBase cd = chunkDataList[i]; // write the chunk pos // in "4 + i * (chkOfsUnitLen * 3 + 12)" the 4 is the length of the chunkcount int at the beginning ByteArrayHelper.IntVector3_to(chunkOffsetBinaryBuffer, 4 + i * ChunkOffsetStructOffsets.length, cd._chunkPos); // write the chunk offset relative to the end of the offset buffer ByteArrayHelper.int_to(chunkOffsetBinaryBuffer, 4 + i * ChunkOffsetStructOffsets.length + ChunkOffsetStructOffsets.Offset, chunkOffsets[i]); // write the svn number ByteArrayHelper.int_to(chunkOffsetBinaryBuffer, 4 + i * ChunkOffsetStructOffsets.length + ChunkOffsetStructOffsets.SVN_key_ba, cd.svn_key_ba); } fs.Write(chunkOffsetBinaryBuffer, 0, chkOfsLen); } else { // it's the chunk offset full listing mode } // phase 2 WriteChunkData(chunkDataList); fs.Close(); }
public void WriteUVHeader(bool compressed, List <B45ChunkDataBase> chunkDataList) { fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write); byte headerByte = chunkOffsetDesc; if (compressed) { // compressed headerByte = (byte)(headerByte | 32); } else { } fs.WriteByte(headerByte); //chkOfsUnitLen = chunkOffsetDesc & 0x7; chkOfsInVectorForm = ((chunkOffsetDesc >> 4) > 0); int chkOfsLen = 4 + chunkDataList.Count * ChunkOffsetStructOffsets.length; byte[] chunkOffsetBinaryBuffer = new byte[chkOfsLen]; if (chkOfsInVectorForm) { // write the chunk count ByteArrayHelper.int_to(chunkOffsetBinaryBuffer, 0, chunkDataList.Count); chunkOffsets = new int[chunkDataList.Count + 1]; // calculate the chunk offsets first chunkOffsets[0] = 0; int i; int lastChunkLength; for (i = 1; i <= chunkDataList.Count; i++) { List <UVKeyCount> uvkc = chunkDataList[i - 1].uvVersionKeys; int uvkc_len = 0; if (uvkc != null) { uvkc_len = uvkc.Count * UVKeyCount.length; } List <UpdateVector> uvs = chunkDataList[i - 1].updateVectors; int uv_len = 0; if (uvs != null) { uv_len = uvs.Count * UpdateVector.length; } lastChunkLength = ChunkUVHeaderOffsets.headerLength + uvkc_len + uv_len; chunkOffsets[i] = chunkOffsets[i - 1] + lastChunkLength; } // write the last length to the extra offset slot for write chunk data reference. // write the offsets into the buffer. phase 1 for (i = 0; i < chunkDataList.Count; i++) { B45ChunkDataBase cd = chunkDataList[i]; // write the chunk pos // in "4 + i * (chkOfsUnitLen * 3 + 12)" the 4 is the length of the chunkcount int at the beginning ByteArrayHelper.IntVector3_to(chunkOffsetBinaryBuffer, 4 + i * ChunkOffsetStructOffsets.length, cd._chunkPos); // write the chunk offset relative to the end of the offset buffer ByteArrayHelper.int_to(chunkOffsetBinaryBuffer, 4 + i * ChunkOffsetStructOffsets.length + ChunkOffsetStructOffsets.Offset, chunkOffsets[i]); // write the svn number ByteArrayHelper.int_to(chunkOffsetBinaryBuffer, 4 + i * ChunkOffsetStructOffsets.length + ChunkOffsetStructOffsets.SVN_key, cd.svn_key); } fs.Write(chunkOffsetBinaryBuffer, 0, chkOfsLen); } else { // it's the chunk offset full listing mode } // phase 2 WriteUVData(chunkDataList); fs.Close(); }