package net.tylermurphy.Minecraft.Chunk; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import net.tylermurphy.Minecraft.Gen.WorldGenerator; import net.tylermurphy.Minecraft.Scene.Objects.Renderable; import net.tylermurphy.Minecraft.Scene.World; public class Chunk { private static final ExecutorService threadpool = Executors.newCachedThreadPool(); public final int gridX; public final int gridZ; public final int chunk_seed; public byte[][][] cubes; private Renderable chunkRenderable, transparentRenderable; private ChunkMesh chunkMesh, transparentChunkMesh; private final boolean generate; private boolean initialized = false; private boolean updating = true; private boolean scheduled = false; private int pendingUpdates = 0; public Chunk(int gridX, int gridZ, boolean generate) { this.gridX = gridX; this.gridZ = gridZ; this.generate = generate; this.chunk_seed = gridX * World.seed ^ gridZ; cubes = new byte[16][256][16]; } public boolean isSafe() { return initialized; } public Renderable renderable() { return chunkRenderable; } public void deleteRenderable(){ this.chunkRenderable = null; } public Renderable transparentRenderable(){ return transparentRenderable; } public void deleteTransparentRenderable(){ this.transparentRenderable = null; } public void scheduleFutureMeshUpdate(){ this.scheduled = true; } public boolean isScheduled(){ return scheduled; } public void updateMesh() { if(!initialized || updating){ pendingUpdates++; return; } chunkMesh = new ChunkMesh(); transparentChunkMesh = new ChunkMesh(); updating = true; scheduled = false; pendingUpdates--; threadpool.submit(() -> { chunkMesh.update(this, false); transparentChunkMesh.update(this, true); }); } public boolean loadMesh() { if(!initialized || !updating) return false; if(chunkMesh.completed && transparentChunkMesh.completed) { if(chunkRenderable != null && chunkRenderable.getMesh() != null) chunkRenderable.getMesh().delete(); chunkRenderable = chunkMesh.createChunkMesh(); chunkMesh = null; if(transparentRenderable != null && transparentRenderable.getMesh() != null) transparentRenderable.getMesh().delete(); transparentRenderable = transparentChunkMesh.createChunkMesh(); transparentChunkMesh = null; updating = false; if(pendingUpdates > 0) updateMesh(); return true; } return false; } public void initialize() { chunkMesh = new ChunkMesh(); transparentChunkMesh = new ChunkMesh(); threadpool.submit(() -> { if(generate) WorldGenerator.generate(this); chunkMesh.update(this, false); transparentChunkMesh.update(this, true); initialized = true; }); } }