<commit_before>package wraith.library.LWJGL.Voxel;

import java.util.ArrayList;
import wraith.library.LWJGL.Cube;
import wraith.library.LWJGL.Texture;

public class VoxelChunk{
	private boolean open;
	private int hidden = 4096;
	private final VoxelBlock[][][] blocks = new VoxelBlock[16][16][16];
	public final int chunkX, chunkY, chunkZ;
	public final int startX, startY, startZ, endX, endY, endZ;
	public final ArrayList<QuadBatch> batches = new ArrayList(1);
	private final VoxelWorld world;
	public VoxelChunk(VoxelWorld world, int chunkX, int chunkY, int chunkZ){
		this.world=world;
		this.chunkX=chunkX;
		this.chunkY=chunkY;
		this.chunkZ=chunkZ;
		startX=chunkX*16;
		startY=chunkY*16;
		startZ=chunkZ*16;
		endX=startX+15;
		endY=startY+15;
		endZ=startZ+15;
	}
	private VoxelBlock createBlock(int x, int y, int z, BlockType type){
		int xPart = x&15;
		int yPart = y&15;
		int zPart = z&15;
		blocks[xPart][yPart][zPart]=new VoxelBlock(this, x, y, z, type);
		removeHidden();
		return blocks[xPart][yPart][zPart];
	}
	public void optimize(){
		int x, y, z;
		for(x=0; x<16; x++)for(y=0; y<16; y++)for(z=0; z<16; z++)optimizeBlock(blocks[x][y][z]);
	}
	public void optimizeSide(int side){
		if(side==0){
			int y, z;
			for(y=0; y<16; y++)for(z=0; z<16; z++)optimizeBlock(blocks[15][y][z], 0);
		}
		if(side==1){
			int y, z;
			for(y=0; y<16; y++)for(z=0; z<16; z++)optimizeBlock(blocks[0][y][z], 1);
		}
		if(side==2){
			int x, z;
			for(x=0; x<16; x++)for(z=0; z<16; z++)optimizeBlock(blocks[x][15][z], 2);
		}
		if(side==3){
			int x, z;
			for(x=0; x<16; x++)for(z=0; z<16; z++)optimizeBlock(blocks[x][0][z], 3);
		}
		if(side==4){
			int x, y;
			for(x=0; x<16; x++)for(y=0; y<16; y++)optimizeBlock(blocks[x][y][15], 4);
		}
		if(side==5){
			int x, y;
			for(x=0; x<16; x++)for(y=0; y<16; y++)optimizeBlock(blocks[x][y][0], 5);
		}
	}
	public void optimizeBlock(VoxelBlock block){
		optimizeBlock(block, 0);
		optimizeBlock(block, 1);
		optimizeBlock(block, 2);
		optimizeBlock(block, 3);
		optimizeBlock(block, 4);
		optimizeBlock(block, 5);
	}
	private void optimizeBlock(VoxelBlock block, int side){
		if(block==null)return;
		open=isNeighborOpen(block, side);
		if(open!=block.isSideShown(side)){
			block.showSide(side, open);
			if(open)getBatch(block.getType().getTexture(side)).addQuad(Cube.generateQuad(side, block.x, block.y, block.z, block.getType().getRotation(side)));
			else getBatch(block.getType().getTexture(side)).removeQuad(Cube.generateQuad(side, block.x, block.y, block.z, block.getType().getRotation(side)));
		}
	}
	private void removeBlock(int x, int y, int z){
		if(blocks[x][y][z]==null)return;
		removeBlockQuads(blocks[x][y][z]);
		blocks[x][y][z]=null;
		VoxelChunk chunk;
		if(x>0)optimizeBlock(blocks[x-1][y][z], 0);
		else{
			chunk=world.getChunk(chunkX-1, chunkY, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[15][y][z], 0);
		}
		if(x<15)optimizeBlock(blocks[x+1][y][z], 1);
		else{
			chunk=world.getChunk(chunkX+1, chunkY, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[0][y][z], 1);
		}
		if(y>0)optimizeBlock(blocks[x][y-1][z], 2);
		else{
			chunk=world.getChunk(chunkX, chunkY-1, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][15][z], 2);
		}
		if(y<15)optimizeBlock(blocks[x][y+1][z], 3);
		else{
			chunk=world.getChunk(chunkX, chunkY+1, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][0][z], 3);
		}
		if(z>0)optimizeBlock(blocks[x][y][z-1], 4);
		else{
			chunk=world.getChunk(chunkX, chunkY, chunkZ-1, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][y][15], 4);
		}
		if(z<15)optimizeBlock(blocks[x][y][z+1], 5);
		else{
			chunk=world.getChunk(chunkX, chunkY, chunkZ+1, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][y][0], 5);
		}
	}
	public VoxelBlock setBlock(int x, int y, int z, BlockType type){
		removeBlock(x&15, y&15, z&15);
		if(type!=null)return createBlock(x, y, z, type);
		return null;
	}
	private boolean isNeighborOpen(VoxelBlock block, int side){
		if(side==0)return getQuickBlock(block.x+1, block.y, block.z)==null;
		if(side==1)return getQuickBlock(block.x-1, block.y, block.z)==null;
		if(side==2)return getQuickBlock(block.x, block.y+1, block.z)==null;
		if(side==3)return (world.hidesNegativeY()?block.y>0:true)&&getQuickBlock(block.x, block.y-1, block.z)==null;
		if(side==4)return getQuickBlock(block.x, block.y, block.z+1)==null;<commit_msg>Block optimizing is now done automatically.<commit_after>package wraith.library.LWJGL.Voxel;

import java.util.ArrayList;
import wraith.library.LWJGL.Cube;
import wraith.library.LWJGL.Texture;

public class VoxelChunk{
	private boolean open;
	private int hidden = 4096;
	private final VoxelBlock[][][] blocks = new VoxelBlock[16][16][16];
	public final int chunkX, chunkY, chunkZ;
	public final int startX, startY, startZ, endX, endY, endZ;
	public final ArrayList<QuadBatch> batches = new ArrayList(1);
	private final VoxelWorld world;
	public VoxelChunk(VoxelWorld world, int chunkX, int chunkY, int chunkZ){
		this.world=world;
		this.chunkX=chunkX;
		this.chunkY=chunkY;
		this.chunkZ=chunkZ;
		startX=chunkX*16;
		startY=chunkY*16;
		startZ=chunkZ*16;
		endX=startX+15;
		endY=startY+15;
		endZ=startZ+15;
	}
	private VoxelBlock createBlock(int x, int y, int z, BlockType type){
		int xPart = x&15;
		int yPart = y&15;
		int zPart = z&15;
		blocks[xPart][yPart][zPart]=new VoxelBlock(this, x, y, z, type);
		removeHidden();
		optimizeBlock(blocks[xPart][yPart][zPart]);
		return blocks[xPart][yPart][zPart];
	}
	public void optimize(){
		int x, y, z;
		for(x=0; x<16; x++)for(y=0; y<16; y++)for(z=0; z<16; z++)optimizeBlock(blocks[x][y][z]);
		world.setNeedsRebatch();
	}
	public void optimizeSide(int side){
		if(side==0){
			int y, z;
			for(y=0; y<16; y++)for(z=0; z<16; z++)optimizeBlock(blocks[15][y][z], 0);
		}
		if(side==1){
			int y, z;
			for(y=0; y<16; y++)for(z=0; z<16; z++)optimizeBlock(blocks[0][y][z], 1);
		}
		if(side==2){
			int x, z;
			for(x=0; x<16; x++)for(z=0; z<16; z++)optimizeBlock(blocks[x][15][z], 2);
		}
		if(side==3){
			int x, z;
			for(x=0; x<16; x++)for(z=0; z<16; z++)optimizeBlock(blocks[x][0][z], 3);
		}
		if(side==4){
			int x, y;
			for(x=0; x<16; x++)for(y=0; y<16; y++)optimizeBlock(blocks[x][y][15], 4);
		}
		if(side==5){
			int x, y;
			for(x=0; x<16; x++)for(y=0; y<16; y++)optimizeBlock(blocks[x][y][0], 5);
		}
		world.setNeedsRebatch();
	}
	public void optimizeBlock(VoxelBlock block){
		optimizeBlock(block, 0);
		optimizeBlock(block, 1);
		optimizeBlock(block, 2);
		optimizeBlock(block, 3);
		optimizeBlock(block, 4);
		optimizeBlock(block, 5);
		world.setNeedsRebatch();
	}
	private void optimizeBlock(VoxelBlock block, int side){
		if(block==null)return;
		open=isNeighborOpen(block, side);
		if(open!=block.isSideShown(side)){
			block.showSide(side, open);
			if(open)getBatch(block.getType().getTexture(side)).addQuad(Cube.generateQuad(side, block.x, block.y, block.z, block.getType().getRotation(side)));
			else getBatch(block.getType().getTexture(side)).removeQuad(Cube.generateQuad(side, block.x, block.y, block.z, block.getType().getRotation(side)));
		}
	}
	private void optimizeAroundBlock(int x, int y, int z){
		VoxelChunk chunk;
		if(x>0)optimizeBlock(blocks[x-1][y][z], 0);
		else{
			chunk=world.getChunk(chunkX-1, chunkY, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[15][y][z], 0);
		}
		if(x<15)optimizeBlock(blocks[x+1][y][z], 1);
		else{
			chunk=world.getChunk(chunkX+1, chunkY, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[0][y][z], 1);
		}
		if(y>0)optimizeBlock(blocks[x][y-1][z], 2);
		else{
			chunk=world.getChunk(chunkX, chunkY-1, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][15][z], 2);
		}
		if(y<15)optimizeBlock(blocks[x][y+1][z], 3);
		else{
			chunk=world.getChunk(chunkX, chunkY+1, chunkZ, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][0][z], 3);
		}
		if(z>0)optimizeBlock(blocks[x][y][z-1], 4);
		else{
			chunk=world.getChunk(chunkX, chunkY, chunkZ-1, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][y][15], 4);
		}
		if(z<15)optimizeBlock(blocks[x][y][z+1], 5);
		else{
			chunk=world.getChunk(chunkX, chunkY, chunkZ+1, false);
			if(chunk!=null)chunk.optimizeBlock(chunk.blocks[x][y][0], 5);
		}
	}
	private void removeBlock(int x, int y, int z){
		if(blocks[x][y][z]==null)return;
		removeBlockQuads(blocks[x][y][z]);
		blocks[x][y][z]=null;
	}
	public VoxelBlock setBlock(int x, int y, int z, BlockType type){
		int subX = x&15;
		int subY = y&15;
		int subZ = z&15;
		world.setNeedsRebatch();
		removeBlock(subX, subY, subZ);
		if(type!=null){
			VoxelBlock block = createBlock(x, y, z, type);
			optimizeBlock(block);
			optimizeAroundBlock(subX, subY, subZ);
			return block;
		}
		optimizeAroundBlock(subX, subY, subZ);
		return null;
	}
	private boolean isNeighborOpen(VoxelBlock block, int side){
		if(side==0)return getQuickBlock(block.x+1, block.y, block.z)==null;
		if(side==1)return getQuickBlock(block.x-1, block.y, block.z)==null;
		if(side==2)return getQuickBlock(block.x, block.y+1, block.z)==null;
		if(side==3)return (world.hidesNegativeY()?block.y>0:true)&&getQuickBlock(block.x, block.y-1, block.z)==null;
		if(side==4)return getQuickBlock(block.x, block.y, block.z+1)==null;
{'fraction_non_alphanumeric': 0.19625267665952892, 'fraction_numerical': 0.034261241970021415, 'mean_word_length': 5.495827538247566, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2273609', 'n_tokens_mistral': 4348, 'n_tokens_neox': 3927, 'n_words': 689}