internal unsafe static void WriteStream(Stream stream, PVSNodeHeader header) { var byteBufferNode = NetByteArrayPool.GetByteBufferNode(Marshal.SizeOf(header)); try { System.IntPtr srcPtr = (System.IntPtr)(&header); Marshal.Copy(srcPtr, byteBufferNode.Buffer, 0, byteBufferNode.DataSize); stream.Write(byteBufferNode.Buffer, 0, byteBufferNode.DataSize); } finally { byteBufferNode.Dispose(); } }
internal unsafe static void ReadFromStream(Stream stream, out PVSNodeHeader ret) { ByteBufferNode node = NetByteArrayPool.GetByteBufferNode(Marshal.SizeOf(typeof(PVSNodeHeader))); try { stream.Read(node.Buffer, 0, node.DataSize); PVSNodeHeader p; System.IntPtr dstPtr = (System.IntPtr)(&p); Marshal.Copy(node.Buffer, 0, dstPtr, node.DataSize); ret = p; } finally { node.Dispose(); } }
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()); }