public void SetToFull() { CellType = MyVoxelRangeType.FULL; m_voxelContentSum = MyVoxelConstants.DATA_CELL_CONTENT_SUM_TOTAL; CheckCellType(); }
public void SetToEmpty() { CellType = MyVoxelRangeType.EMPTY; m_voxelContentSum = 0; CheckCellType(); }
public MyVoxelContentCell() { // Default cell is FULL CellType = MyVoxelRangeType.FULL; // Sums all voxel values. Default is summ of all full voxel in cell, so be subtracting we can switch cell from MIXED to EMPTY. m_voxelContentSum = MyVoxelConstants.DATA_CELL_CONTENT_SUM_TOTAL; }
// Set voxel content for the whole cell. public void SetAllVoxelContents(byte[] buffer) { // quantize the buffer and compute sum m_voxelContentSum = 0; for (int i = 0; i < buffer.Length; i++) { buffer[i] = MyCellStorage.Quantizer.QuantizeValue(buffer[i]); m_voxelContentSum += buffer[i]; } // mixed-->empty/full: deallocate // empty/full-->mixed: allocate // mixed: fill with values from buffer if (m_voxelContentSum == 0) { if (CellType == MyVoxelRangeType.MIXED) { Deallocate(); } CellType = MyVoxelRangeType.EMPTY; } else if (m_voxelContentSum == MyVoxelConstants.DATA_CELL_CONTENT_SUM_TOTAL) { if (CellType == MyVoxelRangeType.MIXED) { Deallocate(); } CellType = MyVoxelRangeType.FULL; } else { if (CellType == MyVoxelRangeType.FULL || CellType == MyVoxelRangeType.EMPTY) { m_cellContent = MyVoxelContentCellContents.Allocate(); } if (m_cellContent != null) { m_cellContent.SetAddVoxelContents(buffer); } CellType = MyVoxelRangeType.MIXED; } }
// This method helps us to maintain correct cell type even after removing or adding voxels from cell // If all voxels were removed from this cell, we change its type to from MIXED to EMPTY. // If voxels were added, we change its type to from EMPTY to MIXED. // If voxels were added to full, we change its type to FULL. void CheckCellType() { // Voxel cell content sum isn't in allowed range. Probably increased or descreased too much. System.Diagnostics.Debug.Assert((m_voxelContentSum >= 0) && (m_voxelContentSum <= MyVoxelConstants.DATA_CELL_CONTENT_SUM_TOTAL)); if (m_voxelContentSum == 0) { CellType = MyVoxelRangeType.EMPTY; } else if (m_voxelContentSum == MyVoxelConstants.DATA_CELL_CONTENT_SUM_TOTAL) { CellType = MyVoxelRangeType.FULL; } else { CellType = MyVoxelRangeType.MIXED; } // If cell changed from MIXED to EMPTY or FULL, we will release it's cell content because it's not needed any more if ((CellType == MyVoxelRangeType.EMPTY) || (CellType == MyVoxelRangeType.FULL)) { Deallocate(); } }
private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream) { // Size of this voxel map (in voxels) Vector3I tmpSize; tmpSize.X = stream.ReadInt32(); tmpSize.Y = stream.ReadInt32(); tmpSize.Z = stream.ReadInt32(); var storage = new MyOctreeStorage(null, tmpSize); // Size of data cell in voxels. Has to be the same as current size specified by our constants. Vector3I cellSize; cellSize.X = stream.ReadInt32(); cellSize.Y = stream.ReadInt32(); cellSize.Z = stream.ReadInt32(); #if !XB1 Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); #else // XB1 System.Diagnostics.Debug.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS && cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS); #endif // XB1 Vector3I cellsCount = tmpSize / cellSize; Dictionary <byte, MyVoxelMaterialDefinition> mappingTable = null; if (fileVersion == STORAGE_TYPE_VERSION_CELL) { // loading material names->index mappings mappingTable = Compatibility_LoadMaterialIndexMapping(stream); } else if (fileVersion == 1) { // material name->index mappings were not saved in this version } var startCoord = Vector3I.Zero; var endCoord = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); var cache = new MyStorageData(); cache.Resize(Vector3I.Zero, endCoord); Vector3I cellCoord; for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc(); // Cell's are FULL by default, therefore we don't need to change them switch (cellType) { case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break; case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break; case MyVoxelRangeType.MIXED: Vector3I v; for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++) { for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++) { for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++) { cache.Content(ref v, stream.ReadByteNoAlloc()); } } } break; } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord); } } } try { // In case materials are not saved, catch any exceptions caused by this. // Read materials and indestructible for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++) { bool isSingleMaterial = stream.ReadByteNoAlloc() == 1; MyVoxelMaterialDefinition material = null; if (isSingleMaterial) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); cache.ClearMaterials(material.Index); } else { byte indestructibleContent; Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable); indestructibleContent = stream.ReadByteNoAlloc(); cache.Material(ref voxelCoordInCell, material.Index); } } } } startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1); storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord); } } } } catch (EndOfStreamException ex) { MySandboxGame.Log.WriteLine(ex); } return(storage); }
// Set voxel content for the whole cell. public void SetAllVoxelContents(byte[] buffer) { // quantize the buffer and compute sum m_voxelContentSum = 0; for (int i = 0; i < buffer.Length; i++) { buffer[i] = MyCellStorage.Quantizer.QuantizeValue(buffer[i]); m_voxelContentSum += buffer[i]; } // mixed-->empty/full: deallocate // empty/full-->mixed: allocate // mixed: fill with values from buffer if (m_voxelContentSum == 0) { if (CellType == MyVoxelRangeType.MIXED) Deallocate(); CellType = MyVoxelRangeType.EMPTY; } else if (m_voxelContentSum == MyVoxelConstants.DATA_CELL_CONTENT_SUM_TOTAL) { if (CellType == MyVoxelRangeType.MIXED) Deallocate(); CellType = MyVoxelRangeType.FULL; } else { if (CellType == MyVoxelRangeType.FULL || CellType == MyVoxelRangeType.EMPTY) m_cellContent = MyVoxelContentCellContents.Allocate(); if (m_cellContent != null) { m_cellContent.SetAddVoxelContents(buffer); } CellType = MyVoxelRangeType.MIXED; } }
internal void DebugDrawCells(MyVoxelRangeType type) { var color = Color.NavajoWhite; color.A = 25; using (var batch = VRageRender.MyRenderProxy.DebugDrawBatchAABB(Matrix.Identity, color, true, true)) { for (int cellIdx = 0; cellIdx < m_contentCells.Length; ++cellIdx) { var cell = m_contentCells[cellIdx]; if ((cell != null && cell.CellType == type) || (cell == null && type == MyVoxelRangeType.FULL)) { Vector3I coord; ComputeCellCoord(cellIdx, out coord); ComputeVoxelCoordOfCell(ref coord, out coord); Vector3 min = (coord + new Vector3(0.5f)) * MyVoxelConstants.VOXEL_SIZE_IN_METRES + VoxelMap.PositionLeftBottomCorner; Vector3 max = min + MyVoxelConstants.DATA_CELL_SIZE_IN_METRES; var bb = new BoundingBox(min, max); batch.Add(ref bb); } } } }