package net.tylermurphy.Minecraft.Chunk; import static net.tylermurphy.Minecraft.Chunk.Cube.*; import java.util.ArrayList; import java.util.List; import net.tylermurphy.Minecraft.Scene.Objects.Transform; import org.json.JSONArray; import org.json.JSONObject; import org.joml.Vector2f; import org.joml.Vector3f; import net.tylermurphy.Minecraft.Render.Data.Mesh; import net.tylermurphy.Minecraft.Scene.World; import net.tylermurphy.Minecraft.Scene.Objects.Renderable; public class ChunkMesh { private List verticies; private List tranaparentVerticies; private List positionsList; private List normalsList; private List tcsList; private List lightingList; private List layerList; public float[] positions, tcs, normals, lighting, layers; private Chunk chunk; private boolean transparent; public boolean completed = false; public void update(Chunk chunk, boolean transparent) { this.chunk = chunk; this.transparent = transparent; this.completed = false; verticies = new ArrayList<>(); tranaparentVerticies = new ArrayList<>(); positionsList = new ArrayList<>(); normalsList = new ArrayList<>(); tcsList = new ArrayList<>(); lightingList = new ArrayList<>(); layerList = new ArrayList<>(); buildMesh(); populateLists(); this.completed = true; } private void buildMesh() { for(int x=0;x<16;x++) { for(int y=0; y<256; y++) { for(int z=0; z<16; z++) { if(chunk.cubes[x][y][z] == AIR) continue; if(getBlock(chunk.cubes[x][y][z]).transparent != transparent) continue; boolean px = true, nx = true, py = true, ny = true, pz = true, nz = true; if(x<15) px = chunk.cubes[x + 1][y][z] != AIR && transparentCheck(x + 1, y, z, x, y, z); else px = getCube(chunk.gridX + 1, chunk.gridZ, 0, y, z) != AIR && transparentCheck(getCube(chunk.gridX + 1, chunk.gridZ, 0, y, z), x, y, z); if(x>0) nx = chunk.cubes[x - 1][y][z] != AIR && transparentCheck(x - 1, y, z, x, y, z); else nx = getCube(chunk.gridX - 1, chunk.gridZ, 15, y, z) != AIR && transparentCheck(getCube(chunk.gridX - 1, chunk.gridZ, 15, y, z), x, y, z); if(y<255) py = chunk.cubes[x][y + 1][z] != AIR && transparentCheck(x, y + 1, z, x, y, z); if(y>0) ny = chunk.cubes[x][y - 1][z] != AIR && transparentCheck(x, y - 1, z, x, y, z); if(z<15) pz = chunk.cubes[x][y][z + 1] != AIR && transparentCheck(x, y, z + 1, x, y, z); else pz = getCube(chunk.gridX, chunk.gridZ + 1, x, y, 0) != AIR && transparentCheck(getCube(chunk.gridX, chunk.gridZ + 1, x, y, 0), x, y, z); if(z>0) nz = chunk.cubes[x][y][z - 1] != AIR && transparentCheck(x, y, z - 1, x, y, z); else nz = getCube(chunk.gridX, chunk.gridZ - 1, x, y, 15) != AIR && transparentCheck(getCube(chunk.gridX, chunk.gridZ - 1, x, y, 15), x, y, z); JSONObject positions = getBlock(chunk.cubes[x][y][z]).positions; if(chunk.cubes[x][y][z]==17 && ( y==255 || chunk.cubes[x][y+1][z] != 17 )) { if(y<255) { byte xp,xn,zp,zn; if(x<15) xp = chunk.cubes[x+1][y+1][z]; else xp = getCube(chunk.gridX+1,chunk.gridZ,0,y+1,z); if(x<0) xn = chunk.cubes[x-1][y+1][z]; else xn = getCube(chunk.gridX-1,chunk.gridZ,15,y+1,z); if(z<15) zp = chunk.cubes[x][y+1][z+1]; else zp = getCube(chunk.gridX,chunk.gridZ+1,x,y+1,0); if(z<0) zn = chunk.cubes[x][y+1][z-1]; else zn = getCube(chunk.gridX,chunk.gridZ-1,x,y+1,15); if(xp != 17 && xn != 17 && zp != 17 && zn != 17) { positions = models.get("water"); py = false; } } else { positions = models.get("water"); py = false; } } if(getBlock(chunk.cubes[x][y][z]).transparent && chunk.cubes[x][y][z] != 17 && (y == 0 || chunk.cubes[x][y-1][z] == 17)) { ny = false; } JSONArray PX_POS = positions.getJSONArray("PX_POS"); JSONArray NX_POS = positions.getJSONArray("NX_POS"); JSONArray PY_POS = positions.getJSONArray("PY_POS"); JSONArray NY_POS = positions.getJSONArray("NY_POS"); JSONArray PZ_POS = positions.getJSONArray("PZ_POS"); JSONArray NZ_POS = positions.getJSONArray("NZ_POS"); if(!px) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) PX_POS.getJSONArray(i).getDouble(0) + x, (float) PX_POS.getJSONArray(i).getDouble(1) + y, (float) PX_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_px, .9f)); } } if(!nx) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) NX_POS.getJSONArray(i).getDouble(0) + x, (float) NX_POS.getJSONArray(i).getDouble(1) + y, (float) NX_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_nx, .9f)); } } if(!py) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) PY_POS.getJSONArray(i).getDouble(0) + x, (float) PY_POS.getJSONArray(i).getDouble(1) + y, (float) PY_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_py, 1f)); } } if(!ny) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) NY_POS.getJSONArray(i).getDouble(0) + x, (float) NY_POS.getJSONArray(i).getDouble(1) + y, (float) NY_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_ny, 1f)); } } if(!pz) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) PZ_POS.getJSONArray(i).getDouble(0) + x, (float) PZ_POS.getJSONArray(i).getDouble(1) + y, (float) PZ_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_pz, .8f)); } } if(!nz) { for(int i=0;i<6;i++) { verticies.add(new Vertex(new Vector3f((float) NZ_POS.getJSONArray(i).getDouble(0) + x, (float) NZ_POS.getJSONArray(i).getDouble(1) + y, (float) NZ_POS.getJSONArray(i).getDouble(2) + z), TEXTURE_CORDS[i], NORMALS[i], getBlock(chunk.cubes[x][y][z]).tex_nz, .8f)); } } } } } } private byte getCube(int gx, int gz, int x, int y, int z) { Chunk c = World.getChunk(gx,gz); if(c == null) return 0; return c.cubes[x][y][z]; } private boolean transparentCheck(int x1,int y1,int z1,int x2,int y2,int z2) { return transparentCheck(chunk.cubes[x1][y1][z1], x2, y2, z2); } private boolean transparentCheck(byte block,int x2,int y2,int z2) { if(getBlock(block).alwaysRenderNeighbors || getBlock(chunk.cubes[x2][y2][z2]).alwaysRenderNeighbors) return false; else if(!getBlock(block).transparent && !getBlock(chunk.cubes[x2][y2][z2]).transparent && block == chunk.cubes[x2][y2][z2]) return true; else return getBlock(block).transparent == getBlock(chunk.cubes[x2][y2][z2]).transparent || !getBlock(block).transparent; } static class Vertex{ Vector3f positions; Vector2f uvs; Vector3f normals; float light; float layer; Vertex(Vector3f positions, Vector2f uvs, Vector3f normals, float layer, float light){ this.positions = positions; this.uvs = uvs; this.normals = normals; this.layer = layer; this.light = light; } } private void populateLists() { for(Vertex vertex : verticies) { positionsList.add(vertex.positions.x); positionsList.add(vertex.positions.y); positionsList.add(vertex.positions.z); tcsList.add(vertex.uvs.x); tcsList.add(vertex.uvs.y); normalsList.add(vertex.normals.x); normalsList.add(vertex.normals.y); normalsList.add(vertex.normals.z); lightingList.add(vertex.light); layerList.add(vertex.layer); } positions = new float[positionsList.size()]; tcs = new float[tcsList.size()]; normals = new float[normalsList.size()]; lighting = new float[lightingList.size()]; layers = new float[layerList.size()]; for(int i=0;i