internal int ItemSize(PVSSaveMode saveMode) { int ret = Marshal.SizeOf(this.position); ret += Marshal.SizeOf(this.lod); if (saveMode == PVSSaveMode.bitsArrayMode) { ret += Marshal.SizeOf(this.visibleBitsIdx); } else if (saveMode == PVSSaveMode.bitsCellMode) { ret += this.visibleBits.Length * Marshal.SizeOf(typeof(byte)); } return(ret); }
internal unsafe void SaveToStream(Stream stream, PVSSaveMode saveMode) { if (stream == null) { return; } PVSManager.WriteStream(stream, this.position); PVSManager.WriteStream(stream, this.lod); if (saveMode == PVSSaveMode.bitsArrayMode) { PVSManager.WriteStream(stream, this.visibleBitsIdx); } else if (saveMode == PVSSaveMode.bitsCellMode) { stream.Write(this.visibleBits, 0, this.visibleBits.Length * Marshal.SizeOf(typeof(byte))); } }
public unsafe static void SaveToStream(Stream stream, PVSCell[] cellResults, Rect quadTreeRect, int customSaveMode = -1) { if (cellResults == null || cellResults.Length <= 0) { return; } PVSNodeHeader header = new PVSNodeHeader(); header.quadTreeSize = quadTreeRect.size; header.quadTreeCenter = quadTreeRect.center; // 合并一样的bit数组,节省空间 int cellCnt = 0; List <byte[]> byteArrList = new List <byte[]>(); for (int i = 0; i < cellResults.Length; ++i) { var cell = cellResults[i]; if (cell == null || cell.visibleBits == null) { continue; } ++cellCnt; bool isFound = false; for (int j = 0; j < byteArrList.Count; ++j) { var oldCell = byteArrList[j]; if (oldCell == null) { continue; } if (cell.CompareVisibleBits(oldCell)) { cell.visibleBits = oldCell; cell.visibleBitsIdx = j; isFound = true; break; } } if (!isFound) { cell.visibleBitsIdx = byteArrList.Count; byteArrList.Add(cell.visibleBits); } } header.bitsArrayLength = byteArrList.Count; header.cellCount = cellCnt; float bitsSize = 0f; if (cellResults.Length > 0 && cellResults[0].visibleBits != null) { bitsSize = (cellResults[0].visibleBits.Length * Marshal.SizeOf(typeof(byte))) / 1024f; } float bitsTotualSize = byteArrList.Count * bitsSize; PVSSaveMode saveMode = PVSSaveMode.bitsArrayMode; float revertSize = header.cellCount * bitsSize - ((header.cellCount * Marshal.SizeOf(typeof(int))) / 1024f + bitsTotualSize); if (revertSize < 0) { saveMode = PVSSaveMode.bitsCellMode; } if (customSaveMode >= 0) { saveMode = (PVSSaveMode)customSaveMode; } header.saveMode = (byte)saveMode; // 1.写入文件头 WriteStream(stream, header); if (saveMode == PVSSaveMode.bitsArrayMode) { // 2.写入byteArray for (int i = 0; i < byteArrList.Count; ++i) { var bs = byteArrList[i]; stream.Write(bs, 0, bs.Length); } } // 3.写入Cell信息 float cellTotualSize = 0; for (int i = 0; i < cellResults.Length; ++i) { var cell = cellResults[i]; if (cell == null) { continue; } cell.SaveToStream(stream, saveMode); cellTotualSize += cell.ItemSize(saveMode); } cellTotualSize /= 1024f; Debug.LogFormat("Bits数组数量:{0:D}个(占用大小:{1}K) 场景CELL数量:{2:D}个(占用大小:{3}K)[节省:{4}K, 存储模式:{5}]", header.bitsArrayLength, bitsTotualSize.ToString(), header.cellCount, cellTotualSize.ToString(), revertSize.ToString(), saveMode.ToString()); }
internal unsafe void LoadFromStream(Stream stream, List <byte[]> byteArrayList, PVSSaveMode saveMode, int bitLen) { if (stream == null) { return; } // 读取位置 PVSManager.ReadFromStream(stream, out this.position); // 读取LOD数据 PVSManager.ReadFromStream(stream, out this.lod); // 可见bit位 if (saveMode == PVSSaveMode.bitsArrayMode) { int idx; PVSManager.ReadFromStream(stream, out idx); this.visibleBits = byteArrayList[idx]; } else if (saveMode == PVSSaveMode.bitsCellMode) { this.visibleBits = new byte[bitLen]; stream.Read(this.visibleBits, 0, bitLen); } }