Renderer/src/main/java/electrosphere/client/block/ClientBlockSelection.java
austin 42e6e1aae8
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
minor block fab improvements
2025-04-26 11:18:35 -04:00

122 lines
4.8 KiB
Java

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);
}
}