private void LoadUncompressedV2(BinaryReader reader, bool loadMaterial, int materialBaseCount) { var materialIndexDict = new Dictionary<byte, byte>(); for (byte i = 0; i < materialBaseCount; i++) { var idx = reader.ReadByte(); var materialName = reader.ReadString(); var resourceIdx = SpaceEngineersCore.Resources.GetMaterialIndex(materialName); materialIndexDict.Add(idx, resourceIdx); } var cellsCount = Size / _cellSize; for (var x = 0; x < cellsCount.X; x++) { for (var y = 0; y < cellsCount.Y; y++) { for (var z = 0; z < cellsCount.Z; z++) { var cellType = (MyVoxelCellType)reader.ReadByte(); // Cell's are FULL by default, therefore we don't need to change them if (cellType != MyVoxelCellType.FULL) { var cellCoord = new Vector3I(x, y, z); var newCell = new MyVoxelContentCell(); _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z] = newCell; if (cellType == MyVoxelCellType.EMPTY) { newCell.SetToEmpty(); } else if (cellType == MyVoxelCellType.MIXED) { BoundingBoxD box; newCell.SetAllVoxelContents(reader.ReadBytes(_cellSize.X * _cellSize.Y * _cellSize.Z), out box); _boundingContent.Min = Vector3D.Min(_boundingContent.Min, new Vector3D((x << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + box.Min.X, (y << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + box.Min.Y, (z << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + box.Min.Z)); _boundingContent.Max = Vector3D.Max(_boundingContent.Max, new Vector3D((x << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + box.Max.X, (y << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + box.Max.Y, (z << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + box.Max.Z)); } // ignore else condition } else { _boundingContent.Min = Vector3D.Min(_boundingContent.Min, new Vector3D(x << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS, y << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS, z << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS)); _boundingContent.Max = Vector3D.Max(_boundingContent.Max, new Vector3D((x + 1 << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) - 1, (y + 1 << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) - 1, (z + 1 << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) - 1)); } } } } if (reader.PeekChar() == -1 || !loadMaterial) { return; } // Read materials. const byte indestructibleContent = 0xff; for (var x = 0; x < cellsCount.X; x++) { for (var y = 0; y < cellsCount.Y; y++) { for (var z = 0; z < cellsCount.Z; z++) { var matCell = _voxelMaterialCells[x][y][z]; var materialCount = reader.ReadByte(); if (materialCount == (byte)MyVoxelCellType.FULL) { var materialIndex = reader.ReadByte(); matCell.Reset(materialIndexDict[materialIndex], indestructibleContent); } else { Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { var materialIndex = reader.ReadByte(); materialCount = reader.ReadByte(); matCell.SetMaterialAndIndestructibleContent(materialIndexDict[materialIndex], indestructibleContent, ref voxelCoordInCell); } } } matCell.CalcAverageCellMaterial(); } } } } }
private void InitVoxelMap(Vector3D position, Vector3I size, string materialName, bool defineMemory) { IsValid = true; Size = size; _sizeMinusOne = new Vector3I(Size.X - 1, Size.Y - 1, Size.Z - 1); VoxelMaterial = SpaceEngineersCore.Resources.GetMaterialIndex(materialName); _positionLeftBottomCorner = position; _boundingContent = new BoundingBoxD(new Vector3I(Size.X, Size.Y, Size.Z), new Vector3I(0, 0, 0)); // this is too big for the current SEToolbox code to cope with, and is probably a planet. if (!defineMemory) return; // If you need larged voxel maps, enlarge this constant. Debug.Assert(Size.X <= MyVoxelConstants.MAX_VOXEL_MAP_SIZE_IN_VOXELS); Debug.Assert(Size.Y <= MyVoxelConstants.MAX_VOXEL_MAP_SIZE_IN_VOXELS); Debug.Assert(Size.Z <= MyVoxelConstants.MAX_VOXEL_MAP_SIZE_IN_VOXELS); // Voxel map size must be multiple of a voxel data cell size. Debug.Assert((Size.X & MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_MASK) == 0); Debug.Assert((Size.Y & MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_MASK) == 0); Debug.Assert((Size.Z & MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_MASK) == 0); _dataCellsCount.X = Size.X >> MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS; _dataCellsCount.Y = Size.Y >> MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS; _dataCellsCount.Z = Size.Z >> MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS; // Voxel map size must be multiple of a voxel data cell size. Debug.Assert((Size.X % MyVoxelConstants.VOXEL_RENDER_CELL_SIZE_IN_VOXELS) == 0); Debug.Assert((Size.Y % MyVoxelConstants.VOXEL_RENDER_CELL_SIZE_IN_VOXELS) == 0); Debug.Assert((Size.Z % MyVoxelConstants.VOXEL_RENDER_CELL_SIZE_IN_VOXELS) == 0); // Array of voxel cells in this voxel map. _voxelContentCells = new MyVoxelContentCell[_dataCellsCount.X][][]; for (var x = 0; x < _voxelContentCells.Length; x++) { _voxelContentCells[x] = new MyVoxelContentCell[_dataCellsCount.Y][]; for (var y = 0; y < _voxelContentCells[x].Length; y++) { _voxelContentCells[x][y] = new MyVoxelContentCell[_dataCellsCount.Z]; } } // Set base material. _voxelMaterialCells = new MyVoxelMaterialCell[_dataCellsCount.X][][]; for (var x = 0; x < _dataCellsCount.X; x++) { _voxelMaterialCells[x] = new MyVoxelMaterialCell[_dataCellsCount.Y][]; for (var y = 0; y < _dataCellsCount.Y; y++) { _voxelMaterialCells[x][y] = new MyVoxelMaterialCell[_dataCellsCount.Z]; for (var z = 0; z < _dataCellsCount.Z; z++) { _voxelMaterialCells[x][y][z] = new MyVoxelMaterialCell(VoxelMaterial, 0xFF); } } } }
/// <summary> /// Check the given cell type against a possible cell contents state (full, empty, mixed) /// </summary> /// <param name="cell">MyVoxelContentCell object to check</param> /// <param name="type">A cell state to check against (MyVoxelCellType enum)</param> /// <returns>whether the cell has the given type or not.</returns> private bool CheckCellType(ref MyVoxelContentCell cell, MyVoxelCellType type) { if (cell == null) return type == MyVoxelCellType.FULL; return cell.CellType == type; }
// Allocates cell from a buffer, store reference to dictionary and return reference to the cell // Use it when changing cell type from full to empty or mixed. private MyVoxelContentCell AddCell(ref Vector3I cellCoord) { // Adding or creating cell can be made only once Debug.Assert(_voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z] == null); var ret = new MyVoxelContentCell(); _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z] = ret; return ret; }
// Checks if cell didn't change to FULL and if is, we set it to null private void CheckIfCellChangedToFull(MyVoxelContentCell voxelCell, ref Vector3I cellCoord) { if (voxelCell.CellType == MyVoxelCellType.FULL) { _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z] = null; } }
public void ReplaceMaterial(string materialName, string replaceFillMaterial) { var materialIndex = SpaceEngineersCore.Resources.GetMaterialIndex(materialName); var replaceMaterialIndex = SpaceEngineersCore.Resources.GetMaterialIndex(replaceFillMaterial); Vector3I cellCoord; for (cellCoord.X = 0; cellCoord.X < _dataCellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < _dataCellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < _dataCellsCount.Z; cellCoord.Z++) { var voxelCell = _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z]; var matCell = _voxelMaterialCells[cellCoord.X][cellCoord.Y][cellCoord.Z]; if (voxelCell == null) { // Voxel wasn't found in cell dictionary, so cell must be FULL if (matCell.IsSingleMaterialForWholeCell) { if (matCell.SingleMaterial == materialIndex) { //matCell.ForceReplaceMaterial(replaceMaterialIndex); //var newCell = new MyVoxelContentCell(); //this._voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z] = newCell; matCell.Reset(replaceMaterialIndex, 0xff); } } else { // A full cell, with mixed materials. Vector3I voxelCoordInCell; MyVoxelContentCell newCell = null; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { var material = matCell.GetMaterial(ref voxelCoordInCell); if (material == materialIndex) { if (newCell == null) { newCell = new MyVoxelContentCell(); _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z] = newCell; } //newCell.SetVoxelContent(0x00, ref voxelCoordInCell); matCell.SetMaterialAndIndestructibleContent(replaceMaterialIndex, 0xff, ref voxelCoordInCell); } } } } } } else if (voxelCell.CellType == MyVoxelCellType.MIXED) { if (matCell.IsSingleMaterialForWholeCell) { if (matCell.SingleMaterial == materialIndex) { //voxelCell.SetToEmpty(); matCell.Reset(replaceMaterialIndex, 0xff); } } else { // A mixed cell, with mixed materials. Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { var material = matCell.GetMaterial(ref voxelCoordInCell); if (material == materialIndex) { //voxelCell.SetVoxelContent(0x00, ref voxelCoordInCell); matCell.SetMaterialAndIndestructibleContent(replaceMaterialIndex, 0xff, ref voxelCoordInCell); } } } } } } } } } }
public void RemoveContent() { Vector3I cellCoord; for (cellCoord.X = 0; cellCoord.X < _dataCellsCount.X; cellCoord.X++) { for (cellCoord.Y = 0; cellCoord.Y < _dataCellsCount.Y; cellCoord.Y++) { for (cellCoord.Z = 0; cellCoord.Z < _dataCellsCount.Z; cellCoord.Z++) { var voxelCell = _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z]; if (voxelCell == null) { var newCell = new MyVoxelContentCell(); _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z] = newCell; newCell.SetToEmpty(); } else if (voxelCell.CellType == MyVoxelCellType.MIXED) { // A mixed cell. Vector3I voxelCoordInCell; for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++) { for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++) { for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++) { voxelCell.SetVoxelContent(0x00, ref voxelCoordInCell); } } } } } } } }