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