summaryrefslogtreecommitdiff
path: root/src/main/java/net/tylermurphy/Minecraft/Chunk/Chunk.java
blob: f9979e6438a3ad2f878e630f82d154b4136c8dd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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;
		});
	}
	
}