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); }
// uvs1 are from the chunks in memory. // uvs2, kcs2 are from the disk. public static int MergeUV(List <UpdateVector> uvs1, List <UpdateVector> uvs2, List <UVKeyCount> kcs2) { int latest_svn_key = kcs2[kcs2.Count - 1].svn_key; UVKeyCount newKC = new UVKeyCount(); newKC.svn_key = latest_svn_key + 1; newKC.count = 0; int kc2Ptr = 0; int currentKeyCount = kcs2[kc2Ptr].count; int currentKeyCountI = 0; byte[] found = new byte[uvs1.Count]; int olduvs2Count = uvs2.Count; for (int j = 0; j < olduvs2Count; j++) { int idxFrom2 = uvs2[j].xyz0 + (uvs2[j].xyz1 << 8); for (int i = 0; i < uvs1.Count; i++) { int idxFrom1 = uvs1[i].xyz0 + (uvs1[i].xyz1 << 8); if (idxFrom1 == idxFrom2) { found[i] = 1; // further compare the voxel bytes. // if they are different, it means one is a newer update. it should supercede the other. if (uvs1[i].voxelData0 != uvs2[j].voxelData0 || uvs1[i].voxelData1 != uvs2[j].voxelData1) { uvs2[j].voxelData0 = uvs1[i].voxelData0; uvs2[j].voxelData1 = uvs1[i].voxelData1; uvs2.Add(uvs2[j]); uvs2[j] = null; kcs2[kc2Ptr].count--; newKC.count++; } } } currentKeyCountI++; if (currentKeyCountI >= currentKeyCount) { currentKeyCountI = 0; kc2Ptr++; if (kc2Ptr < kcs2.Count) { currentKeyCount = kcs2[kc2Ptr].count; } } } // condense uvs2 int adjustment = 0; for (int i = 0; i < uvs2.Count; i++) { if (uvs2[i] != null) { if (adjustment != 0) { uvs2[i - adjustment] = uvs2[i]; uvs2[i] = null; } } else { adjustment++; } } // take out the nulls in uvs2 for (int i = uvs2.Count - 1; i >= 0; i--) { if (uvs2[i] == null) { uvs2.RemoveAt(i); } else { break; } } // add the new uvs. for (int i = 0; i < uvs1.Count; i++) { if (found[i] == 0) { UpdateVector newUV = new UpdateVector(); newUV.xyz0 = uvs1[i].xyz0; newUV.xyz1 = uvs1[i].xyz1; newUV.voxelData0 = uvs1[i].voxelData0; newUV.voxelData1 = uvs1[i].voxelData1; uvs2.Add(newUV); newKC.count++; } } // take out the 0 in kcs2 for (int i = kcs2.Count - 1; i >= 0; i--) { if (kcs2[i].count == 0) { kcs2.RemoveAt(i); } else { break; } } kcs2.Add(newKC); return(latest_svn_key + 1); }