package electrosphere.client.block; import java.io.File; import org.joml.Vector3d; import org.joml.Vector3i; import electrosphere.client.interact.select.AreaSelection; import electrosphere.engine.Globals; import electrosphere.game.data.block.BlockFab; /** * Class for selecting blocks on the client */ public class ClientBlockSelection { /** * Selects all blocks on the client */ public static void selectAllBlocks(){ Vector3d minPos = new Vector3d(); Vector3d maxPos = new Vector3d(); Vector3i minVoxelPos = new Vector3i(); Vector3i maxVoxelPos = new Vector3i(); Vector3i chunkPos = new Vector3i(); boolean encountered = false; for(int x = 0; x < Globals.clientWorldData.getWorldDiscreteSize(); x++){ for(int y = 0; y < Globals.clientWorldData.getWorldDiscreteSize(); y++){ for(int z = 0; z < Globals.clientWorldData.getWorldDiscreteSize(); z++){ chunkPos = new Vector3i(x,y,z); BlockChunkData blockChunkData = Globals.clientBlockManager.getChunkDataAtWorldPoint(chunkPos, 0); if(blockChunkData.getHomogenousValue() == BlockChunkData.BLOCK_TYPE_EMPTY){ continue; } boolean foundVoxel = false; for(int i = 0; i < BlockChunkData.CHUNK_DATA_WIDTH; i++){ for(int j = 0; j < BlockChunkData.CHUNK_DATA_WIDTH; j++){ for(int k = 0; k < BlockChunkData.CHUNK_DATA_WIDTH; k++){ if(blockChunkData.getType(i, j, k) == BlockChunkData.BLOCK_TYPE_EMPTY){ continue; } if(!foundVoxel){ foundVoxel = true; minVoxelPos.set(i,j,k); maxVoxelPos.set(i+1,j+1,k+1); } else { minVoxelPos.min(new Vector3i(i,j,k)); maxVoxelPos.max(new Vector3i(i+1,j+1,k+1)); } } } } Vector3d localMin = Globals.clientWorldData.convertBlockToRealSpace(chunkPos, minVoxelPos); Vector3d localMax = Globals.clientWorldData.convertBlockToRealSpace(chunkPos, maxVoxelPos); if(!encountered){ encountered = true; minPos.set(localMin); maxPos.set(localMax); } else { minPos.min(localMin); maxPos.max(localMax); } } } } AreaSelection selection = AreaSelection.createRect(minPos, maxPos); Globals.cursorState.selectRectangularArea(selection); } /** * Exports currently selected area of voxels */ public static void exportSelection(){ AreaSelection selection = Globals.cursorState.getAreaSelection(); Vector3i startChunk = Globals.clientWorldData.convertRealToWorldSpace(selection.getRectStart()); Vector3i endChunk = Globals.clientWorldData.convertRealToWorldSpace(selection.getRectEnd()); if(!startChunk.equals(endChunk)){ throw new Error("Unsupported case! Selected are coverts multiple chunks.. " + startChunk + " " + endChunk); } Vector3i blockStart = Globals.clientWorldData.convertRealToBlockSpace(selection.getRectStart()); Vector3i blockEnd = Globals.clientWorldData.convertRealToBlockSpace(selection.getRectEnd()); BlockChunkData chunk = Globals.clientBlockManager.getChunkDataAtWorldPoint(startChunk, 0); if(chunk == null){ throw new Error("Failed to grab chunk at " + startChunk); } int blockCount = (blockEnd.x - blockStart.x) * (blockEnd.y - blockStart.y) * (blockEnd.z - blockStart.z); short[] types = new short[blockCount]; short[] metadata = new short[blockCount]; int i = 0; for(int x = blockStart.x; x < blockEnd.x; x++){ for(int y = blockStart.y; y < blockEnd.y; y++){ for(int z = blockStart.z; z < blockEnd.z; z++){ types[i] = chunk.getType(x, y, z); metadata[i] = chunk.getMetadata(x, y, z); i++; } } } Vector3i dimensions = new Vector3i( (blockEnd.x - blockStart.x), (blockEnd.y - blockStart.y), (blockEnd.z - blockStart.z) ); BlockFab fab = BlockFab.create(dimensions, types, metadata); File exportLoc = new File("./assets/Data/fab/struct.block"); fab.save(exportLoc); } }