aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/makamys/neodymium/renderer/NeoChunk.java
blob: c95b2bb889bd6340eaa452ab1bfa6b6d7beb77df (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
112
113
114
115
116
117
118
package makamys.neodymium.renderer;

import java.util.List;

import makamys.neodymium.Neodymium;
import net.minecraft.entity.Entity;

/** A container for the meshes that compose a chunk (16x256x16 region). It keeps track of which meshes should be made visible and which ones should not. */
public class NeoChunk {
	
	int x, z;
	int lod = 0;
	boolean visible;
	boolean dirty;
	NeoRegion region;
	
	ChunkMesh[] chunkMeshes = new ChunkMesh[32];
	
	public boolean[] isSectionVisible = new boolean[16];
	
	NeoRenderer renderer = Neodymium.renderer;
	
	public NeoChunk(int x, int z, NeoRegion region) {
		this.x = x;
		this.z = z;
		this.region = region;
	}
	
	@Override
	public String toString() {
		return "NeoChunk(" + x + ", " + z + ")";
	}
	
	public double distSq(Entity entity) {
		return Math.pow(entity.posX - x * 16, 2) + Math.pow(entity.posZ - z * 16, 2);
	}
	
	public void putChunkMeshes(int cy, List<ChunkMesh> newChunkMeshes) {
		for(int i = 0; i < 2; i++) {
		    ChunkMesh newChunkMesh = newChunkMeshes.size() > i ? newChunkMeshes.get(i) : null;
		    if(chunkMeshes[cy * 2 + i] != null) {
			    if(newChunkMesh != null) {
			        // ??? why is this needed?
	                newChunkMesh.pass = i;
			    }
			    
			    renderer.removeMesh(chunkMeshes[cy * 2 + i]);
			    chunkMeshes[cy * 2 + i].destroy();
			} else {
			    region.meshes++;
			}
		    chunkMeshes[cy * 2 + i] = newChunkMesh;
		}
		Neodymium.renderer.neoChunkChanged(this);
		dirty = true;
	}
	
	public boolean hasChunkMeshes() {
		for(ChunkMesh cm : chunkMeshes) {
			if(cm != null) {
				return true;
			}
		}
		return false;
	}
	
	public void tick() {
        setLOD(2);
	}
	
   public void setLOD(int lod) {
        if(lod == this.lod) return;
        
        this.lod = lod;
        Neodymium.renderer.neoChunkChanged(this);
        if(!dirty) {
            if(lod < 2) {
                for(int i = 0; i < chunkMeshes.length; i++) {
                    if(chunkMeshes[i] != null) {
                        chunkMeshes[i].destroy();
                        chunkMeshes[i] = null;
                        region.meshes--;
                    }
                }
            }
        }
    }
   
	public void destroy() {
	    for(ChunkMesh cm: chunkMeshes) {
	        if(cm != null) {
	            cm.destroy();
	            region.meshes--;
	        }
	    }
	    Neodymium.renderer.setVisible(this, false);
	}
	
	public boolean isFullyVisible() {
	    if(!visible) return false;
	    for(boolean b : isSectionVisible) {
	        if(!b) {
	            return false;
	        }
	    }
	    return true;
	}
	
    public boolean isEmpty() {
        for(ChunkMesh cm: chunkMeshes) {
            if(cm != null) {
                return false;
            }
        }
        return true;
    }
	
}